diff --git a/.vscode/settings.json b/.vscode/settings.json index 21976e68..3ef6b860 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,5 +12,6 @@ }, "search.exclude": { "**/CHANGELOG.md": true - } -} \ No newline at end of file + }, + "js/ts.preferences.autoImportSpecifierExcludeRegexes": ["^@mui/[^/]+$"] +} diff --git a/common/changes/@itwin/imodel-browser-react/alex-imodelgrid-mui_2026-05-20-18-54.json b/common/changes/@itwin/imodel-browser-react/alex-imodelgrid-mui_2026-05-20-18-54.json new file mode 100644 index 00000000..4e4b6b1e --- /dev/null +++ b/common/changes/@itwin/imodel-browser-react/alex-imodelgrid-mui_2026-05-20-18-54.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@itwin/imodel-browser-react", + "comment": "Add Stratakit MUI components", + "type": "patch" + } + ], + "packageName": "@itwin/imodel-browser-react" +} \ No newline at end of file diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index f116945c..f3a051df 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -27,6 +27,9 @@ importers: '@itwin/itwinui-react': ^3.19.4 '@itwin/manage-versions-react': workspace:* '@itwin/storybook-auth-addon': workspace:* + '@mui/material': ~9.0.0 + '@mui/system': ~9.0.0 + '@mui/x-data-grid': ~9.3.0 '@storybook/addon-actions': ^6.5.16 '@storybook/addon-essentials': ^6.5.16 '@storybook/addon-links': ^6.5.16 @@ -37,6 +40,8 @@ importers: '@storybook/manager-webpack5': 6.5.16 '@storybook/react': ^6.5.16 '@storybook/theming': ^6.5.16 + '@stratakit/icons': ~0.3.1 + '@stratakit/mui': ~0.4.1 '@types/react': ^18.3.5 '@types/react-dom': ^18.3.0 '@typescript-eslint/eslint-plugin': ^8.0.0 @@ -78,6 +83,9 @@ importers: '@itwin/itwinui-react': 3.19.4_nnrd3gsncyragczmpvfhocinkq '@itwin/manage-versions-react': link:../../modules/manage-versions '@itwin/storybook-auth-addon': link:../../modules/storybook-auth-addon + '@mui/material': 9.0.1_27kzlijtntas6645qwojwuhdba + '@mui/system': 9.0.1_po4keleilqsm4vrhgxl2cr46aq + '@mui/x-data-grid': 9.3.0_7mpntgkhpya3s3ktsfitjpkb5y '@storybook/addon-actions': 6.5.16_nnrd3gsncyragczmpvfhocinkq '@storybook/addon-essentials': 6.5.16_3nj36ocnb77sx7pc4wrjalbxna '@storybook/addon-links': 6.5.16_nnrd3gsncyragczmpvfhocinkq @@ -88,10 +96,12 @@ importers: '@storybook/manager-webpack5': 6.5.16_6tjimmjzcbmasp2nih2m2kqyle '@storybook/react': 6.5.16_6qtonf5fhtqumudu64uc6l3exq '@storybook/theming': 6.5.16_nnrd3gsncyragczmpvfhocinkq + '@stratakit/icons': 0.3.2 + '@stratakit/mui': 0.4.2_khtwlpggtuvdxv4ufkxjwosrqm '@types/react': 18.3.20 '@types/react-dom': 18.3.6_@types+react@18.3.20 - '@typescript-eslint/eslint-plugin': 8.60.0_wwcgi2ygslsxsvl5y42wqbwvpa - '@typescript-eslint/parser': 8.60.0_c3chdd2it6hsjvbnyur5kul6oq + '@typescript-eslint/eslint-plugin': 8.59.3_tcraa7oljkxsvwn3lqv4kf3bzu + '@typescript-eslint/parser': 8.59.3_c3chdd2it6hsjvbnyur5kul6oq babel-eslint: 10.1.0_eslint@8.57.1 babel-loader: 8.4.1_x2b7la4oj7v77gkgnuhuzjngny css-loader: 6.11.0_webpack@5.99.5 @@ -161,8 +171,8 @@ importers: '@types/jest': 29.5.14 '@types/node': 14.18.63 '@types/react': 18.3.20 - '@typescript-eslint/eslint-plugin': 8.60.0_wwcgi2ygslsxsvl5y42wqbwvpa - '@typescript-eslint/parser': 8.60.0_c3chdd2it6hsjvbnyur5kul6oq + '@typescript-eslint/eslint-plugin': 8.59.3_tcraa7oljkxsvwn3lqv4kf3bzu + '@typescript-eslint/parser': 8.59.3_c3chdd2it6hsjvbnyur5kul6oq eslint: 8.57.1 eslint-config-airbnb: 0.0.4 eslint-config-prettier: 6.15.0_eslint@8.57.1 @@ -185,7 +195,7 @@ importers: rollup-plugin-terser: 7.0.2_rollup@2.79.2 rollup-plugin-typescript2: 0.37.0_tagg7wrwek5xwloewiroaieqza sass: 1.86.3 - ts-jest: 29.4.11_icsvk6wcbjq6ogk6vm4vlhytde + ts-jest: 29.4.9_icsvk6wcbjq6ogk6vm4vlhytde tslib: 2.8.1 typescript: 6.0.3 @@ -236,8 +246,8 @@ importers: '@types/jest': 29.5.14 '@types/node': 14.18.63 '@types/react': 18.3.20 - '@typescript-eslint/eslint-plugin': 8.60.0_wwcgi2ygslsxsvl5y42wqbwvpa - '@typescript-eslint/parser': 8.60.0_c3chdd2it6hsjvbnyur5kul6oq + '@typescript-eslint/eslint-plugin': 8.59.3_tcraa7oljkxsvwn3lqv4kf3bzu + '@typescript-eslint/parser': 8.59.3_c3chdd2it6hsjvbnyur5kul6oq eslint: 8.57.1 eslint-config-airbnb: 0.0.4 eslint-config-prettier: 6.15.0_eslint@8.57.1 @@ -260,7 +270,7 @@ importers: rollup-plugin-terser: 7.0.2_rollup@2.79.2 rollup-plugin-typescript2: 0.37.0_tagg7wrwek5xwloewiroaieqza sass: 1.86.3 - ts-jest: 29.4.11_icsvk6wcbjq6ogk6vm4vlhytde + ts-jest: 29.4.9_icsvk6wcbjq6ogk6vm4vlhytde tslib: 2.8.1 typescript: 6.0.3 @@ -311,8 +321,8 @@ importers: '@types/jest': 29.5.14 '@types/node': 14.18.63 '@types/react': 18.3.20 - '@typescript-eslint/eslint-plugin': 8.60.0_wwcgi2ygslsxsvl5y42wqbwvpa - '@typescript-eslint/parser': 8.60.0_c3chdd2it6hsjvbnyur5kul6oq + '@typescript-eslint/eslint-plugin': 8.59.3_tcraa7oljkxsvwn3lqv4kf3bzu + '@typescript-eslint/parser': 8.59.3_c3chdd2it6hsjvbnyur5kul6oq eslint: 8.57.1 eslint-config-airbnb: 0.0.4 eslint-config-prettier: 6.15.0_eslint@8.57.1 @@ -335,7 +345,7 @@ importers: rollup-plugin-terser: 7.0.2_rollup@2.79.2 rollup-plugin-typescript2: 0.37.0_tagg7wrwek5xwloewiroaieqza sass: 1.86.3 - ts-jest: 29.4.11_icsvk6wcbjq6ogk6vm4vlhytde + ts-jest: 29.4.9_icsvk6wcbjq6ogk6vm4vlhytde tslib: 2.8.1 typescript: 6.0.3 @@ -343,8 +353,13 @@ importers: specifiers: '@itwin/itwinui-icons-react': ^2.9.0 '@itwin/itwinui-react': ^3.19.4 + '@mui/material': ^9.0.0 + '@mui/system': ^9.0.0 + '@mui/x-data-grid': ^9.3.0 '@rollup/plugin-commonjs': ~17.1.0 '@rollup/plugin-url': ^8.0.1 + '@stratakit/icons': ^0.3.1 + '@stratakit/mui': ^0.4.1 '@svgr/rollup': ^5.5.0 '@testing-library/jest-dom': ^6.6.3 '@testing-library/react': ^11.1.0 @@ -397,8 +412,13 @@ importers: react-intersection-observer: 8.34.0_react@18.3.1 devDependencies: '@itwin/itwinui-react': 3.19.4_nnrd3gsncyragczmpvfhocinkq + '@mui/material': 9.0.1_27kzlijtntas6645qwojwuhdba + '@mui/system': 9.0.1_po4keleilqsm4vrhgxl2cr46aq + '@mui/x-data-grid': 9.3.0_7mpntgkhpya3s3ktsfitjpkb5y '@rollup/plugin-commonjs': 17.1.0_rollup@2.79.2 '@rollup/plugin-url': 8.0.2_rollup@2.79.2 + '@stratakit/icons': 0.3.2 + '@stratakit/mui': 0.4.2_khtwlpggtuvdxv4ufkxjwosrqm '@svgr/rollup': 5.5.0 '@testing-library/jest-dom': 6.6.3 '@testing-library/react': 11.2.7_nnrd3gsncyragczmpvfhocinkq @@ -407,8 +427,8 @@ importers: '@types/react': 18.3.20 '@types/react-dom': 18.3.6_@types+react@18.3.20 '@types/react-table': 7.7.20 - '@typescript-eslint/eslint-plugin': 8.60.0_wwcgi2ygslsxsvl5y42wqbwvpa - '@typescript-eslint/parser': 8.60.0_c3chdd2it6hsjvbnyur5kul6oq + '@typescript-eslint/eslint-plugin': 8.59.3_tcraa7oljkxsvwn3lqv4kf3bzu + '@typescript-eslint/parser': 8.59.3_c3chdd2it6hsjvbnyur5kul6oq babel-eslint: 10.1.0_eslint@8.57.1 eslint: 8.57.1 eslint-config-airbnb: 0.0.4 @@ -440,7 +460,7 @@ importers: stylelint-config-sass-guidelines: 7.1.0_stylelint@13.13.1 stylelint-prettier: 1.2.0_fca2x6gd5fv7ftj4befheae2b4 stylelint-scss: 3.21.0_stylelint@13.13.1 - ts-jest: 29.4.11_icsvk6wcbjq6ogk6vm4vlhytde + ts-jest: 29.4.9_icsvk6wcbjq6ogk6vm4vlhytde tslib: 2.8.1 typescript: 6.0.3 @@ -497,8 +517,8 @@ importers: '@types/react': 18.3.20 '@types/react-dom': 18.3.6_@types+react@18.3.20 '@types/react-table': 7.7.20 - '@typescript-eslint/eslint-plugin': 8.60.0_wwcgi2ygslsxsvl5y42wqbwvpa - '@typescript-eslint/parser': 8.60.0_c3chdd2it6hsjvbnyur5kul6oq + '@typescript-eslint/eslint-plugin': 8.59.3_tcraa7oljkxsvwn3lqv4kf3bzu + '@typescript-eslint/parser': 8.59.3_c3chdd2it6hsjvbnyur5kul6oq eslint: 8.57.1 eslint-config-airbnb: 0.0.4 eslint-config-prettier: 6.15.0_eslint@8.57.1 @@ -521,7 +541,7 @@ importers: rollup-plugin-terser: 7.0.2_rollup@2.79.2 rollup-plugin-typescript2: 0.37.0_tagg7wrwek5xwloewiroaieqza sass: 1.86.3 - ts-jest: 29.4.11_icsvk6wcbjq6ogk6vm4vlhytde + ts-jest: 29.4.9_icsvk6wcbjq6ogk6vm4vlhytde tslib: 2.8.1 typescript: 6.0.3 @@ -561,8 +581,8 @@ importers: '@bentley/itwin-client': 2.11.0_7u5scf6prkfxf3zwbn37h5tfme '@types/react': 18.3.20 '@types/react-dom': 18.3.6_@types+react@18.3.20 - '@typescript-eslint/eslint-plugin': 8.60.0_wwcgi2ygslsxsvl5y42wqbwvpa - '@typescript-eslint/parser': 8.60.0_c3chdd2it6hsjvbnyur5kul6oq + '@typescript-eslint/eslint-plugin': 8.59.3_tcraa7oljkxsvwn3lqv4kf3bzu + '@typescript-eslint/parser': 8.59.3_c3chdd2it6hsjvbnyur5kul6oq esbuild: 0.25.12 eslint: 8.57.1 eslint-config-airbnb: 0.0.4 @@ -601,8 +621,8 @@ importers: stylelint-scss: ^3.18.0 typescript: ~6.0.3 devDependencies: - '@typescript-eslint/eslint-plugin': 8.60.0_wwcgi2ygslsxsvl5y42wqbwvpa - '@typescript-eslint/parser': 8.60.0_c3chdd2it6hsjvbnyur5kul6oq + '@typescript-eslint/eslint-plugin': 8.59.3_tcraa7oljkxsvwn3lqv4kf3bzu + '@typescript-eslint/parser': 8.59.3_c3chdd2it6hsjvbnyur5kul6oq babel-eslint: 10.1.0_eslint@8.57.1 eslint: 8.57.1 eslint-config-airbnb: 0.0.4 @@ -636,6 +656,34 @@ packages: '@jridgewell/trace-mapping': 0.3.25 dev: true + /@ariakit/core/0.4.20: + resolution: {integrity: sha512-DJbUnui0fM+2ZgiWLOMuFOmlWSJDNV3f6tqghIYRTWEm51TN/LoU6uM8og6/g7Nrwl4Uo5l8AoQT9Kkr/i/uRg==} + dev: true + + /@ariakit/react-core/0.4.26_nnrd3gsncyragczmpvfhocinkq: + resolution: {integrity: sha512-/Peh1KiVpjj79nCJIa6lEdzSTT9P9FZoy+CxByIFKL3YKdlXmDIIhS1E/tAqKbDq4ODVdynnqmrIDxE5wCoZYw==} + peerDependencies: + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + dependencies: + '@ariakit/core': 0.4.20 + '@floating-ui/dom': 1.7.4 + react: 18.3.1 + react-dom: 18.3.1_react@18.3.1 + use-sync-external-store: 1.6.0_react@18.3.1 + dev: true + + /@ariakit/react/0.4.26_nnrd3gsncyragczmpvfhocinkq: + resolution: {integrity: sha512-NcoPrYE4vgwyODAhdpNNuA7ldwODDuFqZl6jORPVDY3l+oRjl/OYwtQyyC3ZhC/4mjntYBYuKKrPJEizLmoxpg==} + peerDependencies: + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + dependencies: + '@ariakit/react-core': 0.4.26_nnrd3gsncyragczmpvfhocinkq + react: 18.3.1 + react-dom: 18.3.1_react@18.3.1 + dev: true + /@babel/code-frame/7.26.2: resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} @@ -2179,6 +2227,11 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.1 + dev: true + + /@babel/runtime/7.29.2: + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} /@babel/template/7.27.0: resolution: {integrity: sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==} @@ -2272,6 +2325,128 @@ packages: engines: {node: '>=10.0.0'} dev: true + /@emotion/babel-plugin/11.13.5: + resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} + dependencies: + '@babel/helper-module-imports': 7.25.9 + '@babel/runtime': 7.29.2 + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/serialize': 1.3.3 + babel-plugin-macros: 3.1.0 + convert-source-map: 1.9.0 + escape-string-regexp: 4.0.0 + find-root: 1.1.0 + source-map: 0.5.7 + stylis: 4.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@emotion/cache/11.14.0: + resolution: {integrity: sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==} + dependencies: + '@emotion/memoize': 0.9.0 + '@emotion/sheet': 1.4.0 + '@emotion/utils': 1.4.2 + '@emotion/weak-memoize': 0.4.0 + stylis: 4.2.0 + dev: true + + /@emotion/hash/0.9.2: + resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} + dev: true + + /@emotion/is-prop-valid/1.4.0: + resolution: {integrity: sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==} + dependencies: + '@emotion/memoize': 0.9.0 + dev: true + + /@emotion/memoize/0.9.0: + resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} + dev: true + + /@emotion/react/11.14.0_po4keleilqsm4vrhgxl2cr46aq: + resolution: {integrity: sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==} + peerDependencies: + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.29.2 + '@emotion/babel-plugin': 11.13.5 + '@emotion/cache': 11.14.0 + '@emotion/serialize': 1.3.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0_react@18.3.1 + '@emotion/utils': 1.4.2 + '@emotion/weak-memoize': 0.4.0 + '@types/react': 18.3.20 + hoist-non-react-statics: 3.3.2 + react: 18.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@emotion/serialize/1.3.3: + resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==} + dependencies: + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/unitless': 0.10.0 + '@emotion/utils': 1.4.2 + csstype: 3.2.3 + dev: true + + /@emotion/sheet/1.4.0: + resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} + dev: true + + /@emotion/styled/11.14.1_46x4ncsoxvhgfjfiir5bhnd67y: + resolution: {integrity: sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==} + peerDependencies: + '@emotion/react': ^11.0.0-rc.0 + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.29.2 + '@emotion/babel-plugin': 11.13.5 + '@emotion/is-prop-valid': 1.4.0 + '@emotion/react': 11.14.0_po4keleilqsm4vrhgxl2cr46aq + '@emotion/serialize': 1.3.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0_react@18.3.1 + '@emotion/utils': 1.4.2 + '@types/react': 18.3.20 + react: 18.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@emotion/unitless/0.10.0: + resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==} + dev: true + + /@emotion/use-insertion-effect-with-fallbacks/1.2.0_react@18.3.1: + resolution: {integrity: sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==} + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 18.3.1 + dev: true + + /@emotion/utils/1.4.2: + resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==} + dev: true + + /@emotion/weak-memoize/0.4.0: + resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} + dev: true + /@esbuild/aix-ppc64/0.25.12: resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} engines: {node: '>=18'} @@ -2952,7 +3127,7 @@ packages: '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 '@types/node': 14.18.63 - '@types/yargs': 17.0.35 + '@types/yargs': 17.0.33 chalk: 4.1.2 dev: true @@ -3046,6 +3221,228 @@ packages: set-cookie-parser: 2.7.1 dev: true + /@mui/core-downloads-tracker/9.0.1: + resolution: {integrity: sha512-GzamIIhZ1bH77dq7eKaeyRgJdkypsxin4jBFq2EMs4lBWRR0LFO1CSVMsoebn/VvjcNrnrOrjy48MkrkQUK2iw==} + dev: true + + /@mui/material/9.0.1_27kzlijtntas6645qwojwuhdba: + resolution: {integrity: sha512-voyCpeUxcSWLN7KPZuq0pGCIt726T9K6kiVM3XUcywZDAlZSarLHaUxJVQpospbjjOzN53hwyjo8s6KoWl6utw==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@mui/material-pigment-css': ^9.0.1 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@mui/material-pigment-css': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.29.2 + '@mui/core-downloads-tracker': 9.0.1 + '@mui/system': 9.0.1_po4keleilqsm4vrhgxl2cr46aq + '@mui/types': 9.0.0_@types+react@18.3.20 + '@mui/utils': 9.0.1_po4keleilqsm4vrhgxl2cr46aq + '@popperjs/core': 2.11.8 + '@types/react': 18.3.20 + '@types/react-transition-group': 4.4.12_@types+react@18.3.20 + clsx: 2.1.1 + csstype: 3.2.3 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1_react@18.3.1 + react-is: 19.2.6 + react-transition-group: 4.4.5_nnrd3gsncyragczmpvfhocinkq + dev: true + + /@mui/private-theming/9.0.1_po4keleilqsm4vrhgxl2cr46aq: + resolution: {integrity: sha512-pSIGq4Yw749KHEwlkYZWVERgHgwJELP6ODtBNUfV8V4oIb5H+h7IQDFXuk/b2oQccODK1enJAtiEzlgLZmq+8g==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.29.2 + '@mui/utils': 9.0.1_po4keleilqsm4vrhgxl2cr46aq + '@types/react': 18.3.20 + prop-types: 15.8.1 + react: 18.3.1 + dev: true + + /@mui/styled-engine/9.0.0_react@18.3.1: + resolution: {integrity: sha512-9RLGdX4Jg0aQPRuvqh/OLzYSPlgd5zyEw5/1HIRfdavSiOd03WtUaGZH9/w1RoTYuRKwpgy0hpIFaMHIqPVIWg==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.4.1 + '@emotion/styled': ^11.3.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + dependencies: + '@babel/runtime': 7.29.2 + '@emotion/cache': 11.14.0 + '@emotion/serialize': 1.3.3 + '@emotion/sheet': 1.4.0 + csstype: 3.2.3 + prop-types: 15.8.1 + react: 18.3.1 + dev: true + + /@mui/system/9.0.1_po4keleilqsm4vrhgxl2cr46aq: + resolution: {integrity: sha512-WvlioaLxk6ewUIOfh0StxUvOPDS1mCfzaulcudsL1brZNXuh0N9FMk7RpH7ImJKjEz412SEy/V/yvqmtxbqxCQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.29.2 + '@mui/private-theming': 9.0.1_po4keleilqsm4vrhgxl2cr46aq + '@mui/styled-engine': 9.0.0_react@18.3.1 + '@mui/types': 9.0.0_@types+react@18.3.20 + '@mui/utils': 9.0.1_po4keleilqsm4vrhgxl2cr46aq + '@types/react': 18.3.20 + clsx: 2.1.1 + csstype: 3.2.3 + prop-types: 15.8.1 + react: 18.3.1 + dev: true + + /@mui/types/9.0.0_@types+react@18.3.20: + resolution: {integrity: sha512-i1cuFCAWN44b3AJWO7mh7tuh1sqbQSeVr/94oG0TX5uXivac8XalgE4/6fQZcmGZigzbQ35IXxj/4jLpRIBYZg==} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.29.2 + '@types/react': 18.3.20 + dev: true + + /@mui/utils/9.0.0_po4keleilqsm4vrhgxl2cr46aq: + resolution: {integrity: sha512-bQcqyg/gjULUqTuyUjSAFr6LQGLvtkNtDbJerAtoUn9kGZ0hg5QJiN1PLHMLbeFpe3te1831uq7GFl2ITokGdg==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.29.2 + '@mui/types': 9.0.0_@types+react@18.3.20 + '@types/prop-types': 15.7.15 + '@types/react': 18.3.20 + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.3.1 + react-is: 19.2.6 + dev: true + + /@mui/utils/9.0.1_po4keleilqsm4vrhgxl2cr46aq: + resolution: {integrity: sha512-f3UO3jNN1pYg5zxqXC81Bvv8hx5ACcYc0387382ZI7M5ono1heIwHYLrKsz85myguWdeVKPRZGmDdynWUBjK2g==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.29.2 + '@mui/types': 9.0.0_@types+react@18.3.20 + '@types/prop-types': 15.7.15 + '@types/react': 18.3.20 + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.3.1 + react-is: 19.2.6 + dev: true + + /@mui/x-data-grid/9.3.0_7mpntgkhpya3s3ktsfitjpkb5y: + resolution: {integrity: sha512-MWzp4YH4iFFG6H1M6r9zqQhPYGA74noekxi/RxS+Gr3w/jHshNAVJECwjgMazQUwtnO/Pwx0TA/grzmj1Wzamg==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.9.0 + '@emotion/styled': ^11.8.1 + '@mui/material': ^7.3.0 || ^9.0.0 + '@mui/system': ^7.3.0 || ^9.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + dependencies: + '@babel/runtime': 7.29.2 + '@mui/material': 9.0.1_27kzlijtntas6645qwojwuhdba + '@mui/system': 9.0.1_po4keleilqsm4vrhgxl2cr46aq + '@mui/utils': 9.0.1_po4keleilqsm4vrhgxl2cr46aq + '@mui/x-internals': 9.1.0_po4keleilqsm4vrhgxl2cr46aq + '@mui/x-virtualizer': 9.0.0-alpha.7_27kzlijtntas6645qwojwuhdba + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1_react@18.3.1 + use-sync-external-store: 1.6.0_react@18.3.1 + transitivePeerDependencies: + - '@types/react' + dev: true + + /@mui/x-internals/9.1.0_po4keleilqsm4vrhgxl2cr46aq: + resolution: {integrity: sha512-fVezTa1lU+Hb3y9UMI8D/iWXADhs0I8PaZqoh2LOUXjGEUJmKqwsRD19ZXInZsH2yu+YS0dqYMPDvzjYTTyo+Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + dependencies: + '@babel/runtime': 7.29.2 + '@mui/utils': 9.0.0_po4keleilqsm4vrhgxl2cr46aq + react: 18.3.1 + reselect: 5.2.0 + use-sync-external-store: 1.6.0_react@18.3.1 + transitivePeerDependencies: + - '@types/react' + dev: true + + /@mui/x-virtualizer/9.0.0-alpha.7_27kzlijtntas6645qwojwuhdba: + resolution: {integrity: sha512-Hi21IoN7AWiW6vWEjj2mpK2Y3e8dhHwDkf35k6K6L87/6bvd/cYvPHndSCOvzO54qUpRfBumuFyoj1os/9joIA==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + dependencies: + '@babel/runtime': 7.29.2 + '@mui/utils': 9.0.1_po4keleilqsm4vrhgxl2cr46aq + '@mui/x-internals': 9.1.0_po4keleilqsm4vrhgxl2cr46aq + react: 18.3.1 + react-dom: 18.3.1_react@18.3.1 + transitivePeerDependencies: + - '@types/react' + dev: true + /@nodelib/fs.scandir/2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -3076,7 +3473,7 @@ packages: resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==} dependencies: '@gar/promisify': 1.1.3 - semver: 7.8.1 + semver: 7.8.0 dev: true /@npmcli/move-file/1.1.2: @@ -3274,7 +3671,6 @@ packages: /@popperjs/core/2.11.8: resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} - dev: false /@rollup/plugin-commonjs/17.1.0_rollup@2.79.2: resolution: {integrity: sha512-PoMdXCw0ZyvjpCMT5aV4nkL0QywxP29sODQsSGeDpr/oI49Qq9tRtAsb/LbYbDzFlOydVEqHmmZWFtXJEAX9ew==} @@ -3349,7 +3745,7 @@ packages: dependencies: '@types/estree': 1.0.7 estree-walker: 2.0.2 - picomatch: 4.0.2 + picomatch: 4.0.4 rollup: 2.79.2 dev: true @@ -4721,6 +5117,51 @@ packages: resolve-from: 5.0.0 dev: true + /@stratakit/foundations/0.4.8_nnrd3gsncyragczmpvfhocinkq: + resolution: {integrity: sha512-hu5KVGDdxp1x9dmLw0SLJ1iUpr5IF0m6wsKAggl0xHf2XHk3GuYRWHVDBWglnP06kG8xQKa4aegfteVw07i2WA==} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@ariakit/react': 0.4.26_nnrd3gsncyragczmpvfhocinkq + classnames: 2.5.1 + react: 18.3.1 + react-compiler-runtime: 1.0.0_react@18.3.1 + react-dom: 18.3.1_react@18.3.1 + dev: true + + /@stratakit/icons/0.3.2: + resolution: {integrity: sha512-MXwpKADbIYZjDu5Cb29GeleqXp5kSInuAzp/ZMN30bhMxCjVeKufDHFMlf/5xYQuo4ierceDpz9fZt5wyQix+g==} + dev: true + + /@stratakit/mui/0.4.2_khtwlpggtuvdxv4ufkxjwosrqm: + resolution: {integrity: sha512-/Vf90vbEFxF+vW3j24xX3lhjSOcbBpdl9BE7ZsHssCSq7uWUtc6j0ZeX61yme4HvM9tPgmJXEYlBl1rzqdXxUQ==} + peerDependencies: + '@mui/material': ^9.0.0 + react: '>=18.0.0' + react-dom: '>=18.0.0' + dependencies: + '@ariakit/react': 0.4.26_nnrd3gsncyragczmpvfhocinkq + '@emotion/cache': 11.14.0 + '@emotion/react': 11.14.0_po4keleilqsm4vrhgxl2cr46aq + '@emotion/styled': 11.14.1_46x4ncsoxvhgfjfiir5bhnd67y + '@mui/material': 9.0.1_27kzlijtntas6645qwojwuhdba + '@stratakit/foundations': 0.4.8_nnrd3gsncyragczmpvfhocinkq + '@stratakit/icons': 0.3.2 + classnames: 2.5.1 + react: 18.3.1 + react-compiler-runtime: 1.0.0_react@18.3.1 + react-dom: 18.3.1_react@18.3.1 + transitivePeerDependencies: + - '@types/react' + - supports-color + dev: true + /@stylelint/postcss-css-in-js/0.37.3_7g4trlemxbc5ah6sslctzyl7ii: resolution: {integrity: sha512-scLk3cSH1H9KggSniseb2KNAU5D9FWc3H7BxCSAIdtU9OWIyw0zkEZ9qEKHryRM+SExYXRKNb7tOOVNAsQ3iwg==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. @@ -4896,7 +5337,7 @@ packages: engines: {node: '>=10'} dependencies: '@babel/code-frame': 7.26.2 - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.29.2 '@types/aria-query': 4.2.2 aria-query: 4.2.2 chalk: 4.1.2 @@ -5228,6 +5669,10 @@ packages: /@types/prop-types/15.7.14: resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} + /@types/prop-types/15.7.15: + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + dev: true + /@types/q/1.5.8: resolution: {integrity: sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==} dev: true @@ -5255,6 +5700,14 @@ packages: '@types/react': 18.3.20 dev: true + /@types/react-transition-group/4.4.12_@types+react@18.3.20: + resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==} + peerDependencies: + '@types/react': '*' + dependencies: + '@types/react': 18.3.20 + dev: true + /@types/react/18.3.20: resolution: {integrity: sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==} dependencies: @@ -5331,26 +5784,26 @@ packages: '@types/yargs-parser': 21.0.3 dev: true - /@types/yargs/17.0.35: - resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} + /@types/yargs/17.0.33: + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} dependencies: '@types/yargs-parser': 21.0.3 dev: true - /@typescript-eslint/eslint-plugin/8.60.0_wwcgi2ygslsxsvl5y42wqbwvpa: - resolution: {integrity: sha512-QYb/sa74/s7OKMbACMjrYnGspj9Hs5YI5aaffSL65UfeBUzVzBJfVo3oWSpbzPurvm7yaCCo2Lk7lVj610HqKw==} + /@typescript-eslint/eslint-plugin/8.59.3_tcraa7oljkxsvwn3lqv4kf3bzu: + resolution: {integrity: sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.60.0 + '@typescript-eslint/parser': ^8.59.3 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.60.0_c3chdd2it6hsjvbnyur5kul6oq - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/type-utils': 8.60.0_c3chdd2it6hsjvbnyur5kul6oq - '@typescript-eslint/utils': 8.60.0_c3chdd2it6hsjvbnyur5kul6oq - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/parser': 8.59.3_c3chdd2it6hsjvbnyur5kul6oq + '@typescript-eslint/scope-manager': 8.59.3 + '@typescript-eslint/type-utils': 8.59.3_c3chdd2it6hsjvbnyur5kul6oq + '@typescript-eslint/utils': 8.59.3_c3chdd2it6hsjvbnyur5kul6oq + '@typescript-eslint/visitor-keys': 8.59.3 eslint: 8.57.1 ignore: 7.0.5 natural-compare: 1.4.0 @@ -5360,17 +5813,17 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/8.60.0_c3chdd2it6hsjvbnyur5kul6oq: - resolution: {integrity: sha512-fcqpj/MyK4sxDPcbe7STNPbpQL4RLZOPWuaTmwZYuc+hJKzRf58yRxfhqGpc6PIq9ZyfSBpfHgmUHmHs0KwHwg==} + /@typescript-eslint/parser/8.59.3_c3chdd2it6hsjvbnyur5kul6oq: + resolution: {integrity: sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' dependencies: - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0_typescript@6.0.3 - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/scope-manager': 8.59.3 + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/typescript-estree': 8.59.3_typescript@6.0.3 + '@typescript-eslint/visitor-keys': 8.59.3 debug: 4.4.3 eslint: 8.57.1 typescript: 6.0.3 @@ -5378,30 +5831,30 @@ packages: - supports-color dev: true - /@typescript-eslint/project-service/8.60.0_typescript@6.0.3: - resolution: {integrity: sha512-aZu74NNKJeUWqCjDddzdiKaS82dgYgV/vmf+Ui3ZdZejmgfXR/q+pRumgobnQ2cCJTgGTWp4ypiwsuofFubavg==} + /@typescript-eslint/project-service/8.59.3_typescript@6.0.3: + resolution: {integrity: sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' dependencies: - '@typescript-eslint/tsconfig-utils': 8.60.0_typescript@6.0.3 - '@typescript-eslint/types': 8.60.0 + '@typescript-eslint/tsconfig-utils': 8.59.3_typescript@6.0.3 + '@typescript-eslint/types': 8.59.3 debug: 4.4.3 typescript: 6.0.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager/8.60.0: - resolution: {integrity: sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw==} + /@typescript-eslint/scope-manager/8.59.3: + resolution: {integrity: sha512-t2LvZnoEfzKtnPjgeEu41xw5gxq9mQVfYy4OoZ4Vlt0sk3JwxmhCca/AR7DwOiHrjWgjAj6as4AhRLKSDfvZIA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/visitor-keys': 8.59.3 dev: true - /@typescript-eslint/tsconfig-utils/8.60.0_typescript@6.0.3: - resolution: {integrity: sha512-BZPR3RGYlAXnly6ymAxfkVn5rCbZzQNou0rxv3GfWZ8cTQp+hhVd73khbGLAd8k1TlAPLISH337M+tAgAnaJDQ==} + /@typescript-eslint/tsconfig-utils/8.59.3_typescript@6.0.3: + resolution: {integrity: sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -5409,16 +5862,16 @@ packages: typescript: 6.0.3 dev: true - /@typescript-eslint/type-utils/8.60.0_c3chdd2it6hsjvbnyur5kul6oq: - resolution: {integrity: sha512-SX46wEUtitCpq7AN38HkUU/+zvUpdKf7ephtWAFgckH8O7PQIyL5gvrhQgBLuEYgLfuKWOVvWVskMbuFHAz5xg==} + /@typescript-eslint/type-utils/8.59.3_c3chdd2it6hsjvbnyur5kul6oq: + resolution: {integrity: sha512-g71d8QD8UaiHGvrJwyIS1hCX5r63w6Jll+4VEYhEAHXTDIqX1JgxhTAbEHtKntL9kuc4jRo7/GWw5xfCepSccQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' dependencies: - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0_typescript@6.0.3 - '@typescript-eslint/utils': 8.60.0_c3chdd2it6hsjvbnyur5kul6oq + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/typescript-estree': 8.59.3_typescript@6.0.3 + '@typescript-eslint/utils': 8.59.3_c3chdd2it6hsjvbnyur5kul6oq debug: 4.4.3 eslint: 8.57.1 ts-api-utils: 2.5.0_typescript@6.0.3 @@ -5427,24 +5880,24 @@ packages: - supports-color dev: true - /@typescript-eslint/types/8.60.0: - resolution: {integrity: sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA==} + /@typescript-eslint/types/8.59.3: + resolution: {integrity: sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dev: true - /@typescript-eslint/typescript-estree/8.60.0_typescript@6.0.3: - resolution: {integrity: sha512-3AcZNBGMClm6CXDyo8kYvVGT/sx29sS0oBsIb9oZI2gunA4Vm2M3YHzRLPvsUBBsl+yB5FPtltq7gGH0iTlp9g==} + /@typescript-eslint/typescript-estree/8.59.3_typescript@6.0.3: + resolution: {integrity: sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' dependencies: - '@typescript-eslint/project-service': 8.60.0_typescript@6.0.3 - '@typescript-eslint/tsconfig-utils': 8.60.0_typescript@6.0.3 - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/project-service': 8.59.3_typescript@6.0.3 + '@typescript-eslint/tsconfig-utils': 8.59.3_typescript@6.0.3 + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/visitor-keys': 8.59.3 debug: 4.4.3 minimatch: 10.2.5 - semver: 7.8.1 + semver: 7.8.0 tinyglobby: 0.2.16 ts-api-utils: 2.5.0_typescript@6.0.3 typescript: 6.0.3 @@ -5452,28 +5905,28 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/8.60.0_c3chdd2it6hsjvbnyur5kul6oq: - resolution: {integrity: sha512-HtXuPfrHTyBDkameWpl+vJb1Uevu2tznAyahM1Oc4AENidCLTPiZDWIo4GfcxNdC/RcfGcadzzkqbRG87dUrQA==} + /@typescript-eslint/utils/8.59.3_c3chdd2it6hsjvbnyur5kul6oq: + resolution: {integrity: sha512-JAvT14goBzRzzzZyqq3P9BLArIxTtQURUtFgQ/V7FO+eU+Gg6ES+5ymOPP1wRxXcxAYeivCk4uS3jCKWI1K8Zg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' dependencies: '@eslint-community/eslint-utils': 4.9.1_eslint@8.57.1 - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0_typescript@6.0.3 + '@typescript-eslint/scope-manager': 8.59.3 + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/typescript-estree': 8.59.3_typescript@6.0.3 eslint: 8.57.1 typescript: 6.0.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/visitor-keys/8.60.0: - resolution: {integrity: sha512-9WI52t8ZGLVGrPMBet25yAftqY/n95+zmoUUtJBBQTKDSKUu7OsPTroT2op7U9JatkoRccL0YkWDNMFfC4Sjxg==} + /@typescript-eslint/visitor-keys/8.59.3: + resolution: {integrity: sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: - '@typescript-eslint/types': 8.60.0 + '@typescript-eslint/types': 8.59.3 eslint-visitor-keys: 5.0.1 dev: true @@ -6046,7 +6499,7 @@ packages: resolution: {integrity: sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==} engines: {node: '>=6.0'} dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.29.2 '@babel/runtime-corejs3': 7.27.0 dev: true @@ -6544,7 +6997,7 @@ packages: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.29.2 cosmiconfig: 7.1.0 resolve: 1.22.10 dev: true @@ -7431,6 +7884,11 @@ packages: is-regexp: 2.1.0 dev: true + /clsx/2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + dev: true + /co/4.6.0: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} @@ -7898,7 +8356,7 @@ packages: postcss-modules-values: 4.0.0_postcss@8.4.31 postcss-value-parser: 4.2.0 schema-utils: 3.3.0 - semver: 7.8.1 + semver: 7.8.0 webpack: 5.99.5 dev: true @@ -8068,6 +8526,9 @@ packages: /csstype/3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + /csstype/3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + /currently-unhandled/0.4.1: resolution: {integrity: sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==} engines: {node: '>=0.10.0'} @@ -8442,9 +8903,8 @@ packages: /dom-helpers/5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} dependencies: - '@babel/runtime': 7.27.0 - csstype: 3.1.3 - dev: false + '@babel/runtime': 7.29.2 + csstype: 3.2.3 /dom-serializer/0.2.2: resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==} @@ -9755,6 +10215,10 @@ packages: pkg-dir: 4.2.0 dev: true + /find-root/1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + dev: true + /find-up/1.1.2: resolution: {integrity: sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==} engines: {node: '>=0.10.0'} @@ -9865,7 +10329,7 @@ packages: memfs: 3.5.3 minimatch: 3.1.2 schema-utils: 2.7.0 - semver: 7.8.1 + semver: 7.8.0 tapable: 1.1.3 typescript: 6.0.3 webpack: 5.99.5 @@ -9897,7 +10361,7 @@ packages: memfs: 3.5.3 minimatch: 3.1.2 schema-utils: 2.7.0 - semver: 7.8.1 + semver: 7.8.0 tapable: 1.1.3 typescript: 6.0.3 webpack: 4.47.0 @@ -10531,6 +10995,12 @@ packages: minimalistic-crypto-utils: 1.0.1 dev: true + /hoist-non-react-statics/3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + dependencies: + react-is: 16.13.1 + dev: true + /home-or-tmp/1.0.0: resolution: {integrity: sha512-6LKQZpR6gk8uJ3mXbBkyOumsA24BUk9CH/79ivZ8Kk1urzlXNGZBoAMuieC/YzwCyGBVqq+uCNUpA1JS6glrxg==} engines: {node: '>=0.10.0'} @@ -11427,7 +11897,7 @@ packages: '@babel/parser': 7.27.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 - semver: 7.8.1 + semver: 7.8.0 transitivePeerDependencies: - supports-color dev: true @@ -11952,7 +12422,7 @@ packages: jest-util: 29.7.0 natural-compare: 1.4.0 pretty-format: 29.7.0 - semver: 7.8.1 + semver: 7.8.0 transitivePeerDependencies: - supports-color dev: true @@ -12295,7 +12765,7 @@ packages: resolution: {integrity: sha512-prXSYk799h3GY3iOWnC6ZigYzMPjxN2svgjJ9shk7oMadSNX3wXy0B6F32PMJv7qtMnrIbUxoEHzbutvxR2LBQ==} engines: {node: '>=6.0.0', npm: '>=6.0.0', yarn: '>=1.0.0'} dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.29.2 app-root-dir: 1.0.2 core-js: 3.41.0 dotenv: 8.6.0 @@ -12635,7 +13105,7 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} dependencies: - semver: 7.8.1 + semver: 7.8.0 dev: true /make-error/1.3.6: @@ -13304,7 +13774,7 @@ packages: dependencies: hosted-git-info: 4.1.0 is-core-module: 2.16.1 - semver: 7.8.1 + semver: 7.8.0 validate-npm-package-license: 3.0.4 dev: true @@ -13893,11 +14363,6 @@ packages: engines: {node: '>=8.6'} dev: true - /picomatch/4.0.2: - resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} - engines: {node: '>=12'} - dev: true - /picomatch/4.0.4: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} @@ -13983,7 +14448,7 @@ packages: resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==} engines: {node: '>=10'} dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.29.2 dev: true /posix-character-classes/0.1.1: @@ -14119,7 +14584,7 @@ packages: loader-utils: 2.0.4 postcss: 8.4.31 schema-utils: 3.3.0 - semver: 7.8.1 + semver: 7.8.0 webpack: 4.47.0 dev: true @@ -14791,6 +15256,14 @@ packages: webpack: 4.47.0 dev: true + /react-compiler-runtime/1.0.0_react@18.3.1: + resolution: {integrity: sha512-rRfjYv66HlG8896yPUDONgKzG5BxZD1nV9U6rkm+7VCuvQc903C4MjcoZR4zPw53IKSOX9wMQVpA1IAbRtzQ7w==} + peerDependencies: + react: ^17.0.0 || ^18.0.0 || ^19.0.0 || ^0.0.0-experimental + dependencies: + react: 18.3.1 + dev: true + /react-docgen-typescript/2.2.2_typescript@6.0.3: resolution: {integrity: sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==} peerDependencies: @@ -14806,7 +15279,7 @@ packages: dependencies: '@babel/core': 7.26.10 '@babel/generator': 7.27.0 - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.29.2 ast-types: 0.14.2 commander: 2.20.3 doctrine: 3.0.0 @@ -14846,7 +15319,7 @@ packages: peerDependencies: react: '>=16.13.1' dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.29.2 react: 18.3.1 dev: true @@ -14855,7 +15328,7 @@ packages: peerDependencies: react: ^16.8.4 || ^17.0.0 dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.29.2 is-dom: 1.1.0 prop-types: 15.8.1 react: 18.3.1 @@ -14880,6 +15353,10 @@ packages: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} dev: true + /react-is/19.2.6: + resolution: {integrity: sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw==} + dev: true + /react-refresh/0.11.0: resolution: {integrity: sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==} engines: {node: '>=0.10.0'} @@ -14919,13 +15396,12 @@ packages: react: '>=16.6.0' react-dom: '>=16.6.0' dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.29.2 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 react: 18.3.1 react-dom: 18.3.1_react@18.3.1 - dev: false /react/18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} @@ -15098,11 +15574,12 @@ packages: /regenerator-runtime/0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + dev: true /regenerator-transform/0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.29.2 dev: true /regenerator/0.8.40: @@ -15340,6 +15817,10 @@ packages: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} dev: true + /reselect/5.2.0: + resolution: {integrity: sha512-AgZ3UOZm3YndfrJ4OYjgrT7bmCm/1iqkjvEfH/oYjzh6PD2qw4QuT3jjnXIrpdt4MTpMXclMT3lXbmRY+XRakw==} + dev: true + /resolve-cwd/3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} @@ -15497,7 +15978,7 @@ packages: find-cache-dir: 3.3.2 fs-extra: 10.1.0 rollup: 2.79.2 - semver: 7.8.1 + semver: 7.8.0 tslib: 2.8.1 typescript: 6.0.3 dev: true @@ -15744,8 +16225,8 @@ packages: hasBin: true dev: true - /semver/7.8.1: - resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==} + /semver/7.8.0: + resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==} engines: {node: '>=10'} hasBin: true dev: true @@ -16635,6 +17116,10 @@ packages: - supports-color dev: true + /stylis/4.2.0: + resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} + dev: true + /sugarss/2.0.0: resolution: {integrity: sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==} dependencies: @@ -16656,7 +17141,7 @@ packages: mime: 2.6.0 qs: 6.14.0 readable-stream: 3.6.2 - semver: 7.8.1 + semver: 7.8.0 transitivePeerDependencies: - supports-color dev: true @@ -17059,8 +17544,8 @@ packages: resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} engines: {node: '>=6.10'} - /ts-jest/29.4.11_icsvk6wcbjq6ogk6vm4vlhytde: - resolution: {integrity: sha512-IrFl7l9AuB/qrNw5quqvAv/hmKMb8dhWOH4jQOGo0Oq8tCeo1O86/iTFG1FaRimgUkF13l4PcepO8ATFT6Ns4g==} + /ts-jest/29.4.9_icsvk6wcbjq6ogk6vm4vlhytde: + resolution: {integrity: sha512-LTb9496gYPMCqjeDLdPrKuXtncudeV1yRZnF4Wo5l3SFi0RYEnYRNgMrFIdg+FHvfzjCyQk1cLncWVqiSX+EvQ==} engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -17093,7 +17578,7 @@ packages: json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 - semver: 7.8.1 + semver: 7.8.0 type-fest: 4.41.0 typescript: 6.0.3 yargs-parser: 21.1.1 @@ -17499,6 +17984,14 @@ packages: qs: 6.14.0 dev: true + /use-sync-external-store/1.6.0_react@18.3.1: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + dependencies: + react: 18.3.1 + dev: true + /use/3.1.1: resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} engines: {node: '>=0.10.0'} diff --git a/packages/apps/storybook/.storybook/main.js b/packages/apps/storybook/.storybook/main.js index 6af8df98..319d6388 100644 --- a/packages/apps/storybook/.storybook/main.js +++ b/packages/apps/storybook/.storybook/main.js @@ -15,7 +15,7 @@ module.exports = { ], reactOptions: { fastRefresh: true }, core: { - builder: 'webpack5', + builder: "webpack5", }, typescript: { reactDocgen: false, // Storybook 6 does not support react-docgen-typescript with Typescript 6 - once we update Storybook this can be restored @@ -28,58 +28,108 @@ module.exports = { // You can change the configuration based on that. // 'PRODUCTION' is used when building the static version of storybook. - config.resolve.mainFields = ["module", "main"]; + config.resolve.mainFields = ["browser", "module", "main"]; + config.resolve.fallback = { + ...config.resolve.fallback, + fs: false, + }; + // Keep symlinked package paths (e.g. node_modules/@stratakit/icons) instead of + // resolving to pnpm realpaths under common/temp. This prevents "../.." segments + // from leaking into emitted asset URLs. + config.resolve.symlinks = false; + + // Ensure StrataKit icon SVGs are emitted with stable URLs so + // resolves correctly in Storybook (pnpm paths can otherwise leak into URLs). + config.module.rules.unshift({ + test: /\.svg$/i, + include: (resourcePath) => { + if (!resourcePath) { + return false; + } + const normalized = resourcePath.replace(/\\/g, "/"); + return ( + normalized.includes("/node_modules/@stratakit/icons/") || + normalized.includes("/.pnpm/@stratakit+icons@") + ); + }, + type: "asset/resource", + generator: { + filename: "static/media/[name].[contenthash:8][ext]", + }, + }); const packagePaths = { - "@itwin/imodel-browser-react": path.resolve(__dirname, "../../../modules/imodel-browser/src"), - "@itwin/create-imodel-react": path.resolve(__dirname, "../../../modules/create-imodel/src"), - "@itwin/delete-imodel-react": path.resolve(__dirname, "../../../modules/delete-imodel/src"), - "@itwin/delete-itwin-react": path.resolve(__dirname, "../../../modules/delete-itwin/src"), - "@itwin/manage-versions-react": path.resolve(__dirname, "../../../modules/manage-versions/src"), - } + "@itwin/imodel-browser-react/mui": path.resolve( + __dirname, + "../../../modules/imodel-browser/src/mui" + ), + "@itwin/imodel-browser-react": path.resolve( + __dirname, + "../../../modules/imodel-browser/src" + ), + "@itwin/create-imodel-react": path.resolve( + __dirname, + "../../../modules/create-imodel/src" + ), + "@itwin/delete-imodel-react": path.resolve( + __dirname, + "../../../modules/delete-imodel/src" + ), + "@itwin/delete-itwin-react": path.resolve( + __dirname, + "../../../modules/delete-itwin/src" + ), + "@itwin/manage-versions-react": path.resolve( + __dirname, + "../../../modules/manage-versions/src" + ), + }; + // Ensure TypeScript files from source directories are processed + // (needed for both dev and production since some stories use relative imports to source) + config.module.rules.push({ + test: /\.(ts|tsx)$/, + include: Object.values(packagePaths), + use: [ + { + loader: require.resolve("babel-loader"), + options: { + presets: [ + require.resolve("@babel/preset-env"), + require.resolve("@babel/preset-react"), + require.resolve("@babel/preset-typescript"), + ], + }, + }, + ], + }); + + // Handle SCSS files from source directories + config.module.rules.push({ + test: /\.scss$/, + include: Object.values(packagePaths), + use: ["style-loader", "css-loader", "sass-loader"], + }); + // Enable HMR for local packages in development by aliasing to source directories - if (configType === 'DEVELOPMENT') { + if (configType === "DEVELOPMENT") { // Use full source maps to allow VS Code Chrome debugger to map back to TS/TSX sources - config.devtool = 'source-map'; + config.devtool = "source-map"; config.output = config.output || {}; config.output.devtoolModuleFilenameTemplate = (info) => { // Derive repo root (four levels up from .storybook: ../../../../) - const repoRoot = path.resolve(__dirname, '../../../../'); - let relPath = path.relative(repoRoot, info.absoluteResourcePath).replace(/\\/g, '/'); + const repoRoot = path.resolve(__dirname, "../../../../"); + let relPath = path + .relative(repoRoot, info.absoluteResourcePath) + .replace(/\\/g, "/"); return `webpack:///${relPath}`; }; config.resolve.alias = { ...config.resolve.alias, - ...packagePaths + ...packagePaths, }; - - // Ensure TypeScript files from source directories are processed - config.module.rules.push({ - test: /\.(ts|tsx)$/, - include: Object.values(packagePaths), - use: [ - { - loader: require.resolve('babel-loader'), - options: { - presets: [ - require.resolve('@babel/preset-env'), - require.resolve('@babel/preset-react'), - require.resolve('@babel/preset-typescript'), - ], - }, - }, - ], - }); - - // Handle SCSS files from source directories - config.module.rules.push({ - test: /\.scss$/, - include: Object.values(packagePaths), - use: ['style-loader', 'css-loader', 'sass-loader'], - }); } return config; }, - staticDirs: ["../../../modules/storybook-auth-addon/build"] + staticDirs: ["../../../modules/storybook-auth-addon/build"], }; diff --git a/packages/apps/storybook/.storybook/preview.js b/packages/apps/storybook/.storybook/preview.js index 0fb8fbaa..abfc3341 100644 --- a/packages/apps/storybook/.storybook/preview.js +++ b/packages/apps/storybook/.storybook/preview.js @@ -3,6 +3,7 @@ * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ import { ThemeProvider } from "@itwin/itwinui-react"; +import { Root } from "@stratakit/mui"; import { themes } from "@storybook/theming"; import { useDarkMode } from "storybook-dark-mode"; import { darkTheme, lightTheme } from "./itwinTheme"; @@ -32,9 +33,15 @@ export const decorators = [ const theme = isDark ? "dark" : "light"; return ( - + ); }, -]; \ No newline at end of file +]; diff --git a/packages/apps/storybook/package.json b/packages/apps/storybook/package.json index e8cb0eaf..21504e9a 100644 --- a/packages/apps/storybook/package.json +++ b/packages/apps/storybook/package.json @@ -20,6 +20,11 @@ "@itwin/delete-imodel-react": "workspace:*", "@itwin/delete-itwin-react": "workspace:*", "@itwin/imodel-browser-react": "workspace:*", + "@mui/material": "~9.0.0", + "@mui/system": "~9.0.0", + "@mui/x-data-grid": "~9.3.0", + "@stratakit/icons": "~0.3.1", + "@stratakit/mui": "~0.4.1", "@itwin/itwinui-icons-react": "2.10.0", "@itwin/itwinui-react": "^3.19.4", "@itwin/manage-versions-react": "workspace:*", diff --git a/packages/apps/storybook/src/images.d.ts b/packages/apps/storybook/src/images.d.ts new file mode 100644 index 00000000..4d7ded00 --- /dev/null +++ b/packages/apps/storybook/src/images.d.ts @@ -0,0 +1,9 @@ +declare module "*.jpg" { + const src: string; + export default src; +} + +declare module "*.jpeg" { + const src: string; + export default src; +} diff --git a/packages/apps/storybook/src/imodel-browser/BaseCard.stories.tsx b/packages/apps/storybook/src/imodel-browser/BaseCard.stories.tsx new file mode 100644 index 00000000..e36b3361 --- /dev/null +++ b/packages/apps/storybook/src/imodel-browser/BaseCard.stories.tsx @@ -0,0 +1,261 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Bentley Systems, Incorporated. All rights reserved. + * See LICENSE.md in the project root for license terms and full copyright notice. + *--------------------------------------------------------------------------------------------*/ +import { + BaseCard, + BaseCardProps, +} from "../../../../modules/imodel-browser/src/components/baseCard/BaseCard"; +import Avatar from "@mui/material/Avatar"; +import AvatarGroup from "@mui/material/AvatarGroup"; +import Box from "@mui/material/Box"; +import Chip from "@mui/material/Chip"; +import svgPin from "@stratakit/icons/pin.svg"; +import svgStatusSuccess from "@stratakit/icons/status-success.svg"; +import svgStatusWarning from "@stratakit/icons/status-warning.svg"; +import svgStatusError from "@stratakit/icons/status-error.svg"; +import svgGeo from "@stratakit/icons/geospatial-features.svg"; +import bridgeThumbnail from "../utils/bridge.jpg"; +import nightThumbnail from "../utils/night.jpg"; +import { action, actions } from "@storybook/addon-actions"; +import { Meta, Story } from "@storybook/react/types-6-0"; +import React from "react"; +import Typography from "@mui/material/Typography"; +import { + buildContextMenuItemsMUI, + type ContextMenuBuilderItemMUI, +} from "../../../../modules/imodel-browser/src/utils/_buildMenuOptions"; +import { ThumbnailIconButton } from "../../../../modules/imodel-browser/src/components/baseCard/ThumbnailIconButton"; +import { SvgThumbnail } from "@itwin/imodel-browser-react/mui"; + +const InConstrainedContainer = ({ + children, +}: { + children: React.ReactNode; +}) => {children}; + +export const BaseCardStory = (props: BaseCardProps) => ( + + + +); + +export default { + title: "imodel-browser/BaseCard", + component: BaseCardStory, + excludeStories: ["BaseCardStory"], + argTypes: { + slotProps: { control: false }, + thumbnail: { control: false }, + thumbnailTopLeft: { control: false }, + thumbnailTopRight: { control: false }, + thumbnailBottomRight: { control: false }, + headerRight: { control: false }, + statusIconHref: { control: false }, + additionalDescription: { control: false }, + onClick: { control: false }, + onDoubleClick: { control: false }, + onContextMenu: { control: false }, + status: { + options: ["undefined", "positive", "warning", "negative"], + mapping: { + none: undefined, + positive: "positive", + warning: "warning", + negative: "negative", + }, + control: { + type: "radio", + }, + }, + }, +} as Meta; + +const Template: Story = (args) => ; + +const baseArgs: BaseCardProps = { + title: "Main Street Bridge", + description: "3D model of the Main Street bridge structure and components.", + subheader: "Edited 2000-01-02", + thumbnail: bridgeThumbnail, +}; + +// ── Stories ────────────────────────────────────────────────────────────────── + +export const Default = Template.bind({}); +Default.args = { ...baseArgs }; + +const contextMenuItems: ContextMenuBuilderItemMUI[] = [ + { + key: "open", + onClick: action("menu: open clicked"), + children: "Open with", + }, + { + key: "share", + children: "Share", + onClick: action("menu: share clicked"), + }, + { + key: "delete", + children: "Delete", + onClick: action("menu: delete clicked"), + }, +]; +const contextMenuContent = buildContextMenuItemsMUI( + contextMenuItems, + { some: "object" } as const, + () => actions("closeMenu called"), + () => actions("refetch called") +); + +const everythingArgs: BaseCardProps = { + ...baseArgs, + onClick: action("clicked"), + onDoubleClick: action("double-clicked "), + onContextMenu: action("context-menu opened"), + contextMenuContent, + actions: [ + { key: "open", label: "Open", onClick: action("open clicked") }, + { + key: "share", + label: "Share", + onClick: action("share clicked"), + }, + ], + statusIconHref: svgStatusWarning, + headerRight: ( + + + + + + + + + ), + thumbnailTopLeft: , + thumbnailTopRight: ( + <> + + + + ), + thumbnailBottomLeft: , + thumbnailBottomRight: , + additionalContent: ( + + This is some additional content rendered below the description and above + the footer actions. + + ), +}; + +export const Everything = Template.bind({}); +Everything.storyName = "Everything"; +Everything.args = { ...everythingArgs }; + +export const WithoutThumbnail = Template.bind({}); +WithoutThumbnail.storyName = "Without thumbnail"; +WithoutThumbnail.args = { ...everythingArgs, thumbnail: undefined }; + +export const WithDarkThumbnail = Template.bind({}); +WithDarkThumbnail.storyName = "With dark thumbnail"; +WithDarkThumbnail.args = { + ...everythingArgs, + thumbnail: nightThumbnail, +}; + +export const WithoutContent = Template.bind({}); +WithoutContent.storyName = "Without content"; +WithoutContent.args = { + ...everythingArgs, + title: "Main Street Bridge", + description: undefined, + subheader: undefined, + thumbnail: bridgeThumbnail, + additionalContent: undefined, +}; + +export const WithSlotProps = Template.bind({}); +WithSlotProps.storyName = "With slot props"; +WithSlotProps.args = { + ...everythingArgs, + + slotProps: { + thumbnail: { + sx: { opacity: 0.2 }, + }, + content: { + sx: { color: "var(--stratakit-color-border-attention-base)" }, + }, + divider: { + sx: { + borderWidth: 5, + borderColor: "var(--stratakit-color-border-positive-base)", + }, + }, + }, +}; + +export const Statuses = () => ( + + {( + [ + { label: "Positive", icon: svgStatusSuccess, status: "positive" }, + { label: "Warning", icon: svgStatusWarning, status: "warning" }, + { label: "Negative", icon: svgStatusError, status: "negative" }, + ] as const + ).map(({ label, icon, status }) => ( + + ))} + +); + +export const WithSvgThumbnail = Template.bind({}); +WithSvgThumbnail.storyName = "With SVG thumbnail"; +WithSvgThumbnail.args = { + ...baseArgs, + thumbnail: , +}; + +export const Loading = Template.bind({}); +Loading.args = { ...baseArgs, loading: true }; + +export const Selected = Template.bind({}); +Selected.storyName = "Selected state"; +Selected.args = { ...baseArgs, selected: true }; + +export const LongTitle = Template.bind({}); +LongTitle.storyName = "Long title"; +LongTitle.args = { + ...baseArgs, + title: + "This is a very long title that should truncate automagically with an ellipsis at the end", +}; diff --git a/packages/apps/storybook/src/imodel-browser/IModelGrid.stories.tsx b/packages/apps/storybook/src/imodel-browser/IModelGrid.stories.tsx index 2064f526..900f83a1 100644 --- a/packages/apps/storybook/src/imodel-browser/IModelGrid.stories.tsx +++ b/packages/apps/storybook/src/imodel-browser/IModelGrid.stories.tsx @@ -263,28 +263,27 @@ const buildMenuItems = close: () => void, setVersion: React.Dispatch> ) => - (v: Version) => - ( - { - event.stopPropagation(); - }} - > - {v.id === "loading" ? ( - - ) : ( - { - close(); - v.id !== "loading" && setVersion(v); - }} - > - {v.displayName} - - )} - - ); + (v: Version) => ( + { + event.stopPropagation(); + }} + > + {v.id === "loading" ? ( + + ) : ( + { + close(); + v.id !== "loading" && setVersion(v); + }} + > + {v.displayName} + + )} + + ); /** Hook used in StatefulPropsOverrides.args, the function itself must be a stable reference as it is a hook. */ const useIndividualState = (iModel: IModelFull, props: IModelTileProps) => { @@ -343,8 +342,8 @@ const useIndividualState = (iModel: IModelFull, props: IModelTileProps) => { isNew: versions?.length === 0, metadata: ( { - versions === undefined && fetchVersionsList(); + onClick={async () => { + versions === undefined && (await fetchVersionsList()); }} > { + // random versions + const versions = React.useMemo(() => { + return [ + { id: "v1", displayName: `${iModel.displayName} v1` }, + { id: "v2", displayName: `${iModel.displayName} v2` }, + { id: "v3", displayName: `${iModel.displayName} v3` }, + ]; + }, [iModel.displayName]); + + // Create a memo of the tileProps we want to override, depending on the state. + const tileProps = React.useMemo>( + () => ({ + actions: [ + { + key: "default", + label: `Open ${iModel.displayName}`, + onClick: () => {}, + }, + { key: "vr", label: "Open in VR", onClick: () => {} }, + ], + isNew: versions?.length === 0, + additionalContent: ( + + ), + }), + [iModel?.displayName, versions] + ); + + return { + ...props, + ...tileProps, + }; +}; diff --git a/packages/apps/storybook/src/imodel-browser/IModelGridMUI.stories.tsx b/packages/apps/storybook/src/imodel-browser/IModelGridMUI.stories.tsx new file mode 100644 index 00000000..b5d3fa24 --- /dev/null +++ b/packages/apps/storybook/src/imodel-browser/IModelGridMUI.stories.tsx @@ -0,0 +1,350 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Bentley Systems, Incorporated. All rights reserved. + * See LICENSE.md in the project root for license terms and full copyright notice. + *--------------------------------------------------------------------------------------------*/ +import { + IModelGrid as ExternalComponent, + type IModelGridProps as IModelGridMUIProps, + DataStatus, + type IModelFull, + IModelCellColumn, +} from "@itwin/imodel-browser-react/mui"; +import { + useIndividualState, + additionalData, + initialData, +} from "./IModelGridMUI.helpers"; +import SvgDelete from "@stratakit/icons/delete.svg"; +import { Icon } from "@stratakit/mui"; +import { Meta, Story } from "@storybook/react/types-6-0"; +import React from "react"; +import { + accessTokenArgTypes, + withAccessTokenOverride, + withITwinIdOverride, +} from "../utils/storyHelp"; +import Typography from "@mui/material/Typography"; +import Chip from "@mui/material/Chip"; +import AvatarGroup from "@mui/material/AvatarGroup"; +import Avatar from "@mui/material/Avatar"; +import { action } from "@storybook/addon-actions"; +import bridgeThumbnail from "../utils/bridge.jpg"; +import nightThumbnail from "../utils/night.jpg"; + +export const IModelGridMUI = (props: IModelGridMUIProps) => ( + +); + +export default { + title: "imodel-browser/IModelGridMUI", + component: IModelGridMUI, + argTypes: accessTokenArgTypes, + excludeStories: ["IModelGridMUI"], +} as Meta; + +const Template: Story = withITwinIdOverride( + withAccessTokenOverride((args) => ) +); + +const baseArgs: IModelGridMUIProps = { + apiOverrides: { serverEnvironmentPrefix: "qa" }, + sortOptions: { sortType: "name", descending: false }, + onOpen: action("iModel opened"), + onSelect: action("iModel selected"), + iModelActions: [ + { + key: "open", + children: "Open iModel", + onClick: (iModel) => { + action("Open " + iModel?.displayName)(iModel); + }, + }, + { + key: "details", + children: "View details", + onClick: (iModel) => action("Details for " + iModel?.displayName)(iModel), + }, + ], + // tileOverrides: { + // onOpen: (iModel) => alert("Opened " + iModel.displayName), + // onSelect: (iModel) => action("Selected " + iModel.displayName), + // }, +}; + +export const Primary = Template.bind({}); +Primary.args = { ...baseArgs }; + +export const PrimaryCell = Template.bind({}); +PrimaryCell.args = { + ...baseArgs, + viewMode: "cells", +}; + +export const OverrideCellData = Template.bind({}); +OverrideCellData.args = { + ...baseArgs, + viewMode: "cells", + tableOverrides: { + columnOverrides: { + [IModelCellColumn.Name]: { + renderCell: (params) => + params.formattedValue?.includes("*") ? ( +
+ {params.formattedValue}{" "} + + (redacted number in name) + +
+ ) : ( +
+ {params.formattedValue}{" "} + (no redactions) +
+ ), + valueFormatter: (value, iModel) => { + // replace any numbers with * + return iModel.displayName?.replace(/[0-9]/g, "*"); + }, + }, + [IModelCellColumn.Description]: { + renderCell: (params) => ( + + Add random number {Math.floor(Math.random() * 100)} to description + "{params.value}" + + ), + }, + }, + hideColumns: [IModelCellColumn.LastModified], + }, +}; + +export const OverrideApiDataWithLoadMore: Story = + withITwinIdOverride( + withAccessTokenOverride((args) => { + const [data, setData] = React.useState(initialData); + const [isLoading, setIsLoading] = React.useState(false); + const [hasMore, setHasMore] = React.useState(true); + + const handleLoadMore = React.useCallback(async () => { + setIsLoading(true); + // Simulate network delay + await new Promise((resolve) => setTimeout(resolve, 2000)); + setData((prev) => [...prev, ...additionalData]); + setHasMore(false); + setIsLoading(false); + }, []); + + return ( + + ); + }) + ); + +export const IndividualContextMenu = Template.bind({}); +IndividualContextMenu.args = { + ...baseArgs, + iModelActions: [ + { + children: "displayName contains 'R'", + visible: (iModel: IModelFull) => + iModel.displayName?.toLowerCase().includes("r") ?? false, + key: "withR", + onClick: (iModel: IModelFull | undefined) => + alert("Contains R: " + iModel?.displayName), + }, + { + children: "Disabled if name contains 'T'", + disabled: (iModel: IModelFull) => + iModel.displayName?.toLowerCase().includes("t") ?? false, + key: "withT", + onClick: (iModel: IModelFull | undefined) => + alert("Does not contain T: " + iModel?.displayName), + }, + { + children: "Add description", + key: "addD", + onClick: (iModel: IModelFull | undefined) => + alert("Add description: " + iModel?.displayName), + }, + { + children: "Edit description", + visible: (iModel: IModelFull) => !!iModel.description, + key: "editD", + onClick: (iModel: IModelFull | undefined) => + alert("Edit description: " + iModel?.displayName), + }, + ], +}; + +export const SimpleTilePropsOverrides = Template.bind({}); +SimpleTilePropsOverrides.args = { + ...baseArgs, + tileOverrides: { + thumbnail: bridgeThumbnail, + getBadge: () => , + headerRight: ( + + + + + + ), + }, +}; + +export const StatefulPropsOverrides = Template.bind({}); +StatefulPropsOverrides.args = { + ...baseArgs, + useIndividualState, +}; + +function addStartTileCallback(iModels: IModelFull[], status?: DataStatus) { + if (status !== DataStatus.Complete) return iModels; + + iModels.unshift({ + id: "prepended", + displayName: "Some Prepended iModel", + description: "This iModel was added in the postProcessCallback", + thumbnail: nightThumbnail, + }); + return iModels; +} + +export const WithPostProcessCallback = Template.bind({}); +WithPostProcessCallback.args = { + ...baseArgs, + postProcessCallback: addStartTileCallback, +}; + +export const DefaultNoStateComponentOverride = Template.bind({}); +DefaultNoStateComponentOverride.args = { + ...baseArgs, + emptyStateComponent: ( +
+ {/* eslint-disable-next-line jsx-a11y/heading-has-content */} + }> + There are no iModels to show. + +
+ ), +}; + +export const DisableAddToRecents = Template.bind({}); +DisableAddToRecents.args = { + ...baseArgs, + disableAddToRecents: true, +}; +DisableAddToRecents.argTypes = { + accessToken: { table: { disable: true } }, + onOpen: { table: { disable: true } }, + onSelect: { table: { disable: true } }, + sortOptions: { table: { disable: true } }, + iModelActions: { table: { disable: true } }, + useIndividualState: { table: { disable: true } }, + tileOverrides: { table: { disable: true } }, + stringsOverrides: { table: { disable: true } }, + apiOverrides: { table: { disable: true } }, + postProcessCallback: { table: { disable: true } }, + emptyStateComponent: { table: { disable: true } }, + searchText: { table: { disable: true } }, + viewMode: { table: { disable: true } }, + pageSize: { table: { disable: true } }, + maxCount: { table: { disable: true } }, + tableOverrides: { table: { disable: true } }, + className: { table: { disable: true } }, +}; + +export const Recents = Template.bind({}); +Recents.args = { + ...baseArgs, + requestType: "recents", +}; + +export const RecentsWithCustomIcon = Template.bind({}); +RecentsWithCustomIcon.args = { + ...baseArgs, + requestType: "recents", + removeFromRecentsIcon: , +}; + +export const NoResultsWithDefaultEmptyState = Template.bind({}); +NoResultsWithDefaultEmptyState.args = { + ...baseArgs, + apiOverrides: { serverEnvironmentPrefix: "qa" }, + postProcessCallback: (iModels, status) => { + return []; + }, +}; + +export const StringsOverrideGrid = Template.bind({}); +StringsOverrideGrid.args = { + ...baseArgs, + iModelActions: [ + { + children: "Some action", + key: "something", + onClick: (iModel) => action("clicked " + iModel?.displayName)(iModel), + }, + ], + stringsOverrides: { + moreOptions: "Fleiri valkostir", + addToFavorites: "Bæta við eftirlæti", + removeFromFavorites: "Fjarlægja úr eftirlætum", + tableColumnName: "Heiti iModel", + tableColumnDescription: "Lýsing iModel", + tableColumnLastModified: "Síðast breytt", + noRowsLabel: "Engar raðir", + noResultsOverlayLabel: "Engar niðurstöður fundust.", + paginationRowsPerPage: "Raðir á síðu:", + footerRowSelected: (count: number) => + count !== 1 + ? `${count.toLocaleString()} raðir valdar` + : `${count.toLocaleString()} röð valin`, + footerTotalVisibleRows: (visibleCount: number, totalCount: number) => + `${visibleCount.toLocaleString()} af ${totalCount.toLocaleString()}`, + }, +}; + +export const StringsOverrideTable = Template.bind({}); +StringsOverrideTable.args = { + ...baseArgs, + viewMode: "cells", + + iModelActions: [ + { + children: "Some action", + key: "something", + onClick: (iModel) => action("clicked " + iModel?.displayName)(iModel), + }, + ], + stringsOverrides: { + moreOptions: "Fleiri valkostir", + addToFavorites: "Bæta við eftirlæti", + removeFromFavorites: "Fjarlægja úr eftirlætum", + tableColumnName: "Heiti iModel", + tableColumnDescription: "Lýsing iModel", + tableColumnLastModified: "Síðast breytt", + noRowsLabel: "Engar raðir", + noResultsOverlayLabel: "Engar niðurstöður fundust.", + paginationRowsPerPage: "Raðir á síðu:", + footerRowSelected: (count: number) => + count !== 1 + ? `${count.toLocaleString()} raðir valdar` + : `${count.toLocaleString()} röð valin`, + footerTotalVisibleRows: (visibleCount: number, totalCount: number) => + `${visibleCount.toLocaleString()} af ${totalCount.toLocaleString()}`, + }, +}; diff --git a/packages/apps/storybook/src/imodel-browser/IModelTileMUI.stories.tsx b/packages/apps/storybook/src/imodel-browser/IModelTileMUI.stories.tsx new file mode 100644 index 00000000..7161217b --- /dev/null +++ b/packages/apps/storybook/src/imodel-browser/IModelTileMUI.stories.tsx @@ -0,0 +1,140 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Bentley Systems, Incorporated. All rights reserved. + * See LICENSE.md in the project root for license terms and full copyright notice. + *--------------------------------------------------------------------------------------------*/ +import { + IModelTile as IModelTileMUI, + type IModelTileProps as IModelTileMUIProps, + SvgThumbnail, +} from "@itwin/imodel-browser-react/mui"; +import Box from "@mui/material/Box"; +import Chip from "@mui/material/Chip"; +import { Icon } from "@stratakit/mui"; +import svgPlaceholder from "@stratakit/icons/placeholder.svg"; +import SvgShare from "@stratakit/icons/share.svg"; +import SvgDelete from "@stratakit/icons/delete.svg"; +import bridgeThumbnail from "../utils/bridge.jpg"; +import overpassThumbnail from "../utils/overpass.jpg"; +import { action } from "@storybook/addon-actions"; +import { Meta, Story } from "@storybook/react/types-6-0"; +import React from "react"; +import Button from "@mui/material/Button"; +import svgRoad from "@stratakit/icons/road.svg"; + +const InConstrainedContainer = ({ + children, +}: { + children: React.ReactNode; +}) => {children}; + +export const IModelTileMUIStory = (props: IModelTileMUIProps) => ( + + + +); + +export default { + title: "imodel-browser/IModelTileMUI", + component: IModelTileMUIStory, + excludeStories: ["IModelTileMUIStory"], + argTypes: { + status: { + options: ["undefined", "positive", "warning", "negative"], + mapping: { + undefined: undefined, + positive: "positive", + warning: "warning", + negative: "negative", + }, + control: { + type: "radio", + }, + }, + iModel: { control: false }, + onSelect: { control: false }, + onOpen: { control: false }, + thumbnail: { control: false }, + actions: { control: false }, + contextMenuItems: { control: false }, + thumbnailTopLeft: { control: false }, + thumbnailBottomRight: { control: false }, + accessToken: { control: false }, + stringOverrides: { control: false }, + }, +} as Meta; + +const Template: Story = (args) => ( + +); + +const baseArgs: IModelTileMUIProps = { + iModel: { + id: "1", + displayName: "iModel Name", + description: "iModel Description from iModel Hub", + lastChangesetPushDateTime: "2024-01-01T12:00:00Z", + }, + + thumbnail: bridgeThumbnail, + + onSelect: action("iModel selected"), + onOpen: action("iModel opened"), + disabled: false, + loading: false, + selected: false, + contextMenuItems: [ + { + key: "option-1", + icon: , + children: "Context Menu Option 1", + onClick: (iModel) => action("iModel option 1 clicked")(iModel), + }, + { + key: "option-2", + icon: , + children: "Context Menu Option 2", + onClick: (iModel) => action("iModel option 2 clicked")(iModel), + }, + ], +}; + +export const Default = Template.bind({}); +Default.args = { + ...baseArgs, +}; + +export const Extensive = Template.bind({}); +Extensive.args = { + ...baseArgs, + title: "Overridden Title", + description: "Overriden description", + subheader: "Additional description", + additionalContent: , + thumbnail: overpassThumbnail, + getBadge: () => , + thumbnailTopLeft: , + actions: [ + { + key: "button-1", + label: "Open in Viewer", + onClick: action("iModel button 1 clicked"), + }, + { + key: "button-2", + label: "Open in VR Headset", + onClick: action("iModel button 2 clicked"), + }, + ], +}; + +export const NoThumbnail = Template.bind({}); +NoThumbnail.args = { + ...baseArgs, + thumbnail: undefined, +}; + +export const CustomSvgThumbnail = Template.bind({}); +CustomSvgThumbnail.args = { + ...baseArgs, + thumbnail: , +}; diff --git a/packages/apps/storybook/src/imodel-browser/ITwinGrid.stories.tsx b/packages/apps/storybook/src/imodel-browser/ITwinGrid.stories.tsx index 3cf45a61..5ff2a1c7 100644 --- a/packages/apps/storybook/src/imodel-browser/ITwinGrid.stories.tsx +++ b/packages/apps/storybook/src/imodel-browser/ITwinGrid.stories.tsx @@ -147,28 +147,27 @@ const buildMenuItems = close: () => void, setVersion: React.Dispatch> ) => - (v: IModelMinimal) => - ( - { - event.stopPropagation(); - }} - > - {v.id === "loading" ? ( - - ) : ( - { - close(); - v.id !== "loading" && setVersion(v); - }} - > - {v.displayName} - - )} - - ); + (v: IModelMinimal) => ( + { + event.stopPropagation(); + }} + > + {v.id === "loading" ? ( + + ) : ( + { + close(); + v.id !== "loading" && setVersion(v); + }} + > + {v.displayName} + + )} + + ); const Pager = (props: PropsWithChildren<{ onClick: () => void }>) => ( @@ -257,8 +256,8 @@ const useIndividualState: IndividualITwinStateHook = (iTwin, props) => { : [], metadata: ( { - imodels === undefined && fetchIModelList(); + onClick={async () => { + imodels === undefined && (await fetchIModelList()); }} > ; + +export const ITwinGrid = (props: ITwinGridProps) => ( + +); + +const accessToken = accessTokenArgTypes.accessToken; + +const Template: Story = withAccessTokenOverride((args) => ( + +)); + +const baseArgs: ITwinGridProps = { + apiOverrides: { serverEnvironmentPrefix: "qa" }, + viewMode: "tile", + onOpen: (iTwin) => action("Open " + iTwin.displayName)(iTwin), + onSelect: (iTwin) => action("Select " + iTwin.displayName)(iTwin), +}; + +export const Primary = Template.bind({}); +Primary.args = { + ...baseArgs, +}; + +export const TableView = Template.bind({}); +TableView.args = { + ...baseArgs, + viewMode: "cells", +}; + +export const TableViewWithOverrides = Template.bind({}); +TableViewWithOverrides.args = { + ...baseArgs, + viewMode: "cells", + tableOverrides: { + columnOverrides: { + [ITwinCellColumn.Number]: { + renderCell: (params) => ( +
+ { + e.stopPropagation(); + action("Icon Clicked")(); + }} + > + + {" "} + {params.formattedValue} +
+ ), + }, + [ITwinCellColumn.Name]: { + renderCell: (params) => ( + + {params.value} + + ), + }, + }, + hideColumns: [ITwinCellColumn.LastModified], + }, +}; + +export const OverrideApiData = Template.bind({}); +OverrideApiData.args = { + ...baseArgs, + apiOverrides: { + data: [ + { + id: "1", + displayName: "Bridge iTwin", + number: "No Network Calls", + image: bridgeThumbnail, + }, + { + id: "2", + displayName: "Power iTwin", + number: "aaa-bbb-ccc", + image: powerThumbnail, + }, + { + id: "3", + displayName: "Overpass iTwin", + number: "No Network Calls", + image: overpassThumbnail, + }, + + { + id: "4", + displayName: "Highway iTwin", + number: "No Network Calls", + image: nightThumbnail, + }, + ], + }, +}; + +export const IndividualContextMenu = Template.bind({}); +IndividualContextMenu.args = { + ...baseArgs, + + iTwinActions: [ + { + children: "displayName contains 'R'", + visible: (iTwin) => iTwin.displayName?.includes("R") ?? false, + key: "withR", + onClick: (iTwin) => action("Contains R" + iTwin?.displayName)(iTwin), + }, + { + children: "Add iTwinNumber", + visible: (iTwin) => !iTwin.number, + key: "addD", + onClick: (iTwin) => + action("Add iTwinNumber to " + iTwin?.displayName)(iTwin), + }, + { + children: (iTwin) => `Edit iTwin ${iTwin.displayName}`, + visible: (iTwin) => !!iTwin.number, + key: "editD", + onClick: (iTwin) => action("Edit iTwinNumber: " + iTwin?.number)(iTwin), + }, + ], +}; + +export const SimpleTilePropsOverrides = Template.bind({}); +SimpleTilePropsOverrides.args = { + ...baseArgs, + tileOverrides: { + status: "negative", + thumbnail: bridgeThumbnail, + getBadge: () => , + headerRight: ( + + + + + + ), + }, +}; + +interface IModelMinimal { + id: string; + displayName: string; +} +interface IModelsFetchData { + iModels: IModelMinimal[]; + _links: { + prev: { href: string }; + next: { href: string }; + self: { href: string }; + }; +} + +/** Function used in useIndividualState */ +const buildMenuItems = + ( + close: () => void, + setVersion: React.Dispatch> + ) => + (v: IModelMinimal) => ( + { + event.stopPropagation(); + }} + > + {v.id === "loading" ? ( + + + + ) : ( + { + close(); + v.id !== "loading" && setVersion(v); + }} + > + {v.displayName} + + )} + + ); + +/** Hook used in StatefulPropsOverrides.args, the function itself must be a stable reference as it is a hook. */ +const useIndividualState: IndividualITwinStateHook = (iTwin, props) => { + const [selection, setSelection] = React.useState(); + + const [imodels, setIModels] = React.useState(); + // We delay network call until the user wants to query the data, this could be in an effect + // but would automatically trigger for EVERY project, causing potentially huge network traffic at startup. + const fetchIModelList = React.useCallback( + async ( + url = `https://${ + props.gridProps.apiOverrides?.serverEnvironmentPrefix + ? `${props.gridProps.apiOverrides?.serverEnvironmentPrefix}-` + : "" + }api.bentley.com/imodels/?iTwinId=${iTwin.id}&$top=10` + ) => { + try { + // Show the skeleton, plus prevent further calls to this function. + setIModels([ + { + id: "loading", + displayName: "", + }, + ]); + + // Start the fetch + const response = await fetch(url, { + headers: { + Authorization: (props.gridProps.accessToken as string) ?? "", + Prefer: "return=minimal", + }, + }); + if (response.ok) { + const data: IModelsFetchData = await response.json(); + setIModels(data.iModels); + if (data.iModels.length === 0) { + setSelection({ displayName: "No iModels created", id: "none" }); + } + } + } catch (error) { + // If an error occurs, clear the versions so they will be fetched again. + setIModels(undefined); + console.error(error); + } + }, + [ + iTwin.id, + props.gridProps.accessToken, + props.gridProps.apiOverrides?.serverEnvironmentPrefix, + ] + ); + // Create a memo of the tileProps we want to override, depending on the state. + const tileProps = React.useMemo>( + () => ({ + actions: + selection && selection.id !== "none" + ? [ + { + key: "create", + label: "Create IModel", + onClick: action("Create IModel clicked"), + }, + { + key: "open", + label: "Open IModel", + onClick: action("Open IModel clicked"), + }, + ] + : [ + { + key: "create", + label: "Create IModel", + onClick: action("Create IModel clicked"), + }, + ], + headerRight: ( + + + + ), + additionalContent: ( + { + imodels === undefined && (await fetchIModelList()); + }} + > + + + ), + }), + [selection, imodels, fetchIModelList] + ); + // TODO: verify + return { + ...props, + ...tileProps, + }; +}; + +export const StatefulPropsOverrides = Template.bind({}); +StatefulPropsOverrides.args = { + apiOverrides: { serverEnvironmentPrefix: "qa" }, + useIndividualState, +}; + +export const WithPostProcessCallback: Story = + withAccessTokenOverride((args) => { + const addStartTile = React.useCallback( + (iTwins: ITwinFull[], status: any) => { + if (status !== (DataStatus as any).Complete) { + return iTwins; + } + iTwins.unshift({ + id: "newProject", + displayName: "New Project", + number: "Click on this tile to create a new ITwin", + }); + return iTwins; + }, + [] + ); + return ( +
+ + Property postProcessCallback allows modification of the + data that is sent to the grid, here, we add a new tile at the start of + the list for a 'New Project'. + + +
+ ); + }); +WithPostProcessCallback.args = { + apiOverrides: { serverEnvironmentPrefix: "qa" }, +}; + +export const FetchAllSubclasses = Template.bind({}); +FetchAllSubclasses.args = { + apiOverrides: { serverEnvironmentPrefix: "qa" }, + iTwinSubClass: "All", +}; + +export const NoResultsWithDefaultEmptyState = Template.bind({}); +NoResultsWithDefaultEmptyState.args = { + ...baseArgs, + apiOverrides: { serverEnvironmentPrefix: "qa" }, + postProcessCallback: (iModels, status) => { + return []; + }, +}; + +export const StringsOverrideGrid = Template.bind({}); +StringsOverrideGrid.args = { + ...baseArgs, + apiOverrides: { + data: [ + { + id: "1", + displayName: "Bridge iTwin", + number: "1111-2222-3333-4444", + image: bridgeThumbnail, + status: "Trial", + }, + { + id: "2", + displayName: "Power iTwin", + number: "2222-3333-4444-5555", + image: powerThumbnail, + status: "Inactive", + }, + { + id: "3", + displayName: "Highway iTwin", + number: "3333-4444-5555-6666", + image: nightThumbnail, + }, + ], + }, + iTwinActions: [ + { + children: "Some action", + key: "something", + onClick: (iTwin) => action("clicked " + iTwin?.displayName)(iTwin), + }, + ], + stringsOverrides: { + moreOptions: "Flere muligheder", + trialBadge: "Prøveversion", + inactiveBadge: "Inaktiv", + addToFavorites: "Føj til favoritter", + removeFromFavorites: "Fjern fra favoritter", + noRowsLabel: "Ingen rækker", + noResultsOverlayLabel: "Ingen resultater fundet.", + footerRowSelected: (count: number) => + count !== 1 + ? `${count.toLocaleString()} rækker valgt` + : `${count.toLocaleString()} række valgt`, + footerTotalVisibleRows: (visibleCount: number, totalCount: number) => + `${visibleCount.toLocaleString()} af ${totalCount.toLocaleString()}`, + paginationRowsPerPage: "Rækker per side:", + }, +}; + +export const StringsOverrideTable = Template.bind({}); +StringsOverrideTable.args = { + ...baseArgs, + viewMode: "cells", + apiOverrides: { + data: [ + { + id: "1", + displayName: "Bridge iTwin", + number: "1111-2222-3333-4444", + image: bridgeThumbnail, + status: "Trial", + }, + { + id: "2", + displayName: "Power iTwin", + number: "2222-3333-4444-5555", + image: powerThumbnail, + status: "Inactive", + }, + { + id: "3", + displayName: "Highway iTwin", + number: "3333-4444-5555-6666", + image: nightThumbnail, + }, + ], + }, + iTwinActions: [ + { + children: "Some action", + key: "something", + onClick: (iTwin) => action("clicked " + iTwin?.displayName)(iTwin), + }, + ], + stringsOverrides: { + moreOptions: "Flere muligheder", + trialBadge: "Prøveversion", + inactiveBadge: "Inaktiv", + addToFavorites: "Føj til favoritter", + removeFromFavorites: "Fjern fra favoritter", + tableColumnName: "iTwin Navn", + tableColumnDescription: "iTwin Beskrivelse", + tableColumnLastModified: "Sidst ændret", + noRowsLabel: "Ingen rækker", + noResultsOverlayLabel: "Ingen resultater fundet.", + footerRowSelected: (count: number) => + count !== 1 + ? `${count.toLocaleString()} rækker valgt` + : `${count.toLocaleString()} række valgt`, + footerTotalVisibleRows: (visibleCount: number, totalCount: number) => + `${visibleCount.toLocaleString()} af ${totalCount.toLocaleString()}`, + paginationRowsPerPage: "Rækker per side:", + }, +}; + +export default { + title: "imodel-browser/ITwinGridMUI", + component: ITwinGrid, + argTypes: { + accessToken, + }, + excludeStories: ["ITwinGrid"], +} as Meta; diff --git a/packages/apps/storybook/src/imodel-browser/ITwinTileMUI.stories.tsx b/packages/apps/storybook/src/imodel-browser/ITwinTileMUI.stories.tsx new file mode 100644 index 00000000..afe1574b --- /dev/null +++ b/packages/apps/storybook/src/imodel-browser/ITwinTileMUI.stories.tsx @@ -0,0 +1,159 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Bentley Systems, Incorporated. All rights reserved. + * See LICENSE.md in the project root for license terms and full copyright notice. + *--------------------------------------------------------------------------------------------*/ +import { + ITwinTile, + type ITwinTileProps, + type ITwinFull, +} from "@itwin/imodel-browser-react/mui"; +import Box from "@mui/material/Box"; +import Chip from "@mui/material/Chip"; +import { action } from "@storybook/addon-actions"; +import { Meta, Story } from "@storybook/react/types-6-0"; +import React from "react"; +import bridgeThumbnail from "../utils/bridge.jpg"; +import powerThumbnail from "../utils/power.jpg"; +import Grid from "@mui/material/Grid"; +import svgMagnet from "@stratakit/icons/magnet.svg"; +import { DefaultThumbnail } from "../../../../modules/imodel-browser/src/containers/ITwinGrid/ITwinTileMUI"; +import { SvgThumbnail } from "@itwin/imodel-browser-react/mui"; + +const InConstrainedContainer = ({ + children, +}: { + children: React.ReactNode; +}) => {children}; + +export const ITwinTileMUIStory = (props: ITwinTileProps) => ( + + + +); + +const baseITwin: ITwinFull = { + id: "1", + displayName: "iTwin Name", + number: "aaaa-bbbb-cccc-dddd", + status: "Trial", + lastModifiedDateTime: "2024-01-01T12:00:00Z", + image: bridgeThumbnail, +}; + +const baseArgs: ITwinTileProps = { + iTwin: { + ...baseITwin, + }, + contextMenuItems: [ + { + key: "option-1", + children: "Option 1", + onClick: (iTwin) => action("iTwin option 1 clicked")(iTwin), + }, + { + key: "option-2", + children: "Option 2", + onClick: (iTwin) => action("iTwin option 2 clicked")(iTwin), + }, + ], + thumbnail: bridgeThumbnail, + onOpen: action("iTwin opened"), + onSelect: action("iTwin selected"), + addToFavorites: async (iTwinId) => { + action("iTwin add to favorites")(iTwinId); + }, + removeFromFavorites: async (iTwinId) => { + action("iTwin remove from favorites")(iTwinId); + }, +}; + +export default { + title: "imodel-browser/ITwinTileMUI", + component: ITwinTileMUIStory, + excludeStories: ["ITwinTileMUIStory"], + argTypes: { + status: { + options: ["undefined", "positive", "warning", "negative"], + mapping: { + undefined: undefined, + positive: "positive", + warning: "warning", + negative: "negative", + }, + control: { + type: "radio", + }, + }, + iTwin: { + options: ["Active", "Inactive", "Trial"], + mapping: { + Active: { ...baseITwin, status: "Active", displayName: "Active iTwin" }, + Inactive: { + ...baseITwin, + status: "Inactive", + displayName: "Inactive iTwin", + }, + Trial: { ...baseITwin, status: "Trial", displayName: "Trial iTwin" }, + }, + control: { + type: "select", + }, + }, + contextMenuItems: { control: false }, + onSelect: { control: false }, + onOpen: { control: false }, + thumbnailBottomLeft: { control: false }, + thumbnail: { control: false }, + actions: { control: false }, + thumbnailTopLeft: { control: false }, + thumbnailTopRight: { control: false }, + children: { control: false }, + stringsOverrides: { control: false }, + }, +} as Meta; + +const Template: Story = (args) => ( + +); + +export const Default = Template.bind({}); +Default.args = { + ...baseArgs, + isFavorite: false, + disabled: false, + loading: false, + selected: false, +}; + +export const DefaultThumbnailStory = Template.bind({}); +DefaultThumbnailStory.args = { + ...baseArgs, + thumbnail: , +}; +DefaultThumbnailStory.storyName = "Default Thumbnail"; + +export const CustomSvgThumbnail = Template.bind({}); +CustomSvgThumbnail.args = { + ...baseArgs, + thumbnail: , +}; + +export const Extensive = Template.bind({}); +Extensive.args = { + ...baseArgs, + status: "warning", + isFavorite: false, + title: "Overridden Title", + description: "Overriden description", + disabled: false, + loading: false, + selected: false, + thumbnailTopLeft: , + thumbnail: powerThumbnail, + getBadge: () => , + actions: [ + { key: "open", label: "Open", onClick: action("iTwin open clicked") }, + { key: "share", label: "Share", onClick: action("iTwin share clicked") }, + ], + additionalContent: , +}; diff --git a/packages/apps/storybook/src/imodel-browser/NoResultsMUI.stories.tsx b/packages/apps/storybook/src/imodel-browser/NoResultsMUI.stories.tsx new file mode 100644 index 00000000..abe95dda --- /dev/null +++ b/packages/apps/storybook/src/imodel-browser/NoResultsMUI.stories.tsx @@ -0,0 +1,40 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Bentley Systems, Incorporated. All rights reserved. + * See LICENSE.md in the project root for license terms and full copyright notice. + *--------------------------------------------------------------------------------------------*/ +import { + NoResults as ExternalComponent, + type NoResultsProps as NoResultsMUIProps, +} from "@itwin/imodel-browser-react/mui"; +import { Meta, Story } from "@storybook/react/types-6-0"; +import React from "react"; + +export const NoResults = (props: NoResultsMUIProps) => ( + +); + +export default { + title: "imodel-browser/NoResultsMUI", + component: NoResults, + excludeStories: ["NoResults"], +} as Meta; + +const Template: Story = (args) => ; + +export const Primary = Template.bind({}); +Primary.args = { + text: "No iModels available", +}; + +export const SearchResults = Template.bind({}); +SearchResults.args = { + text: "No search results", + subtext: "Try adjusting your search criteria.", + isSearchResult: true, +}; + +export const WithSubtext = Template.bind({}); +WithSubtext.args = { + text: "No iModels available", + subtext: "Please check back later.", +}; diff --git a/packages/apps/storybook/src/stratakit.d.ts b/packages/apps/storybook/src/stratakit.d.ts new file mode 100644 index 00000000..1d70ac44 --- /dev/null +++ b/packages/apps/storybook/src/stratakit.d.ts @@ -0,0 +1 @@ +/// diff --git a/packages/apps/storybook/src/utils/README.md b/packages/apps/storybook/src/utils/README.md new file mode 100644 index 00000000..fda49d5b --- /dev/null +++ b/packages/apps/storybook/src/utils/README.md @@ -0,0 +1,8 @@ +Placeholder images are royalty-free from Unsplash + +"Free to use under the Unsplash License" + +https://unsplash.com/photos/time-lapse-photo-of-concrete-highway-with-cars-vdBE638sszE +https://unsplash.com/photos/golden-gate-bridge-san-francisco-california-vj_9l20fzj0 +https://unsplash.com/photos/high-angle-photo-of-road-with-vehicles-NSuufgf-BME +https://unsplash.com/photos/birds-eye-photography-of-concrete-structure-bv2pvCGMtzg diff --git a/packages/apps/storybook/src/utils/bridge.jpg b/packages/apps/storybook/src/utils/bridge.jpg new file mode 100644 index 00000000..4b88857d Binary files /dev/null and b/packages/apps/storybook/src/utils/bridge.jpg differ diff --git a/packages/apps/storybook/src/utils/night.jpg b/packages/apps/storybook/src/utils/night.jpg new file mode 100644 index 00000000..337af120 Binary files /dev/null and b/packages/apps/storybook/src/utils/night.jpg differ diff --git a/packages/apps/storybook/src/utils/overpass.jpg b/packages/apps/storybook/src/utils/overpass.jpg new file mode 100644 index 00000000..9a88592c Binary files /dev/null and b/packages/apps/storybook/src/utils/overpass.jpg differ diff --git a/packages/apps/storybook/src/utils/power.jpg b/packages/apps/storybook/src/utils/power.jpg new file mode 100644 index 00000000..8ee6b967 Binary files /dev/null and b/packages/apps/storybook/src/utils/power.jpg differ diff --git a/packages/apps/storybook/src/utils/storyHelp.ts b/packages/apps/storybook/src/utils/storyHelp.ts index 47847604..61815021 100644 --- a/packages/apps/storybook/src/utils/storyHelp.ts +++ b/packages/apps/storybook/src/utils/storyHelp.ts @@ -14,7 +14,7 @@ export const accessTokenArgTypes = { /** HOC that will override the "accessToken" prop with the Addon token */ export const withAccessTokenOverride: < - T extends { accessToken?: string | (() => Promise) } + T extends { accessToken?: string | (() => Promise) }, >( story: Story ) => Story = (Story) => (args, context) => @@ -24,4 +24,13 @@ export const withAccessTokenOverride: < export const withITwinIdOverride: ( story: Story ) => Story = (Story) => (args, context) => - Story({ ...args, iTwinId: args.iTwinId ?? context.globals.iTwinId }, context); + Story( + { + ...args, + iTwinId: + args.iTwinId ?? + context.globals.iTwinId ?? + "23a67b97-30b3-4cdb-82c0-752edd10606b", + }, + context + ); diff --git a/packages/apps/storybook/tsconfig.eslint.json b/packages/apps/storybook/tsconfig.eslint.json index 1e483cfb..06164757 100644 --- a/packages/apps/storybook/tsconfig.eslint.json +++ b/packages/apps/storybook/tsconfig.eslint.json @@ -1,10 +1,11 @@ { "compilerOptions": { - "strictNullChecks": true + "strictNullChecks": true, + "paths": { + "@itwin/imodel-browser-react/mui": [ + "../../modules/imodel-browser/src/mui/index.ts" + ] + } }, - "include": [ - "**/*.ts*", - "**/*.js*", - "**/.*.js*" - ], -} \ No newline at end of file + "include": ["**/*.ts*", "**/*.js*", "**/.*.js*"] +} diff --git a/packages/apps/storybook/tsconfig.json b/packages/apps/storybook/tsconfig.json new file mode 100644 index 00000000..67577c3c --- /dev/null +++ b/packages/apps/storybook/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "strictNullChecks": true, + "paths": { + "@itwin/imodel-browser-react/mui": [ + "../../modules/imodel-browser/src/mui/index.ts" + ] + } + }, + "include": [ + "**/*.ts*", + "**/*.js*", + "**/.*.js*", + "../../modules/imodel-browser/src/typings/declarations.d.ts" + ] +} diff --git a/packages/modules/imodel-browser/MUI-MIGRATION.md b/packages/modules/imodel-browser/MUI-MIGRATION.md new file mode 100644 index 00000000..f1a058a9 --- /dev/null +++ b/packages/modules/imodel-browser/MUI-MIGRATION.md @@ -0,0 +1,408 @@ +# MUI Migration Notes + +This file tracks migration notes for the MUI/Stratakit components. + +A new `src/mui/index.ts` barrel re-exports MUI components under legacy-aligned names (e.g. `IModelGridMUI as IModelGrid`). This is built as a separate rollup entry point. + +## Styling approach + +All MUI components use **inline `sx` props** instead of CSS module (`.module.scss`) files. This avoids injecting `