diff --git a/.browserslistrc b/.browserslistrc index 6ab4c0c15806ec..6bf6f0e0e1e601 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -72,66 +72,6 @@ safari 15.4 samsung 23 samsung 22 -[legacy] -ie 11 -and_chr 122 -and_chr 121 -and_ff 123 -and_ff 122 -and_qq 14.9 -and_uc 15.5 -android 122 -android 121 -chrome 122 -chrome 121 -chrome 120 -chrome 119 -chrome 109 -edge 122 -edge 121 -firefox 123 -firefox 122 -firefox 115 -ios_saf 17.4 -ios_saf 17.3 -ios_saf 17.2 -ios_saf 17.1 -ios_saf 17.0 -ios_saf 16.6-16.7 -ios_saf 16.5 -ios_saf 16.4 -ios_saf 16.3 -ios_saf 16.2 -ios_saf 16.1 -ios_saf 16.0 -ios_saf 15.6-15.8 -ios_saf 15.5 -ios_saf 15.4 -kaios 3.0-3.1 -kaios 2.5 -op_mini all -op_mob 80 -opera 108 -opera 107 -opera 106 -safari 17.4 -safari 17.3 -safari 17.2 -safari 17.1 -safari 17.0 -safari 16.6 -safari 16.5 -safari 16.4 -safari 16.3 -safari 16.2 -safari 16.1 -safari 16.0 -safari 15.6 -safari 15.5 -safari 15.4 -samsung 23 -samsung 22 - # snapshot of `npx browserslist "maintained node versions"` # On update check all #stable-snapshot markers [node] diff --git a/.circleci/config.yml b/.circleci/config.yml index 5a36ecd48f0849..fbbeae9ee51a81 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,6 @@ version: 2.1 orbs: - aws-cli: circleci/aws-cli@4.1 + aws-cli: circleci/aws-cli@4.1.3 aws-s3: circleci/aws-s3@4.0 parameters: @@ -45,7 +45,7 @@ default-job: &default-job AWS_REGION_ARTIFACTS: eu-central-1 working_directory: /tmp/material-ui docker: - - image: cimg/node:18.19 + - image: cimg/node:18.20 default-context: &default-context context: @@ -215,6 +215,9 @@ jobs: #!/bin/bash VALE_STR_CLI_VERSION=3.3.0 + # set smart sudo + if [[ $EUID -eq 0 ]]; then export SUDO=""; else export SUDO="sudo"; fi + mkdir /tmp/vale-extract cd /tmp/vale-extract GZIPPED_OUTPUT="vale.tar.gz" @@ -244,7 +247,7 @@ jobs: name: Lint writing style command: | vale sync - pnpm run valelint + pnpm valelint test_static: <<: *default-job steps: @@ -380,7 +383,7 @@ jobs: <<: *default-job resource_class: 'medium+' docker: - - image: mcr.microsoft.com/playwright:v1.43.0-focal + - image: mcr.microsoft.com/playwright:v1.43.1-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -410,7 +413,7 @@ jobs: test_e2e: <<: *default-job docker: - - image: mcr.microsoft.com/playwright:v1.43.0-focal + - image: mcr.microsoft.com/playwright:v1.43.1-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -430,7 +433,7 @@ jobs: # NOTE: This workflow runs after successful docs deploy. See /test/e2e-website/README.md#ci <<: *default-job docker: - - image: mcr.microsoft.com/playwright:v1.43.0-focal + - image: mcr.microsoft.com/playwright:v1.43.1-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -445,7 +448,7 @@ jobs: test_profile: <<: *default-job docker: - - image: mcr.microsoft.com/playwright:v1.43.0-focal + - image: mcr.microsoft.com/playwright:v1.43.1-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -472,7 +475,7 @@ jobs: test_regressions: <<: *default-job docker: - - image: mcr.microsoft.com/playwright:v1.43.0-focal + - image: mcr.microsoft.com/playwright:v1.43.1-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -526,7 +529,7 @@ jobs: <<: *default-job working_directory: /tmp/material-ui/test/bundling/fixtures/next-webpack4/ docker: - - image: mcr.microsoft.com/playwright:v1.43.0-focal + - image: mcr.microsoft.com/playwright:v1.43.1-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -550,7 +553,7 @@ jobs: <<: *default-job working_directory: /tmp/material-ui/test/bundling/fixtures/next-webpack5/ docker: - - image: mcr.microsoft.com/playwright:v1.43.0-focal + - image: mcr.microsoft.com/playwright:v1.43.1-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -574,7 +577,7 @@ jobs: <<: *default-job working_directory: /tmp/material-ui/test/bundling/fixtures/create-react-app/ docker: - - image: mcr.microsoft.com/playwright:v1.43.0-focal + - image: mcr.microsoft.com/playwright:v1.43.1-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -598,7 +601,7 @@ jobs: <<: *default-job working_directory: /tmp/material-ui/test/bundling/fixtures/snowpack/ docker: - - image: mcr.microsoft.com/playwright:v1.43.0-focal + - image: mcr.microsoft.com/playwright:v1.43.1-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -622,7 +625,7 @@ jobs: <<: *default-job working_directory: /tmp/material-ui/test/bundling/fixtures/vite/ docker: - - image: mcr.microsoft.com/playwright:v1.43.0-focal + - image: mcr.microsoft.com/playwright:v1.43.1-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -646,7 +649,7 @@ jobs: <<: *default-job working_directory: /tmp/material-ui/test/bundling/fixtures/esbuild/ docker: - - image: mcr.microsoft.com/playwright:v1.43.0-focal + - image: mcr.microsoft.com/playwright:v1.43.1-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -674,7 +677,7 @@ jobs: <<: *default-job working_directory: /tmp/material-ui/test/bundling/fixtures/gatsby/ docker: - - image: mcr.microsoft.com/playwright:v1.43.0-focal + - image: mcr.microsoft.com/playwright:v1.43.1-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -775,7 +778,7 @@ jobs: test_benchmark: <<: *default-job docker: - - image: mcr.microsoft.com/playwright:v1.43.0-focal + - image: mcr.microsoft.com/playwright:v1.43.1-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: diff --git a/.eslintignore b/.eslintignore index 0c319dcfc059aa..9a58941c035a16 100644 --- a/.eslintignore +++ b/.eslintignore @@ -19,12 +19,6 @@ /packages/mui-icons-material/src/*.js /packages/mui-icons-material/templateSvgIcon.js /packages/mui-utils/macros/__fixtures__/ -/packages/pigment-css-react/utils/ -/packages/pigment-css-react/processors/ -/packages/pigment-css-react/exports/ -/packages/pigment-css-react/theme/ -/packages/pigment-css-react/tests/**/fixtures -/packages/pigment-css-nextjs-plugin/loader.js # Ignore fixtures /packages-internal/scripts/typescript-to-proptypes/test/*/* /test/bundling/fixtures/**/*.fixture.js diff --git a/.eslintrc.js b/.eslintrc.js index a06ac35ae3f3ae..7f2b9b58f5c08a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,8 +1,8 @@ const path = require('path'); const { rules: baseStyleRules } = require('eslint-config-airbnb-base/rules/style'); -const forbidTopLevelMessage = [ - 'Prefer one level nested imports to avoid bundling everything in dev mode', +const OneLevelImportMessage = [ + 'Prefer one level nested imports to avoid bundling everything in dev mode or breaking CJS/ESM split.', 'See https://github.com/mui/material-ui/pull/24147 for the kind of win it can unlock.', ].join('\n'); // This only applies to packages published from this monorepo. @@ -65,7 +65,20 @@ module.exports = { 'no-restricted-imports': [ 'error', { - patterns: ['@mui/*/*/*'], + patterns: [ + { + group: [ + '@mui/*/*/*', + '@pigment-css/*/*/*', + '@base_ui/*/*/*', + // Allow any import depth with any internal packages + '!@mui/internal-*/**', + // TODO delete, @mui/docs should be @mui/internal-docs + '!@mui/docs/**', + ], + message: OneLevelImportMessage, + }, + ], }, ], 'no-continue': 'off', @@ -164,7 +177,7 @@ module.exports = { 'react/state-in-constructor': 'off', // stylistic opinion. For conditional assignment we want it outside, otherwise as static 'react/static-property-placement': 'off', - // noopener is enough, no IE 11 support + // noopener is enough // https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-target-blank.md#rule-options 'react/jsx-no-target-blank': ['error', { allowReferrer: true }], @@ -331,23 +344,6 @@ module.exports = { 'import/export': 'off', // Not sure why it doesn't work }, }, - { - files: ['*.tsx'], - excludedFiles: '*.spec.tsx', - rules: { - // WARNING: If updated, make sure these rules are merged with `no-restricted-imports` (#ts-source-files) - 'no-restricted-imports': [ - 'error', - { - patterns: [ - // Allow deeper imports for TypeScript types. TODO remove - '@mui/*/*/*/*', - ], - }, - ], - }, - }, - // Files used for generating TypeScript declaration files (#ts-source-files) { files: ['packages/*/src/**/*.tsx'], excludedFiles: '*.spec.tsx', @@ -429,11 +425,11 @@ module.exports = { paths: [ { name: '@mui/material', - message: forbidTopLevelMessage, + message: OneLevelImportMessage, }, { name: '@mui/lab', - message: forbidTopLevelMessage, + message: OneLevelImportMessage, }, ], }, diff --git a/.github/workflows/cherry-pick-next-to-master.yml b/.github/workflows/cherry-pick-next-to-master.yml index 2fe2a126d4c30a..20f0f827b8b46d 100644 --- a/.github/workflows/cherry-pick-next-to-master.yml +++ b/.github/workflows/cherry-pick-next-to-master.yml @@ -18,7 +18,7 @@ jobs: if: ${{ contains(github.event.pull_request.labels.*.name, 'needs cherry-pick') && github.event.pull_request.merged == true }} steps: - name: Checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: fetch-depth: 0 - name: Cherry pick and create the new PR diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24255495324d9b..3d726a90bd2a34 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: os: [macos-latest, windows-latest, ubuntu-latest] steps: - run: echo "${{ github.actor }}" - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: # fetch all tags which are required for `pnpm release:changelog` fetch-depth: 0 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0aee3528195eb3..440aea64682bbf 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -16,10 +16,10 @@ jobs: security-events: write steps: - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10 + uses: github/codeql-action/init@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: languages: typescript config-file: ./.github/codeql/codeql-config.yml @@ -30,4 +30,4 @@ jobs: # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # queries: security-extended,security-and-quality - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10 + uses: github/codeql-action/analyze@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 6b65948ab310ff..69f8a46048c068 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -22,7 +22,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false @@ -43,6 +43,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: Upload to code-scanning - uses: github/codeql-action/upload-sarif@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: sarif_file: results.sarif diff --git a/.github/workflows/vale-action.yml b/.github/workflows/vale-action.yml index fce1352d13c355..72538b21e7a49e 100644 --- a/.github/workflows/vale-action.yml +++ b/.github/workflows/vale-action.yml @@ -12,7 +12,7 @@ jobs: contents: read pull-requests: write steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: errata-ai/vale-action@38bf078c328061f59879b347ca344a718a736018 # v2.1.0 continue-on-error: true # GitHub Action flag needed until https://github.com/errata-ai/vale-action/issues/89 is fixed with: diff --git a/CHANGELOG.md b/CHANGELOG.md index b359e9a43437de..65849f441603ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,171 @@ # [Versions](https://mui.com/versions/) +## v6.0.0-alpha.5 + + + +_May 1, 2024_ + +A big thanks to the 9 contributors who made this release possible. Here are some highlights ✨: + +### `@mui/material@6.0.0-alpha.5` + +- [FormControlLabel] Deprecate `componentsProps` (#41767) @sai6855 +- [PaginationItem] Deprecate components prop (#41777) @sai6855 +- [SvgIcon] Convert to support CSS extraction (#41779) @aarongarciah + +### `@mui/base@5.0.0-beta.43` + +- [TextareaAutosize] Fix resizing instability (#41638) @ZeeshanTamboli + +### Docs + +- Fix small SEO issues @oliviertassinari +- [material-ui] Fix minor spelling error in the "About the lab" page (#42073) @ryanhartwig +- [material-ui] Update Figma plugin name (#41967) @danilo-leal +- [material-ui][templates] Fix input props attributes in Landing Page template (#42013) @5-tom +- [system] Update typo on the sx prop page (#42035) @bricker + +### Core + +- [docs-infra] Clean up branding theme file and improve font-face readibility (#42023) @danilo-leal +- [docs-infra] Simplify docs demo (#42016) @oliviertassinari +- [website] Add content about the Sync plugin in the Material UI page (#40515) @danilo-leal +- [website] Sync career roles (#42058) @oliviertassinari +- [website] Add Nadja on the about page (#42021) @mnajdova +- [website] Fix code block design by changing the `MarkdownElement` import (#42022) @danilo-leal +- [wesbite] Remove duplicate MarkdownElement component (#42028) @danilo-leal + +All contributors of this release in alphabetical order: @5-tom, @aarongarciah, @bricker, @danilo-leal, @mnajdova, @oliviertassinari, @ryanhartwig, @sai6855, @ZeeshanTamboli + +## v6.0.0-alpha.4 + + + +_Apr 24, 2024_ + +A big thanks to the 15 contributors who made this release possible. Here are some highlights ✨: + +- 🔥 Converted 3 more Material UI components to use Pigment CSS. +- ℹ️ Pigment CSS now lives in [its own repository](https://github.com/mui/pigment-css)! From now on, all future development will happen there. + +### `@mui/material@6.0.0-alpha.4` + +- [Checkbox] Convert to support CSS extraction (#41957) @lhilgert9 +- [IconButton] Convert to support CSS extraction (#41850) @gijsbotje +- [Radio] Convert to support CSS extraction (#41840) @lhilgert9 +- [Typography] Fix ownerState prop placement (#41903) @sai6855 +- Generate typography tokens (#41703) @siriwatknp +- Move typography CSS variables to `font` (#42003) @siriwatknp +- Fix getOverlayAlpha type (#41995) @oliviertassinari +- Support CSS Extraction using codemod (#41935) @siriwatknp + +### `@mui/icons-material@6.0.0-alpha.4` + +- ​[icons] Update the icons package (#41937) @danilo-leal + +### Docs + +- [material-ui] Remove react-swipeable-views from demos as it's no longer maintained (#41912) @soler1212 +- [material-ui] Add dark theme thumbnails for templates (#41947) @zanivan +- [material-ui] Remove links and interdependencies from free templates (#41941) @zanivan +- [material-ui] Add missing backticks to HTML tag in the installation page (#41972) @Miguelrom +- Fix 301 Toolpad links @oliviertassinari +- Fix 301 image redirections @oliviertassinari + +### Core + +- pnpm docs:zipRules && vale sync @oliviertassinari +- Remove @pigment-css/\* packages (#41965) @mnajdova +- [code-infra] Move the HighlightedCode component to @mui/docs (#41859) @Janpot +- [code-infra] Move the HighlightedCode component to @mui/docs (#41859) @Janpot +- [code-infra] Make Babel config path configurable in API docs builder (#41999) @michaldudak +- [docs-infra] Fix flex-shrink pro-plan (#41990) @oliviertassinari +- [docs-infra] Allow more value uses of MUI (#41706) @oliviertassinari +- [docs-infra] Move CPU to shared config (#41901) @oliviertassinari +- [docs-infra] Improve Twitter OG:image (#41860) @oliviertassinari +- [docs-infra] Adapt docs infra to Base UI docs needs (#41963) @michaldudak +- [docs-infra] Add demo container design refinements (#41948) @danilo-leal +- [docs-infra] Use the `getLayout` on the material demo pages (#41936) @alexfauquette +- [test] Update browser versions in karma config (#42008) @ZeeshanTamboli +- [website] Remove customer support agent role from website (#41969) @rluzists1 +- [website] Fix grid usage and add stray improvements (#41930) @danilo-leal + +All contributors of this release in alphabetical order: @alexfauquette, @danilo-leal, @gijsbotje, @Janpot, @lhilgert9, @michaldudak, @Miguelrom, @mnajdova, @oliviertassinari, @rluzists1, @sai6855, @siriwatknp, @soler1212, @zanivan, @ZeeshanTamboli + +## v6.0.0-alpha.3 + + + +_Apr 17, 2024_ + +A big thanks to the 24 contributors who made this release possible. Here are some highlights ✨: + +- 🔥 Converted 5 more Material UI components to use Pigment CSS. +- 🚀 Added container queries utility to the `@mui/system` package (#41674) @siriwatknp. + +### `@mui/material@6.0.0-alpha.3` + +- Convert `LinearProgress` to support Pigment CSS (#41816) @siriwatknp +- [Dialog] Prevent onClick on the root element from being overwritten (#41881) @ryanburr +- [FloatingActionButton] Convert to support CSS extraction (#41851) @gijsbotje +- Convert `CircularProgress` to support Pigment CSS (#41776) @siriwatknp +- [PaginationItem] Convert to support CSS extraction (#41848) @gijsbotje +- [StepConnector] deprecate composed classes (#41740) @sai6855 +- [StepLabel] Deprecate `StepIconComponent`, `StepIconProps` (#41835) @sai6855 +- [ToggleButton] Convert to support CSS extraction (#41782) @lhilgert9 +- [ToggleButtonGroup] Deprecate composed classes (#41288) @sai6855 +- [Typography] Fix Typography inherit variant styles (#41308) @kealjones-wk + +### `@mui/system@6.0.0-alpha.3` + +- Add container queries utility (#41674) @siriwatknp + +### `@mui/codemod@6.0.0-alpha.3` + +- Add styled v6 transformation (#41743) @siriwatknp + +### `@mui/joy@5.0.0-beta.36` + +- [Button] Disable text highlighting (#41902) @mithun522 + +### `@pigment-css/react@0.0.7` + +- Patch WyW's WeakRef usage (#41909) @DiegoAndai +- Implement sx transform for system components (#41861) @brijeshb42 + +### Docs + +- [material-ui] Add Connect-related content (#40848) @danilo-leal +- [material-ui] Fix credit comment typo (#41872) @aarongarciah +- [material-ui] Remove Data Grid v7 beta callout (#41839) @cherniavskii +- [material-ui] Add stray design tweaks to free templates (#41696) @zanivan +- [material-ui] Simplify components styling on templates (#41845) @zanivan +- [material-ui][Button] Add `onChange` event handler to file upload example (#41863) @aarongarciah +- [material-ui] Fix import statement in migration guide (#41852) @sai6855 +- Fix 301 redirection @oliviertassinari +- Fix format git diff regression (#41882) @oliviertassinari +- Fix small SEO issues @oliviertassinari +- [pigment-css] Fix README typos (#41870) @MohammadShehadeh + +### Core + +- Begin removing IE 11-related code (#41709) @iammminzzy +- [blog] Add post to introduce the Connect plugin (#41763) @danilo-leal +- [code-infra] Fix require.context with aliases (#41682) @Janpot +- [code-infra] Allow customizing hooks imports in API docs generator (#41828) @michaldudak +- [codemod] Add utils for `*Component` and `*Props` props deprecations (#41685) @DiegoAndai +- Replace bundle size reporter filter (#38979) @Janpot +- [docs-infra] Make the whole header clickable (#39603) @MoazMirza-13 +- [docs-infra] Improve demo container and related components design (#41827) @danilo-leal +- [docs-infra] Use edge function for card generation (#41188) (#41836) @alexfauquette +- [docs-infra] Fix code block layout shift (#41917) @oliviertassinari +- [docs-infra] Fine-tune the OG card image design (#41862) @danilo-leal +- [docs-infra] Fix markdown version for material (#41908) @alexfauquette +- [docs-infra] Support multiple tabs in demos (#40901) @bharatkashyap + +All contributors of this release in alphabetical order: @aarongarciah, @alexfauquette, @bharatkashyap, @brijeshb42, @cherniavskii, @danilo-leal, @DiegoAndai, @EyaOuenniche, @gijsbotje, @iammminzzy, @Janpot, @kealjones-wk, @lhilgert9, @magnimarels, @michaldudak, @mithun522, @mnajdova, @MoazMirza-13, @MohammadShehadeh, @oliviertassinari, @ryanburr, @sai6855, @siriwatknp, @zanivan + ## v6.0.0-alpha.2 diff --git a/apps/local-ui-lib/package.json b/apps/local-ui-lib/package.json index 9cf9342c098b12..aebf0777660701 100644 --- a/apps/local-ui-lib/package.json +++ b/apps/local-ui-lib/package.json @@ -3,6 +3,6 @@ "version": "0.0.1", "private": true, "dependencies": { - "@pigment-css/react": "file:../../packages/pigment-css-react" + "@pigment-css/react": "^0.0.9" } } diff --git a/apps/local-ui-lib/tsconfig.json b/apps/local-ui-lib/tsconfig.json index cad7b2a86bf955..4082f16a5d91ce 100644 --- a/apps/local-ui-lib/tsconfig.json +++ b/apps/local-ui-lib/tsconfig.json @@ -1,8 +1,3 @@ { - "extends": "../../tsconfig.json", - "references": [ - { - "path": "../../packages/pigment-css-react" - } - ] + "extends": "../../tsconfig.json" } diff --git a/apps/pigment-css-next-app/README.md b/apps/pigment-css-next-app/README.md index 981a5f388be63e..1f520a3e1172ea 100644 --- a/apps/pigment-css-next-app/README.md +++ b/apps/pigment-css-next-app/README.md @@ -4,10 +4,10 @@ This is a Pigment CSS and [Next.js](https://nextjs.org/) project bootstrapped w ## Getting started -First, build all the packages in the workspace atleast once. Run +First, build all the packages in the workspace at least once. Run ```bash -pnpm build:zero +pnpm build ``` Then start the Next.js development server: diff --git a/apps/pigment-css-next-app/package.json b/apps/pigment-css-next-app/package.json index 54e6c80e27a573..d6122741013d76 100644 --- a/apps/pigment-css-next-app/package.json +++ b/apps/pigment-css-next-app/package.json @@ -9,7 +9,7 @@ "clean": "rimraf .next" }, "dependencies": { - "@pigment-css/react": "workspace:^", + "@pigment-css/react": "^0.0.9", "@mui/utils": "workspace:^", "@mui/base": "workspace:^", "@mui/lab": "workspace:^", @@ -24,12 +24,12 @@ "next": "latest" }, "devDependencies": { - "@pigment-css/nextjs-plugin": "workspace:^", + "@pigment-css/nextjs-plugin": "^0.0.9", "@types/node": "^20.5.7", "@types/react": "^18.2.55", - "@types/react-dom": "^18.2.19", + "@types/react-dom": "^18.3.0", "eslint": "^8.57.0", - "typescript": "^5.4.4" + "typescript": "^5.4.5" }, "nx": { "targets": { diff --git a/apps/pigment-css-next-app/src/app/layout.tsx b/apps/pigment-css-next-app/src/app/layout.tsx index 6cb8bd6887ad1c..77126c9b714539 100644 --- a/apps/pigment-css-next-app/src/app/layout.tsx +++ b/apps/pigment-css-next-app/src/app/layout.tsx @@ -24,6 +24,8 @@ export default function RootLayout(props: { children: React.ReactNode }) { background-color: ${({ theme: t }) => t.vars.palette.background.default}; color: ${({ theme: t }) => t.vars.palette.text.primary}; background-image: url('@/assets/mui.svg'); + background-repeat: no-repeat; + background-position: 1rem 1rem; `}`} > diff --git a/apps/pigment-css-next-app/src/app/material-ui/icons/page.tsx b/apps/pigment-css-next-app/src/app/material-ui/icons/page.tsx new file mode 100644 index 00000000000000..a5a646c5635606 --- /dev/null +++ b/apps/pigment-css-next-app/src/app/material-ui/icons/page.tsx @@ -0,0 +1,72 @@ +'use client'; +import * as React from 'react'; +import CreateSvgIcon from '../../../../../../docs/data/material/components/icons/CreateSvgIcon'; +import FontAwesomeIcon from '../../../../../../docs/data/material/components/icons/FontAwesomeIcon'; +import FontAwesomeIconSize from '../../../../../../docs/data/material/components/icons/FontAwesomeIconSize'; +import FontAwesomeSvgIconDemo from '../../../../../../docs/data/material/components/icons/FontAwesomeSvgIconDemo'; +import Icons from '../../../../../../docs/data/material/components/icons/Icons'; +import SvgIconChildren from '../../../../../../docs/data/material/components/icons/SvgIconChildren'; +import SvgIconsColor from '../../../../../../docs/data/material/components/icons/SvgIconsColor'; +import SvgIconsSize from '../../../../../../docs/data/material/components/icons/SvgIconsSize'; +import SvgMaterialIcons from '../../../../../../docs/data/material/components/icons/SvgMaterialIcons'; + +export default function IconsPage() { + return ( + +
+

Create Svg Icon

+
+ +
+
+
+

Font Awesome Icon

+
+ +
+
+
+

Font Awesome Icon Size

+
+ +
+
+
+

Font Awesome Svg Icon Demo

+
+ +
+
+
+

Icons

+
+ +
+
+
+

Svg Icon Children

+
+ +
+
+
+

Svg Icons Color

+
+ +
+
+
+

Svg Icons Size

+
+ +
+
+
+

Svg Material Icons

+
+ +
+
+
+ ); +} diff --git a/apps/pigment-css-next-app/src/app/material-ui/react-checkbox/page.tsx b/apps/pigment-css-next-app/src/app/material-ui/react-checkbox/page.tsx new file mode 100644 index 00000000000000..94e60f90ae0c67 --- /dev/null +++ b/apps/pigment-css-next-app/src/app/material-ui/react-checkbox/page.tsx @@ -0,0 +1,79 @@ +'use client'; +import * as React from 'react'; +import CheckboxLabels from '../../../../../../docs/data/material/components/checkboxes/CheckboxLabels'; +import CheckboxesComponent from '../../../../../../docs/data/material/components/checkboxes/Checkboxes'; +import CheckboxesGroup from '../../../../../../docs/data/material/components/checkboxes/CheckboxesGroup'; +import ColorCheckboxes from '../../../../../../docs/data/material/components/checkboxes/ColorCheckboxes'; +import ControlledCheckbox from '../../../../../../docs/data/material/components/checkboxes/ControlledCheckbox'; +import CustomizedCheckbox from '../../../../../../docs/data/material/components/checkboxes/CustomizedCheckbox'; +import FormControlLabelPosition from '../../../../../../docs/data/material/components/checkboxes/FormControlLabelPosition'; +import IconCheckboxes from '../../../../../../docs/data/material/components/checkboxes/IconCheckboxes'; +import IndeterminateCheckbox from '../../../../../../docs/data/material/components/checkboxes/IndeterminateCheckbox'; +import SizeCheckboxes from '../../../../../../docs/data/material/components/checkboxes/SizeCheckboxes'; + +export default function Checkboxes() { + return ( + +
+

Checkbox Labels

+
+ +
+
+
+

Checkboxes

+
+ +
+
+
+

Checkboxes Group

+
+ +
+
+
+

Color Checkboxes

+
+ +
+
+
+

Controlled Checkbox

+
+ +
+
+
+

Customized Checkbox

+
+ +
+
+
+

Form Control Label Position

+
+ +
+
+
+

Icon Checkboxes

+
+ +
+
+
+

Indeterminate Checkbox

+
+ +
+
+
+

Size Checkboxes

+
+ +
+
+
+ ); +} diff --git a/apps/pigment-css-next-app/src/app/material-ui/react-floating-action-button/page.tsx b/apps/pigment-css-next-app/src/app/material-ui/react-floating-action-button/page.tsx new file mode 100644 index 00000000000000..4e39c5f719b8dd --- /dev/null +++ b/apps/pigment-css-next-app/src/app/material-ui/react-floating-action-button/page.tsx @@ -0,0 +1,37 @@ +'use client'; +import * as React from 'react'; +import FloatingActionButtonExtendedSize from '../../../../../../docs/data/material/components/floating-action-button/FloatingActionButtonExtendedSize'; +import FloatingActionButtonSize from '../../../../../../docs/data/material/components/floating-action-button/FloatingActionButtonSize'; +import FloatingActionButtonZoom from '../../../../../../docs/data/material/components/floating-action-button/FloatingActionButtonZoom'; +import FloatingActionButtons from '../../../../../../docs/data/material/components/floating-action-button/FloatingActionButtons'; + +export default function FloatingActionButton() { + return ( + +
+

Floating Action Button Extended Size

+
+ +
+
+
+

Floating Action Button Size

+
+ +
+
+
+

Floating Action Button Zoom

+
+ +
+
+
+

Floating Action Buttons

+
+ +
+
+
+ ); +} diff --git a/apps/pigment-css-next-app/src/app/material-ui/react-pagination/page.tsx b/apps/pigment-css-next-app/src/app/material-ui/react-pagination/page.tsx new file mode 100644 index 00000000000000..89723ca9e16b84 --- /dev/null +++ b/apps/pigment-css-next-app/src/app/material-ui/react-pagination/page.tsx @@ -0,0 +1,86 @@ +'use client'; +import * as React from 'react'; +import BasicPagination from '../../../../../../docs/data/material/components/pagination/BasicPagination'; +import CustomIcons from '../../../../../../docs/data/material/components/pagination/CustomIcons'; +import PaginationButtons from '../../../../../../docs/data/material/components/pagination/PaginationButtons'; +import PaginationControlled from '../../../../../../docs/data/material/components/pagination/PaginationControlled'; +import PaginationLink from '../../../../../../docs/data/material/components/pagination/PaginationLink'; +import PaginationOutlined from '../../../../../../docs/data/material/components/pagination/PaginationOutlined'; +import PaginationRanges from '../../../../../../docs/data/material/components/pagination/PaginationRanges'; +import PaginationRounded from '../../../../../../docs/data/material/components/pagination/PaginationRounded'; +import PaginationSize from '../../../../../../docs/data/material/components/pagination/PaginationSize'; +import TablePaginationDemo from '../../../../../../docs/data/material/components/pagination/TablePaginationDemo'; +import UsePagination from '../../../../../../docs/data/material/components/pagination/UsePagination'; + +export default function Pagination() { + return ( + +
+

Basic Pagination

+
+ +
+
+
+

Custom Icons

+
+ +
+
+
+

Pagination Buttons

+
+ +
+
+
+

Pagination Controlled

+
+ +
+
+
+

Pagination Link

+
+ +
+
+
+

Pagination Outlined

+
+ +
+
+
+

Pagination Ranges

+
+ +
+
+
+

Pagination Rounded

+
+ +
+
+
+

Pagination Size

+
+ +
+
+
+

Table Pagination Demo

+
+ +
+
+
+

Use Pagination

+
+ +
+
+
+ ); +} diff --git a/apps/pigment-css-next-app/src/app/material-ui/react-progress/page.tsx b/apps/pigment-css-next-app/src/app/material-ui/react-progress/page.tsx new file mode 100644 index 00000000000000..1a804f5d65e92a --- /dev/null +++ b/apps/pigment-css-next-app/src/app/material-ui/react-progress/page.tsx @@ -0,0 +1,100 @@ +'use client'; +import * as React from 'react'; +import CircularColor from '../../../../../../docs/data/material/components/progress/CircularColor'; +import CircularDeterminate from '../../../../../../docs/data/material/components/progress/CircularDeterminate'; +import CircularIndeterminate from '../../../../../../docs/data/material/components/progress/CircularIndeterminate'; +import CircularIntegration from '../../../../../../docs/data/material/components/progress/CircularIntegration'; +import CircularUnderLoad from '../../../../../../docs/data/material/components/progress/CircularUnderLoad'; +import CircularWithValueLabel from '../../../../../../docs/data/material/components/progress/CircularWithValueLabel'; +import CustomizedProgressBars from '../../../../../../docs/data/material/components/progress/CustomizedProgressBars'; +import DelayingAppearance from '../../../../../../docs/data/material/components/progress/DelayingAppearance'; +import LinearBuffer from '../../../../../../docs/data/material/components/progress/LinearBuffer'; +import LinearColor from '../../../../../../docs/data/material/components/progress/LinearColor'; +import LinearDeterminate from '../../../../../../docs/data/material/components/progress/LinearDeterminate'; +import LinearIndeterminate from '../../../../../../docs/data/material/components/progress/LinearIndeterminate'; +import LinearWithValueLabel from '../../../../../../docs/data/material/components/progress/LinearWithValueLabel'; + +export default function Progress() { + return ( + +
+

Circular Color

+
+ +
+
+
+

Circular Determinate

+
+ +
+
+
+

Circular Indeterminate

+
+ +
+
+
+

Circular Integration

+
+ +
+
+
+

Circular Under Load

+
+ +
+
+
+

Circular With Value Label

+
+ +
+
+
+

Customized Progress Bars

+
+ +
+
+
+

Delaying Appearance

+
+ +
+
+
+

Linear Buffer

+
+ +
+
+
+

Linear Color

+
+ +
+
+
+

Linear Determinate

+
+ +
+
+
+

Linear Indeterminate

+
+ +
+
+
+

Linear With Value Label

+
+ +
+
+
+ ); +} diff --git a/apps/pigment-css-next-app/src/app/material-ui/react-radio-button/page.tsx b/apps/pigment-css-next-app/src/app/material-ui/react-radio-button/page.tsx new file mode 100644 index 00000000000000..dda8ef7fe821b6 --- /dev/null +++ b/apps/pigment-css-next-app/src/app/material-ui/react-radio-button/page.tsx @@ -0,0 +1,79 @@ +'use client'; +import * as React from 'react'; +import ColorRadioButtons from '../../../../../../docs/data/material/components/radio-buttons/ColorRadioButtons'; +import ControlledRadioButtonsGroup from '../../../../../../docs/data/material/components/radio-buttons/ControlledRadioButtonsGroup'; +import CustomizedRadios from '../../../../../../docs/data/material/components/radio-buttons/CustomizedRadios'; +import ErrorRadios from '../../../../../../docs/data/material/components/radio-buttons/ErrorRadios'; +import FormControlLabelPlacement from '../../../../../../docs/data/material/components/radio-buttons/FormControlLabelPlacement'; +import RadioButtonsComponent from '../../../../../../docs/data/material/components/radio-buttons/RadioButtons'; +import RadioButtonsGroup from '../../../../../../docs/data/material/components/radio-buttons/RadioButtonsGroup'; +import RowRadioButtonsGroup from '../../../../../../docs/data/material/components/radio-buttons/RowRadioButtonsGroup'; +import SizeRadioButtons from '../../../../../../docs/data/material/components/radio-buttons/SizeRadioButtons'; +import UseRadioGroup from '../../../../../../docs/data/material/components/radio-buttons/UseRadioGroup'; + +export default function RadioButtons() { + return ( + +
+

Color Radio Buttons

+
+ +
+
+
+

Controlled Radio Buttons Group

+
+ +
+
+
+

Customized Radios

+
+ +
+
+
+

Error Radios

+
+ +
+
+
+

Form Control Label Placement

+
+ +
+
+
+

Radio Buttons

+
+ +
+
+
+

Radio Buttons Group

+
+ +
+
+
+

Row Radio Buttons Group

+
+ +
+
+
+

Size Radio Buttons

+
+ +
+
+
+

Use Radio Group

+
+ +
+
+
+ ); +} diff --git a/apps/pigment-css-next-app/src/app/material-ui/react-stepper/page.tsx b/apps/pigment-css-next-app/src/app/material-ui/react-stepper/page.tsx index 81bc13081eeb64..8e135c3b896a2e 100644 --- a/apps/pigment-css-next-app/src/app/material-ui/react-stepper/page.tsx +++ b/apps/pigment-css-next-app/src/app/material-ui/react-stepper/page.tsx @@ -7,7 +7,6 @@ import HorizontalLinearStepper from '../../../../../../docs/data/material/compon import HorizontalNonLinearStepper from '../../../../../../docs/data/material/components/steppers/HorizontalNonLinearStepper'; import HorizontalStepperWithError from '../../../../../../docs/data/material/components/steppers/HorizontalStepperWithError'; import ProgressMobileStepper from '../../../../../../docs/data/material/components/steppers/ProgressMobileStepper'; -import SwipeableTextMobileStepper from '../../../../../../docs/data/material/components/steppers/SwipeableTextMobileStepper'; import TextMobileStepper from '../../../../../../docs/data/material/components/steppers/TextMobileStepper'; import VerticalLinearStepper from '../../../../../../docs/data/material/components/steppers/VerticalLinearStepper'; @@ -56,12 +55,6 @@ export default function Steppers() { -
-

Swipeable Text Mobile Stepper

-
- -
-

Text Mobile Stepper

diff --git a/apps/pigment-css-next-app/src/app/material-ui/react-toggle-button/page.tsx b/apps/pigment-css-next-app/src/app/material-ui/react-toggle-button/page.tsx new file mode 100644 index 00000000000000..1ff789e4f6d4bf --- /dev/null +++ b/apps/pigment-css-next-app/src/app/material-ui/react-toggle-button/page.tsx @@ -0,0 +1,65 @@ +'use client'; +import * as React from 'react'; +import ColorToggleButton from '../../../../../../docs/data/material/components/toggle-button/ColorToggleButton'; +import CustomizedDividers from '../../../../../../docs/data/material/components/toggle-button/CustomizedDividers'; +import StandaloneToggleButton from '../../../../../../docs/data/material/components/toggle-button/StandaloneToggleButton'; +import ToggleButtonNotEmpty from '../../../../../../docs/data/material/components/toggle-button/ToggleButtonNotEmpty'; +import ToggleButtonSizes from '../../../../../../docs/data/material/components/toggle-button/ToggleButtonSizes'; +import ToggleButtons from '../../../../../../docs/data/material/components/toggle-button/ToggleButtons'; +import ToggleButtonsMultiple from '../../../../../../docs/data/material/components/toggle-button/ToggleButtonsMultiple'; +import VerticalToggleButtons from '../../../../../../docs/data/material/components/toggle-button/VerticalToggleButtons'; + +export default function ToggleButton() { + return ( + +
+

Color Toggle Button

+
+ +
+
+
+

Customized Dividers

+
+ +
+
+
+

Standalone Toggle Button

+
+ +
+
+
+

Toggle Button Not Empty

+
+ +
+
+
+

Toggle Button Sizes

+
+ +
+
+
+

Toggle Buttons

+
+ +
+
+
+

Toggle Buttons Multiple

+
+ +
+
+
+

Vertical Toggle Buttons

+
+ +
+
+
+ ); +} diff --git a/apps/pigment-css-next-app/tsconfig.json b/apps/pigment-css-next-app/tsconfig.json index 49a985026c3a0d..40e9c49eb15b71 100644 --- a/apps/pigment-css-next-app/tsconfig.json +++ b/apps/pigment-css-next-app/tsconfig.json @@ -33,9 +33,6 @@ }, { "path": "../../packages/mui-material/tsconfig.build.json" - }, - { - "path": "../../packages/pigment-css-react/tsconfig.json" } ] } diff --git a/apps/pigment-css-vite-app/README.md b/apps/pigment-css-vite-app/README.md index ea37e4a3adb7de..a34e37f0611e53 100644 --- a/apps/pigment-css-vite-app/README.md +++ b/apps/pigment-css-vite-app/README.md @@ -5,12 +5,7 @@ This project is not part of the workspace yet. ## How to run -You can either run `pnpm build` to build all packages, or else build the two most important ones: - -1. `@pigment-css/react` -2. `@pigment-css/vite-plugin` - -Make sure to run `pnpm release:build` at least once because the project uses the `@mui/material` and `@mui/system` packages. On subsequent runs, you can build only the above packages using: +First, build all the packages in the workspace at least once. Run ```bash pnpm build diff --git a/apps/pigment-css-vite-app/package.json b/apps/pigment-css-vite-app/package.json index 1e662ef5ad83cf..b791a8dff8211c 100644 --- a/apps/pigment-css-vite-app/package.json +++ b/apps/pigment-css-vite-app/package.json @@ -9,31 +9,31 @@ "build": "vite build" }, "dependencies": { - "@pigment-css/react": "workspace:^", + "@pigment-css/react": "^0.0.9", "@mui/utils": "workspace:^", "@mui/base": "workspace:^", "@mui/lab": "workspace:^", "@mui/material": "workspace:^", "@mui/system": "workspace:^", "@mui/icons-material": "workspace:^", - "clsx": "^2.1.0", + "clsx": "^2.1.1", "local-ui-lib": "workspace:^", "react": "^18.2.0", "react-dom": "^18.2.0", "react-error-boundary": "^4.0.13", - "react-router": "^6.22.3", + "react-router": "^6.23.0", "react-router-dom": "^6.22.3" }, "devDependencies": { "@babel/preset-react": "^7.24.1", "@babel/preset-typescript": "^7.24.1", - "@pigment-css/vite-plugin": "workspace:^", + "@pigment-css/vite-plugin": "^0.0.9", "@types/react": "^18.2.55", - "@types/react-dom": "^18.2.19", + "@types/react-dom": "^18.3.0", "@vitejs/plugin-react": "^4.2.1", "postcss": "^8.4.38", "postcss-combine-media-query": "^1.0.1", - "vite": "5.2.8", + "vite": "5.2.10", "vite-plugin-pages": "^0.32.1" }, "nx": { diff --git a/apps/pigment-css-vite-app/src/Slider/ZeroSlider.tsx b/apps/pigment-css-vite-app/src/Slider/ZeroSlider.tsx index 81de28da9f9b23..9d05cf3a262d24 100644 --- a/apps/pigment-css-vite-app/src/Slider/ZeroSlider.tsx +++ b/apps/pigment-css-vite-app/src/Slider/ZeroSlider.tsx @@ -10,7 +10,7 @@ import { import { isHostComponent, useSlotProps } from '@mui/base/utils'; import { styled } from '@pigment-css/react'; import { capitalize } from '@mui/material/utils'; -import SliderValueLabel from '@mui/material/Slider/SliderValueLabel'; +import { SliderValueLabel } from '@mui/material/Slider'; import { useSlider, valueToPercent } from '@mui/base/useSlider'; import { alpha, lighten, darken } from '@mui/system/colorManipulator'; import type { Theme } from '@mui/material/styles'; diff --git a/apps/pigment-css-vite-app/src/pages/material-ui/icons.tsx b/apps/pigment-css-vite-app/src/pages/material-ui/icons.tsx new file mode 100644 index 00000000000000..0839fd022f0bc9 --- /dev/null +++ b/apps/pigment-css-vite-app/src/pages/material-ui/icons.tsx @@ -0,0 +1,73 @@ +import * as React from 'react'; +import MaterialUILayout from '../../Layout'; +import CreateSvgIcon from '../../../../../docs/data/material/components/icons/CreateSvgIcon.tsx'; +import FontAwesomeIcon from '../../../../../docs/data/material/components/icons/FontAwesomeIcon.tsx'; +import FontAwesomeIconSize from '../../../../../docs/data/material/components/icons/FontAwesomeIconSize.tsx'; +import FontAwesomeSvgIconDemo from '../../../../../docs/data/material/components/icons/FontAwesomeSvgIconDemo.tsx'; +import Icons from '../../../../../docs/data/material/components/icons/Icons.tsx'; +import SvgIconChildren from '../../../../../docs/data/material/components/icons/SvgIconChildren.tsx'; +import SvgIconsColor from '../../../../../docs/data/material/components/icons/SvgIconsColor.tsx'; +import SvgIconsSize from '../../../../../docs/data/material/components/icons/SvgIconsSize.tsx'; +import SvgMaterialIcons from '../../../../../docs/data/material/components/icons/SvgMaterialIcons.tsx'; + +export default function IconsPage() { + return ( + +

Icons

+
+

Create Svg Icon

+
+ +
+
+
+

Font Awesome Icon

+
+ +
+
+
+

Font Awesome Icon Size

+
+ +
+
+
+

Font Awesome Svg Icon Demo

+
+ +
+
+
+

Icons

+
+ +
+
+
+

Svg Icon Children

+
+ +
+
+
+

Svg Icons Color

+
+ +
+
+
+

Svg Icons Size

+
+ +
+
+
+

Svg Material Icons

+
+ +
+
+
+ ); +} diff --git a/apps/pigment-css-vite-app/src/pages/material-ui/react-checkbox.tsx b/apps/pigment-css-vite-app/src/pages/material-ui/react-checkbox.tsx new file mode 100644 index 00000000000000..47da6a7f153f10 --- /dev/null +++ b/apps/pigment-css-vite-app/src/pages/material-ui/react-checkbox.tsx @@ -0,0 +1,80 @@ +import * as React from 'react'; +import MaterialUILayout from '../../Layout'; +import CheckboxLabels from '../../../../../docs/data/material/components/checkboxes/CheckboxLabels.tsx'; +import CheckboxesComponent from '../../../../../docs/data/material/components/checkboxes/Checkboxes.tsx'; +import CheckboxesGroup from '../../../../../docs/data/material/components/checkboxes/CheckboxesGroup.tsx'; +import ColorCheckboxes from '../../../../../docs/data/material/components/checkboxes/ColorCheckboxes.tsx'; +import ControlledCheckbox from '../../../../../docs/data/material/components/checkboxes/ControlledCheckbox.tsx'; +import CustomizedCheckbox from '../../../../../docs/data/material/components/checkboxes/CustomizedCheckbox.tsx'; +import FormControlLabelPosition from '../../../../../docs/data/material/components/checkboxes/FormControlLabelPosition.tsx'; +import IconCheckboxes from '../../../../../docs/data/material/components/checkboxes/IconCheckboxes.tsx'; +import IndeterminateCheckbox from '../../../../../docs/data/material/components/checkboxes/IndeterminateCheckbox.tsx'; +import SizeCheckboxes from '../../../../../docs/data/material/components/checkboxes/SizeCheckboxes.tsx'; + +export default function Checkboxes() { + return ( + +

Checkboxes

+
+

Checkbox Labels

+
+ +
+
+
+

Checkboxes

+
+ +
+
+
+

Checkboxes Group

+
+ +
+
+
+

Color Checkboxes

+
+ +
+
+
+

Controlled Checkbox

+
+ +
+
+
+

Customized Checkbox

+
+ +
+
+
+

Form Control Label Position

+
+ +
+
+
+

Icon Checkboxes

+
+ +
+
+
+

Indeterminate Checkbox

+
+ +
+
+
+

Size Checkboxes

+
+ +
+
+
+ ); +} diff --git a/apps/pigment-css-vite-app/src/pages/material-ui/react-floating-action-button.tsx b/apps/pigment-css-vite-app/src/pages/material-ui/react-floating-action-button.tsx new file mode 100644 index 00000000000000..4ea79e2f36f093 --- /dev/null +++ b/apps/pigment-css-vite-app/src/pages/material-ui/react-floating-action-button.tsx @@ -0,0 +1,38 @@ +import * as React from 'react'; +import MaterialUILayout from '../../Layout'; +import FloatingActionButtonExtendedSize from '../../../../../docs/data/material/components/floating-action-button/FloatingActionButtonExtendedSize.tsx'; +import FloatingActionButtonSize from '../../../../../docs/data/material/components/floating-action-button/FloatingActionButtonSize.tsx'; +import FloatingActionButtonZoom from '../../../../../docs/data/material/components/floating-action-button/FloatingActionButtonZoom.tsx'; +import FloatingActionButtons from '../../../../../docs/data/material/components/floating-action-button/FloatingActionButtons.tsx'; + +export default function FloatingActionButton() { + return ( + +

FloatingActionButton

+
+

Floating Action Button Extended Size

+
+ +
+
+
+

Floating Action Button Size

+
+ +
+
+
+

Floating Action Button Zoom

+
+ +
+
+
+

Floating Action Buttons

+
+ +
+
+
+ ); +} diff --git a/apps/pigment-css-vite-app/src/pages/material-ui/react-pagination.tsx b/apps/pigment-css-vite-app/src/pages/material-ui/react-pagination.tsx new file mode 100644 index 00000000000000..0c98e85fc85307 --- /dev/null +++ b/apps/pigment-css-vite-app/src/pages/material-ui/react-pagination.tsx @@ -0,0 +1,87 @@ +import * as React from 'react'; +import MaterialUILayout from '../../Layout'; +import BasicPagination from '../../../../../docs/data/material/components/pagination/BasicPagination.tsx'; +import CustomIcons from '../../../../../docs/data/material/components/pagination/CustomIcons.tsx'; +import PaginationButtons from '../../../../../docs/data/material/components/pagination/PaginationButtons.tsx'; +import PaginationControlled from '../../../../../docs/data/material/components/pagination/PaginationControlled.tsx'; +import PaginationLink from '../../../../../docs/data/material/components/pagination/PaginationLink.tsx'; +import PaginationOutlined from '../../../../../docs/data/material/components/pagination/PaginationOutlined.tsx'; +import PaginationRanges from '../../../../../docs/data/material/components/pagination/PaginationRanges.tsx'; +import PaginationRounded from '../../../../../docs/data/material/components/pagination/PaginationRounded.tsx'; +import PaginationSize from '../../../../../docs/data/material/components/pagination/PaginationSize.tsx'; +import TablePaginationDemo from '../../../../../docs/data/material/components/pagination/TablePaginationDemo.tsx'; +import UsePagination from '../../../../../docs/data/material/components/pagination/UsePagination.tsx'; + +export default function Pagination() { + return ( + +

Pagination

+
+

Basic Pagination

+
+ +
+
+
+

Custom Icons

+
+ +
+
+
+

Pagination Buttons

+
+ +
+
+
+

Pagination Controlled

+
+ +
+
+
+

Pagination Link

+
+ +
+
+
+

Pagination Outlined

+
+ +
+
+
+

Pagination Ranges

+
+ +
+
+
+

Pagination Rounded

+
+ +
+
+
+

Pagination Size

+
+ +
+
+
+

Table Pagination Demo

+
+ +
+
+
+

Use Pagination

+
+ +
+
+
+ ); +} diff --git a/apps/pigment-css-vite-app/src/pages/material-ui/react-progress.tsx b/apps/pigment-css-vite-app/src/pages/material-ui/react-progress.tsx new file mode 100644 index 00000000000000..b1ecf1ebee01ba --- /dev/null +++ b/apps/pigment-css-vite-app/src/pages/material-ui/react-progress.tsx @@ -0,0 +1,101 @@ +import * as React from 'react'; +import MaterialUILayout from '../../Layout'; +import CircularColor from '../../../../../docs/data/material/components/progress/CircularColor.tsx'; +import CircularDeterminate from '../../../../../docs/data/material/components/progress/CircularDeterminate.tsx'; +import CircularIndeterminate from '../../../../../docs/data/material/components/progress/CircularIndeterminate.tsx'; +import CircularIntegration from '../../../../../docs/data/material/components/progress/CircularIntegration.tsx'; +import CircularUnderLoad from '../../../../../docs/data/material/components/progress/CircularUnderLoad.tsx'; +import CircularWithValueLabel from '../../../../../docs/data/material/components/progress/CircularWithValueLabel.tsx'; +import CustomizedProgressBars from '../../../../../docs/data/material/components/progress/CustomizedProgressBars.tsx'; +import DelayingAppearance from '../../../../../docs/data/material/components/progress/DelayingAppearance.tsx'; +import LinearBuffer from '../../../../../docs/data/material/components/progress/LinearBuffer.tsx'; +import LinearColor from '../../../../../docs/data/material/components/progress/LinearColor.tsx'; +import LinearDeterminate from '../../../../../docs/data/material/components/progress/LinearDeterminate.tsx'; +import LinearIndeterminate from '../../../../../docs/data/material/components/progress/LinearIndeterminate.tsx'; +import LinearWithValueLabel from '../../../../../docs/data/material/components/progress/LinearWithValueLabel.tsx'; + +export default function Progress() { + return ( + +

Progress

+
+

Circular Color

+
+ +
+
+
+

Circular Determinate

+
+ +
+
+
+

Circular Indeterminate

+
+ +
+
+
+

Circular Integration

+
+ +
+
+
+

Circular Under Load

+
+ +
+
+
+

Circular With Value Label

+
+ +
+
+
+

Customized Progress Bars

+
+ +
+
+
+

Delaying Appearance

+
+ +
+
+
+

Linear Buffer

+
+ +
+
+
+

Linear Color

+
+ +
+
+
+

Linear Determinate

+
+ +
+
+
+

Linear Indeterminate

+
+ +
+
+
+

Linear With Value Label

+
+ +
+
+
+ ); +} diff --git a/apps/pigment-css-vite-app/src/pages/material-ui/react-radio-button.tsx b/apps/pigment-css-vite-app/src/pages/material-ui/react-radio-button.tsx new file mode 100644 index 00000000000000..138e0386c4446c --- /dev/null +++ b/apps/pigment-css-vite-app/src/pages/material-ui/react-radio-button.tsx @@ -0,0 +1,80 @@ +import * as React from 'react'; +import MaterialUILayout from '../../Layout'; +import ColorRadioButtons from '../../../../../docs/data/material/components/radio-buttons/ColorRadioButtons.tsx'; +import ControlledRadioButtonsGroup from '../../../../../docs/data/material/components/radio-buttons/ControlledRadioButtonsGroup.tsx'; +import CustomizedRadios from '../../../../../docs/data/material/components/radio-buttons/CustomizedRadios.tsx'; +import ErrorRadios from '../../../../../docs/data/material/components/radio-buttons/ErrorRadios.tsx'; +import FormControlLabelPlacement from '../../../../../docs/data/material/components/radio-buttons/FormControlLabelPlacement.tsx'; +import RadioButtonsComponent from '../../../../../docs/data/material/components/radio-buttons/RadioButtons.tsx'; +import RadioButtonsGroup from '../../../../../docs/data/material/components/radio-buttons/RadioButtonsGroup.tsx'; +import RowRadioButtonsGroup from '../../../../../docs/data/material/components/radio-buttons/RowRadioButtonsGroup.tsx'; +import SizeRadioButtons from '../../../../../docs/data/material/components/radio-buttons/SizeRadioButtons.tsx'; +import UseRadioGroup from '../../../../../docs/data/material/components/radio-buttons/UseRadioGroup.tsx'; + +export default function RadioButtons() { + return ( + +

RadioButtons

+
+

Color Radio Buttons

+
+ +
+
+
+

Controlled Radio Buttons Group

+
+ +
+
+
+

Customized Radios

+
+ +
+
+
+

Error Radios

+
+ +
+
+
+

Form Control Label Placement

+
+ +
+
+
+

Radio Buttons

+
+ +
+
+
+

Radio Buttons Group

+
+ +
+
+
+

Row Radio Buttons Group

+
+ +
+
+
+

Size Radio Buttons

+
+ +
+
+
+

Use Radio Group

+
+ +
+
+
+ ); +} diff --git a/apps/pigment-css-vite-app/src/pages/material-ui/react-stepper.tsx b/apps/pigment-css-vite-app/src/pages/material-ui/react-stepper.tsx index 5f9cc1d0e683d6..5a080f5f941d29 100644 --- a/apps/pigment-css-vite-app/src/pages/material-ui/react-stepper.tsx +++ b/apps/pigment-css-vite-app/src/pages/material-ui/react-stepper.tsx @@ -7,7 +7,6 @@ import HorizontalLinearStepper from '../../../../../docs/data/material/component import HorizontalNonLinearStepper from '../../../../../docs/data/material/components/steppers/HorizontalNonLinearStepper.tsx'; import HorizontalStepperWithError from '../../../../../docs/data/material/components/steppers/HorizontalStepperWithError.tsx'; import ProgressMobileStepper from '../../../../../docs/data/material/components/steppers/ProgressMobileStepper.tsx'; -import SwipeableTextMobileStepper from '../../../../../docs/data/material/components/steppers/SwipeableTextMobileStepper.tsx'; import TextMobileStepper from '../../../../../docs/data/material/components/steppers/TextMobileStepper.tsx'; import VerticalLinearStepper from '../../../../../docs/data/material/components/steppers/VerticalLinearStepper.tsx'; @@ -57,12 +56,6 @@ export default function Steppers() {
-
-

Swipeable Text Mobile Stepper

-
- -
-

Text Mobile Stepper

diff --git a/apps/pigment-css-vite-app/src/pages/material-ui/react-toggle-button.tsx b/apps/pigment-css-vite-app/src/pages/material-ui/react-toggle-button.tsx new file mode 100644 index 00000000000000..1e55ee245bf656 --- /dev/null +++ b/apps/pigment-css-vite-app/src/pages/material-ui/react-toggle-button.tsx @@ -0,0 +1,66 @@ +import * as React from 'react'; +import MaterialUILayout from '../../Layout'; +import ColorToggleButton from '../../../../../docs/data/material/components/toggle-button/ColorToggleButton.tsx'; +import CustomizedDividers from '../../../../../docs/data/material/components/toggle-button/CustomizedDividers.tsx'; +import StandaloneToggleButton from '../../../../../docs/data/material/components/toggle-button/StandaloneToggleButton.tsx'; +import ToggleButtonNotEmpty from '../../../../../docs/data/material/components/toggle-button/ToggleButtonNotEmpty.tsx'; +import ToggleButtonSizes from '../../../../../docs/data/material/components/toggle-button/ToggleButtonSizes.tsx'; +import ToggleButtons from '../../../../../docs/data/material/components/toggle-button/ToggleButtons.tsx'; +import ToggleButtonsMultiple from '../../../../../docs/data/material/components/toggle-button/ToggleButtonsMultiple.tsx'; +import VerticalToggleButtons from '../../../../../docs/data/material/components/toggle-button/VerticalToggleButtons.tsx'; + +export default function ToggleButton() { + return ( + +

ToggleButton

+
+

Color Toggle Button

+
+ +
+
+
+

Customized Dividers

+
+ +
+
+
+

Standalone Toggle Button

+
+ +
+
+
+

Toggle Button Not Empty

+
+ +
+
+
+

Toggle Button Sizes

+
+ +
+
+
+

Toggle Buttons

+
+ +
+
+
+

Toggle Buttons Multiple

+
+ +
+
+
+

Vertical Toggle Buttons

+
+ +
+
+
+ ); +} diff --git a/apps/pigment-css-vite-app/tsconfig.json b/apps/pigment-css-vite-app/tsconfig.json index 918f90a862a498..0ed0fe1afa6d97 100644 --- a/apps/pigment-css-vite-app/tsconfig.json +++ b/apps/pigment-css-vite-app/tsconfig.json @@ -13,9 +13,6 @@ }, { "path": "../../packages/mui-material/tsconfig.build.json" - }, - { - "path": "../../packages/pigment-css-react/tsconfig.json" } ] } diff --git a/babel.config.js b/babel.config.js index 48ca2abea4ce50..6b373018b036be 100644 --- a/babel.config.js +++ b/babel.config.js @@ -13,7 +13,7 @@ const productionPlugins = [ ]; module.exports = function getBabelConfig(api) { - const useESModules = api.env(['regressions', 'legacy', 'modern', 'stable', 'rollup']); + const useESModules = api.env(['regressions', 'modern', 'stable', 'rollup']); const defaultAlias = { '@mui/material': resolveAliasPath('./packages/mui-material/src'), @@ -31,7 +31,6 @@ module.exports = function getBabelConfig(api) { '@mui/base': resolveAliasPath('./packages/mui-base/src'), '@mui/utils': resolveAliasPath('./packages/mui-utils/src'), '@mui/joy': resolveAliasPath('./packages/mui-joy/src'), - '@pigment-css/react': resolveAliasPath('./packages/pigment-css-react/src'), '@mui/internal-docs-utils': resolveAliasPath('./packages-internal/docs-utils/src'), docs: resolveAliasPath('./docs'), test: resolveAliasPath('./test'), @@ -153,12 +152,6 @@ module.exports = function getBabelConfig(api) { ], ], }, - legacy: { - plugins: [ - // IE11 support - '@babel/plugin-transform-object-assign', - ], - }, test: { sourceMaps: 'both', plugins: [ diff --git a/benchmark/package.json b/benchmark/package.json index 8434c75feb5ca0..4da6db4f7eaa97 100644 --- a/benchmark/package.json +++ b/benchmark/package.json @@ -24,7 +24,7 @@ "express": "^4.19.2", "fs-extra": "^11.2.0", "jss": "^10.10.0", - "playwright": "^1.43.0", + "playwright": "^1.43.1", "prop-types": "^15.8.1", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -36,6 +36,6 @@ "styled-components": "^6.1.8", "styled-system": "^5.1.5", "theme-ui": "^0.16.2", - "webpack": "^5.90.3" + "webpack": "^5.91.0" } } diff --git a/dangerfile.ts b/dangerfile.ts index 190f1941279805..930d859078c823 100644 --- a/dangerfile.ts +++ b/dangerfile.ts @@ -1,4 +1,4 @@ -// inspire by reacts dangerfile +// Inspired by React dangerfile // danger has to be the first thing required! import { danger, markdown } from 'danger'; import { exec } from 'child_process'; @@ -13,7 +13,7 @@ const parsedSizeChangeThreshold = 300; const gzipSizeChangeThreshold = 100; /** - * executes a git subcommand + * Executes a git subcommand. * @param {any} args */ function git(args: any) { @@ -40,8 +40,8 @@ async function reportBundleSizeCleanup() { } /** - * creates a callback for Object.entries(comparison).filter that excludes every - * entry that does not exceed the given threshold values for parsed and gzip size + * Creates a callback for Object.entries(comparison).filter that excludes every + * entry that does not exceed the given threshold values for parsed and gzip size. * @param {number} parsedThreshold * @param {number} gzipThreshold */ @@ -56,17 +56,7 @@ function createComparisonFilter(parsedThreshold: number, gzipThreshold: number) } /** - * checks if the bundle is of a package e.b. `@mui/material` but not - * `@mui/material/Paper` - * @param {[string, any]} comparisonEntry - */ -function isPackageComparison(comparisonEntry: [string, any]) { - const [bundleKey] = comparisonEntry; - return /^@[\w-]+\/[\w-]+$/.test(bundleKey); -} - -/** - * Generates a user-readable string from a percentage change + * Generates a user-readable string from a percentage change. * @param {number} change * @param {string} goodEmoji emoji on reduction * @param {string} badEmoji emoji on increase @@ -91,7 +81,7 @@ function generateEmphasizedChange([bundle, { parsed, gzip }]: [ } /** - * Puts results in different buckets wh + * Puts results in different buckets. * @param {*} results */ function sieveResults(results: Array<[string, T]>) { @@ -137,8 +127,7 @@ async function loadLastComparison( } async function reportBundleSize() { - // Use git locally to grab the commit which represents the place - // where the branches differ + // Use git locally to grab the commit which represents the place where the branches differ const upstreamRepo = danger.github.pr.base.repo.full_name; const upstreamRef = danger.github.pr.base.ref; try { @@ -161,12 +150,25 @@ async function reportBundleSize() { if (anyResultsChanges.length > 0) { const importantChanges = mainResults .filter(createComparisonFilter(parsedSizeChangeThreshold, gzipSizeChangeThreshold)) - .filter(isPackageComparison) + .sort(([, a], [, b]) => { + const aDiff = Math.abs(a.parsed.absoluteDiff) + Math.abs(a.gzip.absoluteDiff); + const bDiff = Math.abs(b.parsed.absoluteDiff) + Math.abs(b.gzip.absoluteDiff); + return bDiff - aDiff; + }) .map(generateEmphasizedChange); // have to guard against empty strings if (importantChanges.length > 0) { - markdown(importantChanges.join('\n')); + const maxVisible = 20; + + const lines = importantChanges.slice(0, maxVisible); + + const nrOfHiddenChanges = Math.max(0, importantChanges.length - maxVisible); + if (nrOfHiddenChanges > 0) { + lines.push(`and [${nrOfHiddenChanges} more changes](${detailedComparisonToolpadUrl})`); + } + + markdown(lines.join('\n')); } const details = `## Bundle size report diff --git a/docs/babel.config.js b/docs/babel.config.js index 57d4fab1b602af..1ccf95cfbb1b80 100644 --- a/docs/babel.config.js +++ b/docs/babel.config.js @@ -32,8 +32,6 @@ module.exports = { }, ], 'babel-plugin-optimize-clsx', - // for IE11 support - '@babel/plugin-transform-object-assign', ], ignore: [/@babel[\\|/]runtime/], // Fix a Windows issue. env: { diff --git a/docs/data/about/teamMembers.json b/docs/data/about/teamMembers.json index e6b3607816325a..daafd25c12fae7 100644 --- a/docs/data/about/teamMembers.json +++ b/docs/data/about/teamMembers.json @@ -266,6 +266,13 @@ "twitter": "vadym_raksha", "github": "hasdfa" }, + { + "name": "Nadja Kovacev", + "title": "Talent & Culture Partner", + "location": "Novi Sad, Serbia", + "locationCountry": "rs", + "about": "🧠 Psychology geek, 🏂 amateur snowboarder, and 𐃡 pottery enthusiast." + }, { "name": "James Nelson", "title": "Software Engineer - Base UI", diff --git a/docs/data/base/components/autocomplete/autocomplete.md b/docs/data/base/components/autocomplete/autocomplete.md index ec81b25bf8bdb1..27a444d18a48aa 100644 --- a/docs/data/base/components/autocomplete/autocomplete.md +++ b/docs/data/base/components/autocomplete/autocomplete.md @@ -10,7 +10,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/

An autocomplete component is a text input enhanced by a panel of suggested options.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/badge/badge.md b/docs/data/base/components/badge/badge.md index e5c11fd7021bfd..5467bd9d364db6 100644 --- a/docs/data/base/components/badge/badge.md +++ b/docs/data/base/components/badge/badge.md @@ -10,7 +10,7 @@ githubLabel: 'component: badge'

The Badge component generates a small label that is attached to its child element.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/button/button.md b/docs/data/base/components/button/button.md index 33482d138fa452..3d3ad1c1aa5e8f 100644 --- a/docs/data/base/components/button/button.md +++ b/docs/data/base/components/button/button.md @@ -11,7 +11,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/button/

Buttons let users take actions and make choices with a single tap.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/click-away-listener/click-away-listener.md b/docs/data/base/components/click-away-listener/click-away-listener.md index 7d67d0a2390dbe..4ee9cd3c97fd2e 100644 --- a/docs/data/base/components/click-away-listener/click-away-listener.md +++ b/docs/data/base/components/click-away-listener/click-away-listener.md @@ -9,7 +9,7 @@ githubLabel: 'component: ClickAwayListener'

The Click-Away Listener component detects when a click event happens outside of its child element.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/focus-trap/focus-trap.md b/docs/data/base/components/focus-trap/focus-trap.md index e04aa60f994042..bd13cb0d35bcb7 100644 --- a/docs/data/base/components/focus-trap/focus-trap.md +++ b/docs/data/base/components/focus-trap/focus-trap.md @@ -9,7 +9,7 @@ githubLabel: 'component: FocusTrap'

The Focus Trap component prevents the user's focus from escaping its children components.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/form-control/form-control.md b/docs/data/base/components/form-control/form-control.md index e60a78eeae01bd..0179ebdb4e1d54 100644 --- a/docs/data/base/components/form-control/form-control.md +++ b/docs/data/base/components/form-control/form-control.md @@ -10,7 +10,7 @@ githubLabel: 'component: FormControl'

The Form Control component is a utility that lets you associate a form input with auxiliary components, such as labels, error indicators, or helper text.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/input/input.md b/docs/data/base/components/input/input.md index 829f2b3e7487d5..c5889e5340f340 100644 --- a/docs/data/base/components/input/input.md +++ b/docs/data/base/components/input/input.md @@ -10,7 +10,7 @@ githubLabel: 'component: input'

The Input component provides users with a field to enter and edit text.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/menu/menu.md b/docs/data/base/components/menu/menu.md index dfc881cd2684dd..fe7892d6fc09a3 100644 --- a/docs/data/base/components/menu/menu.md +++ b/docs/data/base/components/menu/menu.md @@ -11,7 +11,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/

The Dropdown Menu components provide end users with a list of options on temporary surfaces.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/modal/modal.md b/docs/data/base/components/modal/modal.md index 320a90cef4ea63..d902ca920e1129 100644 --- a/docs/data/base/components/modal/modal.md +++ b/docs/data/base/components/modal/modal.md @@ -11,7 +11,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/

The Modal component lets you create dialogs, popovers, lightboxes, and other elements that force the user to take action before continuing.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/no-ssr/no-ssr.md b/docs/data/base/components/no-ssr/no-ssr.md index 5bdc6fbf9fce0a..61c26b8d1629a7 100644 --- a/docs/data/base/components/no-ssr/no-ssr.md +++ b/docs/data/base/components/no-ssr/no-ssr.md @@ -8,7 +8,7 @@ components: NoSsr

The No-SSR component defers the rendering of children components from the server to the client.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/number-input/number-input.md b/docs/data/base/components/number-input/number-input.md index ac0c977a23a795..a69f324e3e4db4 100644 --- a/docs/data/base/components/number-input/number-input.md +++ b/docs/data/base/components/number-input/number-input.md @@ -10,7 +10,7 @@ githubLabel: 'component: number input'

The Number Input component provides users with a field for integer values, and buttons to increment or decrement the value.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/popper/popper.md b/docs/data/base/components/popper/popper.md index fd37f255e6292a..082f0cb07edaeb 100644 --- a/docs/data/base/components/popper/popper.md +++ b/docs/data/base/components/popper/popper.md @@ -10,7 +10,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/

The Popper component lets you create tooltips and popovers that display information about an element on the page.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/popup/popup.md b/docs/data/base/components/popup/popup.md index c144abc5d8468e..b48c0344a1afb5 100644 --- a/docs/data/base/components/popup/popup.md +++ b/docs/data/base/components/popup/popup.md @@ -10,7 +10,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/

The Popup component is a utility that lets you display content in tooltips and popovers.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/portal/portal.md b/docs/data/base/components/portal/portal.md index 6e060cae6bc911..0a7c4675bfa08c 100644 --- a/docs/data/base/components/portal/portal.md +++ b/docs/data/base/components/portal/portal.md @@ -9,7 +9,7 @@ githubLabel: 'component: Portal'

The Portal component lets you render its children into a DOM node that exists outside of the Portal's own DOM hierarchy.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/select/select.md b/docs/data/base/components/select/select.md index 7b66ecc94cc074..67479247cfd053 100644 --- a/docs/data/base/components/select/select.md +++ b/docs/data/base/components/select/select.md @@ -11,7 +11,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-sel

The Select components let you create lists of options for users to choose from.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/slider/slider.md b/docs/data/base/components/slider/slider.md index daf7b9263aa969..4bbfe6580be394 100644 --- a/docs/data/base/components/slider/slider.md +++ b/docs/data/base/components/slider/slider.md @@ -12,7 +12,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/slider-multithumb/

A slider is a UI element that lets users select a single value or a range of values along a bar.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/snackbar/snackbar.md b/docs/data/base/components/snackbar/snackbar.md index cc2648ec57394a..d10ea1fcb99068 100644 --- a/docs/data/base/components/snackbar/snackbar.md +++ b/docs/data/base/components/snackbar/snackbar.md @@ -10,7 +10,7 @@ githubLabel: 'component: snackbar'

The Snackbar component informs users that an action has been or will be performed by the app.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/switch/switch.md b/docs/data/base/components/switch/switch.md index 395dbbcd8a6e2f..d93177616509a9 100644 --- a/docs/data/base/components/switch/switch.md +++ b/docs/data/base/components/switch/switch.md @@ -11,7 +11,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/switch/

Switches are UI elements that let users choose between two states—most commonly on/off.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/table-pagination/table-pagination.md b/docs/data/base/components/table-pagination/table-pagination.md index 577b677687a432..7ce1e173c99419 100644 --- a/docs/data/base/components/table-pagination/table-pagination.md +++ b/docs/data/base/components/table-pagination/table-pagination.md @@ -9,7 +9,7 @@ githubLabel: 'component: TablePagination'

Table Pagination is an interface tool for splitting up large amounts of data to make it easier for users to navigate.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/tabs/tabs.md b/docs/data/base/components/tabs/tabs.md index aaf0a1a86923b6..bb5bf1c80abf74 100644 --- a/docs/data/base/components/tabs/tabs.md +++ b/docs/data/base/components/tabs/tabs.md @@ -11,7 +11,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/tabs/

Tabs are UI elements for organizing and navigating between groups of related content.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/base/components/textarea-autosize/textarea-autosize.md b/docs/data/base/components/textarea-autosize/textarea-autosize.md index cc8f6e7908272d..3909eb87a6081a 100644 --- a/docs/data/base/components/textarea-autosize/textarea-autosize.md +++ b/docs/data/base/components/textarea-autosize/textarea-autosize.md @@ -9,7 +9,7 @@ githubLabel: 'component: TextareaAutosize'

The Textarea Autosize component gives you a textarea HTML element that automatically adjusts its height to match the length of the content within.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} {{"component": "modules/components/ComponentPageTabs.js"}} diff --git a/docs/data/docs-infra/pages.ts b/docs/data/docs-infra/pages.ts index 0cd74435bba91f..eef5870a61c441 100644 --- a/docs/data/docs-infra/pages.ts +++ b/docs/data/docs-infra/pages.ts @@ -7,6 +7,7 @@ const pages: readonly MuiPage[] = [ children: [ { pathname: '/experiments/docs/headers' }, { pathname: '/experiments/docs/markdown' }, + { pathname: '/experiments/docs/og-card', title: 'OG Image' }, ], }, { @@ -21,7 +22,7 @@ const pages: readonly MuiPage[] = [ }, { pathname: '/experiments/docs/main-parent', - title: 'Main parent', + title: 'Test: pages.js', children: [ { pathname: '/experiments/docs/first-level-child-1', @@ -52,11 +53,46 @@ const pages: readonly MuiPage[] = [ }, ], }, + { + pathname: '/experiments/docs/first-level-child-3', + title: 'Pro plan', + plan: 'pro', + }, + { + pathname: '/experiments/docs/first-level-child-4', + title: 'New feature', + newFeature: true, + }, + { + pathname: '/experiments/docs/first-level-child-5', + title: 'Planned feature', + planned: true, + }, + { + pathname: '/experiments/docs/first-level-child-6', + title: 'Unstable feature', + unstable: true, + }, + { + pathname: '/experiments/docs/first-level-child-7', + title: 'Beta feature', + beta: true, + }, + { + pathname: '/experiments/docs/first-level-child-8', + title: 'Legacy feature', + legacy: true, + }, + { + pathname: '/experiments/docs/first-level-child-9', + title: 'OverflowWithLongApiComponent', + plan: 'pro', + }, ], }, { pathname: '/x/react-data-grid-group', - title: 'Data Grid', + title: 'Test: Data Grid e2e', children: [ { pathname: '/x/react-data-grid', title: 'Overview' }, { pathname: '/x/react-data-grid/demo' }, @@ -168,7 +204,7 @@ const pages: readonly MuiPage[] = [ }, { pathname: '/x/migration-group', - title: 'Migration', + title: 'Test: Migration', children: [ { pathname: '/x/migration-v6', diff --git a/docs/data/joy/components/accordion/AccordionTransition.js b/docs/data/joy/components/accordion/AccordionTransition.js index 15908702f1506d..97d04db1d8f0c0 100644 --- a/docs/data/joy/components/accordion/AccordionTransition.js +++ b/docs/data/joy/components/accordion/AccordionTransition.js @@ -8,7 +8,7 @@ import RadioGroup from '@mui/joy/RadioGroup'; import Radio from '@mui/joy/Radio'; import Stack from '@mui/joy/Stack'; import Typography from '@mui/joy/Typography'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { BrandingProvider } from '@mui/docs/branding'; export default function AccordionTransition() { diff --git a/docs/data/joy/components/alert/alert.md b/docs/data/joy/components/alert/alert.md index 1fbbebc46b645d..560f26be0d45f5 100644 --- a/docs/data/joy/components/alert/alert.md +++ b/docs/data/joy/components/alert/alert.md @@ -10,7 +10,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/alert/

Alerts display brief messages for the user without interrupting their use of the app.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/autocomplete/CountrySelect.js b/docs/data/joy/components/autocomplete/CountrySelect.js index 6b106f6fb33fc5..842bc08b024221 100644 --- a/docs/data/joy/components/autocomplete/CountrySelect.js +++ b/docs/data/joy/components/autocomplete/CountrySelect.js @@ -8,7 +8,6 @@ import Typography from '@mui/joy/Typography'; export default function CountrySelect() { return ( The autocomplete is a text input enhanced by a panel of suggested options when users start typing.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/avatar/avatar.md b/docs/data/joy/components/avatar/avatar.md index ba9fc135dcf91e..89affd7f893952 100644 --- a/docs/data/joy/components/avatar/avatar.md +++ b/docs/data/joy/components/avatar/avatar.md @@ -9,7 +9,7 @@ githubLabel: 'component: avatar'

An avatar is a graphical representation of a user's identity.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/badge/BadgeAlignment.js b/docs/data/joy/components/badge/BadgeAlignment.js index 4d0c4ac31ef6ad..4d634732314b0d 100644 --- a/docs/data/joy/components/badge/BadgeAlignment.js +++ b/docs/data/joy/components/badge/BadgeAlignment.js @@ -5,7 +5,7 @@ import Box from '@mui/joy/Box'; import IconButton from '@mui/joy/IconButton'; import ArrowUpward from '@mui/icons-material/ArrowUpward'; import ArrowDownward from '@mui/icons-material/ArrowDownward'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { BrandingProvider } from '@mui/docs/branding'; export default function BadgeAlignment() { diff --git a/docs/data/joy/components/badge/BadgeAlignment.tsx b/docs/data/joy/components/badge/BadgeAlignment.tsx index 26cef0321dd2f4..f63d48b4b9ce34 100644 --- a/docs/data/joy/components/badge/BadgeAlignment.tsx +++ b/docs/data/joy/components/badge/BadgeAlignment.tsx @@ -5,7 +5,7 @@ import Box from '@mui/joy/Box'; import IconButton from '@mui/joy/IconButton'; import ArrowUpward from '@mui/icons-material/ArrowUpward'; import ArrowDownward from '@mui/icons-material/ArrowDownward'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { BrandingProvider } from '@mui/docs/branding'; export default function BadgeAlignment() { diff --git a/docs/data/joy/components/badge/badge.md b/docs/data/joy/components/badge/badge.md index da680daf92e860..e5ba349dfeaf25 100644 --- a/docs/data/joy/components/badge/badge.md +++ b/docs/data/joy/components/badge/badge.md @@ -10,7 +10,7 @@ unstyled: /base-ui/react-badge/

The Badge component generates a small label that is attached to its child element.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/box/box.md b/docs/data/joy/components/box/box.md index 3e55989f6f1428..2204160edbcd04 100644 --- a/docs/data/joy/components/box/box.md +++ b/docs/data/joy/components/box/box.md @@ -11,7 +11,7 @@ githubLabel: 'component: Box'

The Box component is a generic, theme-aware container with access to CSS utilities from MUI System.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Introduction diff --git a/docs/data/joy/components/breadcrumbs/breadcrumbs.md b/docs/data/joy/components/breadcrumbs/breadcrumbs.md index f1ed8756bd9cd8..84794e25894b40 100644 --- a/docs/data/joy/components/breadcrumbs/breadcrumbs.md +++ b/docs/data/joy/components/breadcrumbs/breadcrumbs.md @@ -9,7 +9,7 @@ githubLabel: 'component: breadcrumbs'

A breadcrumb trail is a navigational tool that helps users keep track of their location within an app.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/button-group/button-group.md b/docs/data/joy/components/button-group/button-group.md index 68e5e8ba128eab..7068e5f0c702fd 100644 --- a/docs/data/joy/components/button-group/button-group.md +++ b/docs/data/joy/components/button-group/button-group.md @@ -9,7 +9,7 @@ githubLabel: 'component: ButtonGroup'

The Button Group combines a set of related buttons.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/button/button.md b/docs/data/joy/components/button/button.md index 9e4f29a8145cce..b6bed946b9590a 100644 --- a/docs/data/joy/components/button/button.md +++ b/docs/data/joy/components/button/button.md @@ -11,7 +11,7 @@ unstyled: /base-ui/react-button/

Buttons let users take actions and make choices with a single tap.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/checkbox/checkbox.md b/docs/data/joy/components/checkbox/checkbox.md index b5635a89535cb0..4583812b0d8664 100644 --- a/docs/data/joy/components/checkbox/checkbox.md +++ b/docs/data/joy/components/checkbox/checkbox.md @@ -10,7 +10,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/

Checkboxes give users binary choices when presented with multiple options in a series.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/chip/chip.md b/docs/data/joy/components/chip/chip.md index 354cae971dac44..49f2700d60a6f7 100644 --- a/docs/data/joy/components/chip/chip.md +++ b/docs/data/joy/components/chip/chip.md @@ -9,7 +9,7 @@ githubLabel: 'component: chip'

Chip generates a compact element that can represent an input, attribute, or action.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/circular-progress/circular-progress.md b/docs/data/joy/components/circular-progress/circular-progress.md index e3013c9b620074..54438dee645a39 100644 --- a/docs/data/joy/components/circular-progress/circular-progress.md +++ b/docs/data/joy/components/circular-progress/circular-progress.md @@ -9,7 +9,7 @@ githubLabel: 'component: CircularProgress'

The Circular Progress component showcases the duration of a process or an indefinite wait period.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/css-baseline/css-baseline.md b/docs/data/joy/components/css-baseline/css-baseline.md index 5cee110d9f696d..9a2eca746350c7 100644 --- a/docs/data/joy/components/css-baseline/css-baseline.md +++ b/docs/data/joy/components/css-baseline/css-baseline.md @@ -8,7 +8,7 @@ githubLabel: 'component: CssBaseline'

Joy UI provides a CssBaseline component to kickstart an elegant, consistent, and simple baseline to build upon.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Global reset diff --git a/docs/data/joy/components/divider/divider.md b/docs/data/joy/components/divider/divider.md index ab444f20c44650..60917da7cbab5f 100644 --- a/docs/data/joy/components/divider/divider.md +++ b/docs/data/joy/components/divider/divider.md @@ -9,7 +9,7 @@ githubLabel: 'component: divider'

A divider is a thin line that groups content in lists and layouts.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/grid/InteractiveGrid.js b/docs/data/joy/components/grid/InteractiveGrid.js index 6752884b6f1483..dcd42d773ad641 100644 --- a/docs/data/joy/components/grid/InteractiveGrid.js +++ b/docs/data/joy/components/grid/InteractiveGrid.js @@ -7,7 +7,7 @@ import Radio from '@mui/joy/Radio'; import Sheet from '@mui/joy/Sheet'; import { BrandingProvider } from '@mui/docs/branding'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; export default function InteractiveGrid() { const [direction, setDirection] = React.useState('row'); diff --git a/docs/data/joy/components/grid/InteractiveGrid.tsx b/docs/data/joy/components/grid/InteractiveGrid.tsx index 8059be0f4b3260..14875c640d8a4a 100644 --- a/docs/data/joy/components/grid/InteractiveGrid.tsx +++ b/docs/data/joy/components/grid/InteractiveGrid.tsx @@ -7,7 +7,7 @@ import Radio from '@mui/joy/Radio'; import Sheet from '@mui/joy/Sheet'; import { GridDirection } from '@mui/system'; import { BrandingProvider } from '@mui/docs/branding'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; type GridItemsAlignment = | 'flex-start' diff --git a/docs/data/joy/components/grid/SpacingGrid.js b/docs/data/joy/components/grid/SpacingGrid.js index 20971a1813de88..56bf0c72b1630d 100644 --- a/docs/data/joy/components/grid/SpacingGrid.js +++ b/docs/data/joy/components/grid/SpacingGrid.js @@ -5,7 +5,7 @@ import FormControl from '@mui/joy/FormControl'; import RadioGroup from '@mui/joy/RadioGroup'; import Radio from '@mui/joy/Radio'; import Sheet from '@mui/joy/Sheet'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { BrandingProvider } from '@mui/docs/branding'; export default function SpacingGrid() { diff --git a/docs/data/joy/components/grid/SpacingGrid.tsx b/docs/data/joy/components/grid/SpacingGrid.tsx index ebb3466624480a..027fd1666a7b17 100644 --- a/docs/data/joy/components/grid/SpacingGrid.tsx +++ b/docs/data/joy/components/grid/SpacingGrid.tsx @@ -5,7 +5,7 @@ import FormControl from '@mui/joy/FormControl'; import RadioGroup from '@mui/joy/RadioGroup'; import Radio from '@mui/joy/Radio'; import Sheet from '@mui/joy/Sheet'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { BrandingProvider } from '@mui/docs/branding'; export default function SpacingGrid() { diff --git a/docs/data/joy/components/input/input.md b/docs/data/joy/components/input/input.md index ce79bb669f6ffa..27575fa6d3bca4 100644 --- a/docs/data/joy/components/input/input.md +++ b/docs/data/joy/components/input/input.md @@ -9,7 +9,7 @@ unstyled: /base-ui/react-input/

The Input component facilitates the entry of text data from the user.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/linear-progress/linear-progress.md b/docs/data/joy/components/linear-progress/linear-progress.md index d5fa84c4a70e36..c3f381602087a2 100644 --- a/docs/data/joy/components/linear-progress/linear-progress.md +++ b/docs/data/joy/components/linear-progress/linear-progress.md @@ -9,7 +9,7 @@ githubLabel: 'component: LinearProgress'

Linear Progress indicators, commonly known as loaders, express an unspecified wait time or display the length of a process.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/link/link.md b/docs/data/joy/components/link/link.md index c72566cec43026..3b4f8a91fda5ad 100644 --- a/docs/data/joy/components/link/link.md +++ b/docs/data/joy/components/link/link.md @@ -10,7 +10,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/link/

The Link component lets you customize anchor tags with theme colors and typography styles.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/modal/modal.md b/docs/data/joy/components/modal/modal.md index 9fe6a5c5621f37..ff5045d23f6792 100644 --- a/docs/data/joy/components/modal/modal.md +++ b/docs/data/joy/components/modal/modal.md @@ -10,7 +10,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/

The modal component provides a solid foundation for creating dialogs, popovers, lightboxes, or whatever else.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/radio-button/radio-button.md b/docs/data/joy/components/radio-button/radio-button.md index 8cce03965dc20a..83d1d72e4e3177 100644 --- a/docs/data/joy/components/radio-button/radio-button.md +++ b/docs/data/joy/components/radio-button/radio-button.md @@ -10,7 +10,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/radio/

Radio buttons enable the user to select one option from a set.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/select/select.md b/docs/data/joy/components/select/select.md index 3d88869106591a..ecfd4ace80361b 100644 --- a/docs/data/joy/components/select/select.md +++ b/docs/data/joy/components/select/select.md @@ -11,7 +11,7 @@ unstyled: /base-ui/react-select/

Select components are used for collecting user-provided information from a list of options.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/sheet/sheet.md b/docs/data/joy/components/sheet/sheet.md index 5aee7ff6591289..390e7b1b8616c1 100644 --- a/docs/data/joy/components/sheet/sheet.md +++ b/docs/data/joy/components/sheet/sheet.md @@ -8,7 +8,7 @@ components: Sheet

Sheet is a generic container that supports Joy UI's global variants.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/slider/slider.md b/docs/data/joy/components/slider/slider.md index b667754bda120d..795077148638bb 100644 --- a/docs/data/joy/components/slider/slider.md +++ b/docs/data/joy/components/slider/slider.md @@ -10,7 +10,7 @@ unstyled: /base-ui/react-slider/

Slider generates a background element that can be used for various purposes.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/snackbar/snackbar.md b/docs/data/joy/components/snackbar/snackbar.md index 7146bbff32b707..c945fa5695f2dd 100644 --- a/docs/data/joy/components/snackbar/snackbar.md +++ b/docs/data/joy/components/snackbar/snackbar.md @@ -10,7 +10,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/alert/

The Snackbar, also commonly referred to as Toast, component informs users that an action has been or will be performed by the app.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/stack/InteractiveStack.js b/docs/data/joy/components/stack/InteractiveStack.js index d5142c84f95783..7243fcf4fc30b4 100644 --- a/docs/data/joy/components/stack/InteractiveStack.js +++ b/docs/data/joy/components/stack/InteractiveStack.js @@ -7,7 +7,7 @@ import RadioGroup from '@mui/joy/RadioGroup'; import Radio from '@mui/joy/Radio'; import Stack from '@mui/joy/Stack'; import { styled } from '@mui/joy/styles'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { BrandingProvider } from '@mui/docs/branding'; const Item = styled(Sheet)(({ theme }) => ({ diff --git a/docs/data/joy/components/stack/InteractiveStack.tsx b/docs/data/joy/components/stack/InteractiveStack.tsx index 971adbb6a0f9c3..2f6ab92a887fb2 100644 --- a/docs/data/joy/components/stack/InteractiveStack.tsx +++ b/docs/data/joy/components/stack/InteractiveStack.tsx @@ -7,7 +7,7 @@ import RadioGroup from '@mui/joy/RadioGroup'; import Radio from '@mui/joy/Radio'; import Stack, { StackProps } from '@mui/joy/Stack'; import { styled } from '@mui/joy/styles'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { BrandingProvider } from '@mui/docs/branding'; const Item = styled(Sheet)(({ theme }) => ({ diff --git a/docs/data/joy/components/stack/stack.md b/docs/data/joy/components/stack/stack.md index a6143207d9ddc9..4e63883a90f3b9 100644 --- a/docs/data/joy/components/stack/stack.md +++ b/docs/data/joy/components/stack/stack.md @@ -9,7 +9,7 @@ githubLabel: 'component: Stack'

Stack is a container component for arranging elements vertically or horizontally.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/switch/switch.md b/docs/data/joy/components/switch/switch.md index b67463b390bd2f..be49a207cf053f 100644 --- a/docs/data/joy/components/switch/switch.md +++ b/docs/data/joy/components/switch/switch.md @@ -10,7 +10,7 @@ unstyled: /base-ui/react-switch/

Switches toggle the state of a single setting on or off.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/table/TableSortAndSelection.js b/docs/data/joy/components/table/TableSortAndSelection.js index 2455a21333b4cf..c7649aa9609b6d 100644 --- a/docs/data/joy/components/table/TableSortAndSelection.js +++ b/docs/data/joy/components/table/TableSortAndSelection.js @@ -65,22 +65,6 @@ function getComparator(order, orderBy) { : (a, b) => -descendingComparator(a, b, orderBy); } -// Since 2020 all major browsers ensure sort stability with Array.prototype.sort(). -// stableSort() brings sort stability to non-modern browsers (notably IE11). If you -// only support modern browsers you can replace stableSort(exampleArray, exampleComparator) -// with exampleArray.slice().sort(exampleComparator) -function stableSort(array, comparator) { - const stabilizedThis = array.map((el, index) => [el, index]); - stabilizedThis.sort((a, b) => { - const order = comparator(a[0], b[0]); - if (order !== 0) { - return order; - } - return a[1] - b[1]; - }); - return stabilizedThis.map((el) => el[0]); -} - const headCells = [ { id: 'name', @@ -348,7 +332,8 @@ export default function TableSortAndSelection() { rowCount={rows.length} /> - {stableSort(rows, getComparator(order, orderBy)) + {[...rows] + .sort(getComparator(order, orderBy)) .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) .map((row, index) => { const isItemSelected = isSelected(row.name); diff --git a/docs/data/joy/components/table/TableSortAndSelection.tsx b/docs/data/joy/components/table/TableSortAndSelection.tsx index f063700890b412..06026b6cfa0758 100644 --- a/docs/data/joy/components/table/TableSortAndSelection.tsx +++ b/docs/data/joy/components/table/TableSortAndSelection.tsx @@ -94,22 +94,6 @@ function getComparator( : (a, b) => -descendingComparator(a, b, orderBy); } -// Since 2020 all major browsers ensure sort stability with Array.prototype.sort(). -// stableSort() brings sort stability to non-modern browsers (notably IE11). If you -// only support modern browsers you can replace stableSort(exampleArray, exampleComparator) -// with exampleArray.slice().sort(exampleComparator) -function stableSort(array: readonly T[], comparator: (a: T, b: T) => number) { - const stabilizedThis = array.map((el, index) => [el, index] as [T, number]); - stabilizedThis.sort((a, b) => { - const order = comparator(a[0], b[0]); - if (order !== 0) { - return order; - } - return a[1] - b[1]; - }); - return stabilizedThis.map((el) => el[0]); -} - interface HeadCell { disablePadding: boolean; id: keyof Data; @@ -390,7 +374,8 @@ export default function TableSortAndSelection() { rowCount={rows.length} /> - {stableSort(rows, getComparator(order, orderBy)) + {[...rows] + .sort(getComparator(order, orderBy)) .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) .map((row, index) => { const isItemSelected = isSelected(row.name); diff --git a/docs/data/joy/components/table/table.md b/docs/data/joy/components/table/table.md index dfe7cf218332be..51148cc5b13b05 100644 --- a/docs/data/joy/components/table/table.md +++ b/docs/data/joy/components/table/table.md @@ -10,7 +10,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/table/

Tables display sets of data organized in rows and columns.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/tabs/tabs.md b/docs/data/joy/components/tabs/tabs.md index 26395c96a11a63..a0370ad6719bde 100644 --- a/docs/data/joy/components/tabs/tabs.md +++ b/docs/data/joy/components/tabs/tabs.md @@ -11,7 +11,7 @@ unstyled: /base-ui/react-tabs/

Tabs make it easy to explore and switch between different views.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/components/textarea/textarea.md b/docs/data/joy/components/textarea/textarea.md index c1a29d13c9a6c1..40513178fa5524 100644 --- a/docs/data/joy/components/textarea/textarea.md +++ b/docs/data/joy/components/textarea/textarea.md @@ -10,7 +10,7 @@ unstyled: /base-ui/react-textarea-autosize/

Textarea component gives you a textarea HTML element that automatically adjusts its height to match the length of the content within.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Introduction diff --git a/docs/data/joy/components/tooltip/tooltip.md b/docs/data/joy/components/tooltip/tooltip.md index 4350e40a1523d3..958b6ce3ab25e4 100644 --- a/docs/data/joy/components/tooltip/tooltip.md +++ b/docs/data/joy/components/tooltip/tooltip.md @@ -10,7 +10,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/

Tooltips display informative text when users hover over, focus on, or tap an element.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/joy/customization/approaches/ButtonThemes.js b/docs/data/joy/customization/approaches/ButtonThemes.js index ee359cacdf3162..e5eb79a876b3fc 100644 --- a/docs/data/joy/customization/approaches/ButtonThemes.js +++ b/docs/data/joy/customization/approaches/ButtonThemes.js @@ -5,7 +5,7 @@ import Button from '@mui/joy/Button'; import FormLabel from '@mui/joy/FormLabel'; import Select from '@mui/joy/Select'; import Option from '@mui/joy/Option'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { BrandingProvider } from '@mui/docs/branding'; const githubTheme = extendTheme({ diff --git a/docs/data/joy/getting-started/templates/TemplateCollection.js b/docs/data/joy/getting-started/templates/TemplateCollection.js index 171ed4e5293c2c..28bad8f0d3e98f 100644 --- a/docs/data/joy/getting-started/templates/TemplateCollection.js +++ b/docs/data/joy/getting-started/templates/TemplateCollection.js @@ -88,7 +88,7 @@ const templates = [ author: authors.MUI, design: { name: 'Frames X', - link: 'https://framesxdesign.com/', + link: 'https://framesxdesign.com/product', }, }, ]; diff --git a/docs/data/joy/getting-started/templates/order-dashboard/components/OrderTable.tsx b/docs/data/joy/getting-started/templates/order-dashboard/components/OrderTable.tsx index d01260b9fcd5d2..06c900a8d05ae1 100644 --- a/docs/data/joy/getting-started/templates/order-dashboard/components/OrderTable.tsx +++ b/docs/data/joy/getting-started/templates/order-dashboard/components/OrderTable.tsx @@ -242,22 +242,6 @@ function getComparator( : (a, b) => -descendingComparator(a, b, orderBy); } -// Since 2020 all major browsers ensure sort stability with Array.prototype.sort(). -// stableSort() brings sort stability to non-modern browsers (notably IE11). If you -// only support modern browsers you can replace stableSort(exampleArray, exampleComparator) -// with exampleArray.slice().sort(exampleComparator) -function stableSort(array: readonly T[], comparator: (a: T, b: T) => number) { - const stabilizedThis = array.map((el, index) => [el, index] as [T, number]); - stabilizedThis.sort((a, b) => { - const order = comparator(a[0], b[0]); - if (order !== 0) { - return order; - } - return a[1] - b[1]; - }); - return stabilizedThis.map((el) => el[0]); -} - function RowMenu() { return ( @@ -451,7 +435,7 @@ export default function OrderTable() { - {stableSort(rows, getComparator(order, 'id')).map((row) => ( + {[...rows].sort(getComparator(order, 'id')).map((row) => ( The Accordion component lets users show and hide sections of related content on a page.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/material/components/alert/alert.md b/docs/data/material/components/alert/alert.md index 1f1a903f2c78ba..185b7013b709e9 100644 --- a/docs/data/material/components/alert/alert.md +++ b/docs/data/material/components/alert/alert.md @@ -10,7 +10,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/alert/

Alerts display brief messages for the user without interrupting their use of the app.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/material/components/app-bar/app-bar.md b/docs/data/material/components/app-bar/app-bar.md index 10ea9272ec4390..c067e4ee03ac22 100644 --- a/docs/data/material/components/app-bar/app-bar.md +++ b/docs/data/material/components/app-bar/app-bar.md @@ -14,7 +14,7 @@ The top App bar provides content and actions related to the current screen. It's It can transform into a contextual action bar or be used as a navbar. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic App bar diff --git a/docs/data/material/components/autocomplete/Asynchronous.js b/docs/data/material/components/autocomplete/Asynchronous.js index ada8153aa99fd6..9244ba11f5b8ef 100644 --- a/docs/data/material/components/autocomplete/Asynchronous.js +++ b/docs/data/material/components/autocomplete/Asynchronous.js @@ -44,7 +44,6 @@ export default function Asynchronous() { return ( { diff --git a/docs/data/material/components/autocomplete/Asynchronous.tsx b/docs/data/material/components/autocomplete/Asynchronous.tsx index c2c4e4720ed519..382bcc2b1dcb97 100644 --- a/docs/data/material/components/autocomplete/Asynchronous.tsx +++ b/docs/data/material/components/autocomplete/Asynchronous.tsx @@ -49,7 +49,6 @@ export default function Asynchronous() { return ( { diff --git a/docs/data/material/components/autocomplete/ComboBox.js b/docs/data/material/components/autocomplete/ComboBox.js index 4e515937746cb4..a27d7aef434c56 100644 --- a/docs/data/material/components/autocomplete/ComboBox.js +++ b/docs/data/material/components/autocomplete/ComboBox.js @@ -1,143 +1,15 @@ import * as React from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; export default function ComboBox() { return ( } /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { label: 'The Shawshank Redemption', year: 1994 }, - { label: 'The Godfather', year: 1972 }, - { label: 'The Godfather: Part II', year: 1974 }, - { label: 'The Dark Knight', year: 2008 }, - { label: '12 Angry Men', year: 1957 }, - { label: "Schindler's List", year: 1993 }, - { label: 'Pulp Fiction', year: 1994 }, - { - label: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { label: 'The Good, the Bad and the Ugly', year: 1966 }, - { label: 'Fight Club', year: 1999 }, - { - label: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - label: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { label: 'Forrest Gump', year: 1994 }, - { label: 'Inception', year: 2010 }, - { - label: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { label: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { label: 'Goodfellas', year: 1990 }, - { label: 'The Matrix', year: 1999 }, - { label: 'Seven Samurai', year: 1954 }, - { - label: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { label: 'City of God', year: 2002 }, - { label: 'Se7en', year: 1995 }, - { label: 'The Silence of the Lambs', year: 1991 }, - { label: "It's a Wonderful Life", year: 1946 }, - { label: 'Life Is Beautiful', year: 1997 }, - { label: 'The Usual Suspects', year: 1995 }, - { label: 'Léon: The Professional', year: 1994 }, - { label: 'Spirited Away', year: 2001 }, - { label: 'Saving Private Ryan', year: 1998 }, - { label: 'Once Upon a Time in the West', year: 1968 }, - { label: 'American History X', year: 1998 }, - { label: 'Interstellar', year: 2014 }, - { label: 'Casablanca', year: 1942 }, - { label: 'City Lights', year: 1931 }, - { label: 'Psycho', year: 1960 }, - { label: 'The Green Mile', year: 1999 }, - { label: 'The Intouchables', year: 2011 }, - { label: 'Modern Times', year: 1936 }, - { label: 'Raiders of the Lost Ark', year: 1981 }, - { label: 'Rear Window', year: 1954 }, - { label: 'The Pianist', year: 2002 }, - { label: 'The Departed', year: 2006 }, - { label: 'Terminator 2: Judgment Day', year: 1991 }, - { label: 'Back to the Future', year: 1985 }, - { label: 'Whiplash', year: 2014 }, - { label: 'Gladiator', year: 2000 }, - { label: 'Memento', year: 2000 }, - { label: 'The Prestige', year: 2006 }, - { label: 'The Lion King', year: 1994 }, - { label: 'Apocalypse Now', year: 1979 }, - { label: 'Alien', year: 1979 }, - { label: 'Sunset Boulevard', year: 1950 }, - { - label: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { label: 'The Great Dictator', year: 1940 }, - { label: 'Cinema Paradiso', year: 1988 }, - { label: 'The Lives of Others', year: 2006 }, - { label: 'Grave of the Fireflies', year: 1988 }, - { label: 'Paths of Glory', year: 1957 }, - { label: 'Django Unchained', year: 2012 }, - { label: 'The Shining', year: 1980 }, - { label: 'WALL·E', year: 2008 }, - { label: 'American Beauty', year: 1999 }, - { label: 'The Dark Knight Rises', year: 2012 }, - { label: 'Princess Mononoke', year: 1997 }, - { label: 'Aliens', year: 1986 }, - { label: 'Oldboy', year: 2003 }, - { label: 'Once Upon a Time in America', year: 1984 }, - { label: 'Witness for the Prosecution', year: 1957 }, - { label: 'Das Boot', year: 1981 }, - { label: 'Citizen Kane', year: 1941 }, - { label: 'North by Northwest', year: 1959 }, - { label: 'Vertigo', year: 1958 }, - { - label: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { label: 'Reservoir Dogs', year: 1992 }, - { label: 'Braveheart', year: 1995 }, - { label: 'M', year: 1931 }, - { label: 'Requiem for a Dream', year: 2000 }, - { label: 'Amélie', year: 2001 }, - { label: 'A Clockwork Orange', year: 1971 }, - { label: 'Like Stars on Earth', year: 2007 }, - { label: 'Taxi Driver', year: 1976 }, - { label: 'Lawrence of Arabia', year: 1962 }, - { label: 'Double Indemnity', year: 1944 }, - { - label: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { label: 'Amadeus', year: 1984 }, - { label: 'To Kill a Mockingbird', year: 1962 }, - { label: 'Toy Story 3', year: 2010 }, - { label: 'Logan', year: 2017 }, - { label: 'Full Metal Jacket', year: 1987 }, - { label: 'Dangal', year: 2016 }, - { label: 'The Sting', year: 1973 }, - { label: '2001: A Space Odyssey', year: 1968 }, - { label: "Singin' in the Rain", year: 1952 }, - { label: 'Toy Story', year: 1995 }, - { label: 'Bicycle Thieves', year: 1948 }, - { label: 'The Kid', year: 1921 }, - { label: 'Inglourious Basterds', year: 2009 }, - { label: 'Snatch', year: 2000 }, - { label: '3 Idiots', year: 2009 }, - { label: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/ComboBox.tsx b/docs/data/material/components/autocomplete/ComboBox.tsx index 4e515937746cb4..a27d7aef434c56 100644 --- a/docs/data/material/components/autocomplete/ComboBox.tsx +++ b/docs/data/material/components/autocomplete/ComboBox.tsx @@ -1,143 +1,15 @@ import * as React from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; export default function ComboBox() { return ( } /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { label: 'The Shawshank Redemption', year: 1994 }, - { label: 'The Godfather', year: 1972 }, - { label: 'The Godfather: Part II', year: 1974 }, - { label: 'The Dark Knight', year: 2008 }, - { label: '12 Angry Men', year: 1957 }, - { label: "Schindler's List", year: 1993 }, - { label: 'Pulp Fiction', year: 1994 }, - { - label: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { label: 'The Good, the Bad and the Ugly', year: 1966 }, - { label: 'Fight Club', year: 1999 }, - { - label: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - label: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { label: 'Forrest Gump', year: 1994 }, - { label: 'Inception', year: 2010 }, - { - label: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { label: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { label: 'Goodfellas', year: 1990 }, - { label: 'The Matrix', year: 1999 }, - { label: 'Seven Samurai', year: 1954 }, - { - label: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { label: 'City of God', year: 2002 }, - { label: 'Se7en', year: 1995 }, - { label: 'The Silence of the Lambs', year: 1991 }, - { label: "It's a Wonderful Life", year: 1946 }, - { label: 'Life Is Beautiful', year: 1997 }, - { label: 'The Usual Suspects', year: 1995 }, - { label: 'Léon: The Professional', year: 1994 }, - { label: 'Spirited Away', year: 2001 }, - { label: 'Saving Private Ryan', year: 1998 }, - { label: 'Once Upon a Time in the West', year: 1968 }, - { label: 'American History X', year: 1998 }, - { label: 'Interstellar', year: 2014 }, - { label: 'Casablanca', year: 1942 }, - { label: 'City Lights', year: 1931 }, - { label: 'Psycho', year: 1960 }, - { label: 'The Green Mile', year: 1999 }, - { label: 'The Intouchables', year: 2011 }, - { label: 'Modern Times', year: 1936 }, - { label: 'Raiders of the Lost Ark', year: 1981 }, - { label: 'Rear Window', year: 1954 }, - { label: 'The Pianist', year: 2002 }, - { label: 'The Departed', year: 2006 }, - { label: 'Terminator 2: Judgment Day', year: 1991 }, - { label: 'Back to the Future', year: 1985 }, - { label: 'Whiplash', year: 2014 }, - { label: 'Gladiator', year: 2000 }, - { label: 'Memento', year: 2000 }, - { label: 'The Prestige', year: 2006 }, - { label: 'The Lion King', year: 1994 }, - { label: 'Apocalypse Now', year: 1979 }, - { label: 'Alien', year: 1979 }, - { label: 'Sunset Boulevard', year: 1950 }, - { - label: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { label: 'The Great Dictator', year: 1940 }, - { label: 'Cinema Paradiso', year: 1988 }, - { label: 'The Lives of Others', year: 2006 }, - { label: 'Grave of the Fireflies', year: 1988 }, - { label: 'Paths of Glory', year: 1957 }, - { label: 'Django Unchained', year: 2012 }, - { label: 'The Shining', year: 1980 }, - { label: 'WALL·E', year: 2008 }, - { label: 'American Beauty', year: 1999 }, - { label: 'The Dark Knight Rises', year: 2012 }, - { label: 'Princess Mononoke', year: 1997 }, - { label: 'Aliens', year: 1986 }, - { label: 'Oldboy', year: 2003 }, - { label: 'Once Upon a Time in America', year: 1984 }, - { label: 'Witness for the Prosecution', year: 1957 }, - { label: 'Das Boot', year: 1981 }, - { label: 'Citizen Kane', year: 1941 }, - { label: 'North by Northwest', year: 1959 }, - { label: 'Vertigo', year: 1958 }, - { - label: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { label: 'Reservoir Dogs', year: 1992 }, - { label: 'Braveheart', year: 1995 }, - { label: 'M', year: 1931 }, - { label: 'Requiem for a Dream', year: 2000 }, - { label: 'Amélie', year: 2001 }, - { label: 'A Clockwork Orange', year: 1971 }, - { label: 'Like Stars on Earth', year: 2007 }, - { label: 'Taxi Driver', year: 1976 }, - { label: 'Lawrence of Arabia', year: 1962 }, - { label: 'Double Indemnity', year: 1944 }, - { - label: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { label: 'Amadeus', year: 1984 }, - { label: 'To Kill a Mockingbird', year: 1962 }, - { label: 'Toy Story 3', year: 2010 }, - { label: 'Logan', year: 2017 }, - { label: 'Full Metal Jacket', year: 1987 }, - { label: 'Dangal', year: 2016 }, - { label: 'The Sting', year: 1973 }, - { label: '2001: A Space Odyssey', year: 1968 }, - { label: "Singin' in the Rain", year: 1952 }, - { label: 'Toy Story', year: 1995 }, - { label: 'Bicycle Thieves', year: 1948 }, - { label: 'The Kid', year: 1921 }, - { label: 'Inglourious Basterds', year: 2009 }, - { label: 'Snatch', year: 2000 }, - { label: '3 Idiots', year: 2009 }, - { label: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/ComboBox.tsx.preview b/docs/data/material/components/autocomplete/ComboBox.tsx.preview index c6f286c340c707..7382e2d5a10c39 100644 --- a/docs/data/material/components/autocomplete/ComboBox.tsx.preview +++ b/docs/data/material/components/autocomplete/ComboBox.tsx.preview @@ -1,6 +1,5 @@ } diff --git a/docs/data/material/components/autocomplete/DisabledOptions.js b/docs/data/material/components/autocomplete/DisabledOptions.js index 10ff390a0390e5..feeee324859c1a 100644 --- a/docs/data/material/components/autocomplete/DisabledOptions.js +++ b/docs/data/material/components/autocomplete/DisabledOptions.js @@ -5,7 +5,6 @@ import Autocomplete from '@mui/material/Autocomplete'; export default function DisabledOptions() { return ( option === timeSlots[0] || option === timeSlots[2] diff --git a/docs/data/material/components/autocomplete/DisabledOptions.tsx b/docs/data/material/components/autocomplete/DisabledOptions.tsx index 10ff390a0390e5..feeee324859c1a 100644 --- a/docs/data/material/components/autocomplete/DisabledOptions.tsx +++ b/docs/data/material/components/autocomplete/DisabledOptions.tsx @@ -5,7 +5,6 @@ import Autocomplete from '@mui/material/Autocomplete'; export default function DisabledOptions() { return ( option === timeSlots[0] || option === timeSlots[2] diff --git a/docs/data/material/components/autocomplete/DisabledOptions.tsx.preview b/docs/data/material/components/autocomplete/DisabledOptions.tsx.preview index f4acfa9a7966e4..528fc85290a1d3 100644 --- a/docs/data/material/components/autocomplete/DisabledOptions.tsx.preview +++ b/docs/data/material/components/autocomplete/DisabledOptions.tsx.preview @@ -1,5 +1,4 @@ option === timeSlots[0] || option === timeSlots[2] diff --git a/docs/data/material/components/autocomplete/Filter.js b/docs/data/material/components/autocomplete/Filter.js index 00e3a63c5d447e..b3a482781108ad 100644 --- a/docs/data/material/components/autocomplete/Filter.js +++ b/docs/data/material/components/autocomplete/Filter.js @@ -10,7 +10,6 @@ const filterOptions = createFilterOptions({ export default function Filter() { return ( option.title} filterOptions={filterOptions} diff --git a/docs/data/material/components/autocomplete/Filter.tsx b/docs/data/material/components/autocomplete/Filter.tsx index 6b3f4bdd4b9280..5a41bcdf275c5b 100644 --- a/docs/data/material/components/autocomplete/Filter.tsx +++ b/docs/data/material/components/autocomplete/Filter.tsx @@ -10,7 +10,6 @@ const filterOptions = createFilterOptions({ export default function Filter() { return ( option.title} filterOptions={filterOptions} diff --git a/docs/data/material/components/autocomplete/Filter.tsx.preview b/docs/data/material/components/autocomplete/Filter.tsx.preview index 3165c14c1e8a8e..7ca0d8bb8625c3 100644 --- a/docs/data/material/components/autocomplete/Filter.tsx.preview +++ b/docs/data/material/components/autocomplete/Filter.tsx.preview @@ -1,5 +1,4 @@ option.title} filterOptions={filterOptions} diff --git a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js index d5f7669578cc79..8f0327c5227592 100644 --- a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js +++ b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js @@ -65,7 +65,6 @@ function MovieSelect() { function CountrySelect() { return ( diff --git a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx index 4703740e9ab0ef..3ec3840e00292a 100644 --- a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx +++ b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx @@ -65,7 +65,6 @@ function MovieSelect() { function CountrySelect() { return ( diff --git a/docs/data/material/components/autocomplete/GoogleMaps.js b/docs/data/material/components/autocomplete/GoogleMaps.js index 9ac81f207c836a..d67aa4cce5cfd6 100644 --- a/docs/data/material/components/autocomplete/GoogleMaps.js +++ b/docs/data/material/components/autocomplete/GoogleMaps.js @@ -91,7 +91,6 @@ export default function GoogleMaps() { return ( typeof option === 'string' ? option : option.description diff --git a/docs/data/material/components/autocomplete/GoogleMaps.tsx b/docs/data/material/components/autocomplete/GoogleMaps.tsx index 269823b32bc4e8..2fe24affecc978 100644 --- a/docs/data/material/components/autocomplete/GoogleMaps.tsx +++ b/docs/data/material/components/autocomplete/GoogleMaps.tsx @@ -115,7 +115,6 @@ export default function GoogleMaps() { return ( typeof option === 'string' ? option : option.description diff --git a/docs/data/material/components/autocomplete/Grouped.js b/docs/data/material/components/autocomplete/Grouped.js index e4b7aac8036a85..e13f7877266db6 100644 --- a/docs/data/material/components/autocomplete/Grouped.js +++ b/docs/data/material/components/autocomplete/Grouped.js @@ -13,7 +13,6 @@ export default function Grouped() { return ( -b.firstLetter.localeCompare(a.firstLetter))} groupBy={(option) => option.firstLetter} getOptionLabel={(option) => option.title} diff --git a/docs/data/material/components/autocomplete/Grouped.tsx b/docs/data/material/components/autocomplete/Grouped.tsx index e4b7aac8036a85..e13f7877266db6 100644 --- a/docs/data/material/components/autocomplete/Grouped.tsx +++ b/docs/data/material/components/autocomplete/Grouped.tsx @@ -13,7 +13,6 @@ export default function Grouped() { return ( -b.firstLetter.localeCompare(a.firstLetter))} groupBy={(option) => option.firstLetter} getOptionLabel={(option) => option.title} diff --git a/docs/data/material/components/autocomplete/Grouped.tsx.preview b/docs/data/material/components/autocomplete/Grouped.tsx.preview index 2ea3bd1d9135e8..861cf451662757 100644 --- a/docs/data/material/components/autocomplete/Grouped.tsx.preview +++ b/docs/data/material/components/autocomplete/Grouped.tsx.preview @@ -1,5 +1,4 @@ -b.firstLetter.localeCompare(a.firstLetter))} groupBy={(option) => option.firstLetter} getOptionLabel={(option) => option.title} diff --git a/docs/data/material/components/autocomplete/Highlights.js b/docs/data/material/components/autocomplete/Highlights.js index 0f56f70ca6e08d..7d5c6950dcde81 100644 --- a/docs/data/material/components/autocomplete/Highlights.js +++ b/docs/data/material/components/autocomplete/Highlights.js @@ -7,7 +7,6 @@ import match from 'autosuggest-highlight/match'; export default function Highlights() { return ( option.title} diff --git a/docs/data/material/components/autocomplete/Highlights.tsx b/docs/data/material/components/autocomplete/Highlights.tsx index 0f56f70ca6e08d..7d5c6950dcde81 100644 --- a/docs/data/material/components/autocomplete/Highlights.tsx +++ b/docs/data/material/components/autocomplete/Highlights.tsx @@ -7,7 +7,6 @@ import match from 'autosuggest-highlight/match'; export default function Highlights() { return ( option.title} diff --git a/docs/data/material/components/autocomplete/RenderGroup.js b/docs/data/material/components/autocomplete/RenderGroup.js index 3d283560dbb4f7..878bf1977e58df 100644 --- a/docs/data/material/components/autocomplete/RenderGroup.js +++ b/docs/data/material/components/autocomplete/RenderGroup.js @@ -29,7 +29,6 @@ export default function RenderGroup() { return ( -b.firstLetter.localeCompare(a.firstLetter))} groupBy={(option) => option.firstLetter} getOptionLabel={(option) => option.title} diff --git a/docs/data/material/components/autocomplete/RenderGroup.tsx b/docs/data/material/components/autocomplete/RenderGroup.tsx index 3d283560dbb4f7..878bf1977e58df 100644 --- a/docs/data/material/components/autocomplete/RenderGroup.tsx +++ b/docs/data/material/components/autocomplete/RenderGroup.tsx @@ -29,7 +29,6 @@ export default function RenderGroup() { return ( -b.firstLetter.localeCompare(a.firstLetter))} groupBy={(option) => option.firstLetter} getOptionLabel={(option) => option.title} diff --git a/docs/data/material/components/autocomplete/RenderGroup.tsx.preview b/docs/data/material/components/autocomplete/RenderGroup.tsx.preview index bf68be03c34532..85d7b49d75f0d7 100644 --- a/docs/data/material/components/autocomplete/RenderGroup.tsx.preview +++ b/docs/data/material/components/autocomplete/RenderGroup.tsx.preview @@ -1,5 +1,4 @@ -b.firstLetter.localeCompare(a.firstLetter))} groupBy={(option) => option.firstLetter} getOptionLabel={(option) => option.title} diff --git a/docs/data/material/components/autocomplete/Virtualize.js b/docs/data/material/components/autocomplete/Virtualize.js index 7b62b6c4f7b938..846554c8c6d9db 100644 --- a/docs/data/material/components/autocomplete/Virtualize.js +++ b/docs/data/material/components/autocomplete/Virtualize.js @@ -138,7 +138,6 @@ const OPTIONS = Array.from(new Array(10000)) export default function Virtualize() { return ( Avatars are found throughout material design with uses in everything from tables to dialog menus.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Image avatars diff --git a/docs/data/material/components/backdrop/backdrop.md b/docs/data/material/components/backdrop/backdrop.md index 8255a55f20623b..480cbb2176b18e 100644 --- a/docs/data/material/components/backdrop/backdrop.md +++ b/docs/data/material/components/backdrop/backdrop.md @@ -12,7 +12,7 @@ githubLabel: 'component: backdrop' The Backdrop signals a state change within the application and can be used for creating loaders, dialogs, and more. In its simplest form, the Backdrop component will add a dimmed layer over your application. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Example diff --git a/docs/data/material/components/badges/BadgeAlignment.js b/docs/data/material/components/badges/BadgeAlignment.js index 1cce1c8ec7005a..f83681e740c61f 100644 --- a/docs/data/material/components/badges/BadgeAlignment.js +++ b/docs/data/material/components/badges/BadgeAlignment.js @@ -7,7 +7,7 @@ import Radio from '@mui/material/Radio'; import RadioGroup from '@mui/material/RadioGroup'; import Box from '@mui/material/Box'; import MailIcon from '@mui/icons-material/Mail'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; export default function BadgeAlignment() { const [horizontal, setHorizontal] = React.useState('right'); diff --git a/docs/data/material/components/badges/badges.md b/docs/data/material/components/badges/badges.md index 143dd849cd3bea..afe2a11c2d73dc 100644 --- a/docs/data/material/components/badges/badges.md +++ b/docs/data/material/components/badges/badges.md @@ -10,7 +10,7 @@ unstyled: /base-ui/react-badge/

Badge generates a small badge to the top-right of its child(ren).

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic badge diff --git a/docs/data/material/components/bottom-navigation/bottom-navigation.md b/docs/data/material/components/bottom-navigation/bottom-navigation.md index ee1c9da6bfbb2a..29e8ff56dfe66e 100644 --- a/docs/data/material/components/bottom-navigation/bottom-navigation.md +++ b/docs/data/material/components/bottom-navigation/bottom-navigation.md @@ -12,7 +12,7 @@ materialDesign: https://m2.material.io/components/bottom-navigation Bottom navigation bars display three to five destinations at the bottom of a screen. Each destination is represented by an icon and an optional text label. When a bottom navigation icon is tapped, the user is taken to the top-level navigation destination associated with that icon. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Bottom navigation diff --git a/docs/data/material/components/box/box.md b/docs/data/material/components/box/box.md index d7067da6199723..1c34e9399eb6fe 100644 --- a/docs/data/material/components/box/box.md +++ b/docs/data/material/components/box/box.md @@ -11,7 +11,7 @@ githubLabel: 'component: Box'

The Box component is a generic, theme-aware container with access to CSS utilities from MUI System.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Introduction diff --git a/docs/data/material/components/breadcrumbs/breadcrumbs.md b/docs/data/material/components/breadcrumbs/breadcrumbs.md index f76696587d0bcb..7468c550e3eba1 100644 --- a/docs/data/material/components/breadcrumbs/breadcrumbs.md +++ b/docs/data/material/components/breadcrumbs/breadcrumbs.md @@ -10,7 +10,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/breadcrumb/

A breadcrumbs is a list of links that help visualize a page's location within a site's hierarchical structure, it allows navigation up to any of the ancestors.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic breadcrumbs diff --git a/docs/data/material/components/button-group/button-group.md b/docs/data/material/components/button-group/button-group.md index a0645298d04bb6..c5a1732e01635c 100644 --- a/docs/data/material/components/button-group/button-group.md +++ b/docs/data/material/components/button-group/button-group.md @@ -9,7 +9,7 @@ githubLabel: 'component: ButtonGroup'

The ButtonGroup component can be used to group related buttons.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic button group diff --git a/docs/data/material/components/buttons/InputFileUpload.js b/docs/data/material/components/buttons/InputFileUpload.js index d1cfcba03567ac..e939eba055432b 100644 --- a/docs/data/material/components/buttons/InputFileUpload.js +++ b/docs/data/material/components/buttons/InputFileUpload.js @@ -24,8 +24,12 @@ export default function InputFileUpload() { tabIndex={-1} startIcon={} > - Upload file - + Upload files + console.log(event.target.files)} + multiple + /> ); } diff --git a/docs/data/material/components/buttons/InputFileUpload.tsx b/docs/data/material/components/buttons/InputFileUpload.tsx index d1cfcba03567ac..e939eba055432b 100644 --- a/docs/data/material/components/buttons/InputFileUpload.tsx +++ b/docs/data/material/components/buttons/InputFileUpload.tsx @@ -24,8 +24,12 @@ export default function InputFileUpload() { tabIndex={-1} startIcon={} > - Upload file - + Upload files + console.log(event.target.files)} + multiple + /> ); } diff --git a/docs/data/material/components/buttons/InputFileUpload.tsx.preview b/docs/data/material/components/buttons/InputFileUpload.tsx.preview index 69ab491553d7c8..c2dccf123cc789 100644 --- a/docs/data/material/components/buttons/InputFileUpload.tsx.preview +++ b/docs/data/material/components/buttons/InputFileUpload.tsx.preview @@ -5,6 +5,10 @@ tabIndex={-1} startIcon={} > - Upload file - + Upload files + console.log(event.target.files)} + multiple + /> \ No newline at end of file diff --git a/docs/data/material/components/buttons/buttons.md b/docs/data/material/components/buttons/buttons.md index 247609d8aa46e9..e4be4419583610 100644 --- a/docs/data/material/components/buttons/buttons.md +++ b/docs/data/material/components/buttons/buttons.md @@ -19,7 +19,7 @@ Buttons communicate actions that users can take. They are typically placed throu - Cards - Toolbars -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic button diff --git a/docs/data/material/components/cards/cards.md b/docs/data/material/components/cards/cards.md index fa18974f8bd743..e6c0ccba1d699f 100644 --- a/docs/data/material/components/cards/cards.md +++ b/docs/data/material/components/cards/cards.md @@ -10,7 +10,7 @@ materialDesign: https://m2.material.io/components/cards

Cards contain content and actions about a single subject.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/material/components/checkboxes/checkboxes.md b/docs/data/material/components/checkboxes/checkboxes.md index c2ef0d2ec1984f..8af3d4f249d28e 100644 --- a/docs/data/material/components/checkboxes/checkboxes.md +++ b/docs/data/material/components/checkboxes/checkboxes.md @@ -17,7 +17,7 @@ If you have multiple options appearing in a list, you can preserve space by using checkboxes instead of on/off switches. If you have a single option, avoid using a checkbox and use an on/off switch instead. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic checkboxes diff --git a/docs/data/material/components/chips/ChipsPlayground.js b/docs/data/material/components/chips/ChipsPlayground.js index fdcc7d5c36d2cd..e7802bb5eaaf8d 100644 --- a/docs/data/material/components/chips/ChipsPlayground.js +++ b/docs/data/material/components/chips/ChipsPlayground.js @@ -9,7 +9,7 @@ import Avatar from '@mui/material/Avatar'; import Chip from '@mui/material/Chip'; import FaceIcon from '@mui/icons-material/Face'; import DoneIcon from '@mui/icons-material/Done'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; function ChipsPlayground() { const [state, setState] = React.useState({ diff --git a/docs/data/material/components/chips/chips.md b/docs/data/material/components/chips/chips.md index 65063426ca27a8..3d44914c403a33 100644 --- a/docs/data/material/components/chips/chips.md +++ b/docs/data/material/components/chips/chips.md @@ -16,7 +16,7 @@ While included here as a standalone component, the most common use will be in some form of input, so some of the behavior demonstrated here is not shown in context. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic chip diff --git a/docs/data/material/components/container/container.md b/docs/data/material/components/container/container.md index 45efa92410cbd7..c585be2d5e869b 100644 --- a/docs/data/material/components/container/container.md +++ b/docs/data/material/components/container/container.md @@ -11,7 +11,7 @@ githubLabel: 'component: Container' While containers can be nested, most layouts do not require a nested container. -{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Fluid diff --git a/docs/data/material/components/css-baseline/css-baseline.md b/docs/data/material/components/css-baseline/css-baseline.md index 3b8a0705dab550..8842568bbd2d65 100644 --- a/docs/data/material/components/css-baseline/css-baseline.md +++ b/docs/data/material/components/css-baseline/css-baseline.md @@ -8,7 +8,7 @@ githubLabel: 'component: CssBaseline'

The CssBaseline component helps to kickstart an elegant, consistent, and simple baseline to build upon.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Global reset diff --git a/docs/data/material/components/dialogs/dialogs.md b/docs/data/material/components/dialogs/dialogs.md index 87a89ff8ed435a..c352355a2982a2 100644 --- a/docs/data/material/components/dialogs/dialogs.md +++ b/docs/data/material/components/dialogs/dialogs.md @@ -15,7 +15,7 @@ A Dialog is a type of [modal](/material-ui/react-modal/) window that appears in Dialogs are purposefully interruptive, so they should be used sparingly. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/material/components/dividers/dividers.md b/docs/data/material/components/dividers/dividers.md index f04e1470606b84..cc755df9900e29 100644 --- a/docs/data/material/components/dividers/dividers.md +++ b/docs/data/material/components/dividers/dividers.md @@ -10,7 +10,7 @@ materialDesign: https://m2.material.io/components/dividers

The Divider component provides a thin, unobtrusive line for grouping elements to reinforce visual hierarchy.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/material/components/drawers/drawers.md b/docs/data/material/components/drawers/drawers.md index 8bd8e8048dce8e..7199a9466051e9 100644 --- a/docs/data/material/components/drawers/drawers.md +++ b/docs/data/material/components/drawers/drawers.md @@ -14,7 +14,7 @@ A navigation drawer can either be permanently on-screen or controlled by a navig [Side sheets](https://m2.material.io/components/sheets-side) are supplementary surfaces primarily used on tablet and desktop. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Temporary drawer diff --git a/docs/data/material/components/floating-action-button/FloatingActionButtonZoom.js b/docs/data/material/components/floating-action-button/FloatingActionButtonZoom.js index e4945c497d8d87..c8313b1319066e 100644 --- a/docs/data/material/components/floating-action-button/FloatingActionButtonZoom.js +++ b/docs/data/material/components/floating-action-button/FloatingActionButtonZoom.js @@ -1,6 +1,5 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import SwipeableViews from 'react-swipeable-views'; import { useTheme } from '@mui/material/styles'; import AppBar from '@mui/material/AppBar'; import Tabs from '@mui/material/Tabs'; @@ -66,10 +65,6 @@ export default function FloatingActionButtonZoom() { setValue(newValue); }; - const handleChangeIndex = (index) => { - setValue(index); - }; - const transitionDuration = { enter: theme.transitions.duration.enteringScreen, exit: theme.transitions.duration.leavingScreen, @@ -119,21 +114,15 @@ export default function FloatingActionButtonZoom() { - - - Item One - - - Item Two - - - Item Three - - + + Item One + + + Item Two + + + Item Three + {fabs.map((fab, index) => ( { - setValue(index); - }; - const transitionDuration = { enter: theme.transitions.duration.enteringScreen, exit: theme.transitions.duration.leavingScreen, @@ -120,21 +115,15 @@ export default function FloatingActionButtonZoom() { - - - Item One - - - Item Two - - - Item Three - - + + Item One + + + Item Two + + + Item Three + {fabs.map((fab, index) => ( The responsive layout grid adapts to screen size and orientation, ensuring consistency across layouts.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} The `Grid` component works well for a layout with a known number of columns. The columns can be configured with multiple breakpoints to specify the column span of each child. diff --git a/docs/data/material/components/hidden/hidden.md b/docs/data/material/components/hidden/hidden.md index 51328ec067352a..d1e62eb96deac6 100644 --- a/docs/data/material/components/hidden/hidden.md +++ b/docs/data/material/components/hidden/hidden.md @@ -15,4 +15,4 @@ To learn more, see [the Hidden section](/material-ui/migration/v5-component-chan

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} diff --git a/docs/data/material/components/icons/CreateSvgIcon.js b/docs/data/material/components/icons/CreateSvgIcon.js index ec540e8058cd14..ee8f3ae3156c51 100644 --- a/docs/data/material/components/icons/CreateSvgIcon.js +++ b/docs/data/material/components/icons/CreateSvgIcon.js @@ -8,7 +8,7 @@ const HomeIcon = createSvgIcon( ); const PlusIcon = createSvgIcon( - // credit: plus icon from https://heroicons.com/ + // credit: plus icon from https://heroicons.com - {/* credit: plus icon from https://heroicons.com/ */} + {/* credit: cog icon from https://heroicons.com */} - {/* credit: plus icon from https://heroicons.com/ */} + {/* credit: cog icon from https://heroicons.com */} - {/* credit: plus icon from https://heroicons.com/ */} + {/* credit: cog icon from https://heroicons.com */} The Link component allows you to easily customize anchor elements with your theme colors and typography styles.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic links diff --git a/docs/data/material/components/lists/lists.md b/docs/data/material/components/lists/lists.md index 0f9fd925005ecb..70b2a98889aca3 100644 --- a/docs/data/material/components/lists/lists.md +++ b/docs/data/material/components/lists/lists.md @@ -12,7 +12,7 @@ materialDesign: https://m2.material.io/components/lists Lists are a continuous group of text or images. They are composed of items containing primary and supplemental actions, which are represented by icons and text. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/material/components/masonry/masonry.md b/docs/data/material/components/masonry/masonry.md index 333c439874680f..d1e9e831eb52e5 100644 --- a/docs/data/material/components/masonry/masonry.md +++ b/docs/data/material/components/masonry/masonry.md @@ -13,7 +13,7 @@ Masonry maintains a list of content blocks with a consistent width but different The contents are ordered by row. If a row is already filled with the specified number of columns, the next item starts another row, and it is added to the shortest column in order to optimize the use of space. -{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Basic masonry diff --git a/docs/data/material/components/material-icons/SearchIcons.js b/docs/data/material/components/material-icons/SearchIcons.js index fc2d1f34e158a5..faf1532ef9ad64 100644 --- a/docs/data/material/components/material-icons/SearchIcons.js +++ b/docs/data/material/components/material-icons/SearchIcons.js @@ -45,7 +45,7 @@ import useQueryParameterState from 'docs/src/modules/utils/useQueryParameterStat // import DeleteForeverRounded from '@mui/icons-material/DeleteForeverRounded'; // import DeleteForeverTwoTone from '@mui/icons-material/DeleteForeverTwoTone'; // import DeleteForeverSharp from '@mui/icons-material/DeleteForeverSharp'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import synonyms from './synonyms'; const FlexSearchIndex = flexsearch.default.Index; diff --git a/docs/data/material/components/material-icons/material-icons.md b/docs/data/material/components/material-icons/material-icons.md index ae09f5b703ff71..12a8e683c8789e 100644 --- a/docs/data/material/components/material-icons/material-icons.md +++ b/docs/data/material/components/material-icons/material-icons.md @@ -10,7 +10,7 @@ githubLabel: 'package: icons'

2,100+ ready-to-use React Material Icons from the official website.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}}
[@mui/icons-material](https://www.npmjs.com/package/@mui/icons-material) diff --git a/docs/data/material/components/material-icons/synonyms.js b/docs/data/material/components/material-icons/synonyms.js index 88b96bc58691f7..5a09c5a3e05d06 100644 --- a/docs/data/material/components/material-icons/synonyms.js +++ b/docs/data/material/components/material-icons/synonyms.js @@ -1,5 +1,5 @@ const synonyms = { - Abc: 'alphabet character font letter symbol text type', + Abc: 'alphabet character font letters symbol text type', AccessAlarm: 'clock time', AccessAlarms: 'clock time', Accessibility: 'accessible body handicap help human people person user', @@ -191,15 +191,16 @@ const synonyms = { AssistWalker: 'accessibility accessible body disability handicap help human injured injury mobility person', AssuredWorkload: - 'compliance confidential federal government regulatory secure sensitive', - Atm: 'alphabet automated bill card cart cash character coin commerce credit currency dollars font letter machine money online payment shopping symbol teller text type', - AttachEmail: 'attachment clip compose envelop letter link message send', + 'account balance bank bill building card cash coin commerce compliance confidential credit currency dollars federal finance government money online payment regulatory secure sensitive', + Atm: 'alphabet automated bill card cart cash character coin commerce credit currency dollars font letters machine money online payment shopping symbol teller text type', + AttachEmail: 'attachment compose envelop letters link message paperclip send', AttachFile: 'add attachment item link mail media paperclip', Attachment: 'compose file image item link paperclip', AttachMoney: 'attachment bill card cash coin commerce cost credit currency dollars finance online payment price profit sale symbol', Attractions: 'amusement entertainment ferris fun maps park places wheel', - Attribution: 'attribute body copyright copywriter human people person', + Attribution: + 'account attribute body circle copyright copywriter human people person profile user youtube', AudioFile: 'document key music note sound track', Audiotrack: 'key music note sound', AutoAwesome: @@ -216,7 +217,7 @@ const synonyms = { AutoFixOff: 'artificial automatic automation custom disabled edit enabled erase genai intelligence magic modify slash smart sparkle stars wand', AutofpsSelect: - 'A alphabet character font frame frequency letter per rate seconds symbol text type', + 'A alphabet character font frame frequency letters per rate seconds symbol text type', AutoGraph: 'analytics chart data diagram infographic line measure metrics stars statistics tracking', AutoMode: @@ -414,7 +415,8 @@ const synonyms = { 'access automobile cars entry key maps password transportation unlock vehicle', CarRepair: 'automobile cars maps transportation vehicle', Cases: 'baggage briefcase business purse suitcase', - Casino: 'dice dots entertainment gamble gambling games luck places', + Casino: + 'casino chips dice dots entertainment gamble gambling games luck places tokens', Cast: 'Android airplay chromecast connect desktop device display hardware iOS mac monitor screencast streaming television tv web window wireless', CastConnected: 'Android airplay chromecast desktop device display hardware iOS mac monitor screencast streaming television tv web window wireless', @@ -422,7 +424,7 @@ const synonyms = { 'Android airplay chrome connect desktop device display hardware iOS learning lessons mac monitor screencast streaming teaching television tv web window wireless', Castle: 'fortress mansion palace', CatchingPokemon: 'go pokestop travel', - Category: 'categories circle collection items product sort square triangle', + Category: 'categories circle collection items product shapes sort square triangle', Celebration: 'activity birthday event fun party', CellTower: 'broadcast casting network signal transmitting wireless', CellWifi: 'connection data internet mobile network phone service signal wireless', @@ -447,7 +449,7 @@ const synonyms = { CheckBoxOutlineBlank: 'button checkmark component control dashed deselected empty form selection square tick toggle ui', CheckCircle: - 'approve checkmark complete done download finished ok select success tick upload validate verified yes', + 'approve checkmark complete confirm done download finished ok select success tick upload validate verified yes', CheckCircleOutline: 'approve checkmark complete done finished ok select success tick validate verified yes', Checklist: @@ -473,11 +475,11 @@ const synonyms = { ClearAll: 'delete document erase format lines list notifications wipe', Close: 'allowed cancel clear cross disable exit not remove status stop times', ClosedCaption: - 'accessible alphabet character decoder font language letter media movies subtitles symbol text tv type', + 'accessible alphabet character decoder font language letters media movies subtitles symbol text tv type', ClosedCaptionDisabled: - 'accessible alphabet character decoder enabled font language letter media movies off slash subtitles symbol text tv type', + 'accessible alphabet character decoder enabled font language letters media movies off slash subtitles symbol text tv type', ClosedCaptionOff: - 'accessible alphabet character decoder font language letter media movies outline subtitles symbol text tv type', + 'accessible alphabet character decoder font language letters media movies outline subtitles symbol text tv type', CloseFullscreen: 'action arrows collapse direction minimize', Cloud: 'climate connection internet network queue sky temperature upload weather', CloudCircle: @@ -521,7 +523,7 @@ const synonyms = { Compress: 'arrows collide pressure push together', Computer: 'Android chrome desktop device hardware iOS laptop mac monitor pc web window', - ConfirmationNumber: 'admission entertainment event ticket', + ConfirmationNumber: 'admission entertainment event numbers ticket', ConnectedTv: 'Android airplay chrome desktop device display hardware iOS mac monitor screencast streaming television web window wireless', ConnectingAirports: 'airplanes flight transportation travel trip', @@ -556,7 +558,7 @@ const synonyms = { Cookie: 'biscuit cookies data dessert wafer', CoPresent: 'arrow co-present presentation screen share slides togather website', CopyAll: 'content cut dashed document file multiple page paper past', - Copyright: 'alphabet character circle emblem font legal letter owner symbol text', + Copyright: 'alphabet character circle emblem font legal letters owner symbol text', Coronavirus: '19 bacteria covid disease germs illness sick social', CorporateFare: 'architecture building business estate organization place real residence residential shelter', @@ -598,7 +600,7 @@ const synonyms = { 'adjustments area arrows editing frame images photos settings size turn', CropSquare: 'adjustments application area components design editing expand frame images interface open photos rectangle screen settings shapes size ui ux website window', - Css: 'alphabet brackets character code developer engineering font html letter platform symbol text type', + Css: 'alphabet brackets character code developer engineering font html letters platform symbol text type', CurrencyBitcoin: 'bill blockchain card cash commerce cost credit digital dollars finance franc money online payment price shopping symbol', CurrencyExchange: @@ -619,7 +621,7 @@ const synonyms = { 'bill card cash coin commerce cost credit dollars finance money online payment price shopping symbol', Curtains: 'blinds cover nest open shutter sunshade', CurtainsClosed: 'blinds cover nest shutter sunshade', - Cyclone: 'crisis disaster natural rain storm weather winds', + Cyclone: 'crisis disaster natural rain storm water weather winds', Dangerous: 'broken fix no sign stop update warning wrong', DarkMode: 'application device interface moon night silent theme ui ux website', Dashboard: 'cards format layout rectangle shapes square website', @@ -671,12 +673,12 @@ const synonyms = { 'Android computer desktop hardware iOS laptop mobile monitor phone tablet watch wearable web', DevicesFold: 'Android cell dashed foldable hardware iOS mobile phone tablet', DevicesOther: - 'Android cell chrome desktop gadget hardware iOS ipad mac mobile monitor phone smartwatch tablet vr wearables window', + 'Android cell chrome desktop gadget hardware iOS ipad mac mobile monitor phone smartwatch tablet virtual_reality vr wearables window', DeviceThermostat: 'celsius fahrenheit temperature thermometer', DeviceUnknown: '? Android assistance cell hardware help iOS information mark mobile phone punctuation question support symbol tablet', DialerSip: - 'alphabet call cell character contact device font hardware initiation internet letter mobile over protocol routing session symbol telephone text type voice', + 'alphabet call cell character contact device font hardware initiation internet letters mobile over protocol routing session symbol telephone text type voice', Dialpad: 'buttons call contact device dots mobile numbers phone', Diamond: 'fashion gems jewelry logo retail valuables', Difference: 'compare content copy cut document duplicate file multiple past stack', @@ -762,7 +764,7 @@ const synonyms = { DownloadDone: 'arrows check downloads drive installed ok tick upload', DownloadForOffline: 'arrow circle for install offline upload', Downloading: 'arrow circle downloads install pending progress upload', - Drafts: 'document email envelope file letter message read', + Drafts: 'document email envelope file letters message read', DragHandle: 'application components design interface layout lines menu move screen ui ux website window', DragIndicator: @@ -806,11 +808,11 @@ const synonyms = { EighteenMp: 'camera digits font image letters megapixels numbers quality resolution symbol text type', EightK: - '8000 8K alphabet character digit display font letter number pixels resolution symbol text type video', + '8000 8K alphabet character digit display font letters numbers pixels resolution symbol text type video', EightKPlus: - '+ 7000 8K alphabet character digit display font letter number pixels resolution symbol text type video', + '+ 7000 8K alphabet character digit display font letters numbers pixels resolution symbol text type video', EightMp: - 'camera digit font image letters megapixels number quality resolution symbol text type', + 'camera digit font image letters megapixels numbers quality resolution symbol text type', EightteenMp: 'camera digits font image letters megapixels numbers quality resolution symbol text type', Eject: 'arrow disc drive dvd player remove triangle up usb', @@ -819,7 +821,7 @@ const synonyms = { 'body cane female gender girl human lady old people person senior social symbol women', ElectricalServices: 'charge cord plug power wire', ElectricBike: - 'automobile cars electricity maps scooter transportation travel vehicle vespa', + 'automobile cars ebike electricity maps scooter transportation travel vehicle vespa', ElectricBolt: 'energy fast instant lightning nest thunderbolt', ElectricCar: 'automobile cars electricity maps transportation travel vehicle', ElectricMeter: @@ -831,11 +833,12 @@ const synonyms = { Elevator: 'body down human people person up', ElevenMp: 'camera digits font image letters megapixels numbers quality resolution symbol text type', - Email: 'envelope letter message note post receive send write', + Email: 'envelope letters message note post receive send write', + Emergency: 'asterisk clinic health hospital maps medical symbol', EmergencyRecording: 'alert attention camera caution danger filming hardware image important motion notification picture videography warning', EmergencyShare: 'alert attention caution danger important notification warning', - EMobiledata: 'alphabet font letter text type', + EMobiledata: 'alphabet font letters text type', EmojiEmotions: '+ add emoticon expressions face feelings glad happiness happy icons insert like mood new person pleased plus smiley smiling social survey symbol', EmojiEvents: @@ -881,7 +884,7 @@ const synonyms = { ExpandLess: 'arrows chevron collapse direction expandable list up', ExpandMore: 'arrows chevron collapse direction down expandable list', Explicit: - 'adult alphabet character content font language letter media movies music parent rating supervision symbol text type', + 'adult alphabet character content font language letters media movies music parent rating supervision symbol text type', Explore: 'compass destination direction east location maps needle north south travel west', ExploreOff: @@ -908,7 +911,7 @@ const synonyms = { 'disabled editing effect emoji emotion enabled faces image natural photography settings slash tag', FactCheck: 'approve complete done list mark ok select tick validate verified yes', Factory: 'industry manufacturing warehouse', - FamilyRestroom: 'bathroom children father kids mother parents wc', + FamilyRestroom: 'bathroom children father gender kids mother parents wc', Fastfood: 'drink hamburger maps meal places', FastForward: 'control ff media music play speed time tv video', FastRewind: 'back control media music play speed time tv video', @@ -926,10 +929,10 @@ const synonyms = { 'backyard barrier boundaries boundary entrance flowers garden gate grass home house nature nest outdoor outside protection', Festival: 'circus event local maps places tent tour travel', FiberDvr: - 'alphabet character digital electronics font letter network recorder symbol text tv type video', + 'alphabet character digital electronics font letters network recorder symbol text tv type video', FiberManualRecord: 'circle dot play watch', - FiberNew: 'alphabet character font letter network symbol text type', - FiberPin: 'alphabet character font letter network symbol text type', + FiberNew: 'alphabet character font letters network symbol text type', + FiberPin: 'alphabet character font letters network symbol text type', FiberSmartRecord: 'circle dot play watch', FifteenMp: 'camera digits font image letters megapixels numbers quality resolution symbol text type', @@ -945,25 +948,25 @@ const synonyms = { FileUpload: 'arrows download drive export', Filter: 'editing effect image landscape mountains photography picture settings', Filter1: - 'digit editing effect images multiple number photography pictures settings stack symbol', + 'digit editing effect images multiple numbers photography pictures settings stack symbol', Filter2: - 'digit editing effect images multiple number photography pictures settings stack symbol', + 'digit editing effect images multiple numbers photography pictures settings stack symbol', Filter3: - 'digit editing effect images multiple number photography pictures settings stack symbol', + 'digit editing effect images multiple numbers photography pictures settings stack symbol', Filter4: - 'digit editing effect images multiple number photography pictures settings stack symbol', + 'digit editing effect images multiple numbers photography pictures settings stack symbol', Filter5: - 'digit editing effect images multiple number photography pictures settings stack symbol', + 'digit editing effect images multiple numbers photography pictures settings stack symbol', Filter6: - 'digit editing effect images multiple number photography pictures settings stack symbol', + 'digit editing effect images multiple numbers photography pictures settings stack symbol', Filter7: - 'digit editing effect images multiple number photography pictures settings stack symbol', + 'digit editing effect images multiple numbers photography pictures settings stack symbol', Filter8: - 'digit editing effect images multiple number photography pictures settings stack symbol', + 'digit editing effect images multiple numbers photography pictures settings stack symbol', Filter9: - 'digit editing effect images multiple number photography pictures settings stack symbol', + 'digit editing effect images multiple numbers photography pictures settings stack symbol', Filter9Plus: - '+ digit editing effect images multiple number photography pictures settings stack symbol', + '+ digit editing effect images multiple numbers photography pictures settings stack symbol', FilterAlt: 'edit funnel options refine sift', FilterAltOff: '[offline] disabled edit funnel options refine sift slash', FilterBAndW: @@ -993,16 +996,16 @@ const synonyms = { 'athlete dumbbell exercise gym health hobby places sport weights workout', FitScreen: 'enlarge format layout reduce scale size', FiveG: - '5g alphabet cellular character data digit font letter mobile network number phone signal speed symbol text type wifi', + '5g alphabet cellular character data digit font letters mobile network numbers phone signal speed symbol text type wifi', FiveK: - '5000 5K alphabet character digit display font letter number pixels resolution symbol text type video', + '5000 5K alphabet character digit display font letters numbers pixels resolution symbol text type video', FiveKPlus: - '+ 5000 5K alphabet character digit display font letter number pixels resolution symbol text type video', + '+ 5000 5K alphabet character digit display font letters numbers pixels resolution symbol text type video', FiveMp: - 'camera digit font image letters megapixels number quality resolution symbol text type', + 'camera digit font image letters megapixels numbers quality resolution symbol text type', FivteenMp: 'camera digits font image letters megapixels numbers quality resolution symbol text type', - Flag: 'country goal mark nation report start', + Flag: 'country destination emoji flags goal landmark location milepost milestone place pole report save social start world', FlagCircle: 'country goal mark nation report round start', Flaky: 'approve check close complete contrast done exit mark no ok options select stop tick verified yes', @@ -1029,7 +1032,7 @@ const synonyms = { 'DISABLE_IOS android disable_ios editing front image mobile orientation rear reverse rotate turn', FlipToBack: 'arrangement dashed format front layout move order sort', FlipToFront: 'arrangement back dashed format layout move order sort', - Flood: 'crisis disaster natural rain storm weather', + Flood: 'crisis disaster flooding natural rain storm water wave weather', Fluorescent: 'bright lamp lightbulb', FlutterDash: 'application bird framework logo mascot open program software source', FmdBad: @@ -1049,9 +1052,10 @@ const synonyms = { 'bookmark data directory document drive favorite file highlight important marked saved shape sheet slide star storage', FolderZip: 'compress data document drive file folders open sheet slide storage', FollowTheSigns: 'arrow body directional human people person right social', - FontDownload: 'A alphabet character letter square symbol text type', + FontDownload: + 'A alphabet character classification letters square symbol text typeface', FontDownloadOff: - 'alphabet character disabled enabled letter slash square symbol text type', + 'alphabet character disabled enabled letters slash square symbol text type', FoodBank: 'architecture building charity eat estate fork house knife meal place real residence residential shelter utensils', Forest: 'jungle nature plantation plants trees woodland', @@ -1066,9 +1070,9 @@ const synonyms = { FormatAlignRight: 'alignment doc editing editor lines spreadsheet text type writing', FormatBold: - 'B alphabet character doc editing editor font letter spreadsheet styles symbol text type writing', + 'B alphabet character doc editing editor font letters spreadsheet styles symbol text type writing', FormatClear: - 'T alphabet character disabled doc editing editor enabled font letter off slash spreadsheet style symbol text type writing', + 'T alphabet character disabled doc editing editor enabled font letters off slash spreadsheet style symbol text type writing', FormatColorFill: 'bucket doc editing editor paint spreadsheet style text type writing', FormatColorReset: @@ -1079,55 +1083,55 @@ const synonyms = { FormatIndentIncrease: 'alignment doc editing editor indentation paragraph spreadsheet text type writing', FormatItalic: - 'alphabet character doc editing editor font letter spreadsheet style symbol text type writing', + 'alphabet character doc editing editor font letters spreadsheet style symbol text type writing', FormatLineSpacing: 'alignment doc editing editor spreadsheet text type writing', FormatListBulleted: 'alignment doc editing editor notes spreadsheet task text todo type writing', FormatListNumbered: - 'alignment digit doc editing editor notes spreadsheet symbol task text todo type writing', + 'alignment digit doc editing editor notes numbers spreadsheet symbol task text todo type writing', FormatListNumberedRtl: - 'alignment digit doc editing editor notes spreadsheet symbol task text todo type writing', + 'alignment digit doc editing editor notes numbers spreadsheet symbol task text todo type writing', FormatOverline: - 'alphabet character doc editing editor font letter spreadsheet style symbol text type under writing', + 'alphabet character doc editing editor font letters spreadsheet style symbol text type under writing', FormatPaint: 'brush color doc editing editor fill paintroller spreadsheet style text type writing', FormatQuote: 'doc editing editor quotation spreadsheet text type writing', FormatShapes: - 'alphabet character color doc editing editor fill font letter paint spreadsheet style symbol text type writing', + 'alphabet character color doc editing editor fill font letters paint spreadsheet style symbol text type writing', FormatSize: - 'alphabet character color doc editing editor fill font letter paint spreadsheet style symbol text type writing', + 'alphabet character color doc editing editor fill font letters paint spreadsheet style symbol text type writing', FormatStrikethrough: - 'alphabet character doc editing editor font letter spreadsheet style symbol text type writing', + 'alphabet character doc editing editor font letters spreadsheet style symbol text type writing', FormatTextdirectionLToR: 'alignment doc editing editor ltr paragraph spreadsheet type writing', FormatTextdirectionRToL: - 'alignment doc editing editor paragraph rtl spreadsheet type writing', + 'alignment doc editing editor ltr paragraph rtl spreadsheet type writing', FormatUnderlined: - 'alphabet character doc editing editor font letter spreadsheet style symbol text type writing', + 'alphabet character doc editing editor font letters spreadsheet style symbol text type writing', Fort: 'castle fortress mansion palace', Forum: 'bubble chat comment communicate community conversation feedback hub messages speech talk', Forward: 'arrow mail message playback right sent', Forward10: - 'arrow circle controls digit fast music number play rotate seconds speed symbol time video', + 'arrow circle controls digit fast music numbers play rotate seconds speed symbol time video', Forward30: - 'arrow circle controls digit fast music number rotate seconds speed symbol time video', + 'arrow circle controls digit fast music numbers rotate seconds speed symbol time video', Forward5: - '10 arrow circle controls digit fast music number rotate seconds speed symbol time video', + '10 arrow circle controls digit fast music numbers rotate seconds speed symbol time video', ForwardToInbox: - 'arrows directions email envelop letter message navigation outgoing right send', + 'arrows directions email envelop letters message navigation outgoing right send', Foundation: 'architecture base basis building construction estate home house real residential', FourGMobiledata: - 'alphabet cellular character digit font letter network number phone signal speed symbol text type wifi', + 'alphabet cellular character digit font letters network numbers phone signal speed symbol text type wifi', FourGPlusMobiledata: - 'alphabet cellular character digit font letter network number phone signal speed symbol text type wifi', + 'alphabet cellular character digit font letters network numbers phone signal speed symbol text type wifi', FourK: - '4000 4K alphabet character digit display font letter number pixels resolution symbol text type video', + '4000 4K alphabet character digit display font letters numbers pixels resolution symbol text type video', FourKPlus: - '+ 4000 4K alphabet character digit display font letter number pixels resolution symbol text type video', + '+ 4000 4K alphabet character digit display font letters numbers pixels resolution symbol text type video', FourMp: - 'camera digit font image letters megapixels number quality resolution symbol text type', + 'camera digit font image letters megapixels numbers quality resolution symbol text type', FourteenMp: 'camera digits font image letters megapixels numbers quality resolution symbol text type', FreeBreakfast: 'beverage cafe coffee cup drink mug tea', @@ -1144,13 +1148,13 @@ const synonyms = { 'agreement contract court document government hammer judge law mallet official police rules terms', Gesture: 'doodle drawing finger gestures hand line motion string thread', GetApp: 'arrows downloads export install play pointing retrieve upload', - Gif: 'alphabet animated animation bitmap character font format graphics interchange letter symbol text type', + Gif: 'alphabet animated animation bitmap character font format graphics interchange letters symbol text type', GifBox: - 'alphabet animated animation bitmap character font format graphics interchange letter symbol text type', + 'alphabet animated animation bitmap character font format graphics interchange letters symbol text type', Girl: 'body female gender human lady people person social symbol woman women', Gite: 'architecture estate home hostel house maps place real residence residential stay traveling', GitHub: 'brand code', - GMobiledata: 'alphabet character font letter network service symbol text type', + GMobiledata: 'alphabet character font letters network service symbol text type', GolfCourse: 'athlete athletic ball club entertainment flag golfer golfing hobby hole places putt sports', Google: 'brand logo', @@ -1197,23 +1201,23 @@ const synonyms = { Handshake: 'agreement partnership', Handyman: 'build construction fix hammer repair screwdriver tools', Hardware: 'break construction hammer nail repair tool', - Hd: 'alphabet character definition display font high letter movies quality resolution screen symbol text tv type video', + Hd: 'alphabet character codec definition display font high letters movies quality resolution screen symbol text tv type video', HdrAuto: - 'A alphabet camera character circle dynamic font high letter photo range symbol text type', + 'A alphabet camera character circle dynamic font high letters photo range symbol text type', HdrAutoSelect: - '+ A alphabet camera character circle dynamic font high letter photo range symbol text type', + '+ A alphabet camera character circle dynamic font high letters photo range symbol text type', HdrEnhancedSelect: - 'add alphabet character dynamic font high letter plus range symbol text type', + 'add alphabet character dynamic font high letters plus range symbol text type', HdrOff: - 'alphabet character disabled dynamic enabled enhance font high letter range select slash symbol text type', + 'alphabet character disabled dynamic enabled enhance font high letters range select slash symbol text type', HdrOffSelect: - 'alphabet camera character circle disabled dynamic enabled font high letter photo range slash symbol text type', + 'alphabet camera character circle disabled dynamic enabled font high letters photo range slash symbol text type', HdrOn: - 'add alphabet character dynamic enhance font high letter plus range select symbol text type', + 'add alphabet character dynamic enhance font high letters plus range select symbol text type', HdrOnSelect: - '+ alphabet camera character circle dynamic font high letter photo range symbol text type', + '+ alphabet camera character circle dynamic font high letters photo range symbol text type', HdrPlus: - '+ add alphabet character circle dynamic enhance font high letter range select symbol text type', + '+ add alphabet character circle dynamic enhance font high letters range select symbol text type', HdrStrong: 'circles dots dynamic enhance high range', HdrWeak: 'circles dots dynamic enhance high range', Headphones: 'accessory audio device earphone headset listen music sound', @@ -1224,14 +1228,14 @@ const synonyms = { HeadsetMic: 'accessory audio chat device earphone headphones listen music sound talk', HeadsetOff: - 'accessory audio chat device disabled earphone enabled headphones listen mic music slash sound talk', + 'accessory audio chat device disabled earphone enabled headphones listen mic music mute slash sound talk', Healing: 'bandage bandaid editing emergency fix health hospital image medicine', HealthAndSafety: '+ add certified cross home nest plus privacy private protection security shield symbol verified', Hearing: 'accessibility accessible aid handicap help impaired listen mono sound volume', HearingDisabled: - 'accessibility accessible aid enabled handicap help impaired listen off on slash sound volume', + 'accessibility accessible aid enabled handicap help impaired listen mute off on slash sound volume', HeartBroken: 'break core crush health nucleus split', HeatPump: 'air conditioner cool energy furnance nest usage', Height: @@ -1241,7 +1245,7 @@ const synonyms = { '? assistance information mark punctuation question recent restore support symbol', HelpOutline: '? alert announcement assistance circle information mark punctuation question recent restore shape support symbol', - Hevc: 'alphabet character coding efficiency font high letter symbol text type video', + Hevc: 'alphabet character coding efficiency font high letters symbol text type video', Hexagon: 'shape sides six', HideImage: 'disabled enabled landscape mountains off on photography picture slash', HideSource: 'circle disabled enabled offline on shape slash', @@ -1251,19 +1255,19 @@ const synonyms = { HighlightOff: 'cancel circle clear click close delete disable exit focus no quit remove stop target times', HighQuality: - 'alphabet character definition display font hq letter movies resolution screen symbol text tv type', + 'alphabet character definition display font hq letters movies resolution screen symbol text tv type', Hiking: 'backpacking bag climbing duffle mountain social sports stick trail travel walking', History: - 'arrow backwards clock date refresh renew reverse revert rotate schedule time turn undo', + 'arrow backwards clock date device home nest refresh renew reset restore reverse revert rotate schedule time turn undo', HistoryEdu: - 'document education feather letter paper pen quill school tools write writing', + 'document education feather letters paper pen quill school tools write writing', HistoryToggleOff: 'clock dashed date schedule time', Hive: 'bee honeycomb', - Hls: 'alphabet character developer engineering font letter platform symbol text type', + Hls: 'alphabet character developer engineering font letters platform symbol text type', HlsOff: - '[offline] alphabet character developer disabled enabled engineering font letter platform slash symbol text type', - HMobiledata: 'alphabet character font letter network service symbol text type', + '[offline] alphabet character developer disabled enabled engineering font letters platform slash symbol text type', + HMobiledata: 'alphabet character font letters network service symbol text type', HolidayVillage: 'architecture beach camping cottage estate home house lake lodge maps place real residence residential stay traveling vacation', Home: 'address application--house architecture building components design estate homepage interface layout place real residence residential screen shelter structure unit ux website window', @@ -1293,9 +1297,9 @@ const synonyms = { 'approve ballot check complete done election mark ok poll register registration select tick to validate verified vote yes', HowToVote: 'ballot election poll', HPlusMobiledata: - '+ alphabet character font letter network service symbol text type', - Html: 'alphabet brackets character code css developer engineering font letter platform symbol text type', - Http: 'alphabet character font internet letter network symbol text transfer type url website', + '+ alphabet character font letters network service symbol text type', + Html: 'alphabet brackets character code css developer engineering font letters platform symbol text type', + Http: 'alphabet character font internet letters network symbol text transfer type url website', Https: 'connection encrypt internet key locked network password privacy private protection safety secure security ssl web', Hub: 'center connection core focal network nucleus point topology', @@ -1342,7 +1346,8 @@ const synonyms = { IntegrationInstructions: 'brackets clipboard code css developer document engineering html platform', Interests: 'circle heart shapes social square triangle', - InterpreterMode: 'language microphone person speaking symbol', + InterpreterMode: + 'accounts committee dictation face family friends group hearing humans keyboard language microphone network noise people persons profiles recorder social sound speaker speaking symbol team users voice', Inventory: 'archive box buy check clipboard document e-commerce file list organize packages product purchase shop stock store supply', Inventory2: 'archive box file organize packages product stock storage supply', @@ -1354,7 +1359,7 @@ const synonyms = { Iron: 'appliance clothes electric ironing machine object', Iso: 'add editing effect image minus photography picture plus sensor shutter speed subtract', Javascript: - 'alphabet brackets character code css developer engineering font html letter platform symbol text type', + 'alphabet brackets character code css developer engineering font html letters platform symbol text type', JoinFull: 'circle combine command left outer outter overlap right sql', JoinInner: 'circle command matching overlap sql values', JoinLeft: 'circle command matching overlap sql values', @@ -1363,8 +1368,8 @@ const synonyms = { 'athlete athletic body canoe entertainment exercise hobby human lake paddle paddling people person rafting river row social sports summer travel water', KebabDining: 'dinner food meal meat skewer', Key: 'access blackout door entry password restricted secret unlock', - Keyboard: 'computer device hardware input keypad letter office text type', - KeyboardAlt: 'computer device hardware input keypad letter office text type', + Keyboard: 'computer device hardware input keypad letters office text type', + KeyboardAlt: 'computer device hardware input keypad letters office text type', KeyboardArrowDown: 'arrows chevron open', KeyboardArrowLeft: 'arrows chevron', KeyboardArrowRight: 'arrows chevron open start', @@ -1381,7 +1386,7 @@ const synonyms = { KeyboardOptionKey: 'alt key modifier', KeyboardReturn: 'arrow back left', KeyboardTab: 'arrow left next right', - KeyboardVoice: 'microphone noise recorder speaker', + KeyboardVoice: 'dictation hearing microphone noise recorder sound speaker', KeyOff: '[offline] access disabled door enabled entry on password slash unlock', KingBed: 'bedroom double furniture home hotel house night pillows queen rest sleep', @@ -1473,17 +1478,17 @@ const synonyms = { 'bill building business buy card cart cash coin commerce credit currency dollars handbag money online payment shopping storefront', LocalOffer: 'deal discount price shopping store tag', LocalParking: - 'alphabet auto car character font garage letter symbol text type vehicle', + 'alphabet auto car character font garage letters symbol text type vehicle', LocalPharmacy: '911 aid cross emergency first food hospital medicine places', LocalPhone: 'booth call telecommunication', LocalPizza: 'drink fastfood meal', LocalPolice: '911 badge law officer protection security shield', LocalPostOffice: - 'delivery email envelop letter message package parcel postal send stamp', + 'delivery email envelop letters message package parcel postal send stamp', LocalPrintshop: 'draft fax ink machine office paper printer send', LocalSee: 'camera lens photography picture', LocalShipping: - 'automobile cars delivery letter mail maps office package parcel postal semi send shopping stamp transportation truck vehicle', + 'automobile cars delivery letters mail maps office package parcel postal semi send shopping stamp transportation truck vehicle', LocalTaxi: 'automobile cab call cars direction lyft maps public transportation uber vehicle yellow', LocationCity: @@ -1520,18 +1525,18 @@ const synonyms = { Loyalty: 'badge benefits card credit heart love membership miles points program sale subscription tag travel trip', LteMobiledata: - 'alphabet character font internet letter network speed symbol text type wifi wireless', + 'alphabet character font internet letters network speed symbol text type wifi wireless', LtePlusMobiledata: - '+ alphabet character font internet letter network speed symbol text type wifi wireless', + '+ alphabet character font internet letters network speed symbol text type wifi wireless', Luggage: 'airport baggage carry flight hotel on suitcase travel trip', LunchDining: 'breakfast dinner drink fastfood hamburger meal', Lyrics: 'audio bubble chat comment communicate feedback key message music note song sound speech track', MacroOff: '[offline] camera disabled enabled flower garden image on slash', - Mail: 'email envelope inbox letter message send', + Mail: 'email envelope inbox letters message send', MailLock: - 'email envelop letter locked message password privacy private protection safety secure security send', - MailOutline: 'email envelope letter message note post receive send write', + 'email envelop letters locked message password privacy private protection safety secure security send', + MailOutline: 'email envelope letters message note post receive send write', Male: 'boy gender man social symbol', Man: 'boy gender male social symbol', Man2: 'boy gender male social symbol', @@ -1547,18 +1552,18 @@ const synonyms = { MapsUgc: '+ add bubble comment communicate feedback message new plus speech symbol', Margin: 'design dots layout padding size square', - MarkAsUnread: 'envelop letter mail postal receive send', + MarkAsUnread: 'envelop letters mail postal receive send', MarkChatRead: 'approve bubble check comment communicate complete done message ok select sent speech tick verified yes', MarkChatUnread: 'alarm alert bubble circle comment communicate dot message notifications notify reminder speech', MarkEmailRead: - 'approve check complete done envelop letter message note ok select send sent tick yes', - MarkEmailUnread: 'check circle envelop letter message note notification send', - Markunread: 'email envelope letter message send', + 'approve check complete done envelop letters message note ok select send sent tick yes', + MarkEmailUnread: 'check circle envelop letters message note notification send', + Markunread: 'email envelope letters message send', MarkUnreadChatAlt: 'alarm alert bubble circle comment communicate dot message notifications notify reminder speech', - MarkunreadMailbox: 'deliver envelop letter postal postbox receive send', + MarkunreadMailbox: 'deliver envelop letters postal postbox receive send', Masks: 'air cover covid face hospital medical pollution protection respirator sick social', Maximize: @@ -1569,7 +1574,7 @@ const synonyms = { 'connection connectivity device disabled enabled music note off online paring signal slash symbol wireless', Mediation: 'alternative arrows compromise direction dots negotiation party right structure', - MedicalInformation: 'badge card health id services', + MedicalInformation: 'badge card health identification services', MedicalServices: 'aid bag briefcase emergency first kit medicine', Medication: 'doctor drug emergency hospital medicine pharmacy pills prescription', MedicationLiquid: @@ -1584,12 +1589,13 @@ const synonyms = { Merge: 'arrows directions maps navigation path route sign traffic', MergeType: 'arrow combine direction format text', Message: 'bubble chat comment communicate feedback speech talk text', - Mic: 'dictation hearing microphone noise record search sound speech voice', + Mic: 'dictation hearing keyboard microphone noise recorder search sound speaker speech voice', MicExternalOff: 'audio disabled enabled microphone slash sound voice', MicExternalOn: 'audio disabled enabled microphone off slash sound voice', - MicNone: 'hearing microphone noise record sound voice', + MicNone: + 'dictation hearing keyboard microphone noise recorder sound speaker voice', MicOff: - 'audio disabled enabled hearing microphone noise recording slash sound voice', + 'audio disabled enabled hearing microphone mute noise recording slash sound voice', Microwave: 'appliance cooking electric heat home house kitchen machine', MilitaryTech: 'army award badge honor medal merit order privilege prize rank reward ribbon soldier star status trophy winner', @@ -1622,7 +1628,7 @@ const synonyms = { MonetizationOn: 'bill card cash circle coin commerce cost credit currency dollars finance money online payment price profit sale shopping symbol', Money: - '100 bill card cash coin commerce cost credit currency digit dollars finance number online payment price profit shopping symbol', + '100 bill card cash coin commerce cost credit currency digit dollars finance numbers online payment price profit shopping symbol', MoneyOff: 'bill card cart cash coin commerce credit currency disabled dollars enabled finance money online payment price profit shopping slash symbol', MoneyOffCsred: @@ -1644,32 +1650,32 @@ const synonyms = { '3 DISABLE_IOS android application components disable_ios dots etc interface screen three ui ux vertical website', Mosque: 'ideology islamic masjid muslim religion spiritual worship', MotionPhotosAuto: - 'A alphabet animation automatic character circle font gif letter live symbol text type video', + 'A alphabet animation automatic character circle font gif letters live symbol text type video', MotionPhotosOff: 'animation circle disabled enabled slash video', Mouse: 'click computer cursor device hardware wireless', MoveDown: 'arrow direction jump navigation transfer', MoveToInbox: - 'archive arrow down email envelop incoming letter message move send to', + 'archive arrow down email envelop incoming letters message move send to', MoveUp: 'arrow direction jump navigation transfer', Movie: 'cinema film media screen show slate tv video watch', MovieCreation: 'cinema clapperboard film movies slate video', MovieFilter: 'artificial automatic automation clapperboard creation custom film genai intelligence magic movies slate smart sparkle stars video', Moving: 'arrow direction navigation travel up', - Mp: 'alphabet character font image letter megapixel photography pixels quality resolution symbol text type', + Mp: 'alphabet character font image letters megapixel photography pixels quality resolution symbol text type', MultilineChart: 'analytics bars data diagram infographic line measure metrics multiple statistics tracking', MultipleStop: 'arrows dashed directions dots left maps navigation right', Museum: 'architecture attraction building estate event exhibition explore local palces places real see shop store tour', MusicNote: 'audiotrack key sound', - MusicOff: 'audiotrack disabled enabled key note on slash sound', + MusicOff: 'audiotrack disabled enabled key mute note on slash sound', MusicVideo: 'band mv recording screen tv watch', MyLocation: 'destination direction maps navigation pin place point stop', Nat: 'communication', Nature: 'forest outdoor outside park tree wilderness', NaturePeople: - 'activity body forest human outdoor outside park person tree wilderness', + 'activity body forest human landscape outdoor outside park person tree wilderness', NavigateBefore: 'arrows direction left', NavigateNext: 'arrows direction right', Navigation: 'arrow destination direction location maps pin place point stop', @@ -1706,11 +1712,11 @@ const synonyms = { NightsStay: 'climate cloud crescent dark lunar mode moon phases silence silent sky time weather', NineK: - '9000 9K alphabet character digit display font letter number pixels resolution symbol text type video', + '9000 9K alphabet character digit display font letters numbers pixels resolution symbol text type video', NineKPlus: - '+ 9000 9K alphabet character digit display font letter number pixels resolution symbol text type video', + '+ 9000 9K alphabet character digit display font letters numbers pixels resolution symbol text type video', NineMp: - 'camera digit font image letters megapixels number quality resolution symbol text type', + 'camera digit font image letters megapixels numbers quality resolution symbol text type', NineteenMp: 'camera digits font image letters megapixels numbers quality resolution symbol text type', NoAccounts: @@ -1779,11 +1785,11 @@ const synonyms = { 'Android chrome desktop device hardware iOS mac monitor play television tv web window', OnDeviceTraining: 'arrow bulb call cell contact hardware idea inprogress light loading mobile model refresh renew restore reverse rotate telephone', - OneK: '1000 1K alphabet character digit display font letter number pixels resolution symbol text type video', + OneK: '1000 1K alphabet character digit display font letters numbers pixels resolution symbol text type video', OneKk: - '10000 10K alphabet character digit display font letter number pixels resolution symbol text type video', + '10000 10K alphabet character digit display font letters numbers pixels resolution symbol text type video', OneKPlus: - '+ 1000 1K alphabet character digit display font letter number pixels resolution symbol text type video', + '+ 1000 1K alphabet character digit display font letters numbers pixels resolution symbol text type video', OnlinePrediction: 'bulb connection idea light network signal wireless', Opacity: 'color droplet hue inverted liquid palette tone water', OpenInBrowser: 'arrow box new up website window', @@ -1820,7 +1826,7 @@ const synonyms = { 'athlete athletic body entertainment exercise fly hobby human parachute people person skydiving social sports travel', Park: 'attraction fresh local nature outside plant tree', PartyMode: 'camera lens photography picture', - Password: 'key login pin security star unlock', + Password: 'code key login pin security star unlock', Pattern: 'key login password pin security star unlock', Pause: 'controls media music pending player status video wait', PauseCircle: 'controls media music video', @@ -1843,7 +1849,7 @@ const synonyms = { 'accounts committee face family friends group humans network persons profiles social team users', PeopleOutline: 'accounts committee face family friends group humans network persons profiles social team users', - Percent: 'math number symbol', + Percent: 'math numbers symbol', PermCameraMic: 'image microphone min photography picture speaker', PermContactCalendar: 'account agenda date face human information people person profile schedule time user', @@ -1881,7 +1887,7 @@ const synonyms = { PersonSearch: 'account avatar face find glass human look magnifying people profile user', PestControl: 'bug exterminator insects', - PestControlRodent: 'exterminator mice', + PestControlRodent: 'exterminator mice mouse', Pets: 'animal cat claw dog hand paw', Phishing: 'fishing fraud hook scam', Phone: 'call cell chat contact device hardware mobile telephone text', @@ -1926,11 +1932,11 @@ const synonyms = { 'adjust album dashed editing image library mountains photography picture', PhotoSizeSelectSmall: 'adjust album editing image large library mountains photography picture', - Php: 'alphabet brackets character code css developer engineering font html letter platform symbol text type', + Php: 'alphabet brackets character code css developer engineering font html letters platform symbol text type', Piano: 'instrument keyboard keys musical social', PianoOff: 'disabled enabled instrument keyboard keys musical on slash social', PictureAsPdf: - 'alphabet character copy document duplicate file font image letter multiple photography stack symbol text type', + 'alphabet character copy document duplicate file font image letters multiple photography stack symbol text type', PictureInPicture: 'chat cropped overlap photo pip position shape sizes talktrack', PictureInPictureAlt: 'chat cropped overlap photo pip position shape sizes talktrack', @@ -1938,7 +1944,7 @@ const synonyms = { 'analytics bars data diagram infographic measure metrics statistics tracking', PieChartOutline: 'analytics bars data diagram infographic measure metrics statistics tracking', - Pin: '1 2 3 digit key login logout number password pattern security star symbol unlock', + Pin: '1 2 3 digit key login logout numbers password pattern security star symbol unlock', Pinch: 'arrows compress direction finger grasp hand navigation nip squeeze tweak', PinDrop: 'destination direction gps location maps navigation place stop', Pinterest: 'brand logo social', @@ -1965,7 +1971,7 @@ const synonyms = { PlaylistPlay: 'arow arrow collection music', PlaylistRemove: '- collection minus music', Plumbing: 'build construction fix handyman repair tools wrench', - PlusOne: '1 add digit increase number symbol', + PlusOne: '1 add digit increase numbers symbol', Podcasts: 'broadcast casting network signal transmitting wireless', PointOfSale: 'checkout cost machine merchant money payment pos retail system transaction', @@ -2046,9 +2052,9 @@ const synonyms = { RampRight: 'arrows directions maps navigation path route sign traffic', RateReview: 'chat comment feedback message pencil stars write', RawOff: - 'alphabet character disabled enabled font image letter original photography slash symbol text type', + 'alphabet character disabled enabled font image letters original photography slash symbol text type', RawOn: - 'alphabet character disabled enabled font image letter off original photography slash symbol text type', + 'alphabet character disabled enabled font image letters off original photography slash symbol text type', ReadMore: 'arrow text', Receipt: 'bill credit invoice paper payment sale transaction', ReceiptLong: 'bill check document list paperwork record store transaction', @@ -2090,16 +2096,16 @@ const synonyms = { Repartition: 'arrows data refresh renew restore table', Repeat: 'arrows controls loop media music video', RepeatOn: 'arrows controls loop media music video', - RepeatOne: '1 arrows controls digit loop media music number symbol video', - RepeatOneOn: 'arrows controls digit loop media music number symbol video', + RepeatOne: '1 arrows controls digit loop media music numbers symbol video', + RepeatOneOn: 'arrows controls digit loop media music numbers symbol video', Replay: 'arrows controls music refresh reload renew repeat retry rewind undo video', Replay10: - 'arrows controls digit music number refresh renew repeat rewind symbol ten video', + 'arrows controls digit music numbers refresh renew repeat rewind symbol ten video', Replay30: - 'arrows controls digit music number refresh renew repeat rewind symbol thirty video', + 'arrows controls digit music numbers refresh renew repeat rewind symbol thirty video', Replay5: - 'arrows controls digit five music number refresh renew repeat rewind symbol video', + 'arrows controls digit five music numbers refresh renew repeat rewind symbol video', ReplayCircleFilled: 'arrows controls music refresh renew repeat video', Reply: 'arrow backward left mail message send share', ReplyAll: 'arrows backward group left mail message multiple send share', @@ -2120,7 +2126,7 @@ const synonyms = { 'breakfast cutlery dining dinner eat food fork knife local lunch meal places spoon utensils', RestaurantMenu: 'book dining eat food fork knife local meal spoon', Restore: - 'arrow backwards clock date history refresh renew reverse rotate schedule time turn undo', + 'arrow backwards clock date device history home nest refresh renew reset reverse rotate schedule time turn undo', RestoreFromTrash: 'arrow backwards can clock date delete garbage history refresh remove renew reverse rotate schedule time turn up', RestorePage: @@ -2130,7 +2136,7 @@ const synonyms = { RiceBowl: 'dinner food lunch meal restaurant', RingVolume: 'calling cell contact device hardware incoming mobile ringer sound telephone', - RMobiledata: 'alphabet character font letter symbol text type', + RMobiledata: 'alphabet character font letters symbol text type', Rocket: 'spaceship', RocketLaunch: 'spaceship takeoff', RollerShades: 'blinds cover curtains nest open shutter sunshade', @@ -2156,7 +2162,7 @@ const synonyms = { Rowing: 'activity boat body canoe human people person sports water', RssFeed: 'application blog connection data internet network service signal website wifi wireless', - Rsvp: 'alphabet character font invitation invite letter plaît respond répondez sil symbol text type vous', + Rsvp: 'alphabet character font invitation invite letters plaît respond répondez sil symbol text type vous', Rtt: 'call real rrt text time', Rule: 'approve check done incomplete line mark missing no ok select tick validate verified wrong x yes', RuleFolder: @@ -2187,7 +2193,7 @@ const synonyms = { ScatterPlot: 'analytics bars chart circles data diagram dot infographic measure metrics statistics tracking', Schedule: 'calendar clock date history mark recent save time', - ScheduleSend: 'calendar clock date email letter remember share time', + ScheduleSend: 'calendar clock date email letters remember share time', Schema: 'analytics chart data diagram flow infographic measure metrics squares statistics tracking', School: @@ -2195,7 +2201,7 @@ const synonyms = { Science: 'beaker chemical chemistry experiment flask glass laboratory research tube', Score: - '2k alphabet analytics bars character chart data diagram digit font infographic letter measure metrics number statistics symbol text tracking type', + '2k alphabet analytics bars character chart data diagram digit font infographic letters measure metrics numbers statistics symbol text tracking type', Scoreboard: 'points sports', ScreenLockLandscape: 'Android device hardware iOS mobile phone rotate security tablet', @@ -2214,7 +2220,7 @@ const synonyms = { ScreenshotMonitor: 'Android chrome desktop device display hardware iOS mac screengrab web window', ScubaDiving: 'entertainment exercise hobby social swimming', - Sd: 'alphabet camera card character data device digital drive flash font image letter memory photo secure symbol text type', + Sd: 'alphabet camera card character data device digital drive flash font image letters memory photo secure symbol text type', SdCard: 'camera digital memory photos secure storage', SdCardAlert: '! attention camera caution danger digital error exclamation important mark memory notification photos secure storage symbol warning', @@ -2234,7 +2240,7 @@ const synonyms = { 'body calm care chi human meditate meditation people person relax sitting wellbeing yoga zen', Sell: 'bill card cart cash coin commerce credit currency dollars money online payment price shopping tag', Send: 'chat email message paper plane reply right share telegram', - SendAndArchive: 'arrow download email letter save share', + SendAndArchive: 'arrow download email letters save share', SendTimeExtension: 'deliver dispatch envelop mail message schedule', SendToMobile: 'Android arrow device export forward hardware iOS phone right share tablet', @@ -2287,11 +2293,11 @@ const synonyms = { SettingsSystemDaydream: 'backup cloud drive storage', SettingsVoice: 'microphone recorder speaker', SevenK: - '7000 7K alphabet character digit display font letter number pixels resolution symbol text type video', + '7000 7K alphabet character digit display font letters numbers pixels resolution symbol text type video', SevenKPlus: - '+ 7000 7K alphabet character digit display font letter number pixels resolution symbol text type video', + '+ 7000 7K alphabet character digit display font letters numbers pixels resolution symbol text type video', SevenMp: - 'camera digit font image letters megapixels number quality resolution symbol text type', + 'camera digit font image letters megapixels numbers quality resolution symbol text type', SeventeenMp: 'camera digits font image letters megapixels numbers quality resolution symbol text type', SevereCold: @@ -2374,15 +2380,15 @@ const synonyms = { SimCardDownload: 'arrow camera chip device memory phone storage', SingleBed: 'bedroom double furniture home hotel house king night pillows queen rest sleep twin', - Sip: 'alphabet call character dialer font initiation internet letter over phone protocol routing session symbol text type voice', - SixK: '6000 6K alphabet character digit display font letter number pixels resolution symbol text type video', + Sip: 'alphabet call character dialer font initiation internet letters over phone protocol routing session symbol text type voice', + SixK: '6000 6K alphabet character digit display font letters numbers pixels resolution symbol text type video', SixKPlus: - '+ 6000 6K alphabet character digit display font letter number pixels resolution symbol text type video', + '+ 6000 6K alphabet character digit display font letters numbers pixels resolution symbol text type video', SixMp: - 'camera digit font image letters megapixels number quality resolution symbol text type', + 'camera digit font image letters megapixels numbers quality resolution symbol text type', SixteenMp: 'camera digits font image letters megapixels numbers quality resolution symbol text type', - SixtyFps: 'camera digit frames number symbol video', + SixtyFps: 'camera digit frames numbers symbol video', SixtyFpsSelect: 'camera digits frame frequency numbers per rate seconds video', Skateboarding: 'athlete athletic body entertainment exercise hobby human people person skateboarder social sports', @@ -2439,11 +2445,11 @@ const synonyms = { 'bubble cards chat comment communicate format list message speech text', SpeakerNotesOff: 'bubble cards chat comment communicate disabled enabled format list message on slash speech text', - SpeakerPhone: 'Android cell device hardware iOS mobile sound tablet volume', + SpeakerPhone: 'Android audio cell device hardware iOS mobile sound tablet volume', Speed: 'arrow clock controls dial fast gauge measure motion music slow speedometer test velocity video', Spellcheck: - 'alphabet approve character checkmark edit font letter ok processor select symbol text tick type word write yes', + 'alphabet approve character checkmark edit font letters ok processor select symbol text tick type word write yes', Splitscreen: 'column grid layout multitasking row two', Spoke: 'connection network radius', Sports: @@ -2454,7 +2460,7 @@ const synonyms = { SportsCricket: 'athlete athletic ball bat entertainment exercise game hobby social', SportsEsports: - 'controller entertainment gamepad gaming hobby online playstation social video xbox', + 'asset console controller device entertainment gamepad gaming google handheld hardware hobby online playstation remote social stadia videogame xbox', SportsFootball: 'american athlete athletic entertainment exercise game hobby social', SportsGolf: @@ -2522,7 +2528,7 @@ const synonyms = { Stream: 'cast connected feed live network signal wireless', Streetview: 'gps location maps', StrikethroughS: - 'alphabet character cross doc editing editor font letter out spreadsheet styles symbol text type writing', + 'alphabet character cross doc editing editor font letters out spreadsheet styles symbol text type writing', Stroller: 'baby care carriage children infant kid newborn toddler young', Style: 'booklet cards filters options tags', SubdirectoryArrowLeft: 'arrow down navigation', @@ -2543,11 +2549,11 @@ const synonyms = { SupervisedUserCircle: 'account avatar control face human parental parents people person profile supervisor', SupervisorAccount: - 'administrator avatar control face human parental parents people person profile supervised user', + 'administrator avatar control custodian face guardian human parental parents people person profile supervised user', Support: 'assist help lifebuoy rescue safety', SupportAgent: 'care customer face headphone person representative service', Surfing: - 'athlete athletic beach body entertainment exercise hobby human people person sea social sports summer water', + 'athlete athletic beach body entertainment exercise hobby human people person sea social sports summer water wave', SurroundSound: 'audio circle signal speaker system volume volumn wireless', SwapCalls: 'arrows device direction mobile share', SwapHoriz: 'arrows back direction forward horizontal', @@ -2575,7 +2581,7 @@ const synonyms = { SwitchAccessShortcutAdd: '+ arrows direction navigation new north plus star symbol up', SwitchAccount: - 'choices face human multiple options people person profile social user', + 'choices face human multiple options people person profile social stack user', SwitchCamera: 'arrows photography picture', SwitchLeft: 'arrows directional navigation toggle', SwitchRight: 'arrows directional navigation toggle', @@ -2610,7 +2616,7 @@ const synonyms = { TableView: 'format grid group layout multiple', TabUnselected: 'browser computer dashed documents folder internet tabs website windows', - Tag: 'hashtag key media number pound social trend', + Tag: 'hashtag key media numbers pound social trend', TagFaces: 'emoji emotion happy satisfied smile', TakeoutDining: 'box container delivery food meal restaurant', TapAndPlay: @@ -2629,47 +2635,47 @@ const synonyms = { Terminal: 'application code emulator program software', Terrain: 'geography landscape mountain', TextDecrease: - '- alphabet character font letter minus remove resize subtract symbol type', - TextFields: 'T add alphabet character font input letter symbol type', - TextFormat: 'A alphabet character font letter square style symbol type', - TextIncrease: '+ add alphabet character font letter new plus resize symbol type', - TextRotateUp: 'A alphabet arrow character field font letter move symbol type', + '- alphabet character font letters minus remove resize subtract symbol type', + TextFields: 'T add alphabet character font input letters symbol type', + TextFormat: 'A alphabet character font letters square style symbol type', + TextIncrease: '+ add alphabet character font letters new plus resize symbol type', + TextRotateUp: 'A alphabet arrow character field font letters move symbol type', TextRotateVertical: - 'A alphabet arrow character down field font letter move symbol type verticle', + 'A alphabet arrow character down field font letters move symbol type verticle', TextRotationAngledown: - 'A alphabet arrow character field font letter move rotate symbol type', + 'A alphabet arrow character field font letters move rotate symbol type', TextRotationAngleup: - 'A alphabet arrow character field font letter move rotate symbol type', + 'A alphabet arrow character field font letters move rotate symbol type', TextRotationDown: - 'A alphabet arrow character field font letter move rotate symbol type', + 'A alphabet arrow character field font letters move rotate symbol type', TextRotationNone: - 'A alphabet arrow character field font letter move rotate symbol type', + 'A alphabet arrow character field font letters move rotate symbol type', Textsms: 'bubble chat comment communicate dots feedback message speech', TextSnippet: 'data document file notes storage writing', Texture: 'diagonal lines pattern stripes', - TheaterComedy: 'broadway event movie musical places show standup tour watch', + TheaterComedy: 'broadway event masks movie musical places show standup tour watch', Theaters: 'film media movies photography showtimes video watch', Thermostat: 'climate forecast temperature weather', ThermostatAuto: 'A celsius fahrenheit temperature thermometer', ThirteenMp: 'camera digits font image letters megapixels numbers quality resolution symbol text type', ThirtyFps: - 'alphabet camera character digit font frames letter number symbol text type video', + 'alphabet camera character digit font frames letters numbers symbol text type video', ThirtyFpsSelect: 'camera digits frame frequency image numbers per rate seconds video', ThreeDRotation: - '3d D alphabet arrows av camera character digit font letter number symbol text type vr', + '3d D alphabet arrows av camera character digit font letters numbers symbol text type virtual_reality vr', ThreeGMobiledata: - 'alphabet cellular character digit font letter network number phone signal speed symbol text type wifi', + 'alphabet cellular character digit font letters network numbers phone signal speed symbol text type wifi', ThreeK: - '3000 3K alphabet character digit display font letter number pixels resolution symbol text type video', + '3000 3K alphabet character digit display font letters numbers pixels resolution symbol text type video', ThreeKPlus: - '+ 3000 3K alphabet character digit display font letter number pixels resolution symbol text type video', + '+ 3000 3K alphabet character digit display font letters numbers pixels resolution symbol text type video', ThreeMp: - 'camera digit font image letters megapixels number quality resolution symbol text type', + 'camera digit font image letters megapixels numbers quality resolution symbol text type', ThreeP: 'account avatar bubble chat comment communicate face human message party people person profile speech user', - ThreeSixty: 'arrow av camera direction rotate rotation vr', + ThreeSixty: 'arrow av camera direction reality rotate rotation virtual vr', ThumbDown: 'dislike downvote favorite fingers gesture hands ranking rate rating reject up', ThumbDownAlt: @@ -2689,22 +2695,23 @@ const synonyms = { 'analytics chart data graph history line movement points tracking trending zigzag zigzap', Timer: 'alarm alart alert bell clock disabled duration enabled notification off slash stopwatch wait', - Timer10: 'digits duration numbers seconds', + Timer10: + 'alarm alert bell clock digits disabled duration enabled notification numbers seconds ten watch', Timer10Select: - 'alphabet camera character digit font letter number seconds symbol text type', - Timer3: 'digits duration numbers seconds', + 'alphabet camera character digit font letters numbers seconds symbol ten text type', + Timer3: 'digits duration numbers seconds three', Timer3Select: - 'alphabet camera character digit font letter number seconds symbol text type', + 'alphabet camera character digit font letters numbers seconds symbol text three type', TimerOff: 'alarm alart alert bell clock disabled duration enabled notification slash stopwatch', TimesOneMobiledata: - 'alphabet cellular character digit font letter network number phone signal speed symbol text type wifi', + 'alphabet cellular character digit font letters network numbers phone signal speed symbol text type wifi', TimeToLeave: 'automobile cars destination direction drive estimate eta maps public transportation travel trip vehicle', TipsAndUpdates: 'alert announcement artificial automatic automation custom electricity genai idea information intelligence lamp lightbulb magic smart sparkle stars', TireRepair: 'automobile cars gauge mechanic pressure vehicle', - Title: 'T alphabet character font header letter subject symbol text type', + Title: 'T alphabet character font header letters subject symbol text type', Toc: 'content format lines list reorder stacked table text titles', Today: 'agenda calendar date event mark month range remember reminder schedule time week', @@ -2741,10 +2748,11 @@ const synonyms = { Troubleshoot: 'analytics chart data diagram find glass infographic line look magnifying measure metrics search see statistics tracking', Try: 'bookmark bubble chat comment communicate favorite feedback highlight important marked message saved shape special speech star', - Tsunami: 'crisis disaster flood rain storm weather', + Tsunami: 'crisis disaster flood ocean rain sea storm water wave weather', Tty: 'call cell contact deaf device hardware impaired mobile speech talk telephone text', Tune: 'adjust audio controls customize editing filters instant mix music options settings sliders switches', - Tungsten: 'electricity indoor lamp lightbulb setting', + Tungsten: + 'balance bright editing electricity indoor iridescent lamp lightbulb lighting settings white wp', TurnedIn: 'archive bookmark favorite item label library reading remember ribbon save submit tag', TurnedInNot: @@ -2771,10 +2779,10 @@ const synonyms = { TwentyZeroMp: 'camera digits font image letters megapixels numbers quality resolution symbol text type', Twitter: 'brand logo social', - TwoK: '2000 2K alphabet character digit display font letter number pixels resolution symbol text type video', - TwoKPlus: '+ alphabet character digit font letter number symbol text type', + TwoK: '2000 2K alphabet character digit display font letters numbers pixels resolution symbol text type video', + TwoKPlus: '+ alphabet character digit font letters numbers symbol text type', TwoMp: - 'camera digit font image letters megapixels number quality resolution symbol text type', + 'camera digit font image letters megapixels numbers quality resolution symbol text type', TwoWheeler: 'automobile bicycle cars direction maps moped motorbike motorcycle public ride riding scooter transportation travel twom vehicle wheeler wheels', Umbrella: 'beach protection rain sunny', @@ -2790,7 +2798,7 @@ const synonyms = { Unpublished: 'approve check circle complete disabled done enabled mark off ok select slash tick validate verified yes', Unsubscribe: - 'cancel close email envelop esubscribe message newsletter off remove send', + 'cancel close email envelop esubscribe letters message newsletter off remove send', Upcoming: 'alarm calendar mail message notification', Update: 'arrow backwards clock forward future history load refresh reverse rotate schedule time', @@ -2838,9 +2846,9 @@ const synonyms = { 'bubble camera comment communicate facetime feedback message speech voice', VideoFile: 'camera document filming hardware image motion picture videography', VideogameAsset: - 'console controller device gamepad gaming nintendo playstation xbox', + 'console controller device entertainment esports gamepad gaming google handheld hardware hobby nintendo online playstation remote social stadia video xbox', VideogameAssetOff: - 'console controller device disabled enabled gamepad gaming playstation slash', + 'console controller device disabled enabled entertainment esports gamepad gaming google handheld hardware hobby online playstation remote slash social stadia video xbox', VideoLabel: 'device item screen window', VideoLibrary: 'arrow collection play', VideoSettings: @@ -2857,7 +2865,7 @@ const synonyms = { ViewCozy: 'comfy design format layout web', ViewDay: 'blocks calendar cards carousel design format grid layout website week', ViewHeadline: 'blocks design format grid layout paragraph text website', - ViewInAr: '3d augmented cube daydream headset reality square vr', + ViewInAr: '3d augmented cube daydream headset square virtual_reality vr', ViewKanban: 'grid layout pattern squares', ViewList: 'blocks design format grid layout lines reorder stacked title website', ViewModule: @@ -2879,7 +2887,7 @@ const synonyms = { 'bubble camera comment communicate facetime feedback message speech video', Voicemail: 'call device message missed mobile phone recording', VoiceOverOff: - 'account disabled enabled face human people person profile recording slash speaking speech transcript user', + 'account disabled enabled face human mute people person profile recording slash speaking speech transcript user', Volcano: 'crisis disaster eruption lava magma natural', VolumeDown: 'audio av control music quieter shh soft sound speaker tv', VolumeMute: 'audio control music sound speaker tv', @@ -2913,10 +2921,11 @@ const synonyms = { Waves: 'beach lake ocean pool river sea swim water', WavingHand: 'fingers gesture goodbye greetings hello palm wave', WbAuto: - 'A W alphabet automatic balance character editing font image letter photography symbol text type white wp', + 'A W alphabet automatic balance character editing font image letters photography symbol text type white wp', WbCloudy: 'balance editing white wp', WbIncandescent: 'balance bright editing lamp lightbulb lighting settings white wp', - WbIridescent: 'balance bright editing lighting settings white wp', + WbIridescent: + 'balance bright editing electricity indoor lamp lightbulb lighting settings tungsten white wp', WbShade: 'balance house lighting white', WbSunny: 'balance bright lighting weather white', WbTwilight: 'balance lighting noon sunset white', diff --git a/docs/data/material/components/menus/menus.md b/docs/data/material/components/menus/menus.md index 28b851d344b98b..259f1c68ead249 100644 --- a/docs/data/material/components/menus/menus.md +++ b/docs/data/material/components/menus/menus.md @@ -14,7 +14,7 @@ unstyled: /base-ui/react-menu/ A menu displays a list of choices on a temporary surface. It appears when the user interacts with a button, or other control. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic menu diff --git a/docs/data/material/components/modal/modal.md b/docs/data/material/components/modal/modal.md index d50cc10cb69af4..4a8d2f040e20e4 100644 --- a/docs/data/material/components/modal/modal.md +++ b/docs/data/material/components/modal/modal.md @@ -21,7 +21,7 @@ The `Modal` offers important features: and keeping it there until the modal is closed. - ♿️ Adds the appropriate ARIA roles automatically. -{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} :::info The term "modal" is sometimes used to mean "dialog", but this is a misnomer. diff --git a/docs/data/material/components/pagination/pagination.md b/docs/data/material/components/pagination/pagination.md index 561f7d4dc5c358..2d5005cadb0f28 100644 --- a/docs/data/material/components/pagination/pagination.md +++ b/docs/data/material/components/pagination/pagination.md @@ -9,7 +9,7 @@ githubLabel: 'component: pagination'

The Pagination component enables the user to select a specific page from a range of pages.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic pagination diff --git a/docs/data/material/components/paper/paper.md b/docs/data/material/components/paper/paper.md index 884d2ffea0f6f1..ffb71f3825ab99 100644 --- a/docs/data/material/components/paper/paper.md +++ b/docs/data/material/components/paper/paper.md @@ -10,7 +10,7 @@ materialDesign: https://m2.material.io/design/environment/elevation.html

The Paper component is a container for displaying content on an elevated surface.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/material/components/popover/AnchorPlayground.js b/docs/data/material/components/popover/AnchorPlayground.js index fc4b5f91e9cd17..694a500ca4482e 100644 --- a/docs/data/material/components/popover/AnchorPlayground.js +++ b/docs/data/material/components/popover/AnchorPlayground.js @@ -12,7 +12,7 @@ import Button from '@mui/material/Button'; import Popover from '@mui/material/Popover'; import Input from '@mui/material/Input'; import InputLabel from '@mui/material/InputLabel'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; const inlineStyles = { anchorVertical: { diff --git a/docs/data/material/components/popover/popover.md b/docs/data/material/components/popover/popover.md index 673969876e2c34..5379cf0ecf4176 100644 --- a/docs/data/material/components/popover/popover.md +++ b/docs/data/material/components/popover/popover.md @@ -14,7 +14,7 @@ Things to know when using the `Popover` component: - The component is built on top of the [`Modal`](/material-ui/react-modal/) component. - The scroll and click away are blocked unlike with the [`Popper`](/material-ui/react-popper/) component. -{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Basic Popover diff --git a/docs/data/material/components/popper/ScrollPlayground.js b/docs/data/material/components/popper/ScrollPlayground.js index d3bc2d9e8f34e6..24cbe701c2f13a 100644 --- a/docs/data/material/components/popper/ScrollPlayground.js +++ b/docs/data/material/components/popper/ScrollPlayground.js @@ -14,7 +14,7 @@ import DialogTitle from '@mui/material/DialogTitle'; import Switch from '@mui/material/Switch'; import TextField from '@mui/material/TextField'; import FormGroup from '@mui/material/FormGroup'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; const Popper = styled(MuiPopper, { shouldForwardProp: (prop) => prop !== 'arrow', diff --git a/docs/data/material/components/popper/popper.md b/docs/data/material/components/popper/popper.md index f955d7f43a8330..bd10fa395b0115 100644 --- a/docs/data/material/components/popper/popper.md +++ b/docs/data/material/components/popper/popper.md @@ -22,7 +22,7 @@ Some important features of the `Popper` component: If you need this behavior, you can use [`ClickAwayListener`](/material-ui/react-click-away-listener/) - see the example in the [menu documentation section](/material-ui/react-menu/#menulist-composition). - The `anchorEl` is passed as the reference object to create a new `Popper.js` instance. -{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Basic popper diff --git a/docs/data/material/components/progress/progress.md b/docs/data/material/components/progress/progress.md index 74893d02d8496a..963bbafed90f5d 100644 --- a/docs/data/material/components/progress/progress.md +++ b/docs/data/material/components/progress/progress.md @@ -17,7 +17,7 @@ Progress indicators inform users about the status of ongoing processes, such as The animations of the components rely on CSS as much as possible to work even before the JavaScript is loaded. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Circular diff --git a/docs/data/material/components/radio-buttons/radio-buttons.md b/docs/data/material/components/radio-buttons/radio-buttons.md index b73b440e9f5b36..28a60256665262 100644 --- a/docs/data/material/components/radio-buttons/radio-buttons.md +++ b/docs/data/material/components/radio-buttons/radio-buttons.md @@ -16,7 +16,7 @@ If available options can be collapsed, consider using a [Select component](/mate Radio buttons should have the most commonly used option selected by default. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Radio group diff --git a/docs/data/material/components/rating/rating.md b/docs/data/material/components/rating/rating.md index 4d39e67366971e..fb2e134f954d67 100644 --- a/docs/data/material/components/rating/rating.md +++ b/docs/data/material/components/rating/rating.md @@ -10,7 +10,7 @@ waiAria: https://www.w3.org/WAI/tutorials/forms/custom-controls/#a-star-rating

Ratings provide insight regarding others' opinions and experiences, and can allow the user to submit a rating of their own.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic rating diff --git a/docs/data/material/components/selects/selects.md b/docs/data/material/components/selects/selects.md index 634af8b9fe4021..10d6a7b198861b 100644 --- a/docs/data/material/components/selects/selects.md +++ b/docs/data/material/components/selects/selects.md @@ -12,7 +12,7 @@ unstyled: /base-ui/react-select/

Select components are used for collecting user provided information from a list of options.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic select diff --git a/docs/data/material/components/skeleton/skeleton.md b/docs/data/material/components/skeleton/skeleton.md index da7cacad060fb6..3a16a710d11297 100644 --- a/docs/data/material/components/skeleton/skeleton.md +++ b/docs/data/material/components/skeleton/skeleton.md @@ -11,7 +11,7 @@ githubLabel: 'component: skeleton' The data for your components might not be immediately available. You can improve the perceived responsiveness of the page by using skeletons. It feels like things are happening immediately, then the information is incrementally displayed on the screen (Cf. [Avoid The Spinner](https://www.lukew.com/ff/entry.asp?1797)). -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Usage diff --git a/docs/data/material/components/slider/slider.md b/docs/data/material/components/slider/slider.md index 3c902577906cd6..ea682f7c11f500 100644 --- a/docs/data/material/components/slider/slider.md +++ b/docs/data/material/components/slider/slider.md @@ -14,7 +14,7 @@ unstyled: /base-ui/react-slider/ Sliders reflect a range of values along a bar, from which users may select a single value. They are ideal for adjusting settings such as volume, brightness, or applying image filters. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Continuous sliders diff --git a/docs/data/material/components/snackbars/snackbars.md b/docs/data/material/components/snackbars/snackbars.md index a8824998e95c23..f860e82866a5f8 100644 --- a/docs/data/material/components/snackbars/snackbars.md +++ b/docs/data/material/components/snackbars/snackbars.md @@ -11,7 +11,7 @@ waiAria: https://www.w3.org/TR/wai-aria-1.1/#alert

Snackbars (also known as toasts) are used for brief notifications of processes that have been or will be performed.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction diff --git a/docs/data/material/components/speed-dial/speed-dial.md b/docs/data/material/components/speed-dial/speed-dial.md index e6095ea490da30..8d9771c6c9911b 100644 --- a/docs/data/material/components/speed-dial/speed-dial.md +++ b/docs/data/material/components/speed-dial/speed-dial.md @@ -13,7 +13,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/ If more than six actions are needed, something other than a FAB should be used to present them. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic speed dial diff --git a/docs/data/material/components/stack/InteractiveStack.js b/docs/data/material/components/stack/InteractiveStack.js index 8c61706ef15893..270c7d2354c96d 100644 --- a/docs/data/material/components/stack/InteractiveStack.js +++ b/docs/data/material/components/stack/InteractiveStack.js @@ -7,7 +7,7 @@ import Paper from '@mui/material/Paper'; import RadioGroup from '@mui/material/RadioGroup'; import Radio from '@mui/material/Radio'; import Stack from '@mui/material/Stack'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; export default function InteractiveStack() { const [direction, setDirection] = React.useState('row'); diff --git a/docs/data/material/components/stack/InteractiveStack.tsx b/docs/data/material/components/stack/InteractiveStack.tsx index c6320ecb8a77c5..2c4fb30f5c44e8 100644 --- a/docs/data/material/components/stack/InteractiveStack.tsx +++ b/docs/data/material/components/stack/InteractiveStack.tsx @@ -7,7 +7,7 @@ import Paper from '@mui/material/Paper'; import RadioGroup from '@mui/material/RadioGroup'; import Radio from '@mui/material/Radio'; import Stack, { StackProps } from '@mui/material/Stack'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; export default function InteractiveStack() { const [direction, setDirection] = React.useState('row'); diff --git a/docs/data/material/components/stack/stack.md b/docs/data/material/components/stack/stack.md index b50b3170526685..5948e3f2d64c14 100644 --- a/docs/data/material/components/stack/stack.md +++ b/docs/data/material/components/stack/stack.md @@ -17,7 +17,7 @@ The Stack component manages the layout of its immediate children along the verti Stack is ideal for one-dimensional layouts, while Grid is preferable when you need both vertical _and_ horizontal arrangement. ::: -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basics diff --git a/docs/data/material/components/steppers/SwipeableTextMobileStepper.js b/docs/data/material/components/steppers/SwipeableTextMobileStepper.js deleted file mode 100644 index d7fd286fadf318..00000000000000 --- a/docs/data/material/components/steppers/SwipeableTextMobileStepper.js +++ /dev/null @@ -1,128 +0,0 @@ -import * as React from 'react'; -import { useTheme } from '@mui/material/styles'; -import Box from '@mui/material/Box'; -import MobileStepper from '@mui/material/MobileStepper'; -import Paper from '@mui/material/Paper'; -import Typography from '@mui/material/Typography'; -import Button from '@mui/material/Button'; -import KeyboardArrowLeft from '@mui/icons-material/KeyboardArrowLeft'; -import KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight'; -import SwipeableViews from 'react-swipeable-views'; -import { autoPlay } from 'react-swipeable-views-utils'; - -const AutoPlaySwipeableViews = autoPlay(SwipeableViews); - -const images = [ - { - label: 'San Francisco – Oakland Bay Bridge, United States', - imgPath: - 'https://images.unsplash.com/photo-1537944434965-cf4679d1a598?auto=format&fit=crop&w=400&h=250&q=60', - }, - { - label: 'Bird', - imgPath: - 'https://images.unsplash.com/photo-1538032746644-0212e812a9e7?auto=format&fit=crop&w=400&h=250&q=60', - }, - { - label: 'Bali, Indonesia', - imgPath: - 'https://images.unsplash.com/photo-1537996194471-e657df975ab4?auto=format&fit=crop&w=400&h=250', - }, - { - label: 'Goč, Serbia', - imgPath: - 'https://images.unsplash.com/photo-1512341689857-198e7e2f3ca8?auto=format&fit=crop&w=400&h=250&q=60', - }, -]; - -function SwipeableTextMobileStepper() { - const theme = useTheme(); - const [activeStep, setActiveStep] = React.useState(0); - const maxSteps = images.length; - - const handleNext = () => { - setActiveStep((prevActiveStep) => prevActiveStep + 1); - }; - - const handleBack = () => { - setActiveStep((prevActiveStep) => prevActiveStep - 1); - }; - - const handleStepChange = (step) => { - setActiveStep(step); - }; - - return ( - - - {images[activeStep].label} - - - {images.map((step, index) => ( -
- {Math.abs(activeStep - index) <= 2 ? ( - - ) : null} -
- ))} -
- - Next - {theme.direction === 'rtl' ? ( - - ) : ( - - )} - - } - backButton={ - - } - /> -
- ); -} - -export default SwipeableTextMobileStepper; diff --git a/docs/data/material/components/steppers/SwipeableTextMobileStepper.tsx b/docs/data/material/components/steppers/SwipeableTextMobileStepper.tsx deleted file mode 100644 index 7eb9ecd57e5960..00000000000000 --- a/docs/data/material/components/steppers/SwipeableTextMobileStepper.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import * as React from 'react'; -import { useTheme } from '@mui/material/styles'; -import Box from '@mui/material/Box'; -import MobileStepper from '@mui/material/MobileStepper'; -import Paper from '@mui/material/Paper'; -import Typography from '@mui/material/Typography'; -import Button from '@mui/material/Button'; -import KeyboardArrowLeft from '@mui/icons-material/KeyboardArrowLeft'; -import KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight'; -import SwipeableViews from 'react-swipeable-views'; -import { autoPlay } from 'react-swipeable-views-utils'; - -const AutoPlaySwipeableViews = autoPlay(SwipeableViews); - -const images = [ - { - label: 'San Francisco – Oakland Bay Bridge, United States', - imgPath: - 'https://images.unsplash.com/photo-1537944434965-cf4679d1a598?auto=format&fit=crop&w=400&h=250&q=60', - }, - { - label: 'Bird', - imgPath: - 'https://images.unsplash.com/photo-1538032746644-0212e812a9e7?auto=format&fit=crop&w=400&h=250&q=60', - }, - { - label: 'Bali, Indonesia', - imgPath: - 'https://images.unsplash.com/photo-1537996194471-e657df975ab4?auto=format&fit=crop&w=400&h=250', - }, - { - label: 'Goč, Serbia', - imgPath: - 'https://images.unsplash.com/photo-1512341689857-198e7e2f3ca8?auto=format&fit=crop&w=400&h=250&q=60', - }, -]; - -function SwipeableTextMobileStepper() { - const theme = useTheme(); - const [activeStep, setActiveStep] = React.useState(0); - const maxSteps = images.length; - - const handleNext = () => { - setActiveStep((prevActiveStep) => prevActiveStep + 1); - }; - - const handleBack = () => { - setActiveStep((prevActiveStep) => prevActiveStep - 1); - }; - - const handleStepChange = (step: number) => { - setActiveStep(step); - }; - - return ( - - - {images[activeStep].label} - - - {images.map((step, index) => ( -
- {Math.abs(activeStep - index) <= 2 ? ( - - ) : null} -
- ))} -
- - Next - {theme.direction === 'rtl' ? ( - - ) : ( - - )} - - } - backButton={ - - } - /> -
- ); -} - -export default SwipeableTextMobileStepper; diff --git a/docs/data/material/components/steppers/steppers.md b/docs/data/material/components/steppers/steppers.md index 909ed00bd884f3..c026f1aec4b2f6 100644 --- a/docs/data/material/components/steppers/steppers.md +++ b/docs/data/material/components/steppers/steppers.md @@ -16,7 +16,7 @@ Steppers may display a transient feedback message after a step is saved. - **Types of Steps**: Editable, Non-editable, Mobile, Optional - **Types of Steppers**: Horizontal, Vertical, Linear, Non-linear -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} :::info This component is no longer documented in the [Material Design guidelines](https://m2.material.io/), but Material UI will continue to support it. @@ -94,13 +94,6 @@ The current step and total number of steps are displayed as text. {{"demo": "TextMobileStepper.js", "bg": true}} -### Text with carousel effect - -This demo uses -[react-swipeable-views](https://github.com/oliviertassinari/react-swipeable-views) to create a carousel. - -{{"demo": "SwipeableTextMobileStepper.js", "bg": true}} - ### Dots Use dots when the number of steps is small. diff --git a/docs/data/material/components/switches/switches.md b/docs/data/material/components/switches/switches.md index 81ba2f452d1077..ab7a8bf20c31b2 100644 --- a/docs/data/material/components/switches/switches.md +++ b/docs/data/material/components/switches/switches.md @@ -15,7 +15,7 @@ Switches are the preferred way to adjust settings on mobile. The option that the switch controls, as well as the state it's in, should be made clear from the corresponding inline label. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic switches diff --git a/docs/data/material/components/table/EnhancedTable.js b/docs/data/material/components/table/EnhancedTable.js index 8417fa180abbe7..b0fa5ea53be9ce 100644 --- a/docs/data/material/components/table/EnhancedTable.js +++ b/docs/data/material/components/table/EnhancedTable.js @@ -65,22 +65,6 @@ function getComparator(order, orderBy) { : (a, b) => -descendingComparator(a, b, orderBy); } -// Since 2020 all major browsers ensure sort stability with Array.prototype.sort(). -// stableSort() brings sort stability to non-modern browsers (notably IE11). If you -// only support modern browsers you can replace stableSort(exampleArray, exampleComparator) -// with exampleArray.slice().sort(exampleComparator) -function stableSort(array, comparator) { - const stabilizedThis = array.map((el, index) => [el, index]); - stabilizedThis.sort((a, b) => { - const order = comparator(a[0], b[0]); - if (order !== 0) { - return order; - } - return a[1] - b[1]; - }); - return stabilizedThis.map((el) => el[0]); -} - const headCells = [ { id: 'name', @@ -288,10 +272,9 @@ export default function EnhancedTable() { const visibleRows = React.useMemo( () => - stableSort(rows, getComparator(order, orderBy)).slice( - page * rowsPerPage, - page * rowsPerPage + rowsPerPage, - ), + [...rows] + .sort(getComparator(order, orderBy)) + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage), [order, orderBy, page, rowsPerPage], ); diff --git a/docs/data/material/components/table/EnhancedTable.tsx b/docs/data/material/components/table/EnhancedTable.tsx index d1fd663dc821cc..23d1f23a1c19d2 100644 --- a/docs/data/material/components/table/EnhancedTable.tsx +++ b/docs/data/material/components/table/EnhancedTable.tsx @@ -88,22 +88,6 @@ function getComparator( : (a, b) => -descendingComparator(a, b, orderBy); } -// Since 2020 all major browsers ensure sort stability with Array.prototype.sort(). -// stableSort() brings sort stability to non-modern browsers (notably IE11). If you -// only support modern browsers you can replace stableSort(exampleArray, exampleComparator) -// with exampleArray.slice().sort(exampleComparator) -function stableSort(array: readonly T[], comparator: (a: T, b: T) => number) { - const stabilizedThis = array.map((el, index) => [el, index] as [T, number]); - stabilizedThis.sort((a, b) => { - const order = comparator(a[0], b[0]); - if (order !== 0) { - return order; - } - return a[1] - b[1]; - }); - return stabilizedThis.map((el) => el[0]); -} - interface HeadCell { disablePadding: boolean; id: keyof Data; @@ -320,10 +304,9 @@ export default function EnhancedTable() { const visibleRows = React.useMemo( () => - stableSort(rows, getComparator(order, orderBy)).slice( - page * rowsPerPage, - page * rowsPerPage + rowsPerPage, - ), + [...rows] + .sort(getComparator(order, orderBy)) + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage), [order, orderBy, page, rowsPerPage], ); diff --git a/docs/data/material/components/table/table.md b/docs/data/material/components/table/table.md index 948ff6a25f8dda..2703eb5b5a14ab 100644 --- a/docs/data/material/components/table/table.md +++ b/docs/data/material/components/table/table.md @@ -17,7 +17,7 @@ Tables display information in a way that's easy to scan, so that users can look - Navigation - Tools to query and manipulate data -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic table @@ -33,11 +33,6 @@ This constraint makes building rich data tables challenging. The [`DataGrid` component](/x/react-data-grid/) is designed for use-cases that are focused on handling large amounts of tabular data. While it comes with a more rigid structure, in exchange, you gain more powerful features. -:::info -The demo below uses the MUI X Data Grid v7, which is currently in beta. -Visit [the documentation](https://next.mui.com/x/react-data-grid/) to learn more about it. -::: - {{"demo": "DataTable.js", "bg": "inline"}} ## Dense table diff --git a/docs/data/material/components/tabs/FullWidthTabs.js b/docs/data/material/components/tabs/FullWidthTabs.js index 8439038ffc54b5..2e8a08deba0e8a 100644 --- a/docs/data/material/components/tabs/FullWidthTabs.js +++ b/docs/data/material/components/tabs/FullWidthTabs.js @@ -1,6 +1,5 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import SwipeableViews from 'react-swipeable-views'; import { useTheme } from '@mui/material/styles'; import AppBar from '@mui/material/AppBar'; import Tabs from '@mui/material/Tabs'; @@ -49,10 +48,6 @@ export default function FullWidthTabs() { setValue(newValue); }; - const handleChangeIndex = (index) => { - setValue(index); - }; - return ( @@ -69,21 +64,15 @@ export default function FullWidthTabs() { - - - Item One - - - Item Two - - - Item Three - - + + Item One + + + Item Two + + + Item Three + ); } diff --git a/docs/data/material/components/tabs/FullWidthTabs.tsx b/docs/data/material/components/tabs/FullWidthTabs.tsx index 0b3b1c34d556cf..99ff253bb02f63 100644 --- a/docs/data/material/components/tabs/FullWidthTabs.tsx +++ b/docs/data/material/components/tabs/FullWidthTabs.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import SwipeableViews from 'react-swipeable-views'; import { useTheme } from '@mui/material/styles'; import AppBar from '@mui/material/AppBar'; import Tabs from '@mui/material/Tabs'; @@ -49,10 +48,6 @@ export default function FullWidthTabs() { setValue(newValue); }; - const handleChangeIndex = (index: number) => { - setValue(index); - }; - return ( @@ -69,21 +64,15 @@ export default function FullWidthTabs() { - - - Item One - - - Item Two - - - Item Three - - + + Item One + + + Item Two + + + Item Three + ); } diff --git a/docs/data/material/components/tabs/tabs.md b/docs/data/material/components/tabs/tabs.md index f75936d72dee57..370b2450044f9c 100644 --- a/docs/data/material/components/tabs/tabs.md +++ b/docs/data/material/components/tabs/tabs.md @@ -14,7 +14,7 @@ unstyled: /base-ui/react-tabs/ Tabs organize and allow navigation between groups of content that are related and at the same level of hierarchy. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Introduction @@ -67,7 +67,6 @@ Fixed tabs should be used with a limited number of tabs, and when a consistent p ### Full width The `variant="fullWidth"` prop should be used for smaller views. -This demo also uses [react-swipeable-views](https://github.com/oliviertassinari/react-swipeable-views) to animate the Tab transition, and allowing tabs to be swiped on touch devices. {{"demo": "FullWidthTabs.js", "bg": true}} diff --git a/docs/data/material/components/text-fields/text-fields.md b/docs/data/material/components/text-fields/text-fields.md index f9a954f8b6b225..190bd80ec72d12 100644 --- a/docs/data/material/components/text-fields/text-fields.md +++ b/docs/data/material/components/text-fields/text-fields.md @@ -13,7 +13,7 @@ unstyled: /base-ui/react-input/ Text fields allow users to enter text into a UI. They typically appear in forms and dialogs. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic TextField diff --git a/docs/data/material/components/timeline/timeline.md b/docs/data/material/components/timeline/timeline.md index ef028c2634763a..63a7b5fa1d475d 100644 --- a/docs/data/material/components/timeline/timeline.md +++ b/docs/data/material/components/timeline/timeline.md @@ -14,7 +14,7 @@ packageName: '@mui/lab' This component is not documented in the [Material Design guidelines](https://m2.material.io/), but it is available in Material UI. ::: -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic timeline diff --git a/docs/data/material/components/toggle-button/toggle-button.md b/docs/data/material/components/toggle-button/toggle-button.md index 1ccc8105bfac1d..ec6b514cbff27a 100644 --- a/docs/data/material/components/toggle-button/toggle-button.md +++ b/docs/data/material/components/toggle-button/toggle-button.md @@ -14,7 +14,7 @@ To emphasize groups of related Toggle buttons, a group should share a common container. The `ToggleButtonGroup` controls the selected state of its child buttons when given its own `value` prop. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Exclusive selection diff --git a/docs/data/material/components/tooltips/tooltips.md b/docs/data/material/components/tooltips/tooltips.md index 632a82cbc63039..4cedae5a300099 100644 --- a/docs/data/material/components/tooltips/tooltips.md +++ b/docs/data/material/components/tooltips/tooltips.md @@ -13,7 +13,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/ When activated, Tooltips display a text label identifying an element, such as a description of its function. -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic tooltip diff --git a/docs/data/material/components/transfer-list/transfer-list.md b/docs/data/material/components/transfer-list/transfer-list.md index b987834672583f..9216e88dac20cc 100644 --- a/docs/data/material/components/transfer-list/transfer-list.md +++ b/docs/data/material/components/transfer-list/transfer-list.md @@ -9,7 +9,7 @@ githubLabel: 'component: transfer list'

A Transfer List (or "shuttle") enables the user to move one or more list items between lists.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Basic transfer list diff --git a/docs/data/material/components/transitions/transitions.md b/docs/data/material/components/transitions/transitions.md index e3dab44b386d9e..de2a39939edd7f 100644 --- a/docs/data/material/components/transitions/transitions.md +++ b/docs/data/material/components/transitions/transitions.md @@ -11,7 +11,7 @@ githubLabel: 'component: transitions' Material UI provides transitions that can be used to introduce some basic [motion](https://m2.material.io/design/motion/) to your applications. -{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Collapse diff --git a/docs/data/material/components/typography/typography.md b/docs/data/material/components/typography/typography.md index ba451b59eda874..3812bd7a91a916 100644 --- a/docs/data/material/components/typography/typography.md +++ b/docs/data/material/components/typography/typography.md @@ -10,7 +10,7 @@ materialDesign: https://m2.material.io/design/typography/the-type-system.html

Use typography to present your design and content as clearly and efficiently as possible.

-{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Roboto font diff --git a/docs/data/material/components/use-media-query/use-media-query.md b/docs/data/material/components/use-media-query/use-media-query.md index caeb6337bfbec5..1c794a18146268 100644 --- a/docs/data/material/components/use-media-query/use-media-query.md +++ b/docs/data/material/components/use-media-query/use-media-query.md @@ -14,7 +14,7 @@ Some of the key features: - 🚀 It's performant, it observes the document to detect when its media queries change, instead of polling the values periodically. - 🤖 It supports server-side rendering. -{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Basic media query diff --git a/docs/data/material/customization/palette/palette.md b/docs/data/material/customization/palette/palette.md index d6074591f49ff9..4cfb782426dcba 100644 --- a/docs/data/material/customization/palette/palette.md +++ b/docs/data/material/customization/palette/palette.md @@ -303,7 +303,7 @@ const theme = createTheme({ :::warning The `contrastThreshold` parameter can produce counterproductive results.\ -Please verify that the [APCA](https://contrast.tools/?tab=apca) color contrast is improved (WCAG 3 [will use](https://typefully.com/u/DanHollick/t/sle13GMW2Brp) this new algorithm). +Please verify that the [APCA](https://contrast.tools/?tab=apca) color contrast is improved (WCAG 3 [will use](https://typefully.com/DanHollick/sle13GMW2Brp) this new algorithm). ::: ## Picking colors diff --git a/docs/data/material/design-resources/material-ui-for-figma/material-ui-for-figma.md b/docs/data/material/design-resources/material-ui-for-figma/material-ui-for-figma.md new file mode 100644 index 00000000000000..77e73319d01b75 --- /dev/null +++ b/docs/data/material/design-resources/material-ui-for-figma/material-ui-for-figma.md @@ -0,0 +1,94 @@ +# Material UI for Figma + +

Enhance designer-developer collaboration between Material UI and Figma.

+ +## Getting started + +Material UI for Figma consists of representations of the library's React components in Figma so designers and developers can communicate and iterate more efficiently. +The kit includes: + +- components with the same design as Material UI +- additional components and features not covered by Material Design +- shared terminology from the React library for props, variables, design tokens, and other values + +### Community vs. full version + +The Material UI design kit is available in the [community (free) version](https://www.figma.com/community/file/912837788133317724/material-ui-for-figma-and-mui-x) and the [full (paid) version](https://mui.com/store/items/figma-react/). + +| | Community | Full version | +| :-------------------------------- | --------: | -----------: | +| Components without customizations | All | All | +| Components with customizations | 4 | All | +| Figma variables | - | ✅ | + +### Installing the full version + +Start by extracting the `.zip` archive which contains the `.fig` files. +Then you can either follow [Figma's import guide](https://help.figma.com/hc/en-us/articles/360041003114-Import-files-into-Figma) or [add it to your team library](https://help.figma.com/hc/en-us/articles/360041051154-Getting-Started-with-Team-Library). + +## Theme + +### Local variables + +The design kit uses Figma's local variables to create a collection of styles comparable to the theme structure of Material UI code. +Follow the steps in the video below to see all the variables available: + + + +### Customizing colors + +Use the variables panel to customize colors as shown in the video below: + + + +### Customizing typography + +Typography customization uses local styles rather than local variables. +The experience is similar to modifying colors, as shown in the video below: + + + +### Switching between light and dark modes + +The design kit uses Figma's local variables to let you toggle the variable mode between light and dark, as shown in the video below: + + + +## Components + +### Editing the main components + +You can use the [Similayer](https://www.figma.com/community/plugin/735733267883397781/Similayer) plugin to select multiple components at once that share some property. + + + +### Table component + +#### Adding new columns + +The video below shows how to add new columns by detaching cells from their row components, allowing you to freely move content around. + + + +#### Adding new columns in the main component + +The Table and Data Grid components come with a limited number of columns by default. +The video below shows how to add new columns by copying cells directly on the main component: + + + +## Code sync + +You can export theme tokens and component customizations to code using [the Sync plugin for Figma](/material-ui/design-resources/material-ui-sync/). +The Design Kit has been built to be as close to the React components as possible, making it for a fluid integration with code. + +Learn more about the Material UI theme structure by visiting the [Theming](https://mui.com/material-ui/customization/theming/) and [Default theme viewer](https://mui.com/material-ui/customization/theming/) pages. + +## Using new design kit versions + +We generally don't release breaking changes in the updates—we add new content instead. +If you need to replace a single component that's been updated, there are a couple of options: + +1. Add the new version of the design kit as a library and use [the new Figma library swap feature](https://www.youtube.com/watch?v=GQ2jztKpxLk). The components must have the same names in both libraries. +2. Observe the new component and re-apply the changes to the existing projects. This is the recommended approach when you need to update multiple projects. +3. Copy and paste the new component into your existing project, give it a different temporary name, then re-link tokens to the new component. When using [Select Similar plugins](https://www.figma.com/community/plugin/792767780551514994/Select-Similar) this shouldn't take more than five minutes. Then you can remove the old component and update the new component name. diff --git a/docs/data/material/design-resources/material-ui-sync/material-ui-sync.md b/docs/data/material/design-resources/material-ui-sync/material-ui-sync.md new file mode 100644 index 00000000000000..c4dcddab439ebb --- /dev/null +++ b/docs/data/material/design-resources/material-ui-sync/material-ui-sync.md @@ -0,0 +1,300 @@ +# Material UI Sync plugin + +

Sync is a Figma plugin that generates Material UI themes directly from design to code.

+ +## Introduction + +[Material UI Sync](https://www.figma.com/community/plugin/1336346114713490235/) is a Figma plugin that lets you generate a theme from the [Material UI for Figma Design Kit](https://www.figma.com/community/file/912837788133317724/material-ui-for-figma-and-mui-x/). + +:::warning +Sync works in combination with the [Material UI for Figma Design Kit v5.16.0](https://github.com/mui/mui-design-kits/releases) and later. +Other kits, such as the Joy UI Design Kit, are not supported yet. +::: + +Customizing the Material UI Switch component in Figma with the Sync plugin running. + +## Running the plugin + +If you don't have the [complete and latest version](/store/items/figma-react/) of the Material UI for Figma Design Kit installed, you can test the plugin by using the [Community version](https://www.figma.com/community/file/912837788133317724/material-ui-for-figma-and-mui-x/) instead. + +After installing and opening it in Figma, head over to the [Material UI Sync plugin page](https://www.figma.com/community/plugin/1336346114713490235/) on the Community tab and click on **Open in...** and select the Material UI for Figma Design Kit. + +Accessing Material UI Sync via the Resources menu in Figma. + +## Customizing design tokens + +Design tokens are defined in the Design Kit's [local variable collections](https://help.figma.com/hc/en-us/articles/15145852043927-Create-and-manage-variables) and include color palettes, breakpoints, shapes, and spacing tokens. +Typography and shadow-related tokens are found in the [local styles collection](https://help.figma.com/hc/en-us/articles/360039820134-Manage-and-share-styles#:~:text=Local%20styles%20are%20styles%20that,or%20from%20the%20style%20picker.). + +### Altering existing tokens + +The Design Kit comes fully loaded with design tokens that map out to the [default theme of the Material UI React library](/material-ui/customization/default-theme/). + +To customize existing tokens, open the [local variable modal](https://help.figma.com/hc/en-us/articles/15145852043927-Create-and-manage-variables) by clicking on the filter icon as shown below. +Tweak any of the variables available in the collections (such as palettes, breakpoints, shapes, and spacing) as you see fit. + +The Local variables menu in Figma, where all design tokens are stored and new ones can be added. + +Then open the Material UI Sync plugin and click on **Generate theme**. + +The Generate theme button in the Material UI Sync plugin UI. + +A theme containing the altered tokens is generated and displayed in the plugin's Theme tab. + +The generated theme displayed in the Material UI Sync plugin UI. + +You can also preview the generated theme and the customized tokens by navigating to the Storybook preview tab. + +The generated theme previewed in Storybook in the Material UI Sync plugin UI. + +### Adding new tokens + +You can extend the existing tokens set with your own either by adding new variables to the existing local variable collections, or by adding new elevation and typography styles to the local style collections. +After you've added your custom tokens, click on **Regenerate theme** to include these tokens in your theme. + +The Regenerate button in the Connect plugin UI. + +## Customizing components + +The Sync plugin can also generate theme styles for customized components, enabling you to completely change their look and feel and create your custom design system from within Figma. + +:::info +This feature is currently limited to the Button, Switch, and Typography components. +Support for more components is coming soon. +::: + +As an example, here's how to customize the checked state, medium size, and primary color of a Switch component to replicate the iOS look and feel: + +A specific variant of the Switch component selected in the Design Kit. + +:::warning +The Design Kit's component layer hierarchy and layer names must remain unaltered for Sync to correctly extract custom component styles and generate the theme. +::: + +The Sync plugin generates the following theme code for the customized Switch: + +```js +{ + components: { + MuiSwitch: { + styleOverrides: { + root: { + '&.MuiSwitch-sizeMedium:has(.MuiSwitch-colorPrimary)': { + '&:has(.Mui-checked):not(:has(.Mui-disabled)):not(:has(.Mui-focusVisible))': + { + width: '40px', + height: '21px', + padding: '0', + '& .MuiSwitch-switchBase': { + transform: 'translateX(19px) translateY(2px)', + padding: '0', + '& .MuiSwitch-thumb': { + width: '17px', + height: '17px', + background: '#FAFAFA', + }, + '& + .MuiSwitch-track': { + width: '38px', + height: '21px', + background: 'var(--mui-palette-success-light)', + opacity: '1', + }, + }, + }, + }, + }, + }, + }, + }, +} +``` + +The generated theme targets classes that correspond to the specific Switch configuration defined above, so styles are only applied when the props and state of the Material UI component match those of the customized Figma component. + +To customize other states, you need to apply the desired design changes to each variant in Figma by following these steps: + +1. Customize a single "base" variant—for example, a Switch component in the checked state, of medium size, and primary color. +2. Clone this variant and rename it to target the next variant you'd like to customize—for example, rename the cloned version of `Checked=True, Size=Medium, Color=Primary, State=Enabled` to `Checked=False, Size=Medium, Color=Primary, State=Enabled`. +3. Delete the old versions of the same variant. +4. Move the new version to the correct square in the variant grid. +5. Make the necessary style adjustments to the variant's child layers. + +Repeat this process for each variant you want to customize. +Here's an example of what this might look like: + +A fully customized Switch component in the Material UI Design Kit. + +From here you can run Sync to generate a new theme—here's what would be generated from the example above: + +```js +{ + components: { + MuiSwitch: { + styleOverrides: { + root: { + "&.MuiSwitch-sizeMedium:has(.MuiSwitch-colorPrimary)": { + width: "40px", + height: "21px", + padding: "0", + "& .MuiSwitch-switchBase": { + padding: "0", + "& .MuiSwitch-thumb": { + width: "17px", + height: "17px", + background: "#FAFAFA", + }, + "& + .MuiSwitch-track": { + width: "38px", + height: "21px", + borderRadius: "100px", + opacity: "1", + }, + }, + "&:not(:has(.Mui-checked)):not(:has(.Mui-disabled)):not(:has(.Mui-focusVisible))": { + "& .MuiSwitch-switchBase": { + transform: "translateX(3px) translateY(2px)", + "& + .MuiSwitch-track": { + background: "#BDBDBD", + }, + }, + }, + "&:not(:has(.Mui-checked)):has(.Mui-disabled):not(:has(.Mui-focusVisible))": { + "& .MuiSwitch-switchBase": { + transform: "translateX(3px) translateY(2px)", + "& + .MuiSwitch-track": { + background: "rgba(229, 229, 229, 0.99)", + }, + }, + }, + "&:not(:has(.Mui-checked)):not(:has(.Mui-disabled)):has(.Mui-focusVisible)": { + "& .MuiSwitch-switchBase": { + transform: "translateX(3px) translateY(2px)", + "& + .MuiSwitch-track": { + border: "1px solid #000", + background: "#BDBDBD", + }, + }, + }, + "&:has(.Mui-checked):has(.Mui-disabled):not(:has(.Mui-focusVisible))": { + "& .MuiSwitch-switchBase": { + transform: "translateX(19px) translateY(2px)", + "& + .MuiSwitch-track": { + background: "rgba(187, 231, 188, 0.99)", + }, + }, + }, + "&:not(:has(.Mui-checked)):not(:has(.Mui-disabled)):not(:has(.Mui-focusVisible)):hover": { + "& .MuiSwitch-switchBase": { + transform: "translateX(3px) translateY(2px)", + "& + .MuiSwitch-track": { + background: "#616161", + }, + }, + }, + "&:has(.Mui-checked):not(:has(.Mui-disabled)):not(:has(.Mui-focusVisible))": { + "& .MuiSwitch-switchBase": { + transform: "translateX(19px) translateY(2px)", + "& + .MuiSwitch-track": { + background: "var(--mui-palette-success-light)", + }, + }, + }, + "&:has(.Mui-checked):not(:has(.Mui-disabled)):not(:has(.Mui-focusVisible)):hover": { + "& .MuiSwitch-switchBase": { + transform: "translateX(19px) translateY(2px)", + "& + .MuiSwitch-track": { + background: "var(--mui-palette-success-dark)", + }, + }, + }, + "&:has(.Mui-checked):not(:has(.Mui-disabled)):has(.Mui-focusVisible)": { + "& .MuiSwitch-switchBase": { + transform: "translateX(19px) translateY(2px)", + "& + .MuiSwitch-track": { + border: "1px solid #000", + background: "var(--mui-palette-success-light)", + }, + }, + }, + }, + }, + }, + }, + }, +} +``` + +:::info +The generated theme may contain the CSS `has()` selector, which is used to target specific child classes. +This selector is not used by other theme-related examples in the docs because it used to have limited browser support. +It is now [supported by all modern browsers](https://caniuse.com/css-has). +::: + +You can also check out the Storybook preview to test the Material UI version of your component. + +A fully customized Switch component in Storybook. + +## Using the generated theme + +:::warning +Themes generated by Sync must be used with Material UI's [`CssVarsProvider`](/material-ui/experimental-api/css-theme-variables/migration/)—the default [`ThemeProvider`](/material-ui/customization/theming/#theme-provider) is not supported. +::: + +Here's an example of how to add a Sync-generated theme to your codebase: + +```tsx title="_app.tsx" +import { + experimental_extendTheme as extendTheme, + Experimental_CssVarsProvider as CssVarsProvider, +} from '@mui/material/styles'; + +export default function MyApp({ Component, pageProps }) { + const theme = extendTheme({ + shape: { + borderRadiusRound: 999, + }, + components: { + MuiSwitch: { + styleOverrides: { + root: { + '&.MuiSwitch-sizeMedium:has(.MuiSwitch-colorPrimary)': { + '&:has(.Mui-checked):not(:has(.Mui-disabled)):not(:has(.Mui-focusVisible))': + { + width: '40px', + height: '21px', + padding: '0', + '& .MuiSwitch-switchBase': { + transform: 'translateX(19px) translateY(2px)', + padding: '0', + '& .MuiSwitch-thumb': { + width: '17px', + height: '17px', + background: '#FAFAFA', + }, + '& + .MuiSwitch-track': { + width: '38px', + height: '21px', + background: 'var(--mui-palette-success-light)', + borderRadius: 'var(--mui-shape-borderRadiusRound)', + opacity: '1', + }, + }, + }, + }, + }, + }, + }, + }, + }); + + return ( + + + + ); +} +``` + +## Feedback and bug reports + +Use [the dedicated Material UI Sync feedback board](https://material-ui-sync.canny.io/) to share feedback, report bugs, or drop feature requests. diff --git a/docs/data/material/discover-more/showcase/appList.js b/docs/data/material/discover-more/showcase/appList.js index 835dfcc44280bf..c094586992d096 100644 --- a/docs/data/material/discover-more/showcase/appList.js +++ b/docs/data/material/discover-more/showcase/appList.js @@ -119,17 +119,6 @@ const appList = [ similarWebVisits: 1800, dateAdded: '2019-01-01', }, - { - title: 'VMware CloudHealth', - description: - 'The most trusted cloud management platform that enables users to analyze and manage cloud ' + - 'cost, usage and performance in one place. ' + - '(Used for the business application, but not the marketing website.)', - image: 'cloudhealth.jpg', - link: 'https://cloudhealth.vmware.com/', - similarWebVisits: 132, - dateAdded: '2018-01-37', - }, { title: 'CityAds', description: diff --git a/docs/data/material/getting-started/design-resources/design-resources.md b/docs/data/material/getting-started/design-resources/design-resources.md index a99aeb2c28a711..f91b3f16f1b8ee 100644 --- a/docs/data/material/getting-started/design-resources/design-resources.md +++ b/docs/data/material/getting-started/design-resources/design-resources.md @@ -2,12 +2,26 @@

Be more efficient designing and developing with the same library.

-## Official kits +## Design kits -Pick your favorite design tool to enjoy and use the Material UI component inventory, including over 1,500 unique elements with their full range of states and variations. +Material UI component designs are available for Figma, Sketch, and Adobe XD, providing accurate representations using shared terminology for all states, variants, and permutations of each component. + +The design kits are composed of over 1,500 unique elements built to speed up the development process and ease communication for teams of designers and developers using the library. {{"component": "modules/components/MaterialUIDesignResources.js"}} +## Material UI Sync Figma plugin + +Sync is a Figma plugin to help bridge the gap between designers and developers using Material UI. + +It generates a theme file that you can add to your codebase with all the design tokens and component customizations from Figma. +You can quickly preview all of the changes through an embedded Storybook panel directly in the plugin interface. + +Sync is currently in beta and [available for free](https://www.figma.com/community/plugin/1336346114713490235/) in the Figma Community. +You can also head over to [the Sync documentation page](/material-ui/design-resources/material-ui-sync/) to learn more. + +Customizing the Material UI Switch component in Figma with the Sync plugin running. + ## Third-party resources ### UXPin diff --git a/docs/data/material/getting-started/installation/installation.md b/docs/data/material/getting-started/installation/installation.md index 5be405621bd99a..b740437dafa801 100644 --- a/docs/data/material/getting-started/installation/installation.md +++ b/docs/data/material/getting-started/installation/installation.md @@ -108,7 +108,7 @@ Fontsource can be configured to load specific subsets, weights and styles. Mater ### Google Web Fonts -To install Roboto through the Google Web Fonts CDN, add the following code inside your project's tag: +To install Roboto through the Google Web Fonts CDN, add the following code inside your project's `` tag: ```html diff --git a/docs/data/material/getting-started/templates/checkout/Checkout.js b/docs/data/material/getting-started/templates/checkout/Checkout.js index d0929cac54591d..32e9da0dc52420 100644 --- a/docs/data/material/getting-started/templates/checkout/Checkout.js +++ b/docs/data/material/getting-started/templates/checkout/Checkout.js @@ -142,7 +142,7 @@ export default function Checkout() { - @@ -190,26 +176,12 @@ function AppAppBar({ mode, toggleColorMode }) { scrollToSection('faq')}>FAQ - - diff --git a/docs/data/material/getting-started/templates/landing-page/components/AppAppBar.tsx b/docs/data/material/getting-started/templates/landing-page/components/AppAppBar.tsx index d0b2a9b6e99a98..5402d2072c46b1 100644 --- a/docs/data/material/getting-started/templates/landing-page/components/AppAppBar.tsx +++ b/docs/data/material/getting-started/templates/landing-page/components/AppAppBar.tsx @@ -135,24 +135,10 @@ export default function AppAppBar({ mode, toggleColorMode }: AppAppBarProps) { }} > - - @@ -194,26 +180,12 @@ export default function AppAppBar({ mode, toggleColorMode }: AppAppBarProps) { scrollToSection('faq')}>FAQ - - diff --git a/docs/data/material/getting-started/templates/landing-page/components/Features.js b/docs/data/material/getting-started/templates/landing-page/components/Features.js index 565084d9b210a9..34b8842a6a8539 100644 --- a/docs/data/material/getting-started/templates/landing-page/components/Features.js +++ b/docs/data/material/getting-started/templates/landing-page/components/Features.js @@ -2,12 +2,15 @@ import * as React from 'react'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Card from '@mui/material/Card'; -import Chip from '@mui/material/Chip'; +import { Chip as MuiChip } from '@mui/material'; import Container from '@mui/material/Container'; import Grid from '@mui/material/Grid'; import Link from '@mui/material/Link'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; + +import { styled } from '@mui/material/styles'; + import ChevronRightRoundedIcon from '@mui/icons-material/ChevronRightRounded'; import DevicesRoundedIcon from '@mui/icons-material/DevicesRounded'; import EdgesensorHighRoundedIcon from '@mui/icons-material/EdgesensorHighRounded'; @@ -40,6 +43,21 @@ const items = [ }, ]; +const Chip = styled(MuiChip)(({ theme, selected }) => ({ + ...(selected && { + borderColor: + theme.palette.mode === 'light' + ? theme.palette.primary.light + : theme.palette.primary.dark, + background: + 'linear-gradient(to bottom right, hsl(210, 98%, 48%), hsl(210, 98%, 35%))', + color: 'hsl(0, 0%, 100%)', + '& .MuiChip-label': { + color: 'hsl(0, 0%, 100%)', + }, + }), +})); + export default function Features() { const [selectedItemIndex, setSelectedItemIndex] = React.useState(0); @@ -73,20 +91,7 @@ export default function Features() { key={index} label={title} onClick={() => handleItemClick(index)} - sx={(theme) => ({ - ...(selectedItemIndex === index && { - borderColor: - theme.palette.mode === 'light' - ? 'primary.light' - : 'primary.dark', - background: - 'linear-gradient(to bottom right, hsl(210, 98%, 48%), hsl(210, 98%, 35%))', - color: 'hsl(0, 0%, 100%)', - '& .MuiChip-label': { - color: 'hsl(0, 0%, 100%)', - }, - }), - })} + selected={selectedItemIndex === index} /> ))} diff --git a/docs/data/material/getting-started/templates/landing-page/components/Features.tsx b/docs/data/material/getting-started/templates/landing-page/components/Features.tsx index f02afaa5483979..1f198bafe9b841 100644 --- a/docs/data/material/getting-started/templates/landing-page/components/Features.tsx +++ b/docs/data/material/getting-started/templates/landing-page/components/Features.tsx @@ -2,12 +2,15 @@ import * as React from 'react'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Card from '@mui/material/Card'; -import Chip from '@mui/material/Chip'; +import { Chip as MuiChip } from '@mui/material'; import Container from '@mui/material/Container'; import Grid from '@mui/material/Grid'; import Link from '@mui/material/Link'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; + +import { styled } from '@mui/material/styles'; + import ChevronRightRoundedIcon from '@mui/icons-material/ChevronRightRounded'; import DevicesRoundedIcon from '@mui/icons-material/DevicesRounded'; import EdgesensorHighRoundedIcon from '@mui/icons-material/EdgesensorHighRounded'; @@ -40,6 +43,25 @@ const items = [ }, ]; +interface ChipProps { + selected?: boolean; +} + +const Chip = styled(MuiChip)(({ theme, selected }) => ({ + ...(selected && { + borderColor: + theme.palette.mode === 'light' + ? theme.palette.primary.light + : theme.palette.primary.dark, + background: + 'linear-gradient(to bottom right, hsl(210, 98%, 48%), hsl(210, 98%, 35%))', + color: 'hsl(0, 0%, 100%)', + '& .MuiChip-label': { + color: 'hsl(0, 0%, 100%)', + }, + }), +})); + export default function Features() { const [selectedItemIndex, setSelectedItemIndex] = React.useState(0); @@ -73,20 +95,7 @@ export default function Features() { key={index} label={title} onClick={() => handleItemClick(index)} - sx={(theme) => ({ - ...(selectedItemIndex === index && { - borderColor: - theme.palette.mode === 'light' - ? 'primary.light' - : 'primary.dark', - background: - 'linear-gradient(to bottom right, hsl(210, 98%, 48%), hsl(210, 98%, 35%))', - color: 'hsl(0, 0%, 100%)', - '& .MuiChip-label': { - color: 'hsl(0, 0%, 100%)', - }, - }), - })} + selected={selectedItemIndex === index} /> ))} diff --git a/docs/data/material/getting-started/templates/landing-page/components/Footer.js b/docs/data/material/getting-started/templates/landing-page/components/Footer.js index d635e85d260315..43aa5115caa990 100644 --- a/docs/data/material/getting-started/templates/landing-page/components/Footer.js +++ b/docs/data/material/getting-started/templates/landing-page/components/Footer.js @@ -76,8 +76,8 @@ export default function Footer() { aria-label="Enter your email address" placeholder="Your email address" inputProps={{ - autocomplete: 'off', - ariaLabel: 'Enter your email address', + autoComplete: 'off', + 'aria-label': 'Enter your email address', }} /> diff --git a/docs/data/material/getting-started/templates/landing-page/components/Pricing.tsx b/docs/data/material/getting-started/templates/landing-page/components/Pricing.tsx index 52ca695ee1ff1e..5c508931a71af3 100644 --- a/docs/data/material/getting-started/templates/landing-page/components/Pricing.tsx +++ b/docs/data/material/getting-started/templates/landing-page/components/Pricing.tsx @@ -199,9 +199,6 @@ export default function Pricing() { diff --git a/docs/data/material/getting-started/templates/landing-page/getLPTheme.js b/docs/data/material/getting-started/templates/landing-page/getLPTheme.js index 8ae6d57199e6fc..ee5fe72b1a3def 100644 --- a/docs/data/material/getting-started/templates/landing-page/getLPTheme.js +++ b/docs/data/material/getting-started/templates/landing-page/getLPTheme.js @@ -225,7 +225,7 @@ export default function getLPTheme(mode) { borderBottomLeftRadius: 10, borderBottomRightRadius: 10, }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { backgroundColor: gray[900], borderColor: gray[800], }), @@ -239,7 +239,7 @@ export default function getLPTheme(mode) { borderRadius: 8, '&:hover': { backgroundColor: gray[100] }, '&:focus-visible': { backgroundColor: 'transparent' }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { '&:hover': { backgroundColor: gray[800] }, }), }), @@ -268,156 +268,195 @@ export default function getLPTheme(mode) { }, MuiButton: { styleOverrides: { - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ boxShadow: 'none', borderRadius: theme.shape.borderRadius, textTransform: 'none', - ...(ownerState.size === 'small' && { - height: '2rem', // 32px - padding: '0 0.5rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', // 40px - }), - ...(ownerState.variant === 'contained' && - ownerState.color === 'primary' && { - color: 'white', - backgroundColor: brand[300], - backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, - boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, - border: `1px solid ${brand[500]}`, - '&:hover': { - backgroundColor: brand[700], - boxShadow: 'none', + variants: [ + { + props: { + size: 'small', }, - '&:active': { - backgroundColor: brand[700], - boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + style: { + height: '2rem', // 32px + padding: '0 0.5rem', }, - }), - ...(ownerState.variant === 'outlined' && { - color: brand[700], - backgroundColor: alpha(brand[300], 0.1), - borderColor: alpha(brand[200], 0.8), - boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, - '&:hover': { - backgroundColor: alpha(brand[300], 0.2), - borderColor: alpha(brand[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(brand[300], 0.3), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, - backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - backgroundColor: alpha(gray[300], 0.1), - borderColor: alpha(gray[300], 0.5), - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), - borderColor: alpha(gray[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(gray[300], 0.4), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, - backgroundImage: 'none', + { + props: { + size: 'medium', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[700], - '&:hover': { - backgroundColor: alpha(brand[300], 0.3), + style: { + height: '2.5rem', // 40px }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), + }, + { + props: { + color: 'primary', + variant: 'contained', }, - }), - ...(theme.palette.mode === 'dark' && { - ...(ownerState.variant === 'outlined' && { - color: brand[200], - backgroundColor: alpha(brand[600], 0.1), - borderColor: alpha(brand[600], 0.6), - boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, - '&:hover': { - backgroundColor: alpha(brand[700], 0.2), - borderColor: alpha(brand[700], 0.5), - boxShadow: 'none', + style: { + color: 'white', + backgroundColor: brand[300], + backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, + boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, + border: `1px solid ${brand[500]}`, + '&:hover': { + backgroundColor: brand[700], + boxShadow: 'none', + }, + '&:active': { + backgroundColor: brand[700], + boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + }, }, - '&:active': { - backgroundColor: alpha(brand[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, - backgroundImage: 'none', + }, + { + props: { + variant: 'outlined', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[200], + style: { + color: brand[700], + backgroundColor: alpha(brand[300], 0.1), + borderColor: alpha(brand[200], 0.8), + boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, '&:hover': { - backgroundColor: alpha(gray[700], 0.3), + backgroundColor: alpha(brand[300], 0.2), + borderColor: alpha(brand[300], 0.5), + boxShadow: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - color: gray[300], - backgroundColor: alpha(gray[600], 0.1), - borderColor: alpha(gray[700], 0.5), - boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:active': { + backgroundColor: alpha(brand[300], 0.3), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, + backgroundImage: 'none', + }, + ...theme.applyStyles('dark', { + color: brand[200], + backgroundColor: alpha(brand[600], 0.1), + borderColor: alpha(brand[600], 0.6), + boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(brand[700], 0.2), + borderColor: alpha(brand[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'secondary', + variant: 'outlined', + }, + style: { + backgroundColor: alpha(gray[300], 0.1), + borderColor: alpha(gray[300], 0.5), + color: gray[700], '&:hover': { - backgroundColor: alpha(gray[700], 0.2), - borderColor: alpha(gray[700], 0.5), + backgroundColor: alpha(gray[300], 0.3), + borderColor: alpha(gray[300], 0.5), boxShadow: 'none', }, '&:active': { - backgroundColor: alpha(gray[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundColor: alpha(gray[300], 0.4), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[200], + ...theme.applyStyles('dark', { + color: gray[300], + backgroundColor: alpha(gray[600], 0.1), + borderColor: alpha(gray[700], 0.5), + boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(gray[700], 0.2), + borderColor: alpha(gray[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(gray[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'primary', + variant: 'text', + }, + style: { + color: brand[700], + '&:hover': { + backgroundColor: alpha(brand[300], 0.3), + }, + ...theme.applyStyles('dark', { + color: brand[200], + '&:hover': { + backgroundColor: alpha(brand[700], 0.3), + }, + }), + }, + }, + { + props: { + color: 'info', + variant: 'text', + }, + style: { + color: gray[700], '&:hover': { - backgroundColor: alpha(brand[700], 0.3), + backgroundColor: alpha(gray[300], 0.3), }, - }), - }), + ...theme.applyStyles('dark', { + color: gray[200], + '&:hover': { + backgroundColor: alpha(gray[700], 0.3), + }, + }), + }, + }, + ], }), }, }, MuiCard: { styleOverrides: { - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ transition: 'all 100ms ease', backgroundColor: gray[50], borderRadius: theme.shape.borderRadius, border: `1px solid ${alpha(gray[200], 0.5)}`, boxShadow: 'none', - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${gray[200]}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { backgroundColor: alpha(gray[800], 0.6), border: `1px solid ${alpha(gray[700], 0.3)}`, - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${alpha(gray[700], 0.4)}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( - gray[800], - 0.5, - )})`, - }), }), + variants: [ + { + props: { + variant: 'outlined', + }, + style: { + border: `1px solid ${gray[200]}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, + ...theme.applyStyles('dark', { + border: `1px solid ${alpha(gray[700], 0.4)}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( + gray[800], + 0.5, + )})`, + }), + }, + }, + ], }), }, }, @@ -443,7 +482,7 @@ export default function getLPTheme(mode) { '& .MuiChip-icon': { color: brand[500], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: `${alpha(brand[500], 0.2)}`, backgroundColor: `${alpha(brand[900], 0.5)}`, '&:hover': { @@ -467,7 +506,7 @@ export default function getLPTheme(mode) { styleOverrides: { root: ({ theme }) => ({ borderColor: `${alpha(gray[200], 0.8)}`, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: `${alpha(gray[700], 0.4)}`, }), }), @@ -483,27 +522,39 @@ export default function getLPTheme(mode) { }, MuiIconButton: { styleOverrides: { - root: ({ theme, ownerState }) => ({ - ...(ownerState.size === 'small' && { - height: '2rem', - width: '2rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', - width: '2.5rem', - }), + root: ({ theme }) => ({ color: brand[500], '&:hover': { backgroundColor: alpha(brand[300], 0.3), borderColor: brand[200], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], '&:hover': { backgroundColor: alpha(brand[600], 0.3), borderColor: brand[700], }, }), + variants: [ + { + props: { + size: 'small', + }, + style: { + height: '2rem', + width: '2rem', + }, + }, + { + props: { + size: 'medium', + }, + style: { + height: '2.5rem', + width: '2.5rem', + }, + }, + ], }), }, }, @@ -544,7 +595,7 @@ export default function getLPTheme(mode) { outlineOffset: '4px', borderRadius: '2px', }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], }), }), @@ -559,7 +610,7 @@ export default function getLPTheme(mode) { fontSize: '0.875rem', fontWeight: 500, borderRadius: theme.shape.borderRadius, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: gray[200], }), }), @@ -573,7 +624,7 @@ export default function getLPTheme(mode) { input: { paddingLeft: 10, }, - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[100]} inset, 0 0 0 1px ${brand[200]}`, maxHeight: '4px', @@ -603,14 +654,7 @@ export default function getLPTheme(mode) { outlineOffset: '2px', borderColor: brand[400], }, - ...(ownerState.color === 'error' && { - borderColor: red[200], - color: red[500], - '& + .MuiFormHelperText-root': { - color: red[500], - }, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[900]} inset, 0 0 0 1px ${brand[600]}`, maxHeight: '6px', @@ -635,14 +679,28 @@ export default function getLPTheme(mode) { outline: `3px solid ${alpha(brand[500], 0.5)}`, outlineOffset: '2px', }, - ...(ownerState.color === 'error' && { - borderColor: red[700], - color: red[300], - '& + .MuiFormHelperText-root': { - color: red[300], - }, - }), }), + variants: [ + { + props: { + color: 'error', + }, + style: { + borderColor: red[200], + color: red[500], + '& + .MuiFormHelperText-root': { + color: red[500], + }, + ...theme.applyStyles('dark', { + borderColor: red[700], + color: red[300], + '& + .MuiFormHelperText-root': { + color: red[300], + }, + }), + }, + }, + ], }), }, }, @@ -684,7 +742,7 @@ export default function getLPTheme(mode) { height: 16, margin: 2, }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { width: 36, height: 24, padding: 0, @@ -727,7 +785,7 @@ export default function getLPTheme(mode) { '& .Mui-selected': { color: brand[500], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { '& .Mui-selected': { color: 'hsl(0, 0%, 100%)', }, @@ -743,7 +801,7 @@ export default function getLPTheme(mode) { textTransform: 'none', borderRadius: theme.shape.borderRadius, fontWeight: 500, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: gray[400], '&.Mui-selected': { color: brand[300] }, }), diff --git a/docs/data/material/getting-started/templates/landing-page/getLPTheme.tsx b/docs/data/material/getting-started/templates/landing-page/getLPTheme.tsx index c513c17f63b408..9aede559b0d583 100644 --- a/docs/data/material/getting-started/templates/landing-page/getLPTheme.tsx +++ b/docs/data/material/getting-started/templates/landing-page/getLPTheme.tsx @@ -244,7 +244,7 @@ export default function getLPTheme(mode: PaletteMode): ThemeOptions { borderBottomLeftRadius: 10, borderBottomRightRadius: 10, }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { backgroundColor: gray[900], borderColor: gray[800], }), @@ -258,7 +258,7 @@ export default function getLPTheme(mode: PaletteMode): ThemeOptions { borderRadius: 8, '&:hover': { backgroundColor: gray[100] }, '&:focus-visible': { backgroundColor: 'transparent' }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { '&:hover': { backgroundColor: gray[800] }, }), }), @@ -287,156 +287,195 @@ export default function getLPTheme(mode: PaletteMode): ThemeOptions { }, MuiButton: { styleOverrides: { - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ boxShadow: 'none', borderRadius: theme.shape.borderRadius, textTransform: 'none', - ...(ownerState.size === 'small' && { - height: '2rem', // 32px - padding: '0 0.5rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', // 40px - }), - ...(ownerState.variant === 'contained' && - ownerState.color === 'primary' && { - color: 'white', - backgroundColor: brand[300], - backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, - boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, - border: `1px solid ${brand[500]}`, - '&:hover': { - backgroundColor: brand[700], - boxShadow: 'none', + variants: [ + { + props: { + size: 'small', }, - '&:active': { - backgroundColor: brand[700], - boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + style: { + height: '2rem', // 32px + padding: '0 0.5rem', }, - }), - ...(ownerState.variant === 'outlined' && { - color: brand[700], - backgroundColor: alpha(brand[300], 0.1), - borderColor: alpha(brand[200], 0.8), - boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, - '&:hover': { - backgroundColor: alpha(brand[300], 0.2), - borderColor: alpha(brand[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(brand[300], 0.3), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, - backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - backgroundColor: alpha(gray[300], 0.1), - borderColor: alpha(gray[300], 0.5), - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), - borderColor: alpha(gray[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(gray[300], 0.4), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, - backgroundImage: 'none', + { + props: { + size: 'medium', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[700], - '&:hover': { - backgroundColor: alpha(brand[300], 0.3), + style: { + height: '2.5rem', // 40px }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), + }, + { + props: { + color: 'primary', + variant: 'contained', }, - }), - ...(theme.palette.mode === 'dark' && { - ...(ownerState.variant === 'outlined' && { - color: brand[200], - backgroundColor: alpha(brand[600], 0.1), - borderColor: alpha(brand[600], 0.6), - boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, - '&:hover': { - backgroundColor: alpha(brand[700], 0.2), - borderColor: alpha(brand[700], 0.5), - boxShadow: 'none', + style: { + color: 'white', + backgroundColor: brand[300], + backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, + boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, + border: `1px solid ${brand[500]}`, + '&:hover': { + backgroundColor: brand[700], + boxShadow: 'none', + }, + '&:active': { + backgroundColor: brand[700], + boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + }, }, - '&:active': { - backgroundColor: alpha(brand[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, - backgroundImage: 'none', + }, + { + props: { + variant: 'outlined', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[200], + style: { + color: brand[700], + backgroundColor: alpha(brand[300], 0.1), + borderColor: alpha(brand[200], 0.8), + boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, '&:hover': { - backgroundColor: alpha(gray[700], 0.3), + backgroundColor: alpha(brand[300], 0.2), + borderColor: alpha(brand[300], 0.5), + boxShadow: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - color: gray[300], - backgroundColor: alpha(gray[600], 0.1), - borderColor: alpha(gray[700], 0.5), - boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:active': { + backgroundColor: alpha(brand[300], 0.3), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, + backgroundImage: 'none', + }, + ...theme.applyStyles('dark', { + color: brand[200], + backgroundColor: alpha(brand[600], 0.1), + borderColor: alpha(brand[600], 0.6), + boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(brand[700], 0.2), + borderColor: alpha(brand[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'secondary', + variant: 'outlined', + }, + style: { + backgroundColor: alpha(gray[300], 0.1), + borderColor: alpha(gray[300], 0.5), + color: gray[700], '&:hover': { - backgroundColor: alpha(gray[700], 0.2), - borderColor: alpha(gray[700], 0.5), + backgroundColor: alpha(gray[300], 0.3), + borderColor: alpha(gray[300], 0.5), boxShadow: 'none', }, '&:active': { - backgroundColor: alpha(gray[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundColor: alpha(gray[300], 0.4), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[200], + ...theme.applyStyles('dark', { + color: gray[300], + backgroundColor: alpha(gray[600], 0.1), + borderColor: alpha(gray[700], 0.5), + boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(gray[700], 0.2), + borderColor: alpha(gray[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(gray[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'primary', + variant: 'text', + }, + style: { + color: brand[700], + '&:hover': { + backgroundColor: alpha(brand[300], 0.3), + }, + ...theme.applyStyles('dark', { + color: brand[200], + '&:hover': { + backgroundColor: alpha(brand[700], 0.3), + }, + }), + }, + }, + { + props: { + color: 'info', + variant: 'text', + }, + style: { + color: gray[700], '&:hover': { - backgroundColor: alpha(brand[700], 0.3), + backgroundColor: alpha(gray[300], 0.3), }, - }), - }), + ...theme.applyStyles('dark', { + color: gray[200], + '&:hover': { + backgroundColor: alpha(gray[700], 0.3), + }, + }), + }, + }, + ], }), }, }, MuiCard: { styleOverrides: { - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ transition: 'all 100ms ease', backgroundColor: gray[50], borderRadius: theme.shape.borderRadius, border: `1px solid ${alpha(gray[200], 0.5)}`, boxShadow: 'none', - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${gray[200]}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { backgroundColor: alpha(gray[800], 0.6), border: `1px solid ${alpha(gray[700], 0.3)}`, - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${alpha(gray[700], 0.4)}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( - gray[800], - 0.5, - )})`, - }), }), + variants: [ + { + props: { + variant: 'outlined', + }, + style: { + border: `1px solid ${gray[200]}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, + ...theme.applyStyles('dark', { + border: `1px solid ${alpha(gray[700], 0.4)}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( + gray[800], + 0.5, + )})`, + }), + }, + }, + ], }), }, }, @@ -462,7 +501,7 @@ export default function getLPTheme(mode: PaletteMode): ThemeOptions { '& .MuiChip-icon': { color: brand[500], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: `${alpha(brand[500], 0.2)}`, backgroundColor: `${alpha(brand[900], 0.5)}`, '&:hover': { @@ -486,7 +525,7 @@ export default function getLPTheme(mode: PaletteMode): ThemeOptions { styleOverrides: { root: ({ theme }) => ({ borderColor: `${alpha(gray[200], 0.8)}`, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: `${alpha(gray[700], 0.4)}`, }), }), @@ -502,27 +541,39 @@ export default function getLPTheme(mode: PaletteMode): ThemeOptions { }, MuiIconButton: { styleOverrides: { - root: ({ theme, ownerState }) => ({ - ...(ownerState.size === 'small' && { - height: '2rem', - width: '2rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', - width: '2.5rem', - }), + root: ({ theme }) => ({ color: brand[500], '&:hover': { backgroundColor: alpha(brand[300], 0.3), borderColor: brand[200], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], '&:hover': { backgroundColor: alpha(brand[600], 0.3), borderColor: brand[700], }, }), + variants: [ + { + props: { + size: 'small', + }, + style: { + height: '2rem', + width: '2rem', + }, + }, + { + props: { + size: 'medium', + }, + style: { + height: '2.5rem', + width: '2.5rem', + }, + }, + ], }), }, }, @@ -563,7 +614,7 @@ export default function getLPTheme(mode: PaletteMode): ThemeOptions { outlineOffset: '4px', borderRadius: '2px', }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], }), }), @@ -578,7 +629,7 @@ export default function getLPTheme(mode: PaletteMode): ThemeOptions { fontSize: '0.875rem', fontWeight: 500, borderRadius: theme.shape.borderRadius, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: gray[200], }), }), @@ -592,7 +643,7 @@ export default function getLPTheme(mode: PaletteMode): ThemeOptions { input: { paddingLeft: 10, }, - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[100]} inset, 0 0 0 1px ${brand[200]}`, maxHeight: '4px', @@ -622,14 +673,7 @@ export default function getLPTheme(mode: PaletteMode): ThemeOptions { outlineOffset: '2px', borderColor: brand[400], }, - ...(ownerState.color === 'error' && { - borderColor: red[200], - color: red[500], - '& + .MuiFormHelperText-root': { - color: red[500], - }, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[900]} inset, 0 0 0 1px ${brand[600]}`, maxHeight: '6px', @@ -654,14 +698,28 @@ export default function getLPTheme(mode: PaletteMode): ThemeOptions { outline: `3px solid ${alpha(brand[500], 0.5)}`, outlineOffset: '2px', }, - ...(ownerState.color === 'error' && { - borderColor: red[700], - color: red[300], - '& + .MuiFormHelperText-root': { - color: red[300], - }, - }), }), + variants: [ + { + props: { + color: 'error', + }, + style: { + borderColor: red[200], + color: red[500], + '& + .MuiFormHelperText-root': { + color: red[500], + }, + ...theme.applyStyles('dark', { + borderColor: red[700], + color: red[300], + '& + .MuiFormHelperText-root': { + color: red[300], + }, + }), + }, + }, + ], }), }, }, @@ -703,7 +761,7 @@ export default function getLPTheme(mode: PaletteMode): ThemeOptions { height: 16, margin: 2, }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { width: 36, height: 24, padding: 0, @@ -746,7 +804,7 @@ export default function getLPTheme(mode: PaletteMode): ThemeOptions { '& .Mui-selected': { color: brand[500], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { '& .Mui-selected': { color: 'hsl(0, 0%, 100%)', }, @@ -762,7 +820,7 @@ export default function getLPTheme(mode: PaletteMode): ThemeOptions { textTransform: 'none', borderRadius: theme.shape.borderRadius, fontWeight: 500, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: gray[400], '&.Mui-selected': { color: brand[300] }, }), diff --git a/docs/data/material/getting-started/templates/sign-in-side/SignInCard.js b/docs/data/material/getting-started/templates/sign-in-side/SignInCard.js index 9c6c23678ee7b9..92d27a719c33fb 100644 --- a/docs/data/material/getting-started/templates/sign-in-side/SignInCard.js +++ b/docs/data/material/getting-started/templates/sign-in-side/SignInCard.js @@ -1,7 +1,7 @@ import * as React from 'react'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; -import Card from '@mui/material/Card'; +import { Card as MuiCard } from '@mui/material'; import Checkbox from '@mui/material/Checkbox'; import Divider from '@mui/material/Divider'; import FormLabel from '@mui/material/FormLabel'; @@ -11,9 +11,28 @@ import Link from '@mui/material/Link'; import TextField from '@mui/material/TextField'; import Typography from '@mui/material/Typography'; +import { styled } from '@mui/material/styles'; + import ForgotPassword from './ForgotPassword'; import { GoogleIcon, FacebookIcon, SitemarkIcon } from './CustomIcons'; +const Card = styled(MuiCard)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + alignSelf: 'center', + gap: theme.spacing(4), + width: '100%', + padding: theme.spacing(2), + boxShadow: + theme.palette.mode === 'light' + ? 'hsla(220, 30%, 5%, 0.05) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.05) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px' + : 'hsla(220, 30%, 5%, 0.5) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.08) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px', + [theme.breakpoints.up('sm')]: { + padding: theme.spacing(4), + width: '450px', + }, +})); + export default function SignInCard() { const [emailError, setEmailError] = React.useState(false); const [emailErrorMessage, setEmailErrorMessage] = React.useState(''); @@ -66,20 +85,7 @@ export default function SignInCard() { }; return ( - ({ - display: 'flex', - flexDirection: 'column', - alignSelf: 'center', - width: { xs: '100%', sm: '450px' }, - p: { xs: 2, sm: 4 }, - gap: 2, - boxShadow: - theme.palette.mode === 'light' - ? 'hsla(220, 30%, 5%, 0.05) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.05) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px' - : 'hsla(220, 30%, 5%, 0.5) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.08) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px', - })} - > + diff --git a/docs/data/material/getting-started/templates/sign-in-side/SignInCard.tsx b/docs/data/material/getting-started/templates/sign-in-side/SignInCard.tsx index 8697dcc3e042df..139b35c8ad4ad7 100644 --- a/docs/data/material/getting-started/templates/sign-in-side/SignInCard.tsx +++ b/docs/data/material/getting-started/templates/sign-in-side/SignInCard.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; -import Card from '@mui/material/Card'; +import { Card as MuiCard } from '@mui/material'; import Checkbox from '@mui/material/Checkbox'; import Divider from '@mui/material/Divider'; import FormLabel from '@mui/material/FormLabel'; @@ -11,9 +11,28 @@ import Link from '@mui/material/Link'; import TextField from '@mui/material/TextField'; import Typography from '@mui/material/Typography'; +import { styled } from '@mui/material/styles'; + import ForgotPassword from './ForgotPassword'; import { GoogleIcon, FacebookIcon, SitemarkIcon } from './CustomIcons'; +const Card = styled(MuiCard)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + alignSelf: 'center', + gap: theme.spacing(4), + width: '100%', + padding: theme.spacing(2), + boxShadow: + theme.palette.mode === 'light' + ? 'hsla(220, 30%, 5%, 0.05) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.05) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px' + : 'hsla(220, 30%, 5%, 0.5) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.08) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px', + [theme.breakpoints.up('sm')]: { + padding: theme.spacing(4), + width: '450px', + }, +})); + export default function SignInCard() { const [emailError, setEmailError] = React.useState(false); const [emailErrorMessage, setEmailErrorMessage] = React.useState(''); @@ -66,20 +85,7 @@ export default function SignInCard() { }; return ( - ({ - display: 'flex', - flexDirection: 'column', - alignSelf: 'center', - width: { xs: '100%', sm: '450px' }, - p: { xs: 2, sm: 4 }, - gap: 2, - boxShadow: - theme.palette.mode === 'light' - ? 'hsla(220, 30%, 5%, 0.05) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.05) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px' - : 'hsla(220, 30%, 5%, 0.5) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.08) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px', - })} - > + diff --git a/docs/data/material/getting-started/templates/sign-in-side/getSignInSideTheme.js b/docs/data/material/getting-started/templates/sign-in-side/getSignInSideTheme.js index e39de16cbf5e55..406f3df6e4fe32 100644 --- a/docs/data/material/getting-started/templates/sign-in-side/getSignInSideTheme.js +++ b/docs/data/material/getting-started/templates/sign-in-side/getSignInSideTheme.js @@ -213,156 +213,195 @@ export default function getSignInSideTheme(mode) { }, MuiButton: { styleOverrides: { - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ boxShadow: 'none', borderRadius: theme.shape.borderRadius, textTransform: 'none', - ...(ownerState.size === 'small' && { - height: '2rem', // 32px - padding: '0 0.5rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', // 40px - }), - ...(ownerState.variant === 'contained' && - ownerState.color === 'primary' && { - color: 'white', - backgroundColor: brand[300], - backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, - boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, - border: `1px solid ${brand[500]}`, - '&:hover': { - backgroundColor: brand[700], - boxShadow: 'none', + variants: [ + { + props: { + size: 'small', }, - '&:active': { - backgroundColor: brand[700], - boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + style: { + height: '2rem', // 32px + padding: '0 0.5rem', }, - }), - ...(ownerState.variant === 'outlined' && { - color: brand[700], - backgroundColor: alpha(brand[300], 0.1), - borderColor: alpha(brand[200], 0.8), - boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, - '&:hover': { - backgroundColor: alpha(brand[300], 0.2), - borderColor: alpha(brand[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(brand[300], 0.3), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, - backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - backgroundColor: alpha(gray[300], 0.1), - borderColor: alpha(gray[300], 0.5), - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), - borderColor: alpha(gray[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(gray[300], 0.4), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, - backgroundImage: 'none', + { + props: { + size: 'medium', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[700], - '&:hover': { - backgroundColor: alpha(brand[300], 0.3), + style: { + height: '2.5rem', // 40px }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), + }, + { + props: { + color: 'primary', + variant: 'contained', }, - }), - ...(theme.palette.mode === 'dark' && { - ...(ownerState.variant === 'outlined' && { - color: brand[200], - backgroundColor: alpha(brand[600], 0.1), - borderColor: alpha(brand[600], 0.6), - boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, - '&:hover': { - backgroundColor: alpha(brand[700], 0.2), - borderColor: alpha(brand[700], 0.5), - boxShadow: 'none', + style: { + color: 'white', + backgroundColor: brand[300], + backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, + boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, + border: `1px solid ${brand[500]}`, + '&:hover': { + backgroundColor: brand[700], + boxShadow: 'none', + }, + '&:active': { + backgroundColor: brand[700], + boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + }, }, - '&:active': { - backgroundColor: alpha(brand[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, - backgroundImage: 'none', + }, + { + props: { + variant: 'outlined', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[200], + style: { + color: brand[700], + backgroundColor: alpha(brand[300], 0.1), + borderColor: alpha(brand[200], 0.8), + boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, '&:hover': { - backgroundColor: alpha(gray[700], 0.3), + backgroundColor: alpha(brand[300], 0.2), + borderColor: alpha(brand[300], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[300], 0.3), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, + backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - color: gray[300], - backgroundColor: alpha(gray[600], 0.1), - borderColor: alpha(gray[700], 0.5), - boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + ...theme.applyStyles('dark', { + color: brand[200], + backgroundColor: alpha(brand[600], 0.1), + borderColor: alpha(brand[600], 0.6), + boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(brand[700], 0.2), + borderColor: alpha(brand[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'secondary', + variant: 'outlined', + }, + style: { + backgroundColor: alpha(gray[300], 0.1), + borderColor: alpha(gray[300], 0.5), + color: gray[700], '&:hover': { - backgroundColor: alpha(gray[700], 0.2), - borderColor: alpha(gray[700], 0.5), + backgroundColor: alpha(gray[300], 0.3), + borderColor: alpha(gray[300], 0.5), boxShadow: 'none', }, '&:active': { - backgroundColor: alpha(gray[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundColor: alpha(gray[300], 0.4), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[200], + ...theme.applyStyles('dark', { + color: gray[300], + backgroundColor: alpha(gray[600], 0.1), + borderColor: alpha(gray[700], 0.5), + boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(gray[700], 0.2), + borderColor: alpha(gray[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(gray[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'primary', + variant: 'text', + }, + style: { + color: brand[700], '&:hover': { - backgroundColor: alpha(brand[700], 0.3), + backgroundColor: alpha(brand[300], 0.3), }, - }), - }), + ...theme.applyStyles('dark', { + color: brand[200], + '&:hover': { + backgroundColor: alpha(brand[700], 0.3), + }, + }), + }, + }, + { + props: { + color: 'info', + variant: 'text', + }, + style: { + color: gray[700], + '&:hover': { + backgroundColor: alpha(gray[300], 0.3), + }, + ...theme.applyStyles('dark', { + color: gray[200], + '&:hover': { + backgroundColor: alpha(gray[700], 0.3), + }, + }), + }, + }, + ], }), }, }, MuiCard: { styleOverrides: { - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ transition: 'all 100ms ease', backgroundColor: gray[50], borderRadius: theme.shape.borderRadius, border: `1px solid ${alpha(gray[200], 0.5)}`, boxShadow: 'none', - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${gray[200]}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { backgroundColor: alpha(gray[800], 0.6), border: `1px solid ${alpha(gray[700], 0.3)}`, - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${alpha(gray[700], 0.4)}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( - gray[800], - 0.5, - )})`, - }), }), + variants: [ + { + props: { + variant: 'outlined', + }, + style: { + border: `1px solid ${gray[200]}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, + ...theme.applyStyles('dark', { + border: `1px solid ${alpha(gray[700], 0.4)}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( + gray[800], + 0.5, + )})`, + }), + }, + }, + ], }), }, }, @@ -404,7 +443,7 @@ export default function getSignInSideTheme(mode) { backgroundColor: brand[600], }, }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: alpha(gray[700], 0.5), boxShadow: '0 0 0 1.5px hsl(210, 0%, 0%) inset', backgroundColor: alpha(gray[900], 0.8), @@ -435,7 +474,7 @@ export default function getSignInSideTheme(mode) { styleOverrides: { root: ({ theme }) => ({ borderColor: `${alpha(gray[200], 0.8)}`, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: `${alpha(gray[700], 0.4)}`, }), }), @@ -451,27 +490,39 @@ export default function getSignInSideTheme(mode) { }, MuiIconButton: { styleOverrides: { - root: ({ theme, ownerState }) => ({ - ...(ownerState.size === 'small' && { - height: '2rem', - width: '2rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', - width: '2.5rem', - }), + root: ({ theme }) => ({ color: brand[500], '&:hover': { backgroundColor: alpha(brand[300], 0.3), borderColor: brand[200], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], '&:hover': { backgroundColor: alpha(brand[600], 0.3), borderColor: brand[700], }, }), + variants: [ + { + props: { + size: 'small', + }, + style: { + height: '2rem', + width: '2rem', + }, + }, + { + props: { + size: 'medium', + }, + style: { + height: '2.5rem', + width: '2.5rem', + }, + }, + ], }), }, }, @@ -512,7 +563,7 @@ export default function getSignInSideTheme(mode) { outlineOffset: '4px', borderRadius: '2px', }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], }), }), @@ -526,7 +577,7 @@ export default function getSignInSideTheme(mode) { input: { paddingLeft: 10, }, - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[100]} inset, 0 0 0 1px ${brand[200]}`, maxHeight: '4px', @@ -556,14 +607,7 @@ export default function getSignInSideTheme(mode) { outlineOffset: '2px', borderColor: brand[400], }, - ...(ownerState.color === 'error' && { - borderColor: red[200], - color: red[500], - '& + .MuiFormHelperText-root': { - color: red[500], - }, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[900]} inset, 0 0 0 1px ${brand[600]}`, maxHeight: '6px', @@ -588,14 +632,28 @@ export default function getSignInSideTheme(mode) { outline: `3px solid ${alpha(brand[500], 0.5)}`, outlineOffset: '2px', }, - ...(ownerState.color === 'error' && { - borderColor: red[700], - color: red[300], - '& + .MuiFormHelperText-root': { - color: red[300], - }, - }), }), + variants: [ + { + props: { + color: 'error', + }, + style: { + borderColor: red[200], + color: red[500], + '& + .MuiFormHelperText-root': { + color: red[500], + }, + ...theme.applyStyles('dark', { + borderColor: red[700], + color: red[300], + '& + .MuiFormHelperText-root': { + color: red[300], + }, + }), + }, + }, + ], }), }, }, @@ -617,7 +675,7 @@ export default function getSignInSideTheme(mode) { '& .Mui-selected': { color: brand[500], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { '& .Mui-selected': { color: 'hsl(0, 0%, 100%)', }, @@ -633,7 +691,7 @@ export default function getSignInSideTheme(mode) { textTransform: 'none', borderRadius: theme.shape.borderRadius, fontWeight: 500, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: gray[400], '&.Mui-selected': { color: brand[300] }, }), diff --git a/docs/data/material/getting-started/templates/sign-in-side/getSignInSideTheme.tsx b/docs/data/material/getting-started/templates/sign-in-side/getSignInSideTheme.tsx index 20e9329142a520..1fddb2216b0ddc 100644 --- a/docs/data/material/getting-started/templates/sign-in-side/getSignInSideTheme.tsx +++ b/docs/data/material/getting-started/templates/sign-in-side/getSignInSideTheme.tsx @@ -231,156 +231,195 @@ export default function getSignInSideTheme(mode: PaletteMode): ThemeOptions { }, MuiButton: { styleOverrides: { - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ boxShadow: 'none', borderRadius: theme.shape.borderRadius, textTransform: 'none', - ...(ownerState.size === 'small' && { - height: '2rem', // 32px - padding: '0 0.5rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', // 40px - }), - ...(ownerState.variant === 'contained' && - ownerState.color === 'primary' && { - color: 'white', - backgroundColor: brand[300], - backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, - boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, - border: `1px solid ${brand[500]}`, - '&:hover': { - backgroundColor: brand[700], - boxShadow: 'none', + variants: [ + { + props: { + size: 'small', }, - '&:active': { - backgroundColor: brand[700], - boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + style: { + height: '2rem', // 32px + padding: '0 0.5rem', }, - }), - ...(ownerState.variant === 'outlined' && { - color: brand[700], - backgroundColor: alpha(brand[300], 0.1), - borderColor: alpha(brand[200], 0.8), - boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, - '&:hover': { - backgroundColor: alpha(brand[300], 0.2), - borderColor: alpha(brand[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(brand[300], 0.3), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, - backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - backgroundColor: alpha(gray[300], 0.1), - borderColor: alpha(gray[300], 0.5), - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), - borderColor: alpha(gray[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(gray[300], 0.4), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, - backgroundImage: 'none', + { + props: { + size: 'medium', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[700], - '&:hover': { - backgroundColor: alpha(brand[300], 0.3), + style: { + height: '2.5rem', // 40px }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), + }, + { + props: { + color: 'primary', + variant: 'contained', }, - }), - ...(theme.palette.mode === 'dark' && { - ...(ownerState.variant === 'outlined' && { - color: brand[200], - backgroundColor: alpha(brand[600], 0.1), - borderColor: alpha(brand[600], 0.6), - boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, - '&:hover': { - backgroundColor: alpha(brand[700], 0.2), - borderColor: alpha(brand[700], 0.5), - boxShadow: 'none', + style: { + color: 'white', + backgroundColor: brand[300], + backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, + boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, + border: `1px solid ${brand[500]}`, + '&:hover': { + backgroundColor: brand[700], + boxShadow: 'none', + }, + '&:active': { + backgroundColor: brand[700], + boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + }, }, - '&:active': { - backgroundColor: alpha(brand[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, - backgroundImage: 'none', + }, + { + props: { + variant: 'outlined', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[200], + style: { + color: brand[700], + backgroundColor: alpha(brand[300], 0.1), + borderColor: alpha(brand[200], 0.8), + boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, '&:hover': { - backgroundColor: alpha(gray[700], 0.3), + backgroundColor: alpha(brand[300], 0.2), + borderColor: alpha(brand[300], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[300], 0.3), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, + backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - color: gray[300], - backgroundColor: alpha(gray[600], 0.1), - borderColor: alpha(gray[700], 0.5), - boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + ...theme.applyStyles('dark', { + color: brand[200], + backgroundColor: alpha(brand[600], 0.1), + borderColor: alpha(brand[600], 0.6), + boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(brand[700], 0.2), + borderColor: alpha(brand[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'secondary', + variant: 'outlined', + }, + style: { + backgroundColor: alpha(gray[300], 0.1), + borderColor: alpha(gray[300], 0.5), + color: gray[700], '&:hover': { - backgroundColor: alpha(gray[700], 0.2), - borderColor: alpha(gray[700], 0.5), + backgroundColor: alpha(gray[300], 0.3), + borderColor: alpha(gray[300], 0.5), boxShadow: 'none', }, '&:active': { - backgroundColor: alpha(gray[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundColor: alpha(gray[300], 0.4), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[200], + ...theme.applyStyles('dark', { + color: gray[300], + backgroundColor: alpha(gray[600], 0.1), + borderColor: alpha(gray[700], 0.5), + boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(gray[700], 0.2), + borderColor: alpha(gray[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(gray[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'primary', + variant: 'text', + }, + style: { + color: brand[700], '&:hover': { - backgroundColor: alpha(brand[700], 0.3), + backgroundColor: alpha(brand[300], 0.3), }, - }), - }), + ...theme.applyStyles('dark', { + color: brand[200], + '&:hover': { + backgroundColor: alpha(brand[700], 0.3), + }, + }), + }, + }, + { + props: { + color: 'info', + variant: 'text', + }, + style: { + color: gray[700], + '&:hover': { + backgroundColor: alpha(gray[300], 0.3), + }, + ...theme.applyStyles('dark', { + color: gray[200], + '&:hover': { + backgroundColor: alpha(gray[700], 0.3), + }, + }), + }, + }, + ], }), }, }, MuiCard: { styleOverrides: { - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ transition: 'all 100ms ease', backgroundColor: gray[50], borderRadius: theme.shape.borderRadius, border: `1px solid ${alpha(gray[200], 0.5)}`, boxShadow: 'none', - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${gray[200]}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { backgroundColor: alpha(gray[800], 0.6), border: `1px solid ${alpha(gray[700], 0.3)}`, - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${alpha(gray[700], 0.4)}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( - gray[800], - 0.5, - )})`, - }), }), + variants: [ + { + props: { + variant: 'outlined', + }, + style: { + border: `1px solid ${gray[200]}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, + ...theme.applyStyles('dark', { + border: `1px solid ${alpha(gray[700], 0.4)}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( + gray[800], + 0.5, + )})`, + }), + }, + }, + ], }), }, }, @@ -422,7 +461,7 @@ export default function getSignInSideTheme(mode: PaletteMode): ThemeOptions { backgroundColor: brand[600], }, }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: alpha(gray[700], 0.5), boxShadow: '0 0 0 1.5px hsl(210, 0%, 0%) inset', backgroundColor: alpha(gray[900], 0.8), @@ -453,7 +492,7 @@ export default function getSignInSideTheme(mode: PaletteMode): ThemeOptions { styleOverrides: { root: ({ theme }) => ({ borderColor: `${alpha(gray[200], 0.8)}`, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: `${alpha(gray[700], 0.4)}`, }), }), @@ -469,27 +508,39 @@ export default function getSignInSideTheme(mode: PaletteMode): ThemeOptions { }, MuiIconButton: { styleOverrides: { - root: ({ theme, ownerState }) => ({ - ...(ownerState.size === 'small' && { - height: '2rem', - width: '2rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', - width: '2.5rem', - }), + root: ({ theme }) => ({ color: brand[500], '&:hover': { backgroundColor: alpha(brand[300], 0.3), borderColor: brand[200], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], '&:hover': { backgroundColor: alpha(brand[600], 0.3), borderColor: brand[700], }, }), + variants: [ + { + props: { + size: 'small', + }, + style: { + height: '2rem', + width: '2rem', + }, + }, + { + props: { + size: 'medium', + }, + style: { + height: '2.5rem', + width: '2.5rem', + }, + }, + ], }), }, }, @@ -530,7 +581,7 @@ export default function getSignInSideTheme(mode: PaletteMode): ThemeOptions { outlineOffset: '4px', borderRadius: '2px', }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], }), }), @@ -544,7 +595,7 @@ export default function getSignInSideTheme(mode: PaletteMode): ThemeOptions { input: { paddingLeft: 10, }, - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[100]} inset, 0 0 0 1px ${brand[200]}`, maxHeight: '4px', @@ -574,14 +625,7 @@ export default function getSignInSideTheme(mode: PaletteMode): ThemeOptions { outlineOffset: '2px', borderColor: brand[400], }, - ...(ownerState.color === 'error' && { - borderColor: red[200], - color: red[500], - '& + .MuiFormHelperText-root': { - color: red[500], - }, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[900]} inset, 0 0 0 1px ${brand[600]}`, maxHeight: '6px', @@ -606,14 +650,28 @@ export default function getSignInSideTheme(mode: PaletteMode): ThemeOptions { outline: `3px solid ${alpha(brand[500], 0.5)}`, outlineOffset: '2px', }, - ...(ownerState.color === 'error' && { - borderColor: red[700], - color: red[300], - '& + .MuiFormHelperText-root': { - color: red[300], - }, - }), }), + variants: [ + { + props: { + color: 'error', + }, + style: { + borderColor: red[200], + color: red[500], + '& + .MuiFormHelperText-root': { + color: red[500], + }, + ...theme.applyStyles('dark', { + borderColor: red[700], + color: red[300], + '& + .MuiFormHelperText-root': { + color: red[300], + }, + }), + }, + }, + ], }), }, }, @@ -635,7 +693,7 @@ export default function getSignInSideTheme(mode: PaletteMode): ThemeOptions { '& .Mui-selected': { color: brand[500], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { '& .Mui-selected': { color: 'hsl(0, 0%, 100%)', }, @@ -651,7 +709,7 @@ export default function getSignInSideTheme(mode: PaletteMode): ThemeOptions { textTransform: 'none', borderRadius: theme.shape.borderRadius, fontWeight: 500, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: gray[400], '&.Mui-selected': { color: brand[300] }, }), diff --git a/docs/data/material/getting-started/templates/sign-in/SignIn.js b/docs/data/material/getting-started/templates/sign-in/SignIn.js index 8398bfef899d8f..ba53cf3e9ddf2a 100644 --- a/docs/data/material/getting-started/templates/sign-in/SignIn.js +++ b/docs/data/material/getting-started/templates/sign-in/SignIn.js @@ -2,7 +2,6 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; -import Card from '@mui/material/Card'; import Checkbox from '@mui/material/Checkbox'; import CssBaseline from '@mui/material/CssBaseline'; import FormControlLabel from '@mui/material/FormControlLabel'; @@ -15,8 +14,8 @@ import ToggleButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import Typography from '@mui/material/Typography'; import Stack from '@mui/material/Stack'; - -import { ThemeProvider, createTheme } from '@mui/material/styles'; +import { Card as MuiCard } from '@mui/material'; +import { ThemeProvider, createTheme, styled } from '@mui/material/styles'; import ArrowBackRoundedIcon from '@mui/icons-material/ArrowBackRounded'; import AutoAwesomeRoundedIcon from '@mui/icons-material/AutoAwesomeRounded'; @@ -68,6 +67,37 @@ ToggleCustomTheme.propTypes = { toggleCustomTheme: PropTypes.func.isRequired, }; +const Card = styled(MuiCard)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + alignSelf: 'center', + gap: theme.spacing(4), + width: '100%', + padding: theme.spacing(2), + boxShadow: + theme.palette.mode === 'light' + ? 'hsla(220, 30%, 5%, 0.05) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.05) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px' + : 'hsla(220, 30%, 5%, 0.5) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.08) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px', + [theme.breakpoints.up('sm')]: { + padding: theme.spacing(4), + width: '450px', + }, +})); + +const SignInContainer = styled(Stack)(({ theme }) => ({ + height: 'auto', + padingBottom: theme.spacing(12), + backgroundImage: + theme.palette.mode === 'light' + ? 'radial-gradient(ellipse at 50% 50%, hsl(210, 100%, 97%), hsl(0, 0%, 100%))' + : 'radial-gradient(at 50% 50%, hsla(210, 100%, 16%, 0.3), hsl(220, 30%, 5%))', + backgroundRepeat: 'no-repeat', + [theme.breakpoints.up('sm')]: { + paddingBottom: 0, + height: '100dvh', + }, +})); + export default function SignIn() { const [mode, setMode] = React.useState('light'); const [showCustomTheme, setShowCustomTheme] = React.useState(true); @@ -134,20 +164,7 @@ export default function SignIn() { return ( - ({ - backgroundImage: - theme.palette.mode === 'light' - ? 'radial-gradient(ellipse at 50% 50%, hsl(210, 100%, 97%), hsl(0, 0%, 100%))' - : 'radial-gradient(at 50% 50%, hsla(210, 100%, 16%, 0.3), hsl(220, 30%, 5%))', - backgroundRepeat: 'no-repeat', - height: { xs: 'auto', sm: '100dvh' }, - pb: { xs: 12, sm: 0 }, - })} - component="main" - > + - ({ - display: 'flex', - flexDirection: 'column', - alignSelf: 'center', - width: { xs: '100%', sm: '450px' }, - p: { xs: 2, sm: 4 }, - gap: 4, - boxShadow: - theme.palette.mode === 'light' - ? 'hsla(220, 30%, 5%, 0.05) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.05) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px' - : 'hsla(220, 30%, 5%, 0.5) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.08) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px', - })} - > + - + ({ + display: 'flex', + flexDirection: 'column', + alignSelf: 'center', + gap: theme.spacing(4), + width: '100%', + padding: theme.spacing(2), + boxShadow: + theme.palette.mode === 'light' + ? 'hsla(220, 30%, 5%, 0.05) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.05) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px' + : 'hsla(220, 30%, 5%, 0.5) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.08) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px', + [theme.breakpoints.up('sm')]: { + padding: theme.spacing(4), + width: '450px', + }, +})); + +const SignInContainer = styled(Stack)(({ theme }) => ({ + height: 'auto', + padingBottom: theme.spacing(12), + backgroundImage: + theme.palette.mode === 'light' + ? 'radial-gradient(ellipse at 50% 50%, hsl(210, 100%, 97%), hsl(0, 0%, 100%))' + : 'radial-gradient(at 50% 50%, hsla(210, 100%, 16%, 0.3), hsl(220, 30%, 5%))', + backgroundRepeat: 'no-repeat', + [theme.breakpoints.up('sm')]: { + paddingBottom: 0, + height: '100dvh', + }, +})); + export default function SignIn() { const [mode, setMode] = React.useState('light'); const [showCustomTheme, setShowCustomTheme] = React.useState(true); @@ -134,20 +164,7 @@ export default function SignIn() { return ( - ({ - backgroundImage: - theme.palette.mode === 'light' - ? 'radial-gradient(ellipse at 50% 50%, hsl(210, 100%, 97%), hsl(0, 0%, 100%))' - : 'radial-gradient(at 50% 50%, hsla(210, 100%, 16%, 0.3), hsl(220, 30%, 5%))', - backgroundRepeat: 'no-repeat', - height: { xs: 'auto', sm: '100dvh' }, - pb: { xs: 12, sm: 0 }, - })} - component="main" - > + - ({ - display: 'flex', - flexDirection: 'column', - alignSelf: 'center', - width: { xs: '100%', sm: '450px' }, - p: { xs: 2, sm: 4 }, - gap: 4, - boxShadow: - theme.palette.mode === 'light' - ? 'hsla(220, 30%, 5%, 0.05) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.05) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px' - : 'hsla(220, 30%, 5%, 0.5) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.08) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px', - })} - > + - + ({ + root: ({ theme }) => ({ boxShadow: 'none', borderRadius: theme.shape.borderRadius, textTransform: 'none', - ...(ownerState.size === 'small' && { - height: '2rem', // 32px - padding: '0 0.5rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', // 40px - }), - ...(ownerState.variant === 'contained' && - ownerState.color === 'primary' && { - color: 'white', - backgroundColor: brand[300], - backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, - boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, - border: `1px solid ${brand[500]}`, - '&:hover': { - backgroundColor: brand[700], - boxShadow: 'none', + variants: [ + { + props: { + size: 'small', }, - '&:active': { - backgroundColor: brand[700], - boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + style: { + height: '2rem', // 32px + padding: '0 0.5rem', }, - }), - ...(ownerState.variant === 'outlined' && { - color: brand[700], - backgroundColor: alpha(brand[300], 0.1), - borderColor: alpha(brand[200], 0.8), - boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, - '&:hover': { - backgroundColor: alpha(brand[300], 0.2), - borderColor: alpha(brand[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(brand[300], 0.3), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, - backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - backgroundColor: alpha(gray[300], 0.1), - borderColor: alpha(gray[300], 0.5), - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), - borderColor: alpha(gray[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(gray[300], 0.4), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, - backgroundImage: 'none', + { + props: { + size: 'medium', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[700], - '&:hover': { - backgroundColor: alpha(brand[300], 0.3), + style: { + height: '2.5rem', // 40px }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), + }, + { + props: { + color: 'primary', + variant: 'contained', }, - }), - ...(theme.palette.mode === 'dark' && { - ...(ownerState.variant === 'outlined' && { - color: brand[200], - backgroundColor: alpha(brand[600], 0.1), - borderColor: alpha(brand[600], 0.6), - boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, - '&:hover': { - backgroundColor: alpha(brand[700], 0.2), - borderColor: alpha(brand[700], 0.5), - boxShadow: 'none', + style: { + color: 'white', + backgroundColor: brand[300], + backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, + boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, + border: `1px solid ${brand[500]}`, + '&:hover': { + backgroundColor: brand[700], + boxShadow: 'none', + }, + '&:active': { + backgroundColor: brand[700], + boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + }, }, - '&:active': { - backgroundColor: alpha(brand[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, - backgroundImage: 'none', + }, + { + props: { + variant: 'outlined', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[200], + style: { + color: brand[700], + backgroundColor: alpha(brand[300], 0.1), + borderColor: alpha(brand[200], 0.8), + boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, '&:hover': { - backgroundColor: alpha(gray[700], 0.3), + backgroundColor: alpha(brand[300], 0.2), + borderColor: alpha(brand[300], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[300], 0.3), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, + backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - color: gray[300], - backgroundColor: alpha(gray[600], 0.1), - borderColor: alpha(gray[700], 0.5), - boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + ...theme.applyStyles('dark', { + color: brand[200], + backgroundColor: alpha(brand[600], 0.1), + borderColor: alpha(brand[600], 0.6), + boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(brand[700], 0.2), + borderColor: alpha(brand[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'secondary', + variant: 'outlined', + }, + style: { + backgroundColor: alpha(gray[300], 0.1), + borderColor: alpha(gray[300], 0.5), + color: gray[700], '&:hover': { - backgroundColor: alpha(gray[700], 0.2), - borderColor: alpha(gray[700], 0.5), + backgroundColor: alpha(gray[300], 0.3), + borderColor: alpha(gray[300], 0.5), boxShadow: 'none', }, '&:active': { - backgroundColor: alpha(gray[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundColor: alpha(gray[300], 0.4), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[200], + ...theme.applyStyles('dark', { + color: gray[300], + backgroundColor: alpha(gray[600], 0.1), + borderColor: alpha(gray[700], 0.5), + boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(gray[700], 0.2), + borderColor: alpha(gray[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(gray[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'primary', + variant: 'text', + }, + style: { + color: brand[700], '&:hover': { - backgroundColor: alpha(brand[700], 0.3), + backgroundColor: alpha(brand[300], 0.3), }, - }), - }), + ...theme.applyStyles('dark', { + color: brand[200], + '&:hover': { + backgroundColor: alpha(brand[700], 0.3), + }, + }), + }, + }, + { + props: { + color: 'info', + variant: 'text', + }, + style: { + color: gray[700], + '&:hover': { + backgroundColor: alpha(gray[300], 0.3), + }, + ...theme.applyStyles('dark', { + color: gray[200], + '&:hover': { + backgroundColor: alpha(gray[700], 0.3), + }, + }), + }, + }, + ], }), }, }, MuiCard: { styleOverrides: { - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ backgroundColor: gray[50], borderRadius: theme.shape.borderRadius, border: `1px solid ${alpha(gray[200], 0.1)}`, boxShadow: 'none', - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${alpha(gray[200], 0.5)}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { backgroundColor: alpha(gray[800], 0.6), border: `1px solid ${alpha(gray[700], 0.2)}`, - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${alpha(gray[700], 0.4)}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( - gray[800], - 0.5, - )})`, - }), }), + variants: [ + { + props: { + variant: 'outlined', + }, + style: { + border: `1px solid ${alpha(gray[200], 0.5)}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, + ...theme.applyStyles('dark', { + border: `1px solid ${alpha(gray[700], 0.4)}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( + gray[800], + 0.5, + )})`, + }), + }, + }, + ], }), }, }, @@ -403,7 +442,7 @@ export default function getSignInTheme(mode) { backgroundColor: brand[600], }, }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: alpha(gray[700], 0.5), boxShadow: '0 0 0 1.5px hsl(210, 0%, 0%) inset', backgroundColor: alpha(gray[900], 0.8), @@ -434,7 +473,7 @@ export default function getSignInTheme(mode) { styleOverrides: { root: ({ theme }) => ({ borderColor: `${alpha(gray[200], 0.8)}`, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: `${alpha(gray[700], 0.4)}`, }), }), @@ -450,27 +489,39 @@ export default function getSignInTheme(mode) { }, MuiIconButton: { styleOverrides: { - root: ({ theme, ownerState }) => ({ - ...(ownerState.size === 'small' && { - height: '2rem', - width: '2rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', - width: '2.5rem', - }), + root: ({ theme }) => ({ color: brand[500], '&:hover': { backgroundColor: alpha(brand[300], 0.3), borderColor: brand[200], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], '&:hover': { backgroundColor: alpha(brand[600], 0.3), borderColor: brand[700], }, }), + variants: [ + { + props: { + size: 'small', + }, + style: { + height: '2rem', + width: '2rem', + }, + }, + { + props: { + size: 'medium', + }, + style: { + height: '2.5rem', + width: '2.5rem', + }, + }, + ], }), }, }, @@ -511,7 +562,7 @@ export default function getSignInTheme(mode) { outlineOffset: '4px', borderRadius: '2px', }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], }), }), @@ -525,7 +576,7 @@ export default function getSignInTheme(mode) { input: { paddingLeft: 10, }, - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[100]} inset, 0 0 0 1px ${brand[200]}`, maxHeight: '4px', @@ -555,14 +606,7 @@ export default function getSignInTheme(mode) { outlineOffset: '2px', borderColor: brand[400], }, - ...(ownerState.color === 'error' && { - borderColor: red[200], - color: red[500], - '& + .MuiFormHelperText-root': { - color: red[500], - }, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[900]} inset, 0 0 0 1px ${brand[600]}`, maxHeight: '6px', @@ -587,14 +631,28 @@ export default function getSignInTheme(mode) { outline: `3px solid ${alpha(brand[500], 0.5)}`, outlineOffset: '2px', }, - ...(ownerState.color === 'error' && { - borderColor: red[700], - color: red[300], - '& + .MuiFormHelperText-root': { - color: red[300], - }, - }), }), + variants: [ + { + props: { + color: 'error', + }, + style: { + borderColor: red[200], + color: red[500], + '& + .MuiFormHelperText-root': { + color: red[500], + }, + ...theme.applyStyles('dark', { + borderColor: red[700], + color: red[300], + '& + .MuiFormHelperText-root': { + color: red[300], + }, + }), + }, + }, + ], }), }, }, @@ -616,7 +674,7 @@ export default function getSignInTheme(mode) { '& .Mui-selected': { color: brand[500], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { '& .Mui-selected': { color: 'hsl(0, 0%, 100%)', }, @@ -632,7 +690,7 @@ export default function getSignInTheme(mode) { textTransform: 'none', borderRadius: theme.shape.borderRadius, fontWeight: 500, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: gray[400], '&.Mui-selected': { color: brand[300] }, }), diff --git a/docs/data/material/getting-started/templates/sign-in/getSignInTheme.tsx b/docs/data/material/getting-started/templates/sign-in/getSignInTheme.tsx index 4c655afff4d56c..75952ee86f3428 100644 --- a/docs/data/material/getting-started/templates/sign-in/getSignInTheme.tsx +++ b/docs/data/material/getting-started/templates/sign-in/getSignInTheme.tsx @@ -231,155 +231,194 @@ export default function getSignInTheme(mode: PaletteMode): ThemeOptions { }, MuiButton: { styleOverrides: { - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ boxShadow: 'none', borderRadius: theme.shape.borderRadius, textTransform: 'none', - ...(ownerState.size === 'small' && { - height: '2rem', // 32px - padding: '0 0.5rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', // 40px - }), - ...(ownerState.variant === 'contained' && - ownerState.color === 'primary' && { - color: 'white', - backgroundColor: brand[300], - backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, - boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, - border: `1px solid ${brand[500]}`, - '&:hover': { - backgroundColor: brand[700], - boxShadow: 'none', + variants: [ + { + props: { + size: 'small', }, - '&:active': { - backgroundColor: brand[700], - boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + style: { + height: '2rem', // 32px + padding: '0 0.5rem', }, - }), - ...(ownerState.variant === 'outlined' && { - color: brand[700], - backgroundColor: alpha(brand[300], 0.1), - borderColor: alpha(brand[200], 0.8), - boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, - '&:hover': { - backgroundColor: alpha(brand[300], 0.2), - borderColor: alpha(brand[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(brand[300], 0.3), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, - backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - backgroundColor: alpha(gray[300], 0.1), - borderColor: alpha(gray[300], 0.5), - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), - borderColor: alpha(gray[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(gray[300], 0.4), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, - backgroundImage: 'none', + { + props: { + size: 'medium', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[700], - '&:hover': { - backgroundColor: alpha(brand[300], 0.3), + style: { + height: '2.5rem', // 40px }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), + }, + { + props: { + color: 'primary', + variant: 'contained', }, - }), - ...(theme.palette.mode === 'dark' && { - ...(ownerState.variant === 'outlined' && { - color: brand[200], - backgroundColor: alpha(brand[600], 0.1), - borderColor: alpha(brand[600], 0.6), - boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, - '&:hover': { - backgroundColor: alpha(brand[700], 0.2), - borderColor: alpha(brand[700], 0.5), - boxShadow: 'none', + style: { + color: 'white', + backgroundColor: brand[300], + backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, + boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, + border: `1px solid ${brand[500]}`, + '&:hover': { + backgroundColor: brand[700], + boxShadow: 'none', + }, + '&:active': { + backgroundColor: brand[700], + boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + }, }, - '&:active': { - backgroundColor: alpha(brand[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, - backgroundImage: 'none', + }, + { + props: { + variant: 'outlined', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[200], + style: { + color: brand[700], + backgroundColor: alpha(brand[300], 0.1), + borderColor: alpha(brand[200], 0.8), + boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, '&:hover': { - backgroundColor: alpha(gray[700], 0.3), + backgroundColor: alpha(brand[300], 0.2), + borderColor: alpha(brand[300], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[300], 0.3), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, + backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - color: gray[300], - backgroundColor: alpha(gray[600], 0.1), - borderColor: alpha(gray[700], 0.5), - boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + ...theme.applyStyles('dark', { + color: brand[200], + backgroundColor: alpha(brand[600], 0.1), + borderColor: alpha(brand[600], 0.6), + boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(brand[700], 0.2), + borderColor: alpha(brand[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'secondary', + variant: 'outlined', + }, + style: { + backgroundColor: alpha(gray[300], 0.1), + borderColor: alpha(gray[300], 0.5), + color: gray[700], '&:hover': { - backgroundColor: alpha(gray[700], 0.2), - borderColor: alpha(gray[700], 0.5), + backgroundColor: alpha(gray[300], 0.3), + borderColor: alpha(gray[300], 0.5), boxShadow: 'none', }, '&:active': { - backgroundColor: alpha(gray[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundColor: alpha(gray[300], 0.4), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[200], + ...theme.applyStyles('dark', { + color: gray[300], + backgroundColor: alpha(gray[600], 0.1), + borderColor: alpha(gray[700], 0.5), + boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(gray[700], 0.2), + borderColor: alpha(gray[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(gray[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'primary', + variant: 'text', + }, + style: { + color: brand[700], '&:hover': { - backgroundColor: alpha(brand[700], 0.3), + backgroundColor: alpha(brand[300], 0.3), }, - }), - }), + ...theme.applyStyles('dark', { + color: brand[200], + '&:hover': { + backgroundColor: alpha(brand[700], 0.3), + }, + }), + }, + }, + { + props: { + color: 'info', + variant: 'text', + }, + style: { + color: gray[700], + '&:hover': { + backgroundColor: alpha(gray[300], 0.3), + }, + ...theme.applyStyles('dark', { + color: gray[200], + '&:hover': { + backgroundColor: alpha(gray[700], 0.3), + }, + }), + }, + }, + ], }), }, }, MuiCard: { styleOverrides: { - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ backgroundColor: gray[50], borderRadius: theme.shape.borderRadius, border: `1px solid ${alpha(gray[200], 0.1)}`, boxShadow: 'none', - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${alpha(gray[200], 0.5)}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { backgroundColor: alpha(gray[800], 0.6), border: `1px solid ${alpha(gray[700], 0.2)}`, - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${alpha(gray[700], 0.4)}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( - gray[800], - 0.5, - )})`, - }), }), + variants: [ + { + props: { + variant: 'outlined', + }, + style: { + border: `1px solid ${alpha(gray[200], 0.5)}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, + ...theme.applyStyles('dark', { + border: `1px solid ${alpha(gray[700], 0.4)}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( + gray[800], + 0.5, + )})`, + }), + }, + }, + ], }), }, }, @@ -421,7 +460,7 @@ export default function getSignInTheme(mode: PaletteMode): ThemeOptions { backgroundColor: brand[600], }, }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: alpha(gray[700], 0.5), boxShadow: '0 0 0 1.5px hsl(210, 0%, 0%) inset', backgroundColor: alpha(gray[900], 0.8), @@ -452,7 +491,7 @@ export default function getSignInTheme(mode: PaletteMode): ThemeOptions { styleOverrides: { root: ({ theme }) => ({ borderColor: `${alpha(gray[200], 0.8)}`, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: `${alpha(gray[700], 0.4)}`, }), }), @@ -468,27 +507,39 @@ export default function getSignInTheme(mode: PaletteMode): ThemeOptions { }, MuiIconButton: { styleOverrides: { - root: ({ theme, ownerState }) => ({ - ...(ownerState.size === 'small' && { - height: '2rem', - width: '2rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', - width: '2.5rem', - }), + root: ({ theme }) => ({ color: brand[500], '&:hover': { backgroundColor: alpha(brand[300], 0.3), borderColor: brand[200], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], '&:hover': { backgroundColor: alpha(brand[600], 0.3), borderColor: brand[700], }, }), + variants: [ + { + props: { + size: 'small', + }, + style: { + height: '2rem', + width: '2rem', + }, + }, + { + props: { + size: 'medium', + }, + style: { + height: '2.5rem', + width: '2.5rem', + }, + }, + ], }), }, }, @@ -529,7 +580,7 @@ export default function getSignInTheme(mode: PaletteMode): ThemeOptions { outlineOffset: '4px', borderRadius: '2px', }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], }), }), @@ -543,7 +594,7 @@ export default function getSignInTheme(mode: PaletteMode): ThemeOptions { input: { paddingLeft: 10, }, - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[100]} inset, 0 0 0 1px ${brand[200]}`, maxHeight: '4px', @@ -573,14 +624,7 @@ export default function getSignInTheme(mode: PaletteMode): ThemeOptions { outlineOffset: '2px', borderColor: brand[400], }, - ...(ownerState.color === 'error' && { - borderColor: red[200], - color: red[500], - '& + .MuiFormHelperText-root': { - color: red[500], - }, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[900]} inset, 0 0 0 1px ${brand[600]}`, maxHeight: '6px', @@ -605,14 +649,28 @@ export default function getSignInTheme(mode: PaletteMode): ThemeOptions { outline: `3px solid ${alpha(brand[500], 0.5)}`, outlineOffset: '2px', }, - ...(ownerState.color === 'error' && { - borderColor: red[700], - color: red[300], - '& + .MuiFormHelperText-root': { - color: red[300], - }, - }), }), + variants: [ + { + props: { + color: 'error', + }, + style: { + borderColor: red[200], + color: red[500], + '& + .MuiFormHelperText-root': { + color: red[500], + }, + ...theme.applyStyles('dark', { + borderColor: red[700], + color: red[300], + '& + .MuiFormHelperText-root': { + color: red[300], + }, + }), + }, + }, + ], }), }, }, @@ -634,7 +692,7 @@ export default function getSignInTheme(mode: PaletteMode): ThemeOptions { '& .Mui-selected': { color: brand[500], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { '& .Mui-selected': { color: 'hsl(0, 0%, 100%)', }, @@ -650,7 +708,7 @@ export default function getSignInTheme(mode: PaletteMode): ThemeOptions { textTransform: 'none', borderRadius: theme.shape.borderRadius, fontWeight: 500, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: gray[400], '&.Mui-selected': { color: brand[300] }, }), diff --git a/docs/data/material/getting-started/templates/sign-up/SignUp.js b/docs/data/material/getting-started/templates/sign-up/SignUp.js index ecf2c3aa9fbf5c..3eec4e23b1b03c 100644 --- a/docs/data/material/getting-started/templates/sign-up/SignUp.js +++ b/docs/data/material/getting-started/templates/sign-up/SignUp.js @@ -2,7 +2,6 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; -import Card from '@mui/material/Card'; import Checkbox from '@mui/material/Checkbox'; import CssBaseline from '@mui/material/CssBaseline'; import Divider from '@mui/material/Divider'; @@ -15,8 +14,8 @@ import ToggleButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import Typography from '@mui/material/Typography'; import Stack from '@mui/material/Stack'; - -import { createTheme, ThemeProvider } from '@mui/material/styles'; +import { Card as MuiCard } from '@mui/material'; +import { createTheme, ThemeProvider, styled } from '@mui/material/styles'; import AutoAwesomeRoundedIcon from '@mui/icons-material/AutoAwesomeRounded'; import ArrowBackRoundedIcon from '@mui/icons-material/ArrowBackRounded'; @@ -67,6 +66,37 @@ ToggleCustomTheme.propTypes = { toggleCustomTheme: PropTypes.func.isRequired, }; +const Card = styled(MuiCard)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + alignSelf: 'center', + gap: theme.spacing(4), + width: '100%', + padding: theme.spacing(2), + boxShadow: + theme.palette.mode === 'light' + ? 'hsla(220, 30%, 5%, 0.05) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.05) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px' + : 'hsla(220, 30%, 5%, 0.5) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.08) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px', + [theme.breakpoints.up('sm')]: { + padding: theme.spacing(4), + width: '450px', + }, +})); + +const SignUpContainer = styled(Stack)(({ theme }) => ({ + height: 'auto', + padingBottom: theme.spacing(12), + backgroundImage: + theme.palette.mode === 'light' + ? 'radial-gradient(ellipse at 50% 50%, hsl(210, 100%, 97%), hsl(0, 0%, 100%))' + : 'radial-gradient(at 50% 50%, hsla(210, 100%, 16%, 0.3), hsl(220, 30%, 5%))', + backgroundRepeat: 'no-repeat', + [theme.breakpoints.up('sm')]: { + paddingBottom: 0, + height: '100dvh', + }, +})); + export default function SignUp() { const [mode, setMode] = React.useState('light'); const [showCustomTheme, setShowCustomTheme] = React.useState(true); @@ -138,19 +168,7 @@ export default function SignUp() { return ( - ({ - backgroundRepeat: 'no-repeat', - backgroundImage: - theme.palette.mode === 'light' - ? 'radial-gradient(ellipse at 50% 50%, hsl(210, 100%, 97%), hsl(0, 0%, 100%))' - : 'radial-gradient(at 50% 50%, hsla(210, 100%, 16%, 0.3), hsl(220, 30%, 5%))', - pb: { xs: 12, sm: 0 }, - })} - > + - ({ - display: 'flex', - flexDirection: 'column', - alignSelf: 'center', - width: { xs: '100%', sm: '450px' }, - p: { xs: 2, sm: 4 }, - gap: 4, - boxShadow: - theme.palette.mode === 'light' - ? 'hsla(220, 30%, 5%, 0.05) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.05) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px' - : 'hsla(220, 30%, 5%, 0.5) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.08) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px', - })} - > + - + ({ + display: 'flex', + flexDirection: 'column', + alignSelf: 'center', + gap: theme.spacing(4), + width: '100%', + padding: theme.spacing(2), + boxShadow: + theme.palette.mode === 'light' + ? 'hsla(220, 30%, 5%, 0.05) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.05) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px' + : 'hsla(220, 30%, 5%, 0.5) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.08) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px', + [theme.breakpoints.up('sm')]: { + padding: theme.spacing(4), + width: '450px', + }, +})); + +const SignUpContainer = styled(Stack)(({ theme }) => ({ + height: 'auto', + padingBottom: theme.spacing(12), + backgroundImage: + theme.palette.mode === 'light' + ? 'radial-gradient(ellipse at 50% 50%, hsl(210, 100%, 97%), hsl(0, 0%, 100%))' + : 'radial-gradient(at 50% 50%, hsla(210, 100%, 16%, 0.3), hsl(220, 30%, 5%))', + backgroundRepeat: 'no-repeat', + [theme.breakpoints.up('sm')]: { + paddingBottom: 0, + height: '100dvh', + }, +})); + export default function SignUp() { const [mode, setMode] = React.useState('light'); const [showCustomTheme, setShowCustomTheme] = React.useState(true); @@ -138,19 +168,7 @@ export default function SignUp() { return ( - ({ - backgroundRepeat: 'no-repeat', - backgroundImage: - theme.palette.mode === 'light' - ? 'radial-gradient(ellipse at 50% 50%, hsl(210, 100%, 97%), hsl(0, 0%, 100%))' - : 'radial-gradient(at 50% 50%, hsla(210, 100%, 16%, 0.3), hsl(220, 30%, 5%))', - pb: { xs: 12, sm: 0 }, - })} - > + - ({ - display: 'flex', - flexDirection: 'column', - alignSelf: 'center', - width: { xs: '100%', sm: '450px' }, - p: { xs: 2, sm: 4 }, - gap: 4, - boxShadow: - theme.palette.mode === 'light' - ? 'hsla(220, 30%, 5%, 0.05) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.05) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px' - : 'hsla(220, 30%, 5%, 0.5) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.08) 0px 15px 35px -5px, hsla(220, 30%, 5%, 0.05) 0px 0px 0px 1px', - })} - > + - + ({ + root: ({ theme }) => ({ boxShadow: 'none', borderRadius: theme.shape.borderRadius, textTransform: 'none', - ...(ownerState.size === 'small' && { - height: '2rem', // 32px - padding: '0 0.5rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', // 40px - }), - ...(ownerState.variant === 'contained' && - ownerState.color === 'primary' && { - color: 'white', - backgroundColor: brand[300], - backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, - boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, - border: `1px solid ${brand[500]}`, - '&:hover': { - backgroundColor: brand[700], - boxShadow: 'none', + variants: [ + { + props: { + size: 'small', }, - '&:active': { - backgroundColor: brand[700], - boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + style: { + height: '2rem', // 32px + padding: '0 0.5rem', }, - }), - ...(ownerState.variant === 'outlined' && { - color: brand[700], - backgroundColor: alpha(brand[300], 0.1), - borderColor: alpha(brand[200], 0.8), - boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, - '&:hover': { - backgroundColor: alpha(brand[300], 0.2), - borderColor: alpha(brand[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(brand[300], 0.3), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, - backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - backgroundColor: alpha(gray[300], 0.1), - borderColor: alpha(gray[300], 0.5), - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), - borderColor: alpha(gray[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(gray[300], 0.4), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, - backgroundImage: 'none', + { + props: { + size: 'medium', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[700], - '&:hover': { - backgroundColor: alpha(brand[300], 0.3), + style: { + height: '2.5rem', // 40px }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), + }, + { + props: { + color: 'primary', + variant: 'contained', }, - }), - ...(theme.palette.mode === 'dark' && { - ...(ownerState.variant === 'outlined' && { - color: brand[200], - backgroundColor: alpha(brand[600], 0.1), - borderColor: alpha(brand[600], 0.6), - boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, - '&:hover': { - backgroundColor: alpha(brand[700], 0.2), - borderColor: alpha(brand[700], 0.5), - boxShadow: 'none', + style: { + color: 'white', + backgroundColor: brand[300], + backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, + boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, + border: `1px solid ${brand[500]}`, + '&:hover': { + backgroundColor: brand[700], + boxShadow: 'none', + }, + '&:active': { + backgroundColor: brand[700], + boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + }, }, - '&:active': { - backgroundColor: alpha(brand[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, - backgroundImage: 'none', + }, + { + props: { + variant: 'outlined', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[200], + style: { + color: brand[700], + backgroundColor: alpha(brand[300], 0.1), + borderColor: alpha(brand[200], 0.8), + boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, '&:hover': { - backgroundColor: alpha(gray[700], 0.3), + backgroundColor: alpha(brand[300], 0.2), + borderColor: alpha(brand[300], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[300], 0.3), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, + backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - color: gray[300], - backgroundColor: alpha(gray[600], 0.1), - borderColor: alpha(gray[700], 0.5), - boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + ...theme.applyStyles('dark', { + color: brand[200], + backgroundColor: alpha(brand[600], 0.1), + borderColor: alpha(brand[600], 0.6), + boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(brand[700], 0.2), + borderColor: alpha(brand[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'secondary', + variant: 'outlined', + }, + style: { + backgroundColor: alpha(gray[300], 0.1), + borderColor: alpha(gray[300], 0.5), + color: gray[700], '&:hover': { - backgroundColor: alpha(gray[700], 0.2), - borderColor: alpha(gray[700], 0.5), + backgroundColor: alpha(gray[300], 0.3), + borderColor: alpha(gray[300], 0.5), boxShadow: 'none', }, '&:active': { - backgroundColor: alpha(gray[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundColor: alpha(gray[300], 0.4), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[200], + ...theme.applyStyles('dark', { + color: gray[300], + backgroundColor: alpha(gray[600], 0.1), + borderColor: alpha(gray[700], 0.5), + boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(gray[700], 0.2), + borderColor: alpha(gray[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(gray[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'primary', + variant: 'text', + }, + style: { + color: brand[700], '&:hover': { - backgroundColor: alpha(brand[700], 0.3), + backgroundColor: alpha(brand[300], 0.3), }, - }), - }), + ...theme.applyStyles('dark', { + color: brand[200], + '&:hover': { + backgroundColor: alpha(brand[700], 0.3), + }, + }), + }, + }, + { + props: { + color: 'info', + variant: 'text', + }, + style: { + color: gray[700], + '&:hover': { + backgroundColor: alpha(gray[300], 0.3), + }, + ...theme.applyStyles('dark', { + color: gray[200], + '&:hover': { + backgroundColor: alpha(gray[700], 0.3), + }, + }), + }, + }, + ], }), }, }, MuiCard: { styleOverrides: { - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ transition: 'all 100ms ease', backgroundColor: gray[50], borderRadius: theme.shape.borderRadius, border: `1px solid ${alpha(gray[200], 0.5)}`, boxShadow: 'none', - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${gray[200]}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { backgroundColor: alpha(gray[800], 0.6), border: `1px solid ${alpha(gray[700], 0.3)}`, - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${alpha(gray[700], 0.4)}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( - gray[800], - 0.5, - )})`, - }), }), + variants: [ + { + props: { + variant: 'outlined', + }, + style: { + border: `1px solid ${gray[200]}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, + ...theme.applyStyles('dark', { + border: `1px solid ${alpha(gray[700], 0.4)}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( + gray[800], + 0.5, + )})`, + }), + }, + }, + ], }), }, }, @@ -404,7 +443,7 @@ export default function getSignUpTheme(mode) { backgroundColor: brand[600], }, }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: alpha(gray[700], 0.5), boxShadow: '0 0 0 1.5px hsl(210, 0%, 0%) inset', backgroundColor: alpha(gray[900], 0.8), @@ -435,7 +474,7 @@ export default function getSignUpTheme(mode) { styleOverrides: { root: ({ theme }) => ({ borderColor: `${alpha(gray[200], 0.8)}`, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: `${alpha(gray[700], 0.4)}`, }), }), @@ -451,27 +490,39 @@ export default function getSignUpTheme(mode) { }, MuiIconButton: { styleOverrides: { - root: ({ theme, ownerState }) => ({ - ...(ownerState.size === 'small' && { - height: '2rem', - width: '2rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', - width: '2.5rem', - }), + root: ({ theme }) => ({ color: brand[500], '&:hover': { backgroundColor: alpha(brand[300], 0.3), borderColor: brand[200], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], '&:hover': { backgroundColor: alpha(brand[600], 0.3), borderColor: brand[700], }, }), + variants: [ + { + props: { + size: 'small', + }, + style: { + height: '2rem', + width: '2rem', + }, + }, + { + props: { + size: 'medium', + }, + style: { + height: '2.5rem', + width: '2.5rem', + }, + }, + ], }), }, }, @@ -512,7 +563,7 @@ export default function getSignUpTheme(mode) { outlineOffset: '4px', borderRadius: '2px', }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], }), }), @@ -526,7 +577,7 @@ export default function getSignUpTheme(mode) { input: { paddingLeft: 10, }, - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[100]} inset, 0 0 0 1px ${brand[200]}`, maxHeight: '4px', @@ -556,14 +607,7 @@ export default function getSignUpTheme(mode) { outlineOffset: '2px', borderColor: brand[400], }, - ...(ownerState.color === 'error' && { - borderColor: red[200], - color: red[500], - '& + .MuiFormHelperText-root': { - color: red[500], - }, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[900]} inset, 0 0 0 1px ${brand[600]}`, maxHeight: '6px', @@ -588,14 +632,28 @@ export default function getSignUpTheme(mode) { outline: `3px solid ${alpha(brand[500], 0.5)}`, outlineOffset: '2px', }, - ...(ownerState.color === 'error' && { - borderColor: red[700], - color: red[300], - '& + .MuiFormHelperText-root': { - color: red[300], - }, - }), }), + variants: [ + { + props: { + color: 'error', + }, + style: { + borderColor: red[200], + color: red[500], + '& + .MuiFormHelperText-root': { + color: red[500], + }, + ...theme.applyStyles('dark', { + borderColor: red[700], + color: red[300], + '& + .MuiFormHelperText-root': { + color: red[300], + }, + }), + }, + }, + ], }), }, }, @@ -617,7 +675,7 @@ export default function getSignUpTheme(mode) { '& .Mui-selected': { color: brand[500], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { '& .Mui-selected': { color: 'hsl(0, 0%, 100%)', }, @@ -633,7 +691,7 @@ export default function getSignUpTheme(mode) { textTransform: 'none', borderRadius: theme.shape.borderRadius, fontWeight: 500, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: gray[400], '&.Mui-selected': { color: brand[300] }, }), diff --git a/docs/data/material/getting-started/templates/sign-up/getSignUpTheme.tsx b/docs/data/material/getting-started/templates/sign-up/getSignUpTheme.tsx index 19490022c87ad3..49d69b56765951 100644 --- a/docs/data/material/getting-started/templates/sign-up/getSignUpTheme.tsx +++ b/docs/data/material/getting-started/templates/sign-up/getSignUpTheme.tsx @@ -231,156 +231,195 @@ export default function getSignUpTheme(mode: PaletteMode): ThemeOptions { }, MuiButton: { styleOverrides: { - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ boxShadow: 'none', borderRadius: theme.shape.borderRadius, textTransform: 'none', - ...(ownerState.size === 'small' && { - height: '2rem', // 32px - padding: '0 0.5rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', // 40px - }), - ...(ownerState.variant === 'contained' && - ownerState.color === 'primary' && { - color: 'white', - backgroundColor: brand[300], - backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, - boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, - border: `1px solid ${brand[500]}`, - '&:hover': { - backgroundColor: brand[700], - boxShadow: 'none', + variants: [ + { + props: { + size: 'small', }, - '&:active': { - backgroundColor: brand[700], - boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + style: { + height: '2rem', // 32px + padding: '0 0.5rem', }, - }), - ...(ownerState.variant === 'outlined' && { - color: brand[700], - backgroundColor: alpha(brand[300], 0.1), - borderColor: alpha(brand[200], 0.8), - boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, - '&:hover': { - backgroundColor: alpha(brand[300], 0.2), - borderColor: alpha(brand[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(brand[300], 0.3), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, - backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - backgroundColor: alpha(gray[300], 0.1), - borderColor: alpha(gray[300], 0.5), - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), - borderColor: alpha(gray[300], 0.5), - boxShadow: 'none', - }, - '&:active': { - backgroundColor: alpha(gray[300], 0.4), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, - backgroundImage: 'none', + { + props: { + size: 'medium', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[700], - '&:hover': { - backgroundColor: alpha(brand[300], 0.3), + style: { + height: '2.5rem', // 40px }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[700], - '&:hover': { - backgroundColor: alpha(gray[300], 0.3), + }, + { + props: { + color: 'primary', + variant: 'contained', }, - }), - ...(theme.palette.mode === 'dark' && { - ...(ownerState.variant === 'outlined' && { - color: brand[200], - backgroundColor: alpha(brand[600], 0.1), - borderColor: alpha(brand[600], 0.6), - boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, - '&:hover': { - backgroundColor: alpha(brand[700], 0.2), - borderColor: alpha(brand[700], 0.5), - boxShadow: 'none', + style: { + color: 'white', + backgroundColor: brand[300], + backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, + boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, + border: `1px solid ${brand[500]}`, + '&:hover': { + backgroundColor: brand[700], + boxShadow: 'none', + }, + '&:active': { + backgroundColor: brand[700], + boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + }, }, - '&:active': { - backgroundColor: alpha(brand[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, - backgroundImage: 'none', + }, + { + props: { + variant: 'outlined', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'info' && { - color: gray[200], + style: { + color: brand[700], + backgroundColor: alpha(brand[300], 0.1), + borderColor: alpha(brand[200], 0.8), + boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, '&:hover': { - backgroundColor: alpha(gray[700], 0.3), + backgroundColor: alpha(brand[300], 0.2), + borderColor: alpha(brand[300], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[300], 0.3), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, + backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - color: gray[300], - backgroundColor: alpha(gray[600], 0.1), - borderColor: alpha(gray[700], 0.5), - boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + ...theme.applyStyles('dark', { + color: brand[200], + backgroundColor: alpha(brand[600], 0.1), + borderColor: alpha(brand[600], 0.6), + boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(brand[700], 0.2), + borderColor: alpha(brand[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'secondary', + variant: 'outlined', + }, + style: { + backgroundColor: alpha(gray[300], 0.1), + borderColor: alpha(gray[300], 0.5), + color: gray[700], '&:hover': { - backgroundColor: alpha(gray[700], 0.2), - borderColor: alpha(gray[700], 0.5), + backgroundColor: alpha(gray[300], 0.3), + borderColor: alpha(gray[300], 0.5), boxShadow: 'none', }, '&:active': { - backgroundColor: alpha(gray[800], 0.2), - boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundColor: alpha(gray[300], 0.4), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, backgroundImage: 'none', }, - }), - ...(ownerState.variant === 'text' && - ownerState.color === 'primary' && { - color: brand[200], + ...theme.applyStyles('dark', { + color: gray[300], + backgroundColor: alpha(gray[600], 0.1), + borderColor: alpha(gray[700], 0.5), + boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(gray[700], 0.2), + borderColor: alpha(gray[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(gray[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + }, + }, + { + props: { + color: 'primary', + variant: 'text', + }, + style: { + color: brand[700], '&:hover': { - backgroundColor: alpha(brand[700], 0.3), + backgroundColor: alpha(brand[300], 0.3), }, - }), - }), + ...theme.applyStyles('dark', { + color: brand[200], + '&:hover': { + backgroundColor: alpha(brand[700], 0.3), + }, + }), + }, + }, + { + props: { + color: 'info', + variant: 'text', + }, + style: { + color: gray[700], + '&:hover': { + backgroundColor: alpha(gray[300], 0.3), + }, + ...theme.applyStyles('dark', { + color: gray[200], + '&:hover': { + backgroundColor: alpha(gray[700], 0.3), + }, + }), + }, + }, + ], }), }, }, MuiCard: { styleOverrides: { - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ transition: 'all 100ms ease', backgroundColor: gray[50], borderRadius: theme.shape.borderRadius, border: `1px solid ${alpha(gray[200], 0.5)}`, boxShadow: 'none', - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${gray[200]}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { backgroundColor: alpha(gray[800], 0.6), border: `1px solid ${alpha(gray[700], 0.3)}`, - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${alpha(gray[700], 0.4)}`, - boxShadow: 'none', - background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( - gray[800], - 0.5, - )})`, - }), }), + variants: [ + { + props: { + variant: 'outlined', + }, + style: { + border: `1px solid ${gray[200]}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, + ...theme.applyStyles('dark', { + border: `1px solid ${alpha(gray[700], 0.4)}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( + gray[800], + 0.5, + )})`, + }), + }, + }, + ], }), }, }, @@ -422,7 +461,7 @@ export default function getSignUpTheme(mode: PaletteMode): ThemeOptions { backgroundColor: brand[600], }, }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: alpha(gray[700], 0.5), boxShadow: '0 0 0 1.5px hsl(210, 0%, 0%) inset', backgroundColor: alpha(gray[900], 0.8), @@ -453,7 +492,7 @@ export default function getSignUpTheme(mode: PaletteMode): ThemeOptions { styleOverrides: { root: ({ theme }) => ({ borderColor: `${alpha(gray[200], 0.8)}`, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { borderColor: `${alpha(gray[700], 0.4)}`, }), }), @@ -469,27 +508,39 @@ export default function getSignUpTheme(mode: PaletteMode): ThemeOptions { }, MuiIconButton: { styleOverrides: { - root: ({ theme, ownerState }) => ({ - ...(ownerState.size === 'small' && { - height: '2rem', - width: '2rem', - }), - ...(ownerState.size === 'medium' && { - height: '2.5rem', - width: '2.5rem', - }), + root: ({ theme }) => ({ color: brand[500], '&:hover': { backgroundColor: alpha(brand[300], 0.3), borderColor: brand[200], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], '&:hover': { backgroundColor: alpha(brand[600], 0.3), borderColor: brand[700], }, }), + variants: [ + { + props: { + size: 'small', + }, + style: { + height: '2rem', + width: '2rem', + }, + }, + { + props: { + size: 'medium', + }, + style: { + height: '2.5rem', + width: '2.5rem', + }, + }, + ], }), }, }, @@ -530,7 +581,7 @@ export default function getSignUpTheme(mode: PaletteMode): ThemeOptions { outlineOffset: '4px', borderRadius: '2px', }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: brand[200], }), }), @@ -544,7 +595,7 @@ export default function getSignUpTheme(mode: PaletteMode): ThemeOptions { input: { paddingLeft: 10, }, - root: ({ theme, ownerState }) => ({ + root: ({ theme }) => ({ 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[100]} inset, 0 0 0 1px ${brand[200]}`, maxHeight: '4px', @@ -574,14 +625,7 @@ export default function getSignUpTheme(mode: PaletteMode): ThemeOptions { outlineOffset: '2px', borderColor: brand[400], }, - ...(ownerState.color === 'error' && { - borderColor: red[200], - color: red[500], - '& + .MuiFormHelperText-root': { - color: red[500], - }, - }), - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { 'input:-webkit-autofill': { WebkitBoxShadow: `0 0 0 1000px ${brand[900]} inset, 0 0 0 1px ${brand[600]}`, maxHeight: '6px', @@ -606,14 +650,28 @@ export default function getSignUpTheme(mode: PaletteMode): ThemeOptions { outline: `3px solid ${alpha(brand[500], 0.5)}`, outlineOffset: '2px', }, - ...(ownerState.color === 'error' && { - borderColor: red[700], - color: red[300], - '& + .MuiFormHelperText-root': { - color: red[300], - }, - }), }), + variants: [ + { + props: { + color: 'error', + }, + style: { + borderColor: red[200], + color: red[500], + '& + .MuiFormHelperText-root': { + color: red[500], + }, + ...theme.applyStyles('dark', { + borderColor: red[700], + color: red[300], + '& + .MuiFormHelperText-root': { + color: red[300], + }, + }), + }, + }, + ], }), }, }, @@ -635,7 +693,7 @@ export default function getSignUpTheme(mode: PaletteMode): ThemeOptions { '& .Mui-selected': { color: brand[500], }, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { '& .Mui-selected': { color: 'hsl(0, 0%, 100%)', }, @@ -651,7 +709,7 @@ export default function getSignUpTheme(mode: PaletteMode): ThemeOptions { textTransform: 'none', borderRadius: theme.shape.borderRadius, fontWeight: 500, - ...(theme.palette.mode === 'dark' && { + ...theme.applyStyles('dark', { color: gray[400], '&.Mui-selected': { color: brand[300] }, }), diff --git a/docs/data/material/getting-started/templates/templates.md b/docs/data/material/getting-started/templates/templates.md index 4d9a40ce5ef0a7..9e46486f534c8d 100644 --- a/docs/data/material/getting-started/templates/templates.md +++ b/docs/data/material/getting-started/templates/templates.md @@ -30,5 +30,10 @@ Please feel free to open an [issue](https://github.com/mui/material-ui/issues/ne Looking for something more? You can find complete templates and themes in the premium template section. -react templates + +The MUI Store includes several carefully curated React templates using Material UI + + +The MUI Store includes several carefully curated React templates using Material UI + diff --git a/docs/data/material/integrations/nextjs/nextjs.md b/docs/data/material/integrations/nextjs/nextjs.md index 880c30fe523c97..5829d5d971a20c 100644 --- a/docs/data/material/integrations/nextjs/nextjs.md +++ b/docs/data/material/integrations/nextjs/nextjs.md @@ -369,10 +369,9 @@ To learn more about theming, check out the [Theming guide](/material-ui/customiz If you want to use [CSS theme variables](/material-ui/experimental-api/css-theme-variables/overview/), use the `extendTheme` and `CssVarsProvider` instead: -````diff title="pages/_app.tsx" +```diff title="pages/_app.tsx" -import { ThemeProvider, createTheme } from '@mui/material/styles'; +import { CssVarsProvider, extendTheme } from '@mui/material/styles'; ``` Learn more about [the advantages of CSS theme variables](/material-ui/experimental-api/css-theme-variables/overview/#advantages). -```` diff --git a/docs/data/material/migration/migrating-from-deprecated-apis/migrating-from-deprecated-apis.md b/docs/data/material/migration/migrating-from-deprecated-apis/migrating-from-deprecated-apis.md index cc2eba3ce351e0..43ac60f957e2e2 100644 --- a/docs/data/material/migration/migrating-from-deprecated-apis/migrating-from-deprecated-apis.md +++ b/docs/data/material/migration/migrating-from-deprecated-apis/migrating-from-deprecated-apis.md @@ -169,9 +169,9 @@ Here's how to migrate: ``` ```diff - import { alertClasses } from '@mui/material/PaginationItem'; + import { alertClasses } from '@mui/material/Alert'; - MuiPaginationItem: { + MuiAlert: { styleOverrides: { root: { - [`&.${alertClasses.standardSuccess}`]: { @@ -872,6 +872,25 @@ The Divider's `light` prop was deprecated, Use `sx={{ opacity : "0.6" }}` (or an /> ``` +## FormControlLabel + +Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#form-control-label-props) below to migrate the code as described in the following sections: + +```bash +npx @mui/codemod@next deprecations/form-control-label-props +``` + +### componentsProps + +The FormControlLabel's `componentsProps` was deprecated in favor of `slotProps`: + +```diff + +``` + ## PaginationItem Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#pagination-item-classes) below to migrate the code as described in the following sections: @@ -924,6 +943,17 @@ Here's how to migrate: }, ``` +### components + +The PaginationItems's `components` was deprecated in favor of `slots`: + +```diff + +``` + ## Slider Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#slider-props) below to migrate the code as described in the following sections: @@ -1012,3 +1042,65 @@ The StepLabel's `componentsProps` was deprecated in favor of `slotProps`: + slotProps={{ label: labelProps }} /> ``` + +### StepIconComponent + +The StepLabel's `StepIconComponent` was deprecated in favor of `slots.stepIcon`: + +```diff + +``` + +### StepIconProps + +The StepLabel's `StepIconProps` was deprecated in favor of `slotProps.stepIcon`: + +```diff + +``` + +## StepConnector + +Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#step-connector-classes) below to migrate the code as described in the following sections: + +```bash +npx @mui/codemod@next deprecations/step-connector-classes +``` + +### Composed CSS classes + +The CSS classes that composed the `line` CSS class and `orientation` prop values were removed. + +Here's how to migrate: + +```diff +- .MuiStepConnector-lineHorizontal ++.MuiStepConnector-horizontal > .MuiStepConnector-line +- .MuiStepConnector-lineVertical ++.MuiStepConnector-vertical > .MuiStepConnector-line +``` + +```diff + import { stepConnectorClasses } from '@mui/material/StepConnector'; + + MuiStepConnector: { + styleOverrides: { + root: { +- [`& .${stepConnectorClasses.lineHorizontal}`]: { ++ [`&.${stepConnectorClasses.horizontal} > .${stepConnectorClasses.line}`]: { + color: 'red', + }, +- [`& .${stepConnectorClasses.lineVertical}`]: { ++ [`&.${stepConnectorClasses.vertical} > .${stepConnectorClasses.line}`]: { + color: 'red', + }, + }, + }, + }, +``` diff --git a/docs/data/material/pages.ts b/docs/data/material/pages.ts index ee15159b9f27f6..9d3f176a50bacd 100644 --- a/docs/data/material/pages.ts +++ b/docs/data/material/pages.ts @@ -327,6 +327,21 @@ const pages: MuiPage[] = [ { pathname: '/material-ui/discover-more/changelog' }, ], }, + { + pathname: '/material-ui/design-resources', + title: 'Design resources', + children: [ + { + pathname: '/material-ui/design-resources/material-ui-for-figma', + title: 'Figma Design Kit', + }, + { + pathname: '/material-ui/design-resources/material-ui-sync', + title: 'Figma Sync plugin', + beta: true, + }, + ], + }, { pathname: 'https://mui.com/store/?utm_source=docs&utm_medium=referral&utm_campaign=sidenav', title: 'Template store', diff --git a/docs/data/system/components/box/box.md b/docs/data/system/components/box/box.md index 7b77c2ddbf098e..62cfb6891c5adb 100644 --- a/docs/data/system/components/box/box.md +++ b/docs/data/system/components/box/box.md @@ -11,7 +11,7 @@ githubLabel: 'component: Box'

The Box component is a generic, theme-aware container with access to CSS utilities from MUI System.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Introduction diff --git a/docs/data/system/components/container/container.md b/docs/data/system/components/container/container.md index 2dc88f7900efa3..20fada82728701 100644 --- a/docs/data/system/components/container/container.md +++ b/docs/data/system/components/container/container.md @@ -11,7 +11,7 @@ githubLabel: 'component: Container' While containers can be nested, most layouts do not require a nested container. -{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Fluid diff --git a/docs/data/system/components/grid/SpacingGrid.js b/docs/data/system/components/grid/SpacingGrid.js index 4ffd3591650ef4..79e2db15c03725 100644 --- a/docs/data/system/components/grid/SpacingGrid.js +++ b/docs/data/system/components/grid/SpacingGrid.js @@ -6,7 +6,7 @@ import FormControlLabel from '@mui/material/FormControlLabel'; import RadioGroup from '@mui/material/RadioGroup'; import Radio from '@mui/material/Radio'; import Paper from '@mui/material/Paper'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; export default function SpacingGrid() { const [spacing, setSpacing] = React.useState(2); diff --git a/docs/data/system/components/grid/SpacingGrid.tsx b/docs/data/system/components/grid/SpacingGrid.tsx index 97c0d5fe114b2d..80a78f26c3ca75 100644 --- a/docs/data/system/components/grid/SpacingGrid.tsx +++ b/docs/data/system/components/grid/SpacingGrid.tsx @@ -6,7 +6,7 @@ import FormControlLabel from '@mui/material/FormControlLabel'; import RadioGroup from '@mui/material/RadioGroup'; import Radio from '@mui/material/Radio'; import Paper from '@mui/material/Paper'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; export default function SpacingGrid() { const [spacing, setSpacing] = React.useState(2); diff --git a/docs/data/system/components/grid/grid.md b/docs/data/system/components/grid/grid.md index 611e9fa91736be..b4819213ab5287 100644 --- a/docs/data/system/components/grid/grid.md +++ b/docs/data/system/components/grid/grid.md @@ -8,7 +8,7 @@ githubLabel: 'component: Grid'

The responsive layout grid adapts to screen size and orientation, ensuring consistency across layouts.

-{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} The `Grid` component works well for a layout with known columns. The columns can be configured in multiple breakpoints which you have to specify the column span of each child. diff --git a/docs/data/system/components/stack/InteractiveStack.js b/docs/data/system/components/stack/InteractiveStack.js index 25f978b8fe2827..ed48e6ac727308 100644 --- a/docs/data/system/components/stack/InteractiveStack.js +++ b/docs/data/system/components/stack/InteractiveStack.js @@ -8,7 +8,7 @@ import Radio from '@mui/material/Radio'; import Grid from '@mui/system/Unstable_Grid'; import Stack from '@mui/system/Stack'; import { styled } from '@mui/system'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; const Item = styled('div')(({ theme }) => ({ backgroundColor: theme.palette.mode === 'dark' ? '#262B32' : '#fff', diff --git a/docs/data/system/components/stack/InteractiveStack.tsx b/docs/data/system/components/stack/InteractiveStack.tsx index 026d18c5ff7d5f..40c09e895eddc1 100644 --- a/docs/data/system/components/stack/InteractiveStack.tsx +++ b/docs/data/system/components/stack/InteractiveStack.tsx @@ -8,7 +8,7 @@ import Radio from '@mui/material/Radio'; import Grid from '@mui/system/Unstable_Grid'; import Stack, { StackProps } from '@mui/system/Stack'; import { styled } from '@mui/system'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; const Item = styled('div')(({ theme }) => ({ backgroundColor: theme.palette.mode === 'dark' ? '#262B32' : '#fff', diff --git a/docs/data/system/components/stack/stack.md b/docs/data/system/components/stack/stack.md index 66851d0c80af6b..44104653a496c6 100644 --- a/docs/data/system/components/stack/stack.md +++ b/docs/data/system/components/stack/stack.md @@ -17,7 +17,7 @@ The Stack component manages the layout of its immediate children along the verti Stack is ideal for one-dimensional layouts, while Grid is preferable when you need both vertical _and_ horizontal arrangement. ::: -{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} +{{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Basics diff --git a/docs/data/system/getting-started/the-sx-prop/the-sx-prop.md b/docs/data/system/getting-started/the-sx-prop/the-sx-prop.md index a3e75054c37355..febdd81139b518 100644 --- a/docs/data/system/getting-started/the-sx-prop/the-sx-prop.md +++ b/docs/data/system/getting-started/the-sx-prop/the-sx-prop.md @@ -1,6 +1,6 @@ # The sx prop -

The sx prop is a shortcut for defining custom styles that has access to the theme.

+

The sx prop is a shortcut for defining custom styles that have access to the theme.

The `sx` prop lets you work with a superset of CSS that packages all of the style functions exposed in `@mui/system`. You can specify any valid CSS using this prop, as well as many _theme-aware_ properties that are unique to MUI System. @@ -179,7 +179,7 @@ Read more on the [Typography page](/system/typography/). ## Responsive values -All properties associated with the `sx` prop also support responsive values for specific breakpoints. +All properties associated with the `sx` prop also support responsive values for specific breakpoints and container queries. Read more on the [Usage page—Responsive values](/system/getting-started/usage/#responsive-values). diff --git a/docs/data/system/getting-started/usage/ContainerQueries.js b/docs/data/system/getting-started/usage/ContainerQueries.js new file mode 100644 index 00000000000000..aa1e523a0989e4 --- /dev/null +++ b/docs/data/system/getting-started/usage/ContainerQueries.js @@ -0,0 +1,88 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; + +export default function ContainerQueries() { + return ( + + + + +
+ + 123 Main St, Phoenix AZ + + + $280,000 — $310,000 + +
+ + Confidence score: 85% + +
+
+
+ ); +} diff --git a/docs/data/system/getting-started/usage/ContainerQueries.tsx b/docs/data/system/getting-started/usage/ContainerQueries.tsx new file mode 100644 index 00000000000000..aa1e523a0989e4 --- /dev/null +++ b/docs/data/system/getting-started/usage/ContainerQueries.tsx @@ -0,0 +1,88 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; + +export default function ContainerQueries() { + return ( + + + + +
+ + 123 Main St, Phoenix AZ + + + $280,000 — $310,000 + +
+ + Confidence score: 85% + +
+
+
+ ); +} diff --git a/docs/data/system/getting-started/usage/usage.md b/docs/data/system/getting-started/usage/usage.md index 487340ad2b1585..1e5d3de608f2f2 100644 --- a/docs/data/system/getting-started/usage/usage.md +++ b/docs/data/system/getting-started/usage/usage.md @@ -291,6 +291,19 @@ The following demo shows how to define a set of breakpoints using the object syn {{"demo": "BreakpointsAsObject.js"}} +:::info +📣 Starting from v6, the object structure supports [container queries](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries) shorthand with `@`. + +We recommend you to check the [browser support](https://caniuse.com/?search=container%20que) before using CSS container queries. +::: + +The shorthand syntax is `@{breakpoint}/{container}`: + +- **breakpoint**: a number for `px` unit or a breakpoint key (e.g. `sm`, `md`, `lg`, `xl` for default breakpoints) or a valid CSS value (e.g. `40em`). +- **container** (optional): the name of the [containment context](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries#naming_containment_contexts). + +{{"demo": "ContainerQueries.js"}} + #### Breakpoints as an array The second option is to define your breakpoints as an array, from smallest to largest. diff --git a/docs/mui-vale.zip b/docs/mui-vale.zip index e54c1641f071fc..bb43a45783468a 100644 Binary files a/docs/mui-vale.zip and b/docs/mui-vale.zip differ diff --git a/docs/mui-vale/styles/MUI/NoCompanyName.yml b/docs/mui-vale/styles/MUI/NoCompanyName.yml index 8556df60383e22..bec8a07649fa86 100644 --- a/docs/mui-vale/styles/MUI/NoCompanyName.yml +++ b/docs/mui-vale/styles/MUI/NoCompanyName.yml @@ -9,7 +9,9 @@ exceptions: - 'MUI System' - 'MUI Store' - 'MUI Core' - - 'MUI Toolpad' - 'MUI Connect' - - 'MUI organization' # valid use of a regular space - - 'MUI ecosystem' # valid use of a regular space + # valid use of a regular space + - 'MUI organization' + - 'MUI ecosystem' + - 'MUI products' + - 'MUI team' diff --git a/docs/next.config.mjs b/docs/next.config.mjs index 825504dbeb620f..720b9a7c4020d4 100644 --- a/docs/next.config.mjs +++ b/docs/next.config.mjs @@ -30,10 +30,6 @@ const pkgContent = fs.readFileSync(path.resolve(workspaceRoot, 'package.json'), const pkg = JSON.parse(pkgContent); export default withDocsInfra({ - experimental: { - workerThreads: true, - cpus: 3, - }, webpack: (config, options) => { const plugins = config.plugins.slice(); @@ -256,7 +252,7 @@ export default withDocsInfra({ return map; }, - // Used to signal we run yarn build + // Used to signal we run pnpm build ...(process.env.NODE_ENV === 'production' ? { output: 'export', diff --git a/docs/nextConfigDocsInfra.js b/docs/nextConfigDocsInfra.js index ba6e0690714473..b5e7a45f170b9d 100644 --- a/docs/nextConfigDocsInfra.js +++ b/docs/nextConfigDocsInfra.js @@ -75,6 +75,8 @@ function withDocsInfra(nextConfig) { experimental: { scrollRestoration: true, esmExternals: false, + workerThreads: true, + cpus: 3, ...nextConfig.experimental, }, eslint: { diff --git a/docs/package.json b/docs/package.json index 7d0914dcd8a336..ee69bb478f12c1 100644 --- a/docs/package.json +++ b/docs/package.json @@ -20,7 +20,6 @@ }, "dependencies": { "@babel/core": "^7.24.4", - "@babel/plugin-transform-object-assign": "^7.24.1", "@babel/runtime": "^7.24.4", "@babel/runtime-corejs2": "^7.24.4", "@docsearch/react": "^3.6.0", @@ -45,10 +44,10 @@ "@mui/types": "workspace:^", "@mui/utils": "workspace:^", "@mui/x-charts": "6.19.8", - "@mui/x-data-grid": "7.1.1", - "@mui/x-data-grid-generator": "7.1.1", - "@mui/x-data-grid-premium": "7.1.1", - "@mui/x-data-grid-pro": "7.1.1", + "@mui/x-data-grid": "7.3.1", + "@mui/x-data-grid-generator": "7.3.1", + "@mui/x-data-grid-premium": "7.3.1", + "@mui/x-data-grid-pro": "7.3.1", "@mui/x-date-pickers": "6.19.9", "@mui/x-date-pickers-pro": "6.19.9", "@mui/x-license-pro": "6.10.2", @@ -57,13 +56,13 @@ "@react-spring/web": "^9.7.3", "autoprefixer": "^10.4.19", "autosuggest-highlight": "^3.3.4", - "babel-plugin-module-resolver": "^5.0.0", + "babel-plugin-module-resolver": "^5.0.2", "babel-plugin-optimize-clsx": "^2.6.2", "babel-plugin-react-remove-properties": "^0.3.0", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "clean-css": "^5.3.3", "clipboard-copy": "^4.0.1", - "clsx": "^2.1.0", + "clsx": "^2.1.1", "core-js": "^2.6.11", "cross-env": "^7.0.3", "css-mediaquery": "^0.1.2", @@ -80,7 +79,7 @@ "jss-rtl": "^0.3.0", "lodash": "^4.17.21", "lz-string": "^1.5.0", - "markdown-to-jsx": "^7.4.6", + "markdown-to-jsx": "^7.4.7", "material-ui-popup-state": "^5.1.0", "next": "^13.5.1", "notistack": "3.0.1", @@ -92,8 +91,8 @@ "react-dom": "^18.2.0", "react-draggable": "^4.4.6", "react-final-form": "^6.5.9", - "react-imask": "^7.5.0", - "react-intersection-observer": "^9.8.1", + "react-imask": "^7.6.0", + "react-intersection-observer": "^9.8.2", "react-is": "^18.2.0", "react-number-format": "^5.3.4", "react-router-dom": "^6.22.3", @@ -103,14 +102,14 @@ "react-swipeable-views": "^0.14.0", "react-swipeable-views-utils": "^0.14.0", "react-transition-group": "^4.4.5", - "react-virtuoso": "^4.7.8", + "react-virtuoso": "^4.7.10", "react-window": "^1.8.10", "rimraf": "^5.0.5", "styled-components": "^6.1.8", "stylis": "4.2.0", "stylis-plugin-rtl": "^2.1.1", "use-count-up": "^3.0.1", - "webpack-bundle-analyzer": "^4.10.1" + "webpack-bundle-analyzer": "^4.10.2" }, "devDependencies": { "@babel/plugin-transform-react-constant-elements": "^7.24.1", @@ -125,7 +124,7 @@ "@types/node": "^18.19.31", "@types/prop-types": "^15.7.12", "@types/react": "^18.2.55", - "@types/react-dom": "^18.2.19", + "@types/react-dom": "^18.3.0", "@types/react-swipeable-views": "^0.13.5", "@types/react-swipeable-views-utils": "^0.13.7", "@types/react-transition-group": "^4.4.10", @@ -135,7 +134,7 @@ "cross-fetch": "^4.0.0", "gm": "^1.25.0", "marked": "^5.1.2", - "playwright": "^1.43.0", + "playwright": "^1.43.1", "prettier": "^3.2.5", "tailwindcss": "^3.4.3", "yargs": "^17.7.2" diff --git a/docs/pages/_app.js b/docs/pages/_app.js index 7931cb56f13147..7ba45523219f4e 100644 --- a/docs/pages/_app.js +++ b/docs/pages/_app.js @@ -18,7 +18,7 @@ import joyPages from 'docs/data/joy/pages'; import systemPages from 'docs/data/system/pages'; import PageContext from 'docs/src/modules/components/PageContext'; import GoogleAnalytics from 'docs/src/modules/components/GoogleAnalytics'; -import { CodeCopyProvider } from 'docs/src/modules/utils/CodeCopy'; +import { CodeCopyProvider } from '@mui/docs/CodeCopy'; import { ThemeProvider } from 'docs/src/modules/components/ThemeContext'; import { CodeVariantProvider } from 'docs/src/modules/utils/codeVariant'; import { CodeStylingProvider } from 'docs/src/modules/utils/codeStylingSolution'; @@ -347,7 +347,7 @@ MyApp.propTypes = { MyApp.getInitialProps = async ({ ctx, Component }) => { let pageProps = {}; - const req = require.context('docs/translations', false, /translations.*\.json$/); + const req = require.context('docs/translations', false, /\.\/translations.*\.json$/); const translations = mapTranslations(req); if (Component.getInitialProps) { diff --git a/docs/pages/_document.js b/docs/pages/_document.js index 15d05e9907b7b4..dc8e2b6ad776d1 100644 --- a/docs/pages/_document.js +++ b/docs/pages/_document.js @@ -132,7 +132,14 @@ export default class MyDocument extends Document { // use https://cssminifier.com/ to minify // eslint-disable-next-line react/no-danger dangerouslySetInnerHTML={{ - __html: `@font-face{font-family:'IBM Plex Sans';src:url(/static/fonts/IBMPlexSans-Regular.woff2) format('woff2'),url(/static/fonts/IBMPlexSans-Regular.woff) format('woff'),url(/static/fonts/IBMPlexSans-Regular.ttf) format('truetype');font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:'IBM Plex Sans';src:url(/static/fonts/IBMPlexSans-Medium.woff2) format('woff2'),url(/static/fonts/IBMPlexSans-Medium.woff) format('woff'),url(/static/fonts/IBMPlexSans-Medium.ttf) format('truetype');font-weight:500;font-style:normal;font-display:swap}@font-face{font-family:'IBM Plex Sans';src:url(/static/fonts/IBMPlexSans-SemiBold.woff2) format('woff2'),url(/static/fonts/IBMPlexSans-SemiBold.woff) format('woff'),url(/static/fonts/IBMPlexSans-SemiBold.ttf) format('truetype');font-weight:600;font-style:normal;font-display:swap}@font-face{font-family:'IBM Plex Sans';src:url(/static/fonts/IBMPlexSans-Bold.woff2) format('woff2'),url(/static/fonts/IBMPlexSans-Bold.woff) format('woff'),url(/static/fonts/IBMPlexSans-Bold.ttf) format('truetype');font-weight:700;font-style:normal;font-display:swap}`, + __html: ` + @font-face{font-family:'IBM Plex Sans';src:url(/static/fonts/IBMPlexSans-Regular.woff2) format('woff2'),url(/static/fonts/IBMPlexSans-Regular.woff) format('woff'),url(/static/fonts/IBMPlexSans-Regular.ttf) format('truetype');font-weight:400;font-style:normal;font-display:swap} + + @font-face{font-family:'IBM Plex Sans';src:url(/static/fonts/IBMPlexSans-Medium.woff2) format('woff2'),url(/static/fonts/IBMPlexSans-Medium.woff) format('woff'),url(/static/fonts/IBMPlexSans-Medium.ttf) format('truetype');font-weight:500;font-style:normal;font-display:swap} + + @font-face{font-family:'IBM Plex Sans';src:url(/static/fonts/IBMPlexSans-SemiBold.woff2) format('woff2'),url(/static/fonts/IBMPlexSans-SemiBold.woff) format('woff'),url(/static/fonts/IBMPlexSans-SemiBold.ttf) format('truetype');font-weight:600;font-style:normal;font-display:swap} + + @font-face{font-family:'IBM Plex Sans';src:url(/static/fonts/IBMPlexSans-Bold.woff2) format('woff2'),url(/static/fonts/IBMPlexSans-Bold.woff) format('woff'),url(/static/fonts/IBMPlexSans-Bold.ttf) format('truetype');font-weight:700;font-style:normal;font-display:swap}`, }} /> +How to upvote on GitHub

Help us prioritize by upvoting.

diff --git a/docs/pages/blog/2020-introducing-sketch.md b/docs/pages/blog/2020-introducing-sketch.md index 731b1ee9549a67..783370d31d57b6 100644 --- a/docs/pages/blog/2020-introducing-sketch.md +++ b/docs/pages/blog/2020-introducing-sketch.md @@ -4,7 +4,7 @@ description: Today, we're excited to announce the introduction of official Sketc date: 2020-03-30T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Material UI', 'Product'] -card: true +manualCard: true --- Today, we're excited to introduce the Sketch symbols 💎 for Material UI. diff --git a/docs/pages/blog/2020-q1-update.md b/docs/pages/blog/2020-q1-update.md index ca6e353e94c685..74974a32703f13 100644 --- a/docs/pages/blog/2020-q1-update.md +++ b/docs/pages/blog/2020-q1-update.md @@ -4,7 +4,7 @@ description: An update on our mission for Q1 2020. date: 2020-04-14T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- Welcome to the new format of our mission update. We are moving from monthly to quarterly updates. diff --git a/docs/pages/blog/2020-q2-update.md b/docs/pages/blog/2020-q2-update.md index 09fc6ee3dc1b4c..6d34a639194694 100644 --- a/docs/pages/blog/2020-q2-update.md +++ b/docs/pages/blog/2020-q2-update.md @@ -4,7 +4,7 @@ description: An update on our mission for Q2 2020. date: 2020-07-17T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- This update covers our progress over the last three months, and what we aim to achieve in the coming months. diff --git a/docs/pages/blog/2020-q3-update.md b/docs/pages/blog/2020-q3-update.md index 54e67b4bcb6b8b..f819f177ff06dc 100644 --- a/docs/pages/blog/2020-q3-update.md +++ b/docs/pages/blog/2020-q3-update.md @@ -4,7 +4,7 @@ description: An update on our mission for Q3 2020. date: 2020-10-14T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- This update covers our progress over the last three months, and what we aim to achieve in the coming months. diff --git a/docs/pages/blog/2020.md b/docs/pages/blog/2020.md index ec3f7aee46de80..811f44cac98d53 100644 --- a/docs/pages/blog/2020.md +++ b/docs/pages/blog/2020.md @@ -4,7 +4,7 @@ description: 2020 has been another great year, not only for MUI, but also for th date: 2020-12-31T00:00:00.000Z authors: ['oliviertassinari', 'mbrookes'] tags: ['Company'] -card: true +manualCard: true --- 2020 has been another great year, not only for MUI, but also for the ecosystem. diff --git a/docs/pages/blog/2021-developer-survey-results.md b/docs/pages/blog/2021-developer-survey-results.md index e6b3eba54ff130..93bb07ccb79477 100644 --- a/docs/pages/blog/2021-developer-survey-results.md +++ b/docs/pages/blog/2021-developer-survey-results.md @@ -4,7 +4,7 @@ description: Your feedback helps us to build better products. Here's what we lea date: 2022-03-15T00:00:00.000Z authors: ['danilo-leal', 'samuelsycamore', 'oliviertassinari'] tags: ['Developer Survey'] -card: true +manualCard: true --- Keeping up with tradition, a few months ago we opened the 2021 MUI Developer Survey. diff --git a/docs/pages/blog/2021-q1-update.md b/docs/pages/blog/2021-q1-update.md index 2c7bf644eed777..6c430546ecb0a2 100644 --- a/docs/pages/blog/2021-q1-update.md +++ b/docs/pages/blog/2021-q1-update.md @@ -4,7 +4,7 @@ description: An update on our mission for Q1 2021. date: 2021-04-12T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- This update covers our progress over the last three months, and what we aim to achieve in the months ahead. diff --git a/docs/pages/blog/2021-q2-update.md b/docs/pages/blog/2021-q2-update.md index 9d730373be91e0..952eb8e27cbafd 100644 --- a/docs/pages/blog/2021-q2-update.md +++ b/docs/pages/blog/2021-q2-update.md @@ -4,7 +4,7 @@ description: An update on our mission for Q2 2021. date: 2021-07-12T00:00:00.000Z authors: ['oliviertassinari', 'mbrookes'] tags: ['Company'] -card: true +manualCard: true --- This update covers our progress over the last three months. diff --git a/docs/pages/blog/2021-q3-update.md b/docs/pages/blog/2021-q3-update.md index f6c3adc2ce5863..6bb1b6a477d07c 100644 --- a/docs/pages/blog/2021-q3-update.md +++ b/docs/pages/blog/2021-q3-update.md @@ -4,7 +4,7 @@ description: An update on our mission for Q3 2021. date: 2021-10-26T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- This update covers our progress over the last three months. diff --git a/docs/pages/blog/2021.md b/docs/pages/blog/2021.md index b13d577f37ca2a..48b56ce6e1d06b 100644 --- a/docs/pages/blog/2021.md +++ b/docs/pages/blog/2021.md @@ -4,7 +4,7 @@ description: 2021 has been another great year, not only for MUI but also for the date: 2021-12-31T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- diff --git a/docs/pages/blog/2022-tenerife-retreat.md b/docs/pages/blog/2022-tenerife-retreat.md index b111d056ac85e3..1402e4240838c4 100644 --- a/docs/pages/blog/2022-tenerife-retreat.md +++ b/docs/pages/blog/2022-tenerife-retreat.md @@ -4,7 +4,7 @@ description: Our internationally distributed startup gathered on a remote island date: 2022-07-28T00:00:00.000Z authors: ['samuelsycamore'] tags: ['Company'] -card: true +manualCard: true --- One of the toughest challenges to overcome as a fully remote team is fostering a supportive and inclusive company culture. diff --git a/docs/pages/blog/2023-chamonix-retreat.md b/docs/pages/blog/2023-chamonix-retreat.md index 19b8559a739580..d6bccc7e15406f 100644 --- a/docs/pages/blog/2023-chamonix-retreat.md +++ b/docs/pages/blog/2023-chamonix-retreat.md @@ -4,7 +4,7 @@ description: The MUI team spent five days in the French Alps team-building, prob date: 2023-03-16T00:00:00.000Z authors: ['mikailaread'] tags: ['Company'] -card: true +manualCard: true --- ## Why the Chamonix gathering? diff --git a/docs/pages/blog/2023-material-ui-v6-and-beyond.md b/docs/pages/blog/2023-material-ui-v6-and-beyond.md index 24bebf7f41ee2f..aee8654af71152 100644 --- a/docs/pages/blog/2023-material-ui-v6-and-beyond.md +++ b/docs/pages/blog/2023-material-ui-v6-and-beyond.md @@ -3,7 +3,7 @@ title: The road to Material UI v6 and beyond description: We're tightening up the Material UI release schedule and shipping two major versions in 2024. Here's what to expect. date: 2023-12-23T00:00:00.000Z authors: ['mnajdova'] -card: true +manualCard: true tags: ['Material UI', 'Product'] --- diff --git a/docs/pages/blog/2023-mui-values.md b/docs/pages/blog/2023-mui-values.md index 79668d65b69148..27e3dd49b1d642 100644 --- a/docs/pages/blog/2023-mui-values.md +++ b/docs/pages/blog/2023-mui-values.md @@ -4,7 +4,7 @@ description: After significant growth, we united as a team to rediscover the val date: 2023-09-26T00:00:00.000Z authors: ['mikailaread'] tags: ['Company'] -card: true +manualCard: true --- ## Why we chose to revise our core values diff --git a/docs/pages/blog/2023-phuket-retreat.md b/docs/pages/blog/2023-phuket-retreat.md index 2b9b1d338e2446..35bf504c9ba842 100644 --- a/docs/pages/blog/2023-phuket-retreat.md +++ b/docs/pages/blog/2023-phuket-retreat.md @@ -4,7 +4,7 @@ description: The latest team retreat left MUIers feeling more connected and invi date: 2023-12-13T00:00:00.000Z authors: ['mikailaread'] tags: ['Company'] -card: true +manualCard: true --- ## What is MUI's Together Week? diff --git a/docs/pages/blog/2023-toolpad-beta-announcement.md b/docs/pages/blog/2023-toolpad-beta-announcement.md index 318dfe94bfe1e9..8fe6a5caef3361 100644 --- a/docs/pages/blog/2023-toolpad-beta-announcement.md +++ b/docs/pages/blog/2023-toolpad-beta-announcement.md @@ -3,13 +3,13 @@ title: Introducing Toolpad: MUI's low-code admin builder description: Assemble admin panels and internal tools faster than ever before with Toolpad—now in beta. date: 2023-07-24T00:00:00.000Z authors: ['prakhargupta'] -card: true +manualCard: true tags: ['Product', 'Toolpad'] --- It's been over a year since we released the first version of Toolpad. Today, we're excited to take the next step on that journey with the release of Toolpad Beta. If you aren't familiar with Toolpad yet, it's an admin panel builder catering to the internal tooling needs of an organization, designed for developers who want to build a functional application quickly. It harnesses the speed of a UI builder for the front end and closely integrates into your back end. If this excites you, then read on! - + Introducing Toolpad @@ -27,7 +27,7 @@ Toolpad is an open-source, low-code, drag-and-drop admin builder. The primary pu Toolpad is not ideal for building static web pages, mobile apps, or customer-facing custom-designed front-ends. It's for building admin applications, CRUD interfaces, custom internal tools, and analytics dashboards. - + Building an application on Toolpad @@ -45,7 +45,7 @@ Toolpad is for you if you're a full-stack or back-end developer who builds, mana Easily create user interfaces by dragging and dropping pre-built components onto the canvas. Utilize constraints to speed up the building process. - + Dragging components to the canvas @@ -53,13 +53,13 @@ Easily create user interfaces by dragging and dropping pre-built components onto A Postman-like query builder allows you to integrate any REST API quickly. A binding editor, which supports JavaScript, allows you to wire query responses directly to the components. - + Building an application on Toolpad ### 3. Bring your own components -Toolpad can import [external React components](https://mui.com/toolpad/concepts/custom-components/), ready to be used in its visual designer. Your past effort shouldn't go to waste and you shouldn't be limited by the stock component suite. +Toolpad can import [external React components](https://mui.com/toolpad/studio/concepts/custom-components/), ready to be used in its visual designer. Your past effort shouldn't go to waste and you shouldn't be limited by the stock component suite. ### 4. Bring your own back-end @@ -69,7 +69,7 @@ Directly integrate with your Node.js back-end and have your data available on th Toolpad runs completely locally. You're not stuck with an online code editor or a suboptimal GitHub integration. All configuration is stored in local files which you can version-control, edit, and deploy in any way you want. - + Building an application on Toolpad @@ -77,7 +77,7 @@ Toolpad runs completely locally. You're not stuck with an online code editor or Material UI provides production-ready React components; a chosen few are currently available inside Toolpad, and we're adding more all the time. - + Building an application on Toolpad @@ -97,7 +97,7 @@ Lastly, Toolpad is the only product that offers a drag-and-drop UI builder close ## How can I use Toolpad? -Toolpad is available as an npm package. Follow the [Installation guide](https://mui.com/toolpad/getting-started/installation/) in the docs to get started. +Toolpad is available as an npm package. Follow the [Installation guide](https://mui.com/toolpad/studio/getting-started/installation/) in the docs to get started. You can learn more about Toolpad by visiting the [home page](https://mui.com/toolpad/). Toolpad documentation and instructions on how to use it diff --git a/docs/pages/blog/aggregation-functions.md b/docs/pages/blog/aggregation-functions.md index 68ddfb0d169974..58254350d5292a 100644 --- a/docs/pages/blog/aggregation-functions.md +++ b/docs/pages/blog/aggregation-functions.md @@ -4,7 +4,7 @@ description: Aggregation functions and summary rows are now available in the MUI date: 2022-08-01T00:00:00.000Z authors: ['josefreitas', 'flaviendelangle', 'cherniavskii'] tags: ['MUI X', 'Product'] -card: true +manualCard: true --- If you've ever worked with a data-heavy grid, then you understand how important it is for the end user to be able to set different perspectives on the data to gather the information they're looking for. diff --git a/docs/pages/blog/april-2019-update.md b/docs/pages/blog/april-2019-update.md index 4b6a76792a9db7..c4a81e258dba49 100644 --- a/docs/pages/blog/april-2019-update.md +++ b/docs/pages/blog/april-2019-update.md @@ -4,7 +4,7 @@ description: Here are the most significant improvements in April. date: 2019-05-07T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- Here are the most significant improvements in April: diff --git a/docs/pages/blog/august-2019-update.md b/docs/pages/blog/august-2019-update.md index 5bde138036b660..77fa9cbb761278 100644 --- a/docs/pages/blog/august-2019-update.md +++ b/docs/pages/blog/august-2019-update.md @@ -4,7 +4,7 @@ description: Here are the most significant improvements in August. date: 2019-09-07T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- Here are the most significant improvements in August: diff --git a/docs/pages/blog/base-ui-2024-plans.md b/docs/pages/blog/base-ui-2024-plans.md index 12d33c4406a1b6..8298409dbe85f2 100644 --- a/docs/pages/blog/base-ui-2024-plans.md +++ b/docs/pages/blog/base-ui-2024-plans.md @@ -4,7 +4,7 @@ description: The unstyled component library will get a stable release, lots of n date: 2024-02-13T00:00:00.000Z authors: ['danilo-leal', 'michaldudak', 'colmtuite', 'oliviertassinari'] tags: ['Base UI', 'Product'] -card: true +manualCard: true --- The [story of Base UI](/blog/introducing-base-ui/) began several years ago—long before headless React component libraries skyrocketed in popularity—when we started to imagine a world in which Material UI could exist without Material Design. diff --git a/docs/pages/blog/benny-joo-joining.md b/docs/pages/blog/benny-joo-joining.md index 4fac8d9b5f4338..bcecb2de2b043e 100644 --- a/docs/pages/blog/benny-joo-joining.md +++ b/docs/pages/blog/benny-joo-joining.md @@ -4,7 +4,7 @@ description: We are excited to share that Benny Joo has joined MUI. He has start date: 2021-11-16T00:00:00.000Z authors: ['mnajdova'] tags: ['Company'] -card: true +manualCard: true --- We are excited to share that [Benny Joo](https://github.com/hbjORbj) has joined MUI. diff --git a/docs/pages/blog/bringing-consistency-to-material-ui-customization-apis.md b/docs/pages/blog/bringing-consistency-to-material-ui-customization-apis.md index dc43c0bb98c9aa..c3f1b7330f0cee 100644 --- a/docs/pages/blog/bringing-consistency-to-material-ui-customization-apis.md +++ b/docs/pages/blog/bringing-consistency-to-material-ui-customization-apis.md @@ -4,7 +4,7 @@ description: We're standardizing two key areas of the Material UI customization date: 2024-03-18T10:00:00.000Z authors: ['diegoandai'] tags: ['Material UI', 'Product'] -card: true +manualCard: true --- The Material UI team is working on two initiatives to standardize the Material UI API: The first applies to overriding inner elements, and the second applies to component CSS classes. diff --git a/docs/pages/blog/build-layouts-faster-with-grid-v2.md b/docs/pages/blog/build-layouts-faster-with-grid-v2.md index b40ad11e25f25f..b2b6a5834b37ce 100644 --- a/docs/pages/blog/build-layouts-faster-with-grid-v2.md +++ b/docs/pages/blog/build-layouts-faster-with-grid-v2.md @@ -4,7 +4,7 @@ description: The new Grid v2 features simplified logic, support for offsetting a date: 2022-08-20T00:00:00.000Z authors: ['siriwatknp'] tags: ['Material UI', 'Guide'] -card: true +manualCard: true --- You can now use the new `Grid` component, shipped with [Material UI v5.9.0](https://github.com/mui/material-ui/releases/tag/v5.9.0), for updated features and a better developer experience when building layouts. diff --git a/docs/pages/blog/callback-support-in-style-overrides.md b/docs/pages/blog/callback-support-in-style-overrides.md index 77325f31e9dfbc..42019929c4721f 100644 --- a/docs/pages/blog/callback-support-in-style-overrides.md +++ b/docs/pages/blog/callback-support-in-style-overrides.md @@ -4,7 +4,7 @@ description: We're excited to introduce callback support for global theme overri date: 2022-01-31T00:00:00.000Z authors: ['siriwatknp'] tags: ['Material UI', 'Product'] -card: true +manualCard: true --- [Material UI v5.3.0](https://github.com/mui/material-ui/releases/tag/v5.3.0) introduces the ability to write a callback in style overrides (global theming), giving you full control of component customization at the theme level. diff --git a/docs/pages/blog/danail-hadjiatanasov-joining.md b/docs/pages/blog/danail-hadjiatanasov-joining.md index 5f0904549b960e..b39eeb6a65ce42 100644 --- a/docs/pages/blog/danail-hadjiatanasov-joining.md +++ b/docs/pages/blog/danail-hadjiatanasov-joining.md @@ -4,7 +4,7 @@ description: We are excited to share that Danail Hadjiatanasov has joined MUI as date: 2020-10-23T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- We are excited to share that [Danail Hadjiatanasov](https://twitter.com/danail_h) has joined MUI as part of the enterprise team. This was his first full-time week. diff --git a/docs/pages/blog/danilo-leal-joining.md b/docs/pages/blog/danilo-leal-joining.md index e18707c8f16947..55e6c3032a036c 100644 --- a/docs/pages/blog/danilo-leal-joining.md +++ b/docs/pages/blog/danilo-leal-joining.md @@ -4,7 +4,7 @@ description: We are excited to share that Danilo Leal has joined MUI. date: 2021-07-15T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- We are excited to share that [Danilo Leal](https://daniloleal.co/) has joined MUI! diff --git a/docs/pages/blog/date-pickers-stable-v5.md b/docs/pages/blog/date-pickers-stable-v5.md index 306637c250c28c..61b15bc7f59f2f 100644 --- a/docs/pages/blog/date-pickers-stable-v5.md +++ b/docs/pages/blog/date-pickers-stable-v5.md @@ -4,7 +4,7 @@ description: Migrate to the latest version for improved DX, customizability, and date: 2022-09-19T00:00:00.000Z authors: ['alexfauquette', 'josefreitas'] tags: ['MUI X', 'Product'] -card: true +manualCard: true --- About four months ago, we moved the date and time pickers from `@mui/lab` and released the first alpha version of the date pickers package. diff --git a/docs/pages/blog/december-2019-update.md b/docs/pages/blog/december-2019-update.md index 28cb4694f2c35d..e747320df73cf6 100644 --- a/docs/pages/blog/december-2019-update.md +++ b/docs/pages/blog/december-2019-update.md @@ -4,7 +4,7 @@ description: Here are the most significant improvements in December. date: 2020-01-07T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- Here are the most significant improvements in December: diff --git a/docs/pages/blog/discord-announcement.md b/docs/pages/blog/discord-announcement.md index 4a58bb279a84c7..fc0cd949e5a01f 100644 --- a/docs/pages/blog/discord-announcement.md +++ b/docs/pages/blog/discord-announcement.md @@ -4,7 +4,7 @@ description: Come join our community to engage in lively discussions, share your date: 2023-08-02T00:00:00.000Z authors: ['richbustos'] tags: ['Company'] -card: true +manualCard: true --- Discord banner with link diff --git a/docs/pages/blog/docs-restructure-2022.md b/docs/pages/blog/docs-restructure-2022.md index 6fe7e34853094e..1ea829b42c889f 100644 --- a/docs/pages/blog/docs-restructure-2022.md +++ b/docs/pages/blog/docs-restructure-2022.md @@ -4,7 +4,7 @@ description: Each of MUI's products now has its own dedicated documentation, mak date: 2022-04-06T00:00:00.000Z authors: ['danilo-leal'] tags: ['Product'] -card: true +manualCard: true --- As MUI continues to grow beyond our flagship product, Material UI (we [rebranded the company](/blog/material-ui-is-now-mui/) last year as a first step), it has become clear that the documentation for our products can no longer all live under one roof. diff --git a/docs/pages/blog/first-look-at-joy.md b/docs/pages/blog/first-look-at-joy.md index e8f541cfff3b40..56a77bd1dc57d3 100644 --- a/docs/pages/blog/first-look-at-joy.md +++ b/docs/pages/blog/first-look-at-joy.md @@ -4,7 +4,7 @@ description: A sneak peek at MUI's new starting point for your design system. date: 2022-06-08T00:00:00.000Z authors: ['danilo-leal', 'siriwatknp'] tags: ['Joy UI', 'Product'] -card: true +manualCard: true --- First look at Joy UI: a new starting point for your design system. diff --git a/docs/pages/blog/introducing-base-ui.md b/docs/pages/blog/introducing-base-ui.md index 9b49539b13eb2b..4846ce5df26df8 100644 --- a/docs/pages/blog/introducing-base-ui.md +++ b/docs/pages/blog/introducing-base-ui.md @@ -4,7 +4,7 @@ description: The Base UI component library gives you complete control over the date: 2022-09-07T00:00:00.000Z authors: ['michaldudak', 'samuelsycamore'] tags: ['Base UI', 'Product'] -card: true +manualCard: true --- Demo components built with Base UI, a newly introduced library of unstyled components and hooks diff --git a/docs/pages/blog/introducing-sync-plugin.js b/docs/pages/blog/introducing-sync-plugin.js new file mode 100644 index 00000000000000..0df1baf6886277 --- /dev/null +++ b/docs/pages/blog/introducing-sync-plugin.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import TopLayoutBlog from 'docs/src/modules/components/TopLayoutBlog'; +import { docs } from './introducing-sync-plugin.md?muiMarkdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/blog/introducing-sync-plugin.md b/docs/pages/blog/introducing-sync-plugin.md new file mode 100644 index 00000000000000..bc6d8c6e519cc6 --- /dev/null +++ b/docs/pages/blog/introducing-sync-plugin.md @@ -0,0 +1,68 @@ +--- +title: 'Introducing Sync: a Figma plugin that exports Material UI theme code' +description: Enable designers to generate production-ready code directly from the Material UI Figma Design Kit. +date: 2024-04-30T00:00:00.000Z +authors: ['danilo-leal', 'DavidCnoops'] +tags: ['Material UI', 'Product'] +manualCard: true +--- + +Over the last few years, we've seen designers increasingly seeking out ways to participate more directly and collaborate more effectively in the development process. +The [Material UI Design Kit for Figma](/store/items/figma-react/) was our first attempt to meet those needs by providing designers with one-to-one mockups of Material UI components for implementing custom design systems. +But it doesn't go far enough on its own to bridge the gap between design and code—the developer still needs to write the designer's custom styles from scratch. + +That got us thinking: +What if designers could generate production-ready code directly from their design software to hand off to developers working with a Material UI codebase? + +That's why we created Sync, a Figma plugin for generating styles that can be copied and pasted straight into your Material UI app's theme. +We're happy to share that the beta version is [available now on Figma](https://www.figma.com/community/plugin/1336346114713490235/material-ui-sync). 🚀 + +Material UI Sync is a Figma plugin that lets you generate a theme from the Material UI for Figma Design Kit. + +Let's take a look at some of its key features: + +## Theme customization + +Figma's local variables significantly matured the use of design tokens, making it possible to mirror Material UI more closely. +Sync relies on these local variables to generate code corresponding to each element and state. +(As such, it requires [v5.16.0 or later](https://github.com/mui/mui-design-kits/releases/tag/v5.16.0) of the Material UI Design Kit; earlier versions do not support local variables.) + + + +Visit the documentation to learn [how to insert the generated code into your theme file](/material-ui/design-resources/material-ui-sync/#using-the-generated-theme). + +## Component customization + +You can fully customize a component's appearance across multiple states in the Design Kit and then generate the corresponding theme code. +This is one of the most exciting features because it enables designers to use the visual design tools they're already comfortable with to make changes to the code itself. + + + +:::warning +While in beta, not all components are supported yet. +We'll expand component coverage progressively in the coming months. +For now, you can experiment with the Button, Switch, and Typography. +::: + +## Quick Storybook preview + +The Material UI Sync plugin also bakes in an embedded Storybook preview panel so that you can conveniently play around with your changes and see how they interact with other props and states available in the component API. + + + +## Try Sync now + +Get the beta version of Material UI Sync now, available for free in the [Figma Community](https://www.figma.com/community/plugin/1336346114713490235/material-ui-sync)! + +There's still a lot to do, and we're looking forward to hearing from all of you [who requested this plugin years ago](https://github.com/mui/mui-design-kits/issues/10). + +- Check out the documentation for [the Sync plugin](/material-ui/design-resources/material-ui-sync/) and [the Material UI Design Kit](/material-ui/design-resources/material-ui-for-figma/). +- If you've got any feedback, we'd love to [hear from you](https://material-ui-sync.canny.io/). + +Happy designing! 👨‍🎨 diff --git a/docs/pages/blog/introducing-the-row-grouping-feature.md b/docs/pages/blog/introducing-the-row-grouping-feature.md index 817909ca6361e9..f4a7aae089a900 100644 --- a/docs/pages/blog/introducing-the-row-grouping-feature.md +++ b/docs/pages/blog/introducing-the-row-grouping-feature.md @@ -4,7 +4,7 @@ description: The new row grouping feature gives your users more customization op date: 2022-01-20T00:00:00.000Z authors: ['alexfauquette'] tags: ['MUI X', 'Product'] -card: true +manualCard: true --- After an incredible year fully focused on improving our Data Grid component, we are moving forward by launching the first feature of our new Premium plan: [row grouping](/x/react-data-grid/row-grouping/), released in [v5.3.0](https://github.com/mui/mui-x/releases/tag/v5.3.0). diff --git a/docs/pages/blog/july-2019-update.md b/docs/pages/blog/july-2019-update.md index 26f0470b57f311..9ee2ae7e852852 100644 --- a/docs/pages/blog/july-2019-update.md +++ b/docs/pages/blog/july-2019-update.md @@ -4,7 +4,7 @@ description: Here are the most significant improvements in July. date: 2019-08-04T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- Here are the most significant improvements in July: diff --git a/docs/pages/blog/june-2019-update.md b/docs/pages/blog/june-2019-update.md index 92e81c2dbdaabe..5781f76514ce57 100644 --- a/docs/pages/blog/june-2019-update.md +++ b/docs/pages/blog/june-2019-update.md @@ -4,7 +4,7 @@ description: Here are the most significant improvements in June. date: 2019-07-08T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- Here are the most significant improvements in June: diff --git a/docs/pages/blog/lab-date-pickers-to-mui-x.md b/docs/pages/blog/lab-date-pickers-to-mui-x.md index 9d7ddc8dfacb24..e8ab79741f5006 100644 --- a/docs/pages/blog/lab-date-pickers-to-mui-x.md +++ b/docs/pages/blog/lab-date-pickers-to-mui-x.md @@ -4,7 +4,7 @@ description: Migrate to the new package to start building with our powerful Date date: 2022-04-03T00:00:00.000Z authors: ['flaviendelangle'] tags: ['MUI X', 'Product'] -card: true +manualCard: true --- After more than 18 months in the lab, the Date and Time Picker components have found a new home as part of MUI X. diff --git a/docs/pages/blog/lab-tree-view-to-mui-x.md b/docs/pages/blog/lab-tree-view-to-mui-x.md index 7a35a33f599044..cb876949ef5087 100644 --- a/docs/pages/blog/lab-tree-view-to-mui-x.md +++ b/docs/pages/blog/lab-tree-view-to-mui-x.md @@ -4,7 +4,7 @@ description: Migrate to the new package to start building with our powerful Tree date: 2023-08-21T00:00:00.000Z authors: ['flaviendelangle'] tags: ['MUI X', 'Product'] -card: true +manualCard: true --- After more than 4 years in the lab, the [Tree View](https://mui.com/x/react-tree-view/) components have found a new home as part of MUI X. diff --git a/docs/pages/blog/making-customizable-components.md b/docs/pages/blog/making-customizable-components.md index 071e08af31bf0c..fb170deb030d07 100644 --- a/docs/pages/blog/making-customizable-components.md +++ b/docs/pages/blog/making-customizable-components.md @@ -4,7 +4,7 @@ description: Explore the tradeoffs between different customization techniques, a date: 2022-08-22T00:00:00.000Z authors: ['alexfauquette'] tags: ['MUI X', 'Material UI', 'Guide'] -card: true +manualCard: true --- Material UI's components are used by hundreds of thousands of developers worldwide, encompassing the full range of implementation from minor side projects to massive company websites. diff --git a/docs/pages/blog/march-2019-update.md b/docs/pages/blog/march-2019-update.md index 743c1d67f13d0f..1ea42cd92ed75e 100644 --- a/docs/pages/blog/march-2019-update.md +++ b/docs/pages/blog/march-2019-update.md @@ -4,7 +4,7 @@ description: Here are the most significant improvements in March. date: 2019-04-05T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- Here are the most significant improvements in March: diff --git a/docs/pages/blog/marija-najdova-joining.md b/docs/pages/blog/marija-najdova-joining.md index 344a665e26b27e..003b0880ef8b59 100644 --- a/docs/pages/blog/marija-najdova-joining.md +++ b/docs/pages/blog/marija-najdova-joining.md @@ -4,7 +4,7 @@ description: We are excited to share that Marija Najdova has joined MUI. She has date: 2020-09-15T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- We are excited to share that [Marija Najdova](https://twitter.com/marijanajdova) has joined MUI. She has started this week full-time, and is now part of the community team. diff --git a/docs/pages/blog/material-ui-is-now-mui.md b/docs/pages/blog/material-ui-is-now-mui.md index b956024eae46cd..926d85ea2a8fb2 100644 --- a/docs/pages/blog/material-ui-is-now-mui.md +++ b/docs/pages/blog/material-ui-is-now-mui.md @@ -4,7 +4,7 @@ description: Starting today, we are evolving our brand identity. We are clarifyi date: 2021-09-16T00:00:00.000Z authors: ['oliviertassinari', 'danilo-leal', 'mbrookes'] tags: ['Material UI'] -card: true +manualCard: true --- The new Material UI logo diff --git a/docs/pages/blog/material-ui-v1-is-out.md b/docs/pages/blog/material-ui-v1-is-out.md index d88daf681f8ec3..f2e6395ae67ead 100644 --- a/docs/pages/blog/material-ui-v1-is-out.md +++ b/docs/pages/blog/material-ui-v1-is-out.md @@ -4,7 +4,7 @@ description: It has taken us two years to do it, but Material UI v1 has finally date: 2018-05-18T00:00:00.000Z authors: ['oliviertassinari', 'mbrookes'] tags: ['Material UI', 'Product'] -card: true +manualCard: true --- > React components that implement Google's Material Design. @@ -32,7 +32,7 @@ Material UI v1 is our second stab at the execution of [the vision](/material-ui We want Material UI to become whatever is generally useful for application development, all in the spirit of the Material Design guidelines. Material UI is not only an implementation of the Material Design guidelines, but a general use UI library of components that are needed by many. We are even allowing developers to build non Material themes on top of Material UI components. We will soon open source examples of this. - **CSS-in-JS**. We have seen [a great potential for **inline-styles** in the past](https://github.com/mui/material-ui/issues/30). It was an opportunity to solve four problems at once: removing the LESS toolchain dependency, allowing dynamic styles, allowing style code splitting and make overrides simpler. - Unfortunately, the **[execution didn't deliver](https://github.com/mui/material-ui/issues/4066)**. We were lacking key features only available in CSS: media queries, pseudo selectors, pseudo elements, browser prefixes. Debugging was much harder. Overriding styles was very challenging – developers always had to look the implementation, and couldn't use CSS without relying on !important. + Unfortunately, the **[execution didn't deliver](https://github.com/mui/material-ui/issues/4066)**. We were lacking key features only available in CSS: media queries, pseudo selectors, pseudo-elements, browser prefixes. Debugging was much harder. Overriding styles was very challenging – developers always had to look the implementation, and couldn't use CSS without relying on !important. Two years ago, we decided to move away [from inline-styles toward **CSS-in-JS**](https://github.com/oliviertassinari/a-journey-toward-better-style). We are very happy with the outcome. We would like to thank [@kof](https://github.com/kof) for the awesome work he has done with [JSS](https://github.com/cssinjs/jss), the internal solution we use. It's allowing us to be [interoperable](/material-ui/integrations/interoperability/) with all the other styling solutions. - **Theme**. You can't have a good customizability story without a good theming story. We have been redesigning the theme. It's a [JavaScript object](/material-ui/customization/default-theme/) that contains all the variables and utility functions you might need to style your components: a palette, a typography, breakpoints helpers, transition helpers, etc. @@ -40,14 +40,14 @@ We want Material UI to become whatever is generally useful for application deve ### Ease of use -We know the ease of use is a critical part of user acquisition. The more user we have, the more likely we can make the project sustainable. Improving the ease of use comes in different flavors: +We know the ease of use is a critical part of user acquisition. The more users we have, the more likely we can make the project sustainable. Improving the ease of use comes in different flavors: - **Onboarding**. We have reduced the onboarding friction as much as possible. We know the onboarding is a critical step for user acquisition. The onboarding friction comes in different flavors: We have reduced the number of installation steps needed. It should be as simple as 1. npm install @mui/material and 2. import Button from '@mui/material/Button'; . We don't ask for polyfill, custom Webpack plugin or any specific build tool. The usage of MuiThemeProvider is no longer mandatory. - **Examples**. We are hosting [example projects](https://github.com/mui/material-ui/tree/master/examples) with the most popular solutions to start a project: [create-react-app](https://github.com/facebook/create-react-app), [Next.js](https://github.com/vercel/next.js), [Gatsby](https://github.com/gatsbyjs/gatsby), and CDN. -- **Isolation**. Our components now work in isolation. You should be able to use a single Material UI component in an existing codebase without any side effect. No global CSS override needed, no bundle size bloat. +- **Isolation**. Our components now work in isolation. You should be able to use a single Material UI component in an existing codebase without any side effects. No global CSS override needed, no bundle size bloat. - **Documentation**. We have made a huge investment in the documentation. We use [Next.js](https://github.com/vercel/next.js) for a blazingly fast navigation experience. It's also allowing us to provide a first server-side support for the components. We had added a search bar powered by [Algolia's DocSearch](https://docsearch.algolia.com/). (don't miss the s shortcut to focus the search bar). We have added many new documentation sections: guides, FAQ, etc. We have made the demos more interactive thanks to a direct integration with CodeSandbox. @@ -59,19 +59,19 @@ Many people discover web development through Material UI but it's also used in - **Best practices.** We are following the best practices as much as possible. We have made the components: fully accessible, fully [HTML5 compliant](https://validator.w3.org/) and SEO friendly. -![[Lighthouse](https://github.com/GoogleChrome/lighthouse) report of the Material UI documentation homepage](https://cdn-images-1.medium.com/max/2000/1*_x_j-jasswGw0WaDyeHk-g.png) +![[Lighthouse](https://github.com/GoogleChrome/lighthouse) report of the Material UI documentation homepage](https://cdn-images-1.medium.com/v2/resize:fit:2000/1*_x_j-jasswGw0WaDyeHk-g.png)

Lighthouse report of the Material UI documentation homepage

- **Continuous integration.** Every single line of code is tested. We have an impressive [💯% test coverage](https://codecov.io/gh/mui/material-ui/branch/master). With more than 700 contributors, it's really important. All these tests allow us to quickly iterate and with confidence. We run the test suite runs on all the supported platforms. We also run more than [180 visual regression tests](https://app.argos-ci.com/mui/material-ui/builds) thanks to [Argos-CI](https://www.argos-ci.com/). -![An example [BrowserStack](https://www.browserstack.com/) build](https://cdn-images-1.medium.com/max/2000/1*bnWGqotk36ivrYTp3dY7fA.png) +![An example [BrowserStack](https://www.browserstack.com/) build](https://cdn-images-1.medium.com/v2/resize:fit:2000/1*bnWGqotk36ivrYTp3dY7fA.png)

An example BrowserStack build

-- **Bundle size**. If you take all the Material UI components, your bundle will weight more than 100 kB gzipped. Material UI looks like a huge dependency but it's fine in practice with code splitting. You will most likely use ~40% of the library on a given page/screen. The bundle size is important. It's [constantly monitored](https://github.com/mui/material-ui/blob/ca69253843208c21593fff230151e1fffd93a566/.size-limit), which prevents us from introducing size regressions, and allows us to recognize positive efforts. +- **Bundle size**. If you take all the Material UI components, your bundle will weigh more than 100 kB gzipped. Material UI looks like a huge dependency but it's fine in practice with code splitting. You will most likely use ~40% of the library on a given page/screen. The bundle size is important. It's [constantly monitored](https://github.com/mui/material-ui/blob/ca69253843208c21593fff230151e1fffd93a566/.size-limit), which prevents us from introducing size regressions, and allows us to recognize positive efforts. -![An example of [size-limit](https://github.com/ai/size-limit) output](https://cdn-images-1.medium.com/max/2000/1*AQoyq9OvjFZJE2Ep0UtCzA.png) +![An example of [size-limit](https://github.com/ai/size-limit) output](https://cdn-images-1.medium.com/v2/resize:fit:2000/1*AQoyq9OvjFZJE2Ep0UtCzA.png)

An example of size-limit

@@ -107,25 +107,25 @@ There are so many new things, we can't be exhaustive. Aside from what we have al We have shipped the long-awaited Material UI v1 stable release. With a new codebase designed to better support customization, it's the perfect timing to start building and promoting premium themes. We are very happy to announce [the first two](https://mui.com/store/) from [Creative Tim](https://mui.com/store/contributors/creative-tim/). More are coming. -![Creative Tim themes](https://cdn-images-1.medium.com/max/2000/1*jPOu6n1EMsqv4Gh652MtPA.png) +![Creative Tim themes](https://cdn-images-1.medium.com/v2/resize:fit:2000/1*jPOu6n1EMsqv4Gh652MtPA.png)

Creative Tim themes

-![A preview of an open source theme we will soon release.](https://cdn-images-1.medium.com/max/2000/1*CThJG6Kuk-XlSM53jM6KLQ.png) +![A preview of an open-source theme we will soon release.](https://cdn-images-1.medium.com/v2/resize:fit:2000/1*CThJG6Kuk-XlSM53jM6KLQ.png) -

A preview of an open source theme we will soon release.

+

A preview of an open-source theme we will soon release.

## Thank you Finally, one last thank you to everyone who's contributed to Material UI v1. I'm so excited at the idea we are making it stable, but rest assured, it's just the beginning. We will keep working hard on delivering the best possible UI library components. -Material UI is an MIT-licensed open source project. It's an independent project with ongoing development helped by the support of these awesome [backers](/material-ui/discover-more/backers/). If you'd like to join them, please consider: +Material UI is an MIT-licensed open-source project. It's an independent project with ongoing development helped by the support of these awesome [backers](/material-ui/discover-more/backers/). If you'd like to join them, please consider: - [Become a backer or sponsor on Open Collective](https://opencollective.com/mui-org). - [Become a backer or sponsor on Patreon](https://www.patreon.com/oliviertassinari). -![Our gold sponsors](https://cdn-images-1.medium.com/max/2000/1*fx_BaOxYY0ZJo3n9iXI1Jg.png)

Our gold sponsors

+![Our gold sponsors](https://cdn-images-1.medium.com/v2/resize:fit:2000/1*fx_BaOxYY0ZJo3n9iXI1Jg.png)

Our gold sponsors

- GitHub: https://github.com/mui/material-ui ⭐ - X: https://twitter.com/MUI_hq diff --git a/docs/pages/blog/material-ui-v4-is-out.md b/docs/pages/blog/material-ui-v4-is-out.md index dfefd5a27ec56a..1dc63490f2f542 100644 --- a/docs/pages/blog/material-ui-v4-is-out.md +++ b/docs/pages/blog/material-ui-v4-is-out.md @@ -4,7 +4,7 @@ description: Material UI v4 has finally arrived. We are so excited about this r date: 2019-05-23T00:00:00.000Z authors: ['oliviertassinari', 'mbrookes', 'eps1lon'] tags: ['Material UI', 'Product'] -card: true +manualCard: true --- > React components for faster and simpler web development. Build your own design system, or start with Material Design. diff --git a/docs/pages/blog/matheus-wichman-joining.md b/docs/pages/blog/matheus-wichman-joining.md index 17ac52ad24e52b..8d9579d01873f0 100644 --- a/docs/pages/blog/matheus-wichman-joining.md +++ b/docs/pages/blog/matheus-wichman-joining.md @@ -4,7 +4,7 @@ description: We are excited to share that Matheus Wichman has joined MUI. date: 2021-04-05T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- We are excited to share that [Matheus Wichman](https://github.com/m4theushw) has joined MUI. diff --git a/docs/pages/blog/may-2019-update.md b/docs/pages/blog/may-2019-update.md index f8cf8fa3e259a1..9707d0f28b783d 100644 --- a/docs/pages/blog/may-2019-update.md +++ b/docs/pages/blog/may-2019-update.md @@ -4,7 +4,7 @@ description: Here are the most significant improvements in May. date: 2019-06-08T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- Here are the most significant improvements in May: diff --git a/docs/pages/blog/michal-dudak-joining.md b/docs/pages/blog/michal-dudak-joining.md index fe4c351bd27a09..4186fbcfc08548 100644 --- a/docs/pages/blog/michal-dudak-joining.md +++ b/docs/pages/blog/michal-dudak-joining.md @@ -4,7 +4,7 @@ description: We are excited to share that Michał Dudak has joined MUI. date: 2021-06-14T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- We are excited to share that [Michał Dudak](https://twitter.com/michaldudak) has joined MUI! diff --git a/docs/pages/blog/mui-core-v5-migration-update.md b/docs/pages/blog/mui-core-v5-migration-update.md index 04a9be054133ad..f050089780ec73 100644 --- a/docs/pages/blog/mui-core-v5-migration-update.md +++ b/docs/pages/blog/mui-core-v5-migration-update.md @@ -3,7 +3,7 @@ title: Why you should migrate to Material UI v5 today description: We have completely revamped our Migration guide to reduce friction when upgrading to v5. Get started now! date: 2022-06-20T00:00:00.000Z authors: ['samuelsycamore'] -card: true +manualCard: true tags: ['Material UI'] --- diff --git a/docs/pages/blog/mui-core-v5.md b/docs/pages/blog/mui-core-v5.md index 41b88056fc045f..868808c1e65088 100644 --- a/docs/pages/blog/mui-core-v5.md +++ b/docs/pages/blog/mui-core-v5.md @@ -12,7 +12,7 @@ authors: 'danilo-leal', 'mbrookes', ] -card: true +manualCard: true tags: ['Product', 'Material UI'] --- @@ -477,7 +477,7 @@ Although each product has its unique vision and mission statements, they complem - Vision: Create the last UI component library developers will ever need. High quality, consistent, feature-rich, and covering the most frequent/challenging use-cases. - Mission: Make building rich, data-intensive, dynamic apps a breeze. -MUI Core has a positive cash flow thanks to its paid templates, design assets, ads on the documentation, and backers/sponsors (❤️). The [MIT](https://tldrlegal.com/license/mit-license) license model works great for it. +MUI Core has a positive cash flow thanks to its paid templates, design assets, ads on the documentation, and backers/sponsors (❤️). The [MIT](https://www.tldrlegal.com/license/mit-license) license model works great for it. However, none of these revenue sources would scale with the outcome and amount of work required for MUI X. It's why we are using an [open core license model](https://en.m.wikipedia.org/wiki/Open-core_model) for this new product. diff --git a/docs/pages/blog/mui-next-js-app-router.md b/docs/pages/blog/mui-next-js-app-router.md index 344fc0faa7b52c..2c00e3dc372be3 100644 --- a/docs/pages/blog/mui-next-js-app-router.md +++ b/docs/pages/blog/mui-next-js-app-router.md @@ -3,7 +3,7 @@ title: MUI Core libraries support the Next.js App Router description: Material UI, Base UI, and Joy UI are now compatible with the App Router as Client Components. Get started using the latest Next.js features with MUI! date: 2023-07-18T00:00:00.000Z authors: ['samuelsycamore'] -card: true +manualCard: true tags: ['Product'] --- diff --git a/docs/pages/blog/mui-product-comparison.md b/docs/pages/blog/mui-product-comparison.md index 5268b3104d6e57..dfb8c4b542f939 100644 --- a/docs/pages/blog/mui-product-comparison.md +++ b/docs/pages/blog/mui-product-comparison.md @@ -3,7 +3,7 @@ title: An introduction to the MUI ecosystem description: MUI is more than just Material UI. Consider Joy UI, Base UI, MUI X, and Toolpad for your next project. date: 2022-11-01T00:00:00.000Z authors: ['samuelsycamore'] -card: true +manualCard: true tags: ['Product'] --- diff --git a/docs/pages/blog/mui-x-end-v6-features.md b/docs/pages/blog/mui-x-end-v6-features.md index 19dd6b95f107bc..e350c4af838be7 100644 --- a/docs/pages/blog/mui-x-end-v6-features.md +++ b/docs/pages/blog/mui-x-end-v6-features.md @@ -3,7 +3,7 @@ title: MUI X v6.18.0 and the latest features before the next major description: New components, polished features, better performance and more. date: 2023-11-13T00:00:00.000Z authors: ['josefreitas'] -card: true +manualCard: true tags: ['MUI X', 'Product'] --- diff --git a/docs/pages/blog/mui-x-mid-v6-features.md b/docs/pages/blog/mui-x-mid-v6-features.md index 64c7da76591a52..8348b66c7e2baa 100644 --- a/docs/pages/blog/mui-x-mid-v6-features.md +++ b/docs/pages/blog/mui-x-mid-v6-features.md @@ -3,7 +3,7 @@ title: MUI X v6.11.0. A roundup of all new features description: Support for time zones, Charts in alpha, Data Grid filtering, and more. date: 2023-08-14T00:00:00.000Z authors: ['richbustos', 'josefreitas'] -card: true +manualCard: true tags: ['MUI X', 'Product'] --- diff --git a/docs/pages/blog/mui-x-v5.md b/docs/pages/blog/mui-x-v5.md index 3e68847e5763e1..8ca2616041f276 100644 --- a/docs/pages/blog/mui-x-v5.md +++ b/docs/pages/blog/mui-x-v5.md @@ -4,7 +4,7 @@ description: We are excited to introduce MUI X v5.0.0! date: 2021-11-22T00:00:00.000Z authors: ['oliviertassinari', 'm4theushw', 'flaviendelangle', 'DanailH', 'alexfauquette'] -card: true +manualCard: true tags: ['MUI X', 'Product'] --- diff --git a/docs/pages/blog/mui-x-v6-alpha-zero.md b/docs/pages/blog/mui-x-v6-alpha-zero.md index eefcf84e50348f..de7976f967cfe6 100644 --- a/docs/pages/blog/mui-x-v6-alpha-zero.md +++ b/docs/pages/blog/mui-x-v6-alpha-zero.md @@ -4,7 +4,7 @@ description: Let us know what you want to see in MUI X v6 as we begin the alpha date: 2022-09-30T00:00:00.000Z authors: ['josefreitas'] tags: ['MUI X', 'Product'] -card: true +manualCard: true --- We're kicking off the development of [MUI X v6](https://github.com/mui/mui-x/releases/tag/v6.0.0-alpha.0). diff --git a/docs/pages/blog/mui-x-v6.md b/docs/pages/blog/mui-x-v6.md index 4b666d5c82b42a..06e97177a0f0c7 100644 --- a/docs/pages/blog/mui-x-v6.md +++ b/docs/pages/blog/mui-x-v6.md @@ -3,7 +3,7 @@ title: Introducing MUI X v6 description: Introducing the new major version of the advanced components. date: 2023-03-06T00:00:00.000Z authors: ['josefreitas'] -card: true +manualCard: true tags: ['MUI X', 'Product'] --- diff --git a/docs/pages/blog/mui-x-v7-beta.md b/docs/pages/blog/mui-x-v7-beta.md index 258a29b7fc57e7..f32df9cab0212e 100644 --- a/docs/pages/blog/mui-x-v7-beta.md +++ b/docs/pages/blog/mui-x-v7-beta.md @@ -4,7 +4,7 @@ description: Check out what's new and what's next for v7 stable. date: 2024-01-29T00:00:00.000Z authors: ['josefreitas'] tags: ['MUI X', 'Product'] -card: true +manualCard: true ---
diff --git a/docs/pages/blog/mui-x-v7.md b/docs/pages/blog/mui-x-v7.md index 3bdea7324095d6..cce65bad6eefb9 100644 --- a/docs/pages/blog/mui-x-v7.md +++ b/docs/pages/blog/mui-x-v7.md @@ -4,7 +4,7 @@ description: Check out all the newest additions to the next major of the advance date: 2024-03-22T08:00:00.000Z authors: ['josefreitas'] tags: ['MUI X', 'Product'] -card: true +manualCard: true ---
diff --git a/docs/pages/blog/november-2019-update.md b/docs/pages/blog/november-2019-update.md index fc9f1bf498ab4d..afb3cbff843fc9 100644 --- a/docs/pages/blog/november-2019-update.md +++ b/docs/pages/blog/november-2019-update.md @@ -4,7 +4,7 @@ description: Here are the most significant improvements in November. date: 2019-12-12T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- Here are the most significant improvements in November: diff --git a/docs/pages/blog/october-2019-update.md b/docs/pages/blog/october-2019-update.md index 7644683613f25d..d5b3c21f260dda 100644 --- a/docs/pages/blog/october-2019-update.md +++ b/docs/pages/blog/october-2019-update.md @@ -4,7 +4,7 @@ description: Here are the most significant improvements in October. date: 2019-11-08T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- Here are the most significant improvements in October: diff --git a/docs/pages/blog/premium-plan-release.md b/docs/pages/blog/premium-plan-release.md index 4d5166c36c263f..d7ab992827f551 100644 --- a/docs/pages/blog/premium-plan-release.md +++ b/docs/pages/blog/premium-plan-release.md @@ -4,7 +4,7 @@ description: Introducing the MUI X Premium plan, and a new licensing model. date: 2022-05-12T00:00:00.000Z authors: ['josefreitas', 'alexfauquette'] tags: ['MUI X', 'Product'] -card: true +manualCard: true --- We're happy to announce that the Premium plan is [finally out](https://mui.com/pricing/)! diff --git a/docs/pages/blog/remote-award-win-2024.md b/docs/pages/blog/remote-award-win-2024.md index bb8cddee874266..0162f0e8a93f06 100644 --- a/docs/pages/blog/remote-award-win-2024.md +++ b/docs/pages/blog/remote-award-win-2024.md @@ -4,7 +4,7 @@ description: We're delighted to be honored with this global recognition for our date: 2024-03-20T12:00:00.000Z authors: ['mikailaread'] tags: ['Company'] -card: true +manualCard: true --- MUI has been named a **winner** in the first-ever [Remote Excellence Awards](https://remote.com/remote-excellence-awards), in the Small & Mighty category! 🎉 diff --git a/docs/pages/blog/september-2019-update.md b/docs/pages/blog/september-2019-update.md index 851cda97d166b7..55c9c442b742f5 100644 --- a/docs/pages/blog/september-2019-update.md +++ b/docs/pages/blog/september-2019-update.md @@ -4,7 +4,7 @@ description: Here are the most significant improvements in September. date: 2019-10-12T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- Here are the most significant improvements in September: diff --git a/docs/pages/blog/siriwat-kunaporn-joining.md b/docs/pages/blog/siriwat-kunaporn-joining.md index c858b89ccf4e33..2150a1835d1760 100644 --- a/docs/pages/blog/siriwat-kunaporn-joining.md +++ b/docs/pages/blog/siriwat-kunaporn-joining.md @@ -4,7 +4,7 @@ description: We are excited to share that Siriwat Kunaporn has joined MUI. date: 2021-05-17T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- We are excited to share that [Siriwat Kunaporn](https://twitter.com/siriwatknp) (Jun) has joined MUI. diff --git a/docs/pages/blog/spotlight-damien-tassone.md b/docs/pages/blog/spotlight-damien-tassone.md index 6952fe623e1c35..8dc08dd0c823e6 100644 --- a/docs/pages/blog/spotlight-damien-tassone.md +++ b/docs/pages/blog/spotlight-damien-tassone.md @@ -4,7 +4,7 @@ description: Damien Tassone has joined MUI. He's the first full-time member to f date: 2020-09-15T00:00:00.000Z authors: ['oliviertassinari'] tags: ['Company'] -card: true +manualCard: true --- A few months ago, right in the middle of the COVID-19 outbreak, [Damien Tassone](https://twitter.com/madKakoO) joined MUI. He's the first full-time member to focus on enterprise components. Back then, we only made a quick mention of it. It's never too late to introduce him properly. diff --git a/docs/pages/blog/toolpad-use-cases.md b/docs/pages/blog/toolpad-use-cases.md index 30879950a648e4..8fc2bab05029e6 100644 --- a/docs/pages/blog/toolpad-use-cases.md +++ b/docs/pages/blog/toolpad-use-cases.md @@ -3,7 +3,7 @@ title: How does MUI use Toolpad? description: Explore how we use Toolpad for production use cases at MUI. date: 2024-03-04T00:00:00.000Z authors: ['prakhargupta'] -card: true +manualCard: true tags: ['Product', 'Toolpad'] --- @@ -40,16 +40,16 @@ They share their issue through a Priority Support template in our repository whe Here's how we built an app for this: The [`updateMuiPaidSupport.ts`](https://github.com/mui/mui-public/blob/master/tools-public/toolpad/resources/updateMuiPaidSupport.ts) file hosts all functions that are called from Toolpad. -It uses the [custom function](https://mui.com/toolpad/concepts/custom-functions/) feature and combines GitHub Actions, Google Sheets, and Octokit to read and verify user information. +It uses the [custom function](https://mui.com/toolpad/studio/concepts/custom-functions/) feature and combines GitHub Actions, Google Sheets, and Octokit to read and verify user information. The fetched data is then bound to the UI components. -It uses Toolpad's [page parameters](https://mui.com/toolpad/concepts/page-properties/#page-parameters), [secrets handling](https://mui.com/toolpad/concepts/custom-functions/#secrets-handling), [shell removal](https://mui.com/toolpad/concepts/page-properties/#display-mode), and custom styling features. +It uses Toolpad's [page parameters](https://mui.com/toolpad/studio/concepts/page-properties/#page-parameters), [secrets handling](https://mui.com/toolpad/studio/concepts/custom-functions/#secrets-handling), [shell removal](https://mui.com/toolpad/studio/concepts/page-properties/#display-mode), and custom styling features. This app took one developer just a few hours to build which otherwise would have taken much longer. ## 2. Customer support KPI tracker -The read-only page illustrated below uses [HTTP requests](https://mui.com/toolpad/concepts/http-requests/) for its data source. +The read-only page illustrated below uses [HTTP requests](https://mui.com/toolpad/studio/concepts/http-requests/) for its data source. Through the query builder UI we fetch the 100 latest support tickets from Zendesk to calculate the average time it takes us to respond to and resolve customer requests. -It uses a [custom component](https://mui.com/toolpad/concepts/custom-components/) which we call the "health badge." +It uses a [custom component](https://mui.com/toolpad/studio/concepts/custom-components/) which we call the "health badge." Based on the metric value, the component shows three color-coded states: Problem (red), Warning (yellow), and OK (green). Other KPI pages also use this health badge and pre-built Chart components to compare stats, observe trends, and spot anomalies. @@ -104,5 +104,5 @@ Internal apps are often very specific to the needs of the organization, but hope - Do you wish you didn't have to do any maintenance on the front ends of your internal tools? Toolpad handles state management, data fetching, routing, and UI creation, and it can be imported directly into your code base to save you time. -I encourage you to check out more [examples](https://mui.com/toolpad/examples/) and visit our [GitHub repository](https://github.com/mui/mui-toolpad/) to evaluate the product. +I encourage you to check out more [examples](https://mui.com/toolpad/studio/examples/) and visit our [GitHub repository](https://github.com/mui/mui-toolpad/) to evaluate the product. In case you need any further information, feel free to reach out to the team at toolpad@mui.com. diff --git a/docs/pages/blog/v6-beta-pickers.md b/docs/pages/blog/v6-beta-pickers.md index 8ceeca29aa63cf..22f03ed385fd00 100644 --- a/docs/pages/blog/v6-beta-pickers.md +++ b/docs/pages/blog/v6-beta-pickers.md @@ -4,7 +4,7 @@ description: Check out the new features coming in v6 beta. date: 2023-01-22T00:00:00.000Z authors: ['josefreitas'] tags: ['MUI X', 'Product'] -card: true +manualCard: true --- There's a lot of exciting news in [MUI X v6.0.0-beta.0](https://github.com/mui/mui-x/releases/v6.0.0-beta.0), but there's hardly anything comparable to the revamp we're delivering for the Date and Time Pickers. diff --git a/docs/pages/careers.tsx b/docs/pages/careers.tsx index c1abb1f4579da4..5bac0c83edf0ae 100644 --- a/docs/pages/careers.tsx +++ b/docs/pages/careers.tsx @@ -145,32 +145,19 @@ const faqData = [ const openRolesData = [ { title: 'Engineering', - roles: [ - // { - // title: 'React Engineer — xCharts', - // description: - // 'You will help form the xCharts team, build ambitious and complex new features, work on strategic problems, and help grow adoption.', - // url: '/careers/react-engineer-x-charts/', - // }, - // { - // title: 'React Engineer — X', - // description: - // 'You will strengthen the MUI X product, build ambitious and complex new features, work on strategic problems, and help grow adoption.', - // url: '/careers/react-engineer-x/', - // }, - ], - }, - { - title: 'Design', roles: [ { - title: 'Design Engineer — xGrid', + title: 'React Engineer — X', description: - 'You will design and implement a great user and developer experience for the MUI X Data Grid.', - url: '/careers/design-engineer-x-grid/', + 'You will strengthen the MUI X product, build ambitious and complex new features, work on strategic problems, and help grow adoption.', + url: '/careers/react-engineer-x/', }, ], }, + { + title: 'Design', + roles: [], + }, { title: 'Developer Experience', roles: [ @@ -182,17 +169,6 @@ const openRolesData = [ }, ], }, - { - title: 'Support', - roles: [ - { - title: 'Customer Support Agent', - description: - 'You will help MUI provide timely and efficient support to our customers and continue to streamline our customer operations across the board.', - url: '/careers/support-agent/', - }, - ], - }, ]; const nextRolesData = [ @@ -208,15 +184,9 @@ const nextRolesData = [ { title: 'Full-stack Engineer — Toolpad', description: - 'You will join the MUI Toolpad team, to explore the role of MUI in the low code space and help bring the early prototype to a usable product.', + 'You will join the Toolpad team, to explore the role of MUI in the low code space and help bring the early prototype to a usable product.', url: '/careers/fullstack-engineer/', }, - { - title: 'React Engineer — X', - description: - 'You will strengthen the MUI X product, build ambitious and complex new features, work on strategic problems, and help grow adoption.', - url: '/careers/react-engineer-x/', - }, { title: 'React Engineer — xCharts', description: @@ -229,12 +199,6 @@ const nextRolesData = [ 'You will lead the development of MUI Core, positioning the library as the industry standard for design teams while doubling its adoption.', url: '/careers/react-tech-lead-core/', }, - { - title: 'React Engineer — Core', - description: - 'You will strengthen the core components team by collaborating with the community to land contributions.', - url: '/careers/react-engineer-core/', - }, { title: 'React Community Engineer — X', description: @@ -243,16 +207,6 @@ const nextRolesData = [ }, ], }, - { - title: 'Design', - roles: [ - { - title: 'Design Engineer', - description: 'You will focus on design to implement great product experiences.', - url: '/careers/design-engineer/', - }, - ], - }, { title: 'People', roles: [ @@ -275,13 +229,7 @@ const nextRolesData = [ }, { title: 'Marketing', - roles: [ - { - title: 'Product Marketing Manager', - description: 'You will own the marketing efforts at MUI.', - url: '/careers/product-marketing-manager/', - }, - ], + roles: [], }, ] as typeof openRolesData; @@ -467,7 +415,13 @@ export default function Careers() { href={routeUrl} noLinkStyle variant="outlined" - sx={{ p: 2, width: '100%', flexGrow: 1 }} + sx={{ + p: 2, + width: '100%', + flexGrow: 1, + display: 'flex', + flexDirection: 'column', + }} > {title} @@ -475,7 +429,12 @@ export default function Careers() { {description} - + Learn more{' '} }> - {openRolesData.map((category) => { - const roles = category.roles; - return ( - - - {category.title} - - {roles.length > 0 ? ( - roles.map((role) => ( + {openRolesData + .filter((category) => category.roles.length > 0) + .map((category) => { + return ( + + + {category.title} + + {category.roles.map((role) => ( - )) - ) : ( - No open roles. - )} - - ); - })} + ))} + + ); + })}
@@ -555,28 +511,25 @@ export default function Careers() { /> }> - {nextRolesData.map((category) => { - const roles = category.roles; - return ( - - - {category.title} - - {roles.length > 0 ? ( - roles.map((role) => ( + {nextRolesData + .filter((category) => category.roles.length > 0) + .map((category) => { + return ( + + + {category.title} + + {category.roles.map((role) => ( - )) - ) : ( - No plans yet. - )} - - ); - })} + ))} + + ); + })} diff --git a/docs/pages/careers/design-engineer-x-grid.js b/docs/pages/careers/design-engineer-x-grid.js deleted file mode 100644 index 6a16aa286ab36d..00000000000000 --- a/docs/pages/careers/design-engineer-x-grid.js +++ /dev/null @@ -1,7 +0,0 @@ -import * as React from 'react'; -import TopLayoutCareers from 'docs/src/modules/components/TopLayoutCareers'; -import * as pageProps from 'docs/pages/careers/design-engineer-x-grid.md?muiMarkdown'; - -export default function Page() { - return ; -} diff --git a/docs/pages/careers/design-engineer.js b/docs/pages/careers/design-engineer.js deleted file mode 100644 index bde4ff97075192..00000000000000 --- a/docs/pages/careers/design-engineer.js +++ /dev/null @@ -1,7 +0,0 @@ -import * as React from 'react'; -import TopLayoutCareers from 'docs/src/modules/components/TopLayoutCareers'; -import * as pageProps from 'docs/pages/careers/design-engineer.md?muiMarkdown'; - -export default function Page() { - return ; -} diff --git a/docs/pages/careers/product-marketing-manager.js b/docs/pages/careers/product-marketing-manager.js deleted file mode 100644 index 9449a4b0d6af7c..00000000000000 --- a/docs/pages/careers/product-marketing-manager.js +++ /dev/null @@ -1,7 +0,0 @@ -import * as React from 'react'; -import TopLayoutCareers from 'docs/src/modules/components/TopLayoutCareers'; -import * as pageProps from 'docs/pages/careers/product-marketing-manager.md?muiMarkdown'; - -export default function Page() { - return ; -} diff --git a/docs/pages/careers/react-engineer-core.js b/docs/pages/careers/react-engineer-core.js deleted file mode 100644 index 5a416da5d8eff0..00000000000000 --- a/docs/pages/careers/react-engineer-core.js +++ /dev/null @@ -1,7 +0,0 @@ -import * as React from 'react'; -import TopLayoutCareers from 'docs/src/modules/components/TopLayoutCareers'; -import * as pageProps from 'docs/pages/careers/react-engineer-core.md?muiMarkdown'; - -export default function Page() { - return ; -} diff --git a/docs/pages/careers/react-engineer-x.md b/docs/pages/careers/react-engineer-x.md index 08f68be0f38e2f..07607712a31e18 100644 --- a/docs/pages/careers/react-engineer-x.md +++ b/docs/pages/careers/react-engineer-x.md @@ -1,4 +1,4 @@ -# React Engineer — X (future role) +# React Engineer — X

You will strengthen the MUI X product, build ambitious and complex new features, work on strategic problems, and help grow adoption.

diff --git a/docs/pages/careers/support-agent.js b/docs/pages/careers/support-agent.js deleted file mode 100644 index c5372798f40bc1..00000000000000 --- a/docs/pages/careers/support-agent.js +++ /dev/null @@ -1,7 +0,0 @@ -import * as React from 'react'; -import TopLayoutCareers from 'docs/src/modules/components/TopLayoutCareers'; -import * as pageProps from 'docs/pages/careers/support-agent.md?muiMarkdown'; - -export default function Page() { - return ; -} diff --git a/docs/pages/design-kits.tsx b/docs/pages/design-kits.tsx index 64eecfde906434..c8259e97bfb5e2 100644 --- a/docs/pages/design-kits.tsx +++ b/docs/pages/design-kits.tsx @@ -7,8 +7,8 @@ import DesignKitHero from 'docs/src/components/productDesignKit/DesignKitHero'; import DesignKitValues from 'docs/src/components/productDesignKit/DesignKitValues'; import DesignKitDemo from 'docs/src/components/productDesignKit/DesignKitDemo'; import DesignKitFAQ from 'docs/src/components/productDesignKit/DesignKitFAQ'; -import Testimonials from 'docs/src/components/home/Testimonials'; -import HeroEnd from 'docs/src/components/home/HeroEnd'; +import SyncFeatures from 'docs/src/components/productDesignKit/SyncFeatures'; +import MaterialEnd from 'docs/src/components/productMaterial/MaterialEnd'; import BrandingCssVarsProvider from 'docs/src/BrandingCssVarsProvider'; import References, { DESIGNKITS_CUSTOMERS } from 'docs/src/components/home/References'; import AppHeaderBanner from 'docs/src/components/banner/AppHeaderBanner'; @@ -31,11 +31,11 @@ export default function DesignKits() { - + - + - + diff --git a/docs/pages/experiments/blog/blog-custom-card.js b/docs/pages/experiments/blog/blog-custom-card.js new file mode 100644 index 00000000000000..57dfbb8a95e4d0 --- /dev/null +++ b/docs/pages/experiments/blog/blog-custom-card.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import TopLayoutBlog from 'docs/src/modules/components/TopLayoutBlog'; +import { docs } from './blog-custom-card.md?muiMarkdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/experiments/blog/blog-custom-card.md b/docs/pages/experiments/blog/blog-custom-card.md new file mode 100644 index 00000000000000..1c26c97454e62d --- /dev/null +++ b/docs/pages/experiments/blog/blog-custom-card.md @@ -0,0 +1,30 @@ +--- +title: Blog post title +description: Our internationally distributed startup gathered on a remote island to get to know each other better. Here's what happened! +date: 2022-07-28T00:00:00.000Z +authors: ['alexfauquette'] +tags: ['Company'] +manualCard: false +cardTitle: blog with\n*custom* card +--- + +## Description + +### Image + +Satellite image of Tenerife + +

An image description with a link.

+ +More text below. + +### Code + +```jsx +// add margin: 8px 0px; + +``` + +

CodeSandbox

+ +More text below. diff --git a/docs/pages/experiments/blog/blog.md b/docs/pages/experiments/blog/blog.md index 0579a43e8f4eff..42c229e45f99c0 100644 --- a/docs/pages/experiments/blog/blog.md +++ b/docs/pages/experiments/blog/blog.md @@ -4,14 +4,14 @@ description: Our internationally distributed startup gathered on a remote island date: 2022-07-28T00:00:00.000Z authors: ['samuelsycamore'] tags: ['Company'] -card: false +manualCard: false --- ## Description ### Image -Satellite image of Tenerife +Satellite image of Tenerife

An image description with a link.

diff --git a/docs/pages/experiments/docs/DemoInDocs.js b/docs/pages/experiments/docs/DemoInDocs.js index fb2cb617cde09d..959249d1f46116 100644 --- a/docs/pages/experiments/docs/DemoInDocs.js +++ b/docs/pages/experiments/docs/DemoInDocs.js @@ -5,8 +5,6 @@ import Stack from '@mui/material/Stack'; export default function DemoInDocs() { return ( - This is an error alert — check it out! - This is a warning alert — check it out! This is an info alert — check it out! This is a success alert — check it out! diff --git a/docs/pages/experiments/docs/DemoInDocs.tsx.preview b/docs/pages/experiments/docs/DemoInDocs.tsx.preview index 7b26ce399bd8f5..35aa272c353c04 100644 --- a/docs/pages/experiments/docs/DemoInDocs.tsx.preview +++ b/docs/pages/experiments/docs/DemoInDocs.tsx.preview @@ -1,4 +1,2 @@ -This is an error alert — check it out! -This is a warning alert — check it out! This is an info alert — check it out! This is a success alert — check it out! \ No newline at end of file diff --git a/docs/pages/experiments/docs/DemoInDocsNotEditable.js b/docs/pages/experiments/docs/DemoInDocsNotEditable.js new file mode 100644 index 00000000000000..959249d1f46116 --- /dev/null +++ b/docs/pages/experiments/docs/DemoInDocsNotEditable.js @@ -0,0 +1,12 @@ +import * as React from 'react'; +import Alert from '@mui/material/Alert'; +import Stack from '@mui/material/Stack'; + +export default function DemoInDocs() { + return ( + + This is an info alert — check it out! + This is a success alert — check it out! + + ); +} diff --git a/docs/pages/experiments/docs/DemoInDocsNotEditable.tsx.preview b/docs/pages/experiments/docs/DemoInDocsNotEditable.tsx.preview new file mode 100644 index 00000000000000..35aa272c353c04 --- /dev/null +++ b/docs/pages/experiments/docs/DemoInDocsNotEditable.tsx.preview @@ -0,0 +1,2 @@ +This is an info alert — check it out! +This is a success alert — check it out! \ No newline at end of file diff --git a/docs/pages/experiments/docs/DemoMultiTabs.js b/docs/pages/experiments/docs/DemoMultiTabs.js new file mode 100644 index 00000000000000..77f396e925cec7 --- /dev/null +++ b/docs/pages/experiments/docs/DemoMultiTabs.js @@ -0,0 +1,37 @@ +import * as React from 'react'; +import { BarChart } from '@mui/x-charts/BarChart'; +import { axisClasses } from '@mui/x-charts'; +import dataset from './dataset.json'; + +const chartSetting = { + yAxis: [ + { + label: 'rainfall (mm)', + }, + ], + width: 500, + height: 300, + sx: { + [`.${axisClasses.left} .${axisClasses.label}`]: { + transform: 'translate(-20px, 0)', + }, + }, +}; + +const valueFormatter = (value) => `${value}mm`; + +export default function BarsDataset() { + return ( + + ); +} diff --git a/docs/pages/experiments/docs/custom-components.md b/docs/pages/experiments/docs/custom-components.md index 18548cb1b10dda..69b8d873fa0a34 100644 --- a/docs/pages/experiments/docs/custom-components.md +++ b/docs/pages/experiments/docs/custom-components.md @@ -4,7 +4,7 @@ ## Header chips -{{"component": "modules/components/ComponentLinkHeader.js"}} +{{"component": "@mui/docs/ComponentLinkHeader"}} ## Feature list diff --git a/docs/pages/experiments/docs/dataset.json b/docs/pages/experiments/docs/dataset.json new file mode 100644 index 00000000000000..c3c44c6bd91174 --- /dev/null +++ b/docs/pages/experiments/docs/dataset.json @@ -0,0 +1,88 @@ +{ + "data": [ + { + "london": 59, + "paris": 57, + "newYork": 86, + "seoul": 21, + "month": "Jan" + }, + { + "london": 50, + "paris": 52, + "newYork": 78, + "seoul": 28, + "month": "Fev" + }, + { + "london": 47, + "paris": 53, + "newYork": 106, + "seoul": 41, + "month": "Mar" + }, + { + "london": 54, + "paris": 56, + "newYork": 92, + "seoul": 73, + "month": "Apr" + }, + { + "london": 57, + "paris": 69, + "newYork": 92, + "seoul": 99, + "month": "May" + }, + { + "london": 60, + "paris": 63, + "newYork": 103, + "seoul": 144, + "month": "June" + }, + { + "london": 59, + "paris": 60, + "newYork": 105, + "seoul": 319, + "month": "July" + }, + { + "london": 65, + "paris": 60, + "newYork": 106, + "seoul": 249, + "month": "Aug" + }, + { + "london": 51, + "paris": 51, + "newYork": 95, + "seoul": 131, + "month": "Sept" + }, + { + "london": 60, + "paris": 65, + "newYork": 97, + "seoul": 55, + "month": "Oct" + }, + { + "london": 67, + "paris": 64, + "newYork": 76, + "seoul": 48, + "month": "Nov" + }, + { + "london": 61, + "paris": 70, + "newYork": 103, + "seoul": 25, + "month": "Dec" + } + ] +} diff --git a/docs/pages/experiments/docs/demos.md b/docs/pages/experiments/docs/demos.md index 9334e1a03b1097..43d1c4e0a3e655 100644 --- a/docs/pages/experiments/docs/demos.md +++ b/docs/pages/experiments/docs/demos.md @@ -1,12 +1,19 @@ # Demos -

Demos

+

The different variants of demo containers we have in the docs.

## Standard demo +"Standard" refers to when no background is explicitly defined. +So, it renders the "outlined" background variant. + {{"demo": "DemoInDocs.js"}} -## "bg": "inline" demo +## "bg": "outlined" + +{{"demo": "DemoInDocs.js", "bg": "outlined"}} + +## "bg": "inline" {{"demo": "DemoInDocs.js", "bg": "inline"}} @@ -14,14 +21,22 @@ {{"demo": "DemoInDocs.js", "bg": true}} +## "bg": gradient + +{{"demo": "DemoInDocs.js", "bg": "gradient"}} + ## "hideToolbar": true -{{"demo": "DemoInDocs.js", "hideToolbar": true}} +{{"demo": "DemoInDocsNotEditable.js", "hideToolbar": true}} ## "hideToolbar": true, "bg": true -{{"demo": "DemoInDocs.js", "hideToolbar": true, "bg": true}} +{{"demo": "DemoInDocsNotEditable.js", "hideToolbar": true, "bg": true}} ## "hideToolbar": true, "bg": "inline" -{{"demo": "DemoInDocs.js", "hideToolbar": true, "bg": "inline"}} +{{"demo": "DemoInDocsNotEditable.js", "hideToolbar": true, "bg": "inline"}} + +## Multiple Tabs demo + +{{"demo": "DemoMultiTabs.js" }} diff --git a/docs/pages/experiments/docs/og-card.js b/docs/pages/experiments/docs/og-card.js new file mode 100644 index 00000000000000..3c3ab187e0adcf --- /dev/null +++ b/docs/pages/experiments/docs/og-card.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from './og-card.md?muiMarkdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/experiments/docs/og-card.md b/docs/pages/experiments/docs/og-card.md new file mode 100644 index 00000000000000..7abbc4ef0e84e9 --- /dev/null +++ b/docs/pages/experiments/docs/og-card.md @@ -0,0 +1,28 @@ +# OG Image + +

How the docs platform generate Open Graph card images.

+ +## The edge function + +The URL `mui.com/edge-functions/og-image` can be queried with 4 search parameters: + +- `product`: the text element displayed next to the MUI logo +- `title`: the title which can contains `\*` to delimit the highlighted (in blue) text sections +- `description`: a paragraph added under the main title +- `authors`: the GitHub username of the authors. It should be divided by a coma. + +## Usage with Markdown + +By default, the card is generated using the page title and description. +You can override this behavior by providing different/specific `cardTitle` and `cardDescription` in the Markdown header, like so: + +```markup +-- +cardTitle: A *different* title than the page title +cardDecription: The word "different" on the title is highlighted +-- +``` + +## Card design preview + +Visit [this StackBlitz demo](https://stackblitz.com/edit/vitejs-vite-ukeejd?file=src%2FApp.tsx) to see how the card looks like without having to run a random page on an OG preview site. diff --git a/docs/pages/material-ui/about-the-lab.js b/docs/pages/material-ui/about-the-lab.js index c0961474d0a02f..c028dfbaea4932 100644 --- a/docs/pages/material-ui/about-the-lab.js +++ b/docs/pages/material-ui/about-the-lab.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/about-the-lab/about-the-lab.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/api/chip.json b/docs/pages/material-ui/api/chip.json index 1d3b02d127913a..1854ff2494185f 100644 --- a/docs/pages/material-ui/api/chip.json +++ b/docs/pages/material-ui/api/chip.json @@ -97,6 +97,12 @@ "isGlobal": false, "isDeprecated": true }, + { + "key": "colorDefault", + "className": "MuiChip-colorDefault", + "description": "Styles applied to the root element if `color=\"default\"`.", + "isGlobal": false + }, { "key": "colorError", "className": "MuiChip-colorError", diff --git a/docs/pages/material-ui/api/form-control-label.json b/docs/pages/material-ui/api/form-control-label.json index 223633117b9393..8cc2cfe4790b17 100644 --- a/docs/pages/material-ui/api/form-control-label.json +++ b/docs/pages/material-ui/api/form-control-label.json @@ -5,7 +5,9 @@ "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, "componentsProps": { "type": { "name": "shape", "description": "{ typography?: object }" }, - "default": "{}" + "default": "{}", + "deprecated": true, + "deprecationInfo": "use the slotProps prop instead. This prop will be removed in v7. How to migrate." }, "disabled": { "type": { "name": "bool" } }, "disableTypography": { "type": { "name": "bool" } }, @@ -27,7 +29,11 @@ }, "required": { "type": { "name": "bool" } }, "slotProps": { - "type": { "name": "shape", "description": "{ typography?: object }" }, + "type": { "name": "shape", "description": "{ typography?: func
| object }" }, + "default": "{}" + }, + "slots": { + "type": { "name": "shape", "description": "{ typography?: elementType }" }, "default": "{}" }, "sx": { @@ -44,6 +50,14 @@ "import FormControlLabel from '@mui/material/FormControlLabel';", "import { FormControlLabel } from '@mui/material';" ], + "slots": [ + { + "name": "typography", + "description": "The component that renders the label.\nThis is unused if `disableTypography` is true.", + "default": "Typography", + "class": null + } + ], "classes": [ { "key": "asterisk", diff --git a/docs/pages/material-ui/api/pagination-item.json b/docs/pages/material-ui/api/pagination-item.json index 68f0269d48d3bb..cbdec459121eab 100644 --- a/docs/pages/material-ui/api/pagination-item.json +++ b/docs/pages/material-ui/api/pagination-item.json @@ -14,7 +14,9 @@ "name": "shape", "description": "{ first?: elementType, last?: elementType, next?: elementType, previous?: elementType }" }, - "default": "{}" + "default": "{}", + "deprecated": true, + "deprecationInfo": "use the slots prop instead. This prop will be removed in v7. How to migrate." }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "page": { "type": { "name": "node" } }, @@ -30,6 +32,13 @@ }, "default": "'medium'" }, + "slotProps": { + "type": { + "name": "shape", + "description": "{ first?: func
| object, last?: func
| object, next?: func
| object, previous?: func
| object }" + }, + "default": "{}" + }, "slots": { "type": { "name": "shape", @@ -64,6 +73,12 @@ "import PaginationItem from '@mui/material/PaginationItem';", "import { PaginationItem } from '@mui/material';" ], + "slots": [ + { "name": "first", "description": "", "class": null }, + { "name": "last", "description": "", "class": null }, + { "name": "next", "description": "", "class": null }, + { "name": "previous", "description": "", "class": null } + ], "classes": [ { "key": "colorPrimary", diff --git a/docs/pages/material-ui/api/step-connector.json b/docs/pages/material-ui/api/step-connector.json index c0d62fb18711f6..ddfa3bb8b11fef 100644 --- a/docs/pages/material-ui/api/step-connector.json +++ b/docs/pages/material-ui/api/step-connector.json @@ -54,14 +54,16 @@ { "key": "lineHorizontal", "className": "MuiStepConnector-lineHorizontal", - "description": "Styles applied to the root element if `orientation=\"horizontal\"`.", - "isGlobal": false + "description": "Styles applied to the line element if `orientation=\"horizontal\"`.", + "isGlobal": false, + "isDeprecated": true }, { "key": "lineVertical", "className": "MuiStepConnector-lineVertical", - "description": "Styles applied to the root element if `orientation=\"vertical\"`.", - "isGlobal": false + "description": "Styles applied to the line element if `orientation=\"vertical\"`.", + "isGlobal": false, + "isDeprecated": true }, { "key": "root", diff --git a/docs/pages/material-ui/api/step-label.json b/docs/pages/material-ui/api/step-label.json index cc855fad1f48fa..07a2c71835e352 100644 --- a/docs/pages/material-ui/api/step-label.json +++ b/docs/pages/material-ui/api/step-label.json @@ -12,15 +12,26 @@ "icon": { "type": { "name": "node" } }, "optional": { "type": { "name": "node" } }, "slotProps": { - "type": { "name": "shape", "description": "{ label?: func
| object }" }, + "type": { + "name": "shape", + "description": "{ label?: func
| object, stepIcon?: func
| object }" + }, "default": "{}" }, "slots": { - "type": { "name": "shape", "description": "{ label?: elementType }" }, + "type": { "name": "shape", "description": "{ label?: elementType, stepIcon?: elementType }" }, "default": "{}" }, - "StepIconComponent": { "type": { "name": "elementType" } }, - "StepIconProps": { "type": { "name": "object" } }, + "StepIconComponent": { + "type": { "name": "elementType" }, + "deprecated": true, + "deprecationInfo": "Use slots.stepIcon instead. This prop will be removed in v7. How to migrate." + }, + "StepIconProps": { + "type": { "name": "object" }, + "deprecated": true, + "deprecationInfo": "Use slotProps.stepIcon instead. This prop will be removed in v7. How to migrate." + }, "sx": { "type": { "name": "union", @@ -40,6 +51,11 @@ "description": "The component that renders the label.", "default": "span", "class": "MuiStepLabel-label" + }, + { + "name": "stepIcon", + "description": "The component to render in place of the [`StepIcon`](/material-ui/api/step-icon/).", + "class": null } ], "classes": [ diff --git a/docs/pages/material-ui/design-resources/material-ui-for-figma.js b/docs/pages/material-ui/design-resources/material-ui-for-figma.js new file mode 100644 index 00000000000000..a38c5cd4d88ddb --- /dev/null +++ b/docs/pages/material-ui/design-resources/material-ui-for-figma.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docs/data/material/design-resources/material-ui-for-figma/material-ui-for-figma.md?muiMarkdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/material-ui/design-resources/material-ui-sync.js b/docs/pages/material-ui/design-resources/material-ui-sync.js new file mode 100644 index 00000000000000..1aed9400cb48fb --- /dev/null +++ b/docs/pages/material-ui/design-resources/material-ui-sync.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docs/data/material/design-resources/material-ui-sync/material-ui-sync.md?muiMarkdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/material-ui/getting-started/design-resources.js b/docs/pages/material-ui/getting-started/design-resources.js index 4df5b129ae956d..8e1e24b65a2436 100644 --- a/docs/pages/material-ui/getting-started/design-resources.js +++ b/docs/pages/material-ui/getting-started/design-resources.js @@ -3,5 +3,5 @@ import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; import * as pageProps from 'docs/data/material/getting-started/design-resources/design-resources.md?muiMarkdown'; export default function Page() { - return ; + return ; } diff --git a/docs/pages/material-ui/icons.js b/docs/pages/material-ui/icons.js index 567b92d1ef1e9c..07de341709f0e8 100644 --- a/docs/pages/material-ui/icons.js +++ b/docs/pages/material-ui/icons.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/icons/icons.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/material-icons.js b/docs/pages/material-ui/material-icons.js index 8bdbc9d6729753..88344171346946 100644 --- a/docs/pages/material-ui/material-icons.js +++ b/docs/pages/material-ui/material-icons.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/material-icons/material-icons.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-accordion.js b/docs/pages/material-ui/react-accordion.js index 26291b13befe10..1c7e53c5306d51 100644 --- a/docs/pages/material-ui/react-accordion.js +++ b/docs/pages/material-ui/react-accordion.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/accordion/accordion.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-alert.js b/docs/pages/material-ui/react-alert.js index 84552123aacd05..5ff0b8e14c5653 100644 --- a/docs/pages/material-ui/react-alert.js +++ b/docs/pages/material-ui/react-alert.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/alert/alert.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-app-bar.js b/docs/pages/material-ui/react-app-bar.js index 2a58a66711a75c..84efc04925f535 100644 --- a/docs/pages/material-ui/react-app-bar.js +++ b/docs/pages/material-ui/react-app-bar.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/app-bar/app-bar.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-autocomplete.js b/docs/pages/material-ui/react-autocomplete.js index 1ec006a4f20a34..8902dffd65db28 100644 --- a/docs/pages/material-ui/react-autocomplete.js +++ b/docs/pages/material-ui/react-autocomplete.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/autocomplete/autocomplete.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-avatar.js b/docs/pages/material-ui/react-avatar.js index 0c74ca45a6b3d7..fb69aa1b721484 100644 --- a/docs/pages/material-ui/react-avatar.js +++ b/docs/pages/material-ui/react-avatar.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/avatars/avatars.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-backdrop.js b/docs/pages/material-ui/react-backdrop.js index cac8c8788807d3..9246804b99e358 100644 --- a/docs/pages/material-ui/react-backdrop.js +++ b/docs/pages/material-ui/react-backdrop.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/backdrop/backdrop.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-badge.js b/docs/pages/material-ui/react-badge.js index 096d87c87f47f8..bf7e789c24b2dd 100644 --- a/docs/pages/material-ui/react-badge.js +++ b/docs/pages/material-ui/react-badge.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/badges/badges.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-bottom-navigation.js b/docs/pages/material-ui/react-bottom-navigation.js index edefefdea6dbce..133c440143c6e5 100644 --- a/docs/pages/material-ui/react-bottom-navigation.js +++ b/docs/pages/material-ui/react-bottom-navigation.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/bottom-navigation/bottom-navigation.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-box.js b/docs/pages/material-ui/react-box.js index e9439033fd229e..350423ce30f00b 100644 --- a/docs/pages/material-ui/react-box.js +++ b/docs/pages/material-ui/react-box.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/box/box.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-breadcrumbs.js b/docs/pages/material-ui/react-breadcrumbs.js index 0cd1f21647d87d..f64f67b09fd1d0 100644 --- a/docs/pages/material-ui/react-breadcrumbs.js +++ b/docs/pages/material-ui/react-breadcrumbs.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/breadcrumbs/breadcrumbs.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-card.js b/docs/pages/material-ui/react-card.js index 67fa766a02990f..8fb6f72afe1968 100644 --- a/docs/pages/material-ui/react-card.js +++ b/docs/pages/material-ui/react-card.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/cards/cards.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-checkbox.js b/docs/pages/material-ui/react-checkbox.js index 16ebde8c0e0a9a..e6c610d0dd0ba6 100644 --- a/docs/pages/material-ui/react-checkbox.js +++ b/docs/pages/material-ui/react-checkbox.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/checkboxes/checkboxes.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-chip.js b/docs/pages/material-ui/react-chip.js index 548d240e966a38..9af1f9e4bd4785 100644 --- a/docs/pages/material-ui/react-chip.js +++ b/docs/pages/material-ui/react-chip.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/chips/chips.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-click-away-listener.js b/docs/pages/material-ui/react-click-away-listener.js index 8b51c04a6b1cf2..fb964ae06144a5 100644 --- a/docs/pages/material-ui/react-click-away-listener.js +++ b/docs/pages/material-ui/react-click-away-listener.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/click-away-listener/click-away-listener.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-container.js b/docs/pages/material-ui/react-container.js index d5d647dc828dfa..974047436f4464 100644 --- a/docs/pages/material-ui/react-container.js +++ b/docs/pages/material-ui/react-container.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/container/container.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-css-baseline.js b/docs/pages/material-ui/react-css-baseline.js index 68d27f2b41af7c..fb43be46fc6ea0 100644 --- a/docs/pages/material-ui/react-css-baseline.js +++ b/docs/pages/material-ui/react-css-baseline.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/css-baseline/css-baseline.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-dialog.js b/docs/pages/material-ui/react-dialog.js index 537a476553a2eb..2ded281a496a7a 100644 --- a/docs/pages/material-ui/react-dialog.js +++ b/docs/pages/material-ui/react-dialog.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/dialogs/dialogs.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-divider.js b/docs/pages/material-ui/react-divider.js index 7c32aa1c784f47..4ca13335073941 100644 --- a/docs/pages/material-ui/react-divider.js +++ b/docs/pages/material-ui/react-divider.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/dividers/dividers.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-drawer.js b/docs/pages/material-ui/react-drawer.js index 6d8905e8275778..8aac39efcdfaca 100644 --- a/docs/pages/material-ui/react-drawer.js +++ b/docs/pages/material-ui/react-drawer.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/drawers/drawers.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-floating-action-button.js b/docs/pages/material-ui/react-floating-action-button.js index 681bebda025a79..66a5658de6a2cf 100644 --- a/docs/pages/material-ui/react-floating-action-button.js +++ b/docs/pages/material-ui/react-floating-action-button.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/floating-action-button/floating-action-button.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-grid.js b/docs/pages/material-ui/react-grid.js index 78ddcb6ee321ee..2ffecb31f92132 100644 --- a/docs/pages/material-ui/react-grid.js +++ b/docs/pages/material-ui/react-grid.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/grid/grid.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-grid2.js b/docs/pages/material-ui/react-grid2.js index b4dbffc77707c3..99e253537cc1a6 100644 --- a/docs/pages/material-ui/react-grid2.js +++ b/docs/pages/material-ui/react-grid2.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/grid2/grid2.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-hidden.js b/docs/pages/material-ui/react-hidden.js index 51cccdd38378a2..6f2d3fabf003e6 100644 --- a/docs/pages/material-ui/react-hidden.js +++ b/docs/pages/material-ui/react-hidden.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/hidden/hidden.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-image-list.js b/docs/pages/material-ui/react-image-list.js index f0f150afe7277e..79a5925eb05e95 100644 --- a/docs/pages/material-ui/react-image-list.js +++ b/docs/pages/material-ui/react-image-list.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/image-list/image-list.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-link.js b/docs/pages/material-ui/react-link.js index c288ac87affe2b..6a3c6bbb71149c 100644 --- a/docs/pages/material-ui/react-link.js +++ b/docs/pages/material-ui/react-link.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/links/links.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-list.js b/docs/pages/material-ui/react-list.js index c78ea0de33ba26..5ff15e226ab828 100644 --- a/docs/pages/material-ui/react-list.js +++ b/docs/pages/material-ui/react-list.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/lists/lists.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-masonry.js b/docs/pages/material-ui/react-masonry.js index 56633ff2e8d6d0..8d60dbed5893bf 100644 --- a/docs/pages/material-ui/react-masonry.js +++ b/docs/pages/material-ui/react-masonry.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/masonry/masonry.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-menu.js b/docs/pages/material-ui/react-menu.js index 33113e15a78f28..adeeb30a02ab9c 100644 --- a/docs/pages/material-ui/react-menu.js +++ b/docs/pages/material-ui/react-menu.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/menus/menus.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-modal.js b/docs/pages/material-ui/react-modal.js index 46d8fc442d7d0d..2fd8152936ee4d 100644 --- a/docs/pages/material-ui/react-modal.js +++ b/docs/pages/material-ui/react-modal.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/modal/modal.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-no-ssr.js b/docs/pages/material-ui/react-no-ssr.js index ee83206a71178d..3b2bf08f6f15a8 100644 --- a/docs/pages/material-ui/react-no-ssr.js +++ b/docs/pages/material-ui/react-no-ssr.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/no-ssr/no-ssr.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-pagination.js b/docs/pages/material-ui/react-pagination.js index 9a48a0ed86d11b..fe739abc49562b 100644 --- a/docs/pages/material-ui/react-pagination.js +++ b/docs/pages/material-ui/react-pagination.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/pagination/pagination.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-paper.js b/docs/pages/material-ui/react-paper.js index 41ece6824d65db..1d3530c004087e 100644 --- a/docs/pages/material-ui/react-paper.js +++ b/docs/pages/material-ui/react-paper.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/paper/paper.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-popover.js b/docs/pages/material-ui/react-popover.js index 48cba31980a1c7..9bbd2deb5f5e5f 100644 --- a/docs/pages/material-ui/react-popover.js +++ b/docs/pages/material-ui/react-popover.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/popover/popover.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-popper.js b/docs/pages/material-ui/react-popper.js index 6ab2616c48f0af..f228bcde1491d2 100644 --- a/docs/pages/material-ui/react-popper.js +++ b/docs/pages/material-ui/react-popper.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/popper/popper.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-portal.js b/docs/pages/material-ui/react-portal.js index 07a891e7658072..ad08e80adecda0 100644 --- a/docs/pages/material-ui/react-portal.js +++ b/docs/pages/material-ui/react-portal.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/portal/portal.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-progress.js b/docs/pages/material-ui/react-progress.js index 85e37159117a78..e4a2a09cd1db57 100644 --- a/docs/pages/material-ui/react-progress.js +++ b/docs/pages/material-ui/react-progress.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/progress/progress.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-radio-button.js b/docs/pages/material-ui/react-radio-button.js index b881c8a18b6f80..e8db25df8ce071 100644 --- a/docs/pages/material-ui/react-radio-button.js +++ b/docs/pages/material-ui/react-radio-button.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/radio-buttons/radio-buttons.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-rating.js b/docs/pages/material-ui/react-rating.js index ece9b071bf2aaa..a4fba7027ca9c6 100644 --- a/docs/pages/material-ui/react-rating.js +++ b/docs/pages/material-ui/react-rating.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/rating/rating.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-select.js b/docs/pages/material-ui/react-select.js index d5d9459ff95307..e158606f9199b5 100644 --- a/docs/pages/material-ui/react-select.js +++ b/docs/pages/material-ui/react-select.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/selects/selects.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-skeleton.js b/docs/pages/material-ui/react-skeleton.js index 40aeb2ea2b2bbe..2ff3091f92006f 100644 --- a/docs/pages/material-ui/react-skeleton.js +++ b/docs/pages/material-ui/react-skeleton.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/skeleton/skeleton.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-slider.js b/docs/pages/material-ui/react-slider.js index 2762b71458c831..e11443c469eaf4 100644 --- a/docs/pages/material-ui/react-slider.js +++ b/docs/pages/material-ui/react-slider.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/slider/slider.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-snackbar.js b/docs/pages/material-ui/react-snackbar.js index ef9cd9110e75e7..b1f6c4efa1a6a3 100644 --- a/docs/pages/material-ui/react-snackbar.js +++ b/docs/pages/material-ui/react-snackbar.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/snackbars/snackbars.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-speed-dial.js b/docs/pages/material-ui/react-speed-dial.js index b51a5eece1a78d..3ed86f5fde2a05 100644 --- a/docs/pages/material-ui/react-speed-dial.js +++ b/docs/pages/material-ui/react-speed-dial.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/speed-dial/speed-dial.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-stack.js b/docs/pages/material-ui/react-stack.js index 44e36ffc1eeff3..af230dcf002b3f 100644 --- a/docs/pages/material-ui/react-stack.js +++ b/docs/pages/material-ui/react-stack.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/stack/stack.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-stepper.js b/docs/pages/material-ui/react-stepper.js index f56275b1654708..7a389033833b41 100644 --- a/docs/pages/material-ui/react-stepper.js +++ b/docs/pages/material-ui/react-stepper.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/steppers/steppers.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-switch.js b/docs/pages/material-ui/react-switch.js index d8d850f538c943..59f5eae99895ea 100644 --- a/docs/pages/material-ui/react-switch.js +++ b/docs/pages/material-ui/react-switch.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/switches/switches.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-table.js b/docs/pages/material-ui/react-table.js index 10b6203c6b830b..398a5a9a46a551 100644 --- a/docs/pages/material-ui/react-table.js +++ b/docs/pages/material-ui/react-table.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/table/table.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-tabs.js b/docs/pages/material-ui/react-tabs.js index 51e69d3a7630ae..2406fcc3a665ce 100644 --- a/docs/pages/material-ui/react-tabs.js +++ b/docs/pages/material-ui/react-tabs.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/tabs/tabs.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-text-field.js b/docs/pages/material-ui/react-text-field.js index f7756ce29ddd50..c3f07ee5467c48 100644 --- a/docs/pages/material-ui/react-text-field.js +++ b/docs/pages/material-ui/react-text-field.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/text-fields/text-fields.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-textarea-autosize.js b/docs/pages/material-ui/react-textarea-autosize.js index 7d1def906c2aec..4c87d54571af4e 100644 --- a/docs/pages/material-ui/react-textarea-autosize.js +++ b/docs/pages/material-ui/react-textarea-autosize.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/textarea-autosize/textarea-autosize.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-timeline.js b/docs/pages/material-ui/react-timeline.js index 83869d3365841c..87167e7220fba0 100644 --- a/docs/pages/material-ui/react-timeline.js +++ b/docs/pages/material-ui/react-timeline.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/timeline/timeline.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-toggle-button.js b/docs/pages/material-ui/react-toggle-button.js index 822839b3fad4a8..c5df44f259cd62 100644 --- a/docs/pages/material-ui/react-toggle-button.js +++ b/docs/pages/material-ui/react-toggle-button.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/toggle-button/toggle-button.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-tooltip.js b/docs/pages/material-ui/react-tooltip.js index 4cd5c404f860db..3893fc2aed36a6 100644 --- a/docs/pages/material-ui/react-tooltip.js +++ b/docs/pages/material-ui/react-tooltip.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/tooltips/tooltips.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-transfer-list.js b/docs/pages/material-ui/react-transfer-list.js index 952f286ac40fc6..2ae58dcfb4ff3b 100644 --- a/docs/pages/material-ui/react-transfer-list.js +++ b/docs/pages/material-ui/react-transfer-list.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/transfer-list/transfer-list.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-typography.js b/docs/pages/material-ui/react-typography.js index f5014b469b0416..4a0b190155e9ea 100644 --- a/docs/pages/material-ui/react-typography.js +++ b/docs/pages/material-ui/react-typography.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/typography/typography.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/react-use-media-query.js b/docs/pages/material-ui/react-use-media-query.js index 44e229472b0685..ae24bc8ce38672 100644 --- a/docs/pages/material-ui/react-use-media-query.js +++ b/docs/pages/material-ui/react-use-media-query.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/use-media-query/use-media-query.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/pages/material-ui/transitions.js b/docs/pages/material-ui/transitions.js index c60770e5e2c518..2647d9bc2870e8 100644 --- a/docs/pages/material-ui/transitions.js +++ b/docs/pages/material-ui/transitions.js @@ -1,7 +1,12 @@ import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; +import AppFrame from 'docs/src/modules/components/AppFrame'; import * as pageProps from 'docs/data/material/components/transitions/transitions.md?muiMarkdown'; export default function Page() { return ; } + +Page.getLayout = (page) => { + return {page}; +}; diff --git a/docs/public/_redirects b/docs/public/_redirects index 017dbacffa4757..86426d708e1b11 100644 --- a/docs/public/_redirects +++ b/docs/public/_redirects @@ -527,7 +527,7 @@ https://v4.material-ui.com/* https://v4.mui.com/:splat 301! /r/x-* https://material-ui-x.netlify.app/r/x-:splat 200 /:lang/x/* https://material-ui-x.netlify.app/:lang/x/:splat 200 -## MUI Toolpad +## Toolpad /static/toolpad/* https://mui-toolpad-docs.netlify.app/static/toolpad/:splat 200 /toolpad/_next/* https://mui-toolpad-docs.netlify.app/_next/:splat 200 /toolpad/* https://mui-toolpad-docs.netlify.app/toolpad/:splat 200 diff --git a/docs/public/static/blog/introducing-sync-plugin/card.png b/docs/public/static/blog/introducing-sync-plugin/card.png new file mode 100644 index 00000000000000..8875501c3310d2 Binary files /dev/null and b/docs/public/static/blog/introducing-sync-plugin/card.png differ diff --git a/docs/public/static/blog/introducing-sync-plugin/sync-component.mp4 b/docs/public/static/blog/introducing-sync-plugin/sync-component.mp4 new file mode 100644 index 00000000000000..cedb174f20c375 Binary files /dev/null and b/docs/public/static/blog/introducing-sync-plugin/sync-component.mp4 differ diff --git a/docs/public/static/blog/introducing-sync-plugin/sync-storybook.mp4 b/docs/public/static/blog/introducing-sync-plugin/sync-storybook.mp4 new file mode 100644 index 00000000000000..1745bb0fff93c5 Binary files /dev/null and b/docs/public/static/blog/introducing-sync-plugin/sync-storybook.mp4 differ diff --git a/docs/public/static/blog/introducing-sync-plugin/sync-theme.mp4 b/docs/public/static/blog/introducing-sync-plugin/sync-theme.mp4 new file mode 100644 index 00000000000000..dbceee7accdc3e Binary files /dev/null and b/docs/public/static/blog/introducing-sync-plugin/sync-theme.mp4 differ diff --git a/docs/public/static/branding/about/nadja-kovacev.png b/docs/public/static/branding/about/nadja-kovacev.png new file mode 100644 index 00000000000000..838c0a9530c8e5 Binary files /dev/null and b/docs/public/static/branding/about/nadja-kovacev.png differ diff --git a/docs/public/static/branding/design-kits/material-sync-dark.png b/docs/public/static/branding/design-kits/material-sync-dark.png new file mode 100644 index 00000000000000..3cba4740f68b10 Binary files /dev/null and b/docs/public/static/branding/design-kits/material-sync-dark.png differ diff --git a/docs/public/static/branding/design-kits/material-sync-light.png b/docs/public/static/branding/design-kits/material-sync-light.png new file mode 100644 index 00000000000000..e0ee6491a87ccc Binary files /dev/null and b/docs/public/static/branding/design-kits/material-sync-light.png differ diff --git a/docs/public/static/branding/design-kits/sync-base1-dark.png b/docs/public/static/branding/design-kits/sync-base1-dark.png new file mode 100644 index 00000000000000..1e7b15b95aa7eb Binary files /dev/null and b/docs/public/static/branding/design-kits/sync-base1-dark.png differ diff --git a/docs/public/static/branding/design-kits/sync-base1-light.png b/docs/public/static/branding/design-kits/sync-base1-light.png new file mode 100644 index 00000000000000..be25591a7324e2 Binary files /dev/null and b/docs/public/static/branding/design-kits/sync-base1-light.png differ diff --git a/docs/public/static/branding/design-kits/sync-base2-dark.png b/docs/public/static/branding/design-kits/sync-base2-dark.png new file mode 100644 index 00000000000000..a4bbfea480d9ce Binary files /dev/null and b/docs/public/static/branding/design-kits/sync-base2-dark.png differ diff --git a/docs/public/static/branding/design-kits/sync-base2-light.png b/docs/public/static/branding/design-kits/sync-base2-light.png new file mode 100644 index 00000000000000..d2e905a4a86c0e Binary files /dev/null and b/docs/public/static/branding/design-kits/sync-base2-light.png differ diff --git a/docs/public/static/branding/design-kits/sync-shot1-dark.png b/docs/public/static/branding/design-kits/sync-shot1-dark.png new file mode 100644 index 00000000000000..674ae8ff69d79e Binary files /dev/null and b/docs/public/static/branding/design-kits/sync-shot1-dark.png differ diff --git a/docs/public/static/branding/design-kits/sync-shot1-light.png b/docs/public/static/branding/design-kits/sync-shot1-light.png new file mode 100644 index 00000000000000..78dca9bffa2f72 Binary files /dev/null and b/docs/public/static/branding/design-kits/sync-shot1-light.png differ diff --git a/docs/public/static/branding/design-kits/sync-shot3-dark.png b/docs/public/static/branding/design-kits/sync-shot3-dark.png new file mode 100644 index 00000000000000..12dcb9abb6c2c7 Binary files /dev/null and b/docs/public/static/branding/design-kits/sync-shot3-dark.png differ diff --git a/docs/public/static/branding/design-kits/sync-shot3-light.png b/docs/public/static/branding/design-kits/sync-shot3-light.png new file mode 100644 index 00000000000000..67d09a4a001969 Binary files /dev/null and b/docs/public/static/branding/design-kits/sync-shot3-light.png differ diff --git a/docs/public/static/error-codes.json b/docs/public/static/error-codes.json index a6486f38f45d49..c5acc584689575 100644 --- a/docs/public/static/error-codes.json +++ b/docs/public/static/error-codes.json @@ -18,5 +18,6 @@ "17": "MUI: Expected valid input target. Did you use a custom `slots.input` and forget to forward refs? See https://mui.com/r/input-component-ref-interface for more info.", "18": "MUI: `vars` is a private field used for CSS variables support.\nPlease use another name.", "19": "MUI: `useColorScheme` must be called under ", - "20": "MUI: The `experimental_sx` has been moved to `theme.unstable_sx`.For more details, see https://github.com/mui/material-ui/pull/35150." + "20": "MUI: The `experimental_sx` has been moved to `theme.unstable_sx`.For more details, see https://github.com/mui/material-ui/pull/35150.", + "21": "MUI: The provided shorthand %s is invalid. The format should be `@` or `@/`.\nFor example, `@sm` or `@600` or `@40rem/sidebar`." } diff --git a/docs/public/static/images/showcase/cloudhealth.jpg b/docs/public/static/images/showcase/cloudhealth.jpg deleted file mode 100644 index 84c980d6dd56f1..00000000000000 Binary files a/docs/public/static/images/showcase/cloudhealth.jpg and /dev/null differ diff --git a/docs/public/static/images/templates/blog-dark.png b/docs/public/static/images/templates/blog-dark.png new file mode 100644 index 00000000000000..03ad60a492a907 Binary files /dev/null and b/docs/public/static/images/templates/blog-dark.png differ diff --git a/docs/public/static/images/templates/blog-light.png b/docs/public/static/images/templates/blog-light.png new file mode 100644 index 00000000000000..ff252d1e7aa33e Binary files /dev/null and b/docs/public/static/images/templates/blog-light.png differ diff --git a/docs/public/static/images/templates/blog.png b/docs/public/static/images/templates/blog.png deleted file mode 100644 index debe0f3ed3a9b4..00000000000000 Binary files a/docs/public/static/images/templates/blog.png and /dev/null differ diff --git a/docs/public/static/images/templates/checkout-dark.png b/docs/public/static/images/templates/checkout-dark.png new file mode 100644 index 00000000000000..6269d11fed5dd8 Binary files /dev/null and b/docs/public/static/images/templates/checkout-dark.png differ diff --git a/docs/public/static/images/templates/checkout-light.png b/docs/public/static/images/templates/checkout-light.png new file mode 100644 index 00000000000000..6bdda36f908a5a Binary files /dev/null and b/docs/public/static/images/templates/checkout-light.png differ diff --git a/docs/public/static/images/templates/checkout.png b/docs/public/static/images/templates/checkout.png deleted file mode 100644 index e5cfba2cd01c55..00000000000000 Binary files a/docs/public/static/images/templates/checkout.png and /dev/null differ diff --git a/docs/public/static/images/templates/dashboard-dark.png b/docs/public/static/images/templates/dashboard-dark.png new file mode 100644 index 00000000000000..42984725db85dc Binary files /dev/null and b/docs/public/static/images/templates/dashboard-dark.png differ diff --git a/docs/public/static/images/templates/dashboard-light.png b/docs/public/static/images/templates/dashboard-light.png new file mode 100644 index 00000000000000..e93b5e52c57954 Binary files /dev/null and b/docs/public/static/images/templates/dashboard-light.png differ diff --git a/docs/public/static/images/templates/dashboard.png b/docs/public/static/images/templates/dashboard.png deleted file mode 100644 index 2a10b08116f94f..00000000000000 Binary files a/docs/public/static/images/templates/dashboard.png and /dev/null differ diff --git a/docs/public/static/images/templates/landing-page-dark.png b/docs/public/static/images/templates/landing-page-dark.png new file mode 100644 index 00000000000000..e48adbb205b1f3 Binary files /dev/null and b/docs/public/static/images/templates/landing-page-dark.png differ diff --git a/docs/public/static/images/templates/landing-page-light.png b/docs/public/static/images/templates/landing-page-light.png new file mode 100644 index 00000000000000..b6d375da2a36c0 Binary files /dev/null and b/docs/public/static/images/templates/landing-page-light.png differ diff --git a/docs/public/static/images/templates/landing-page.png b/docs/public/static/images/templates/landing-page.png deleted file mode 100644 index a6dfeac3242598..00000000000000 Binary files a/docs/public/static/images/templates/landing-page.png and /dev/null differ diff --git a/docs/public/static/images/templates/pricing.png b/docs/public/static/images/templates/pricing.png deleted file mode 100644 index 745f03cbeb7689..00000000000000 Binary files a/docs/public/static/images/templates/pricing.png and /dev/null differ diff --git a/docs/public/static/images/templates/sign-in-dark.png b/docs/public/static/images/templates/sign-in-dark.png new file mode 100644 index 00000000000000..a67406f45f8a81 Binary files /dev/null and b/docs/public/static/images/templates/sign-in-dark.png differ diff --git a/docs/public/static/images/templates/sign-in-light.png b/docs/public/static/images/templates/sign-in-light.png new file mode 100644 index 00000000000000..888b41cff9c4f5 Binary files /dev/null and b/docs/public/static/images/templates/sign-in-light.png differ diff --git a/docs/public/static/images/templates/sign-in-side-dark.png b/docs/public/static/images/templates/sign-in-side-dark.png new file mode 100644 index 00000000000000..b3332ca4079314 Binary files /dev/null and b/docs/public/static/images/templates/sign-in-side-dark.png differ diff --git a/docs/public/static/images/templates/sign-in-side-light.png b/docs/public/static/images/templates/sign-in-side-light.png new file mode 100644 index 00000000000000..b8180488e28e20 Binary files /dev/null and b/docs/public/static/images/templates/sign-in-side-light.png differ diff --git a/docs/public/static/images/templates/sign-in-side.png b/docs/public/static/images/templates/sign-in-side.png deleted file mode 100644 index fb00a2d01160fb..00000000000000 Binary files a/docs/public/static/images/templates/sign-in-side.png and /dev/null differ diff --git a/docs/public/static/images/templates/sign-in.png b/docs/public/static/images/templates/sign-in.png deleted file mode 100644 index 597b57ae1d1356..00000000000000 Binary files a/docs/public/static/images/templates/sign-in.png and /dev/null differ diff --git a/docs/public/static/images/templates/sign-up-dark.png b/docs/public/static/images/templates/sign-up-dark.png new file mode 100644 index 00000000000000..ad19c16a0de062 Binary files /dev/null and b/docs/public/static/images/templates/sign-up-dark.png differ diff --git a/docs/public/static/images/templates/sign-up-light.png b/docs/public/static/images/templates/sign-up-light.png new file mode 100644 index 00000000000000..514db1bcce3d1a Binary files /dev/null and b/docs/public/static/images/templates/sign-up-light.png differ diff --git a/docs/public/static/images/templates/sign-up.png b/docs/public/static/images/templates/sign-up.png deleted file mode 100644 index b92eca0b42a10a..00000000000000 Binary files a/docs/public/static/images/templates/sign-up.png and /dev/null differ diff --git a/docs/public/static/images/templates/sticky-footer-dark.png b/docs/public/static/images/templates/sticky-footer-dark.png new file mode 100644 index 00000000000000..276cd14a764555 Binary files /dev/null and b/docs/public/static/images/templates/sticky-footer-dark.png differ diff --git a/docs/public/static/images/templates/sticky-footer-light.png b/docs/public/static/images/templates/sticky-footer-light.png new file mode 100644 index 00000000000000..5a44b3e9168bfb Binary files /dev/null and b/docs/public/static/images/templates/sticky-footer-light.png differ diff --git a/docs/public/static/images/templates/sticky-footer.png b/docs/public/static/images/templates/sticky-footer.png deleted file mode 100644 index 72f56aab9cc854..00000000000000 Binary files a/docs/public/static/images/templates/sticky-footer.png and /dev/null differ diff --git a/docs/public/static/images/themes-display-dark.png b/docs/public/static/images/themes-display-dark.png new file mode 100644 index 00000000000000..bf9e83555f2b25 Binary files /dev/null and b/docs/public/static/images/themes-display-dark.png differ diff --git a/docs/public/static/images/themes-display-light.png b/docs/public/static/images/themes-display-light.png new file mode 100644 index 00000000000000..4b18dd868eb00f Binary files /dev/null and b/docs/public/static/images/themes-display-light.png differ diff --git a/docs/public/static/images/themes-display.png b/docs/public/static/images/themes-display.png deleted file mode 100644 index 43069c6f6855bf..00000000000000 Binary files a/docs/public/static/images/themes-display.png and /dev/null differ diff --git a/docs/public/static/material-ui/design-resources/sync-access.png b/docs/public/static/material-ui/design-resources/sync-access.png new file mode 100644 index 00000000000000..b258cb89eb10b4 Binary files /dev/null and b/docs/public/static/material-ui/design-resources/sync-access.png differ diff --git a/docs/public/static/material-ui/design-resources/sync-code-editor.png b/docs/public/static/material-ui/design-resources/sync-code-editor.png new file mode 100644 index 00000000000000..1a46a265069fdc Binary files /dev/null and b/docs/public/static/material-ui/design-resources/sync-code-editor.png differ diff --git a/docs/public/static/material-ui/design-resources/sync-component-variant.png b/docs/public/static/material-ui/design-resources/sync-component-variant.png new file mode 100644 index 00000000000000..dbf37d0afc2697 Binary files /dev/null and b/docs/public/static/material-ui/design-resources/sync-component-variant.png differ diff --git a/docs/public/static/material-ui/design-resources/sync-generate.png b/docs/public/static/material-ui/design-resources/sync-generate.png new file mode 100644 index 00000000000000..e57963487eb749 Binary files /dev/null and b/docs/public/static/material-ui/design-resources/sync-generate.png differ diff --git a/docs/public/static/material-ui/design-resources/sync-regenerate.png b/docs/public/static/material-ui/design-resources/sync-regenerate.png new file mode 100644 index 00000000000000..303a8e690438ec Binary files /dev/null and b/docs/public/static/material-ui/design-resources/sync-regenerate.png differ diff --git a/docs/public/static/material-ui/design-resources/sync-storybook.png b/docs/public/static/material-ui/design-resources/sync-storybook.png new file mode 100644 index 00000000000000..7604236bfa31aa Binary files /dev/null and b/docs/public/static/material-ui/design-resources/sync-storybook.png differ diff --git a/docs/public/static/material-ui/design-resources/sync-switch-component-customized-storybook.png b/docs/public/static/material-ui/design-resources/sync-switch-component-customized-storybook.png new file mode 100644 index 00000000000000..f5b794d21988da Binary files /dev/null and b/docs/public/static/material-ui/design-resources/sync-switch-component-customized-storybook.png differ diff --git a/docs/public/static/material-ui/design-resources/sync-switch-component-customized.png b/docs/public/static/material-ui/design-resources/sync-switch-component-customized.png new file mode 100644 index 00000000000000..565769a85fe770 Binary files /dev/null and b/docs/public/static/material-ui/design-resources/sync-switch-component-customized.png differ diff --git a/docs/public/static/material-ui/design-resources/sync-switch.png b/docs/public/static/material-ui/design-resources/sync-switch.png new file mode 100644 index 00000000000000..17c8d4af23f16f Binary files /dev/null and b/docs/public/static/material-ui/design-resources/sync-switch.png differ diff --git a/docs/public/static/material-ui/design-resources/sync-variables.png b/docs/public/static/material-ui/design-resources/sync-variables.png new file mode 100644 index 00000000000000..ba5d96c4db307f Binary files /dev/null and b/docs/public/static/material-ui/design-resources/sync-variables.png differ diff --git a/docs/public/static/material-ui/design-resources/sync.png b/docs/public/static/material-ui/design-resources/sync.png new file mode 100644 index 00000000000000..e6da5b6e5c9ad2 Binary files /dev/null and b/docs/public/static/material-ui/design-resources/sync.png differ diff --git a/docs/src/MuiPage.ts b/docs/src/MuiPage.ts index 934782c099a824..36296ce8f71096 100644 --- a/docs/src/MuiPage.ts +++ b/docs/src/MuiPage.ts @@ -53,6 +53,10 @@ export interface MuiPage { * Indicates if the component/hook is not stable yet. */ unstable?: boolean; + /** + * Indicates the item is in beta release. + */ + beta?: boolean; } export interface OrderedMuiPage extends MuiPage { diff --git a/docs/src/components/about/HowToSupport.tsx b/docs/src/components/about/HowToSupport.tsx index 99bc248bd1db31..128763cae41126 100644 --- a/docs/src/components/about/HowToSupport.tsx +++ b/docs/src/components/about/HowToSupport.tsx @@ -27,17 +27,12 @@ function Widget({ ({ - p: 4, + p: 3, height: '100%', display: 'flex', flexDirection: 'column', - borderRadius: '12px', - border: '1px solid', - borderColor: 'grey.100', background: `${(theme.vars || theme).palette.gradients.linearSubtle}`, ...theme.applyDarkStyles({ - bgcolor: 'primaryDark.900', - borderColor: 'primaryDark.700', background: `${(theme.vars || theme).palette.gradients.linearSubtle}`, }), })} @@ -85,12 +80,12 @@ export default function HowToSupport() { @@ -146,12 +141,12 @@ export default function HowToSupport() { @@ -173,12 +168,12 @@ export default function HowToSupport() { diff --git a/docs/src/components/action/Frame.tsx b/docs/src/components/action/Frame.tsx index 64ecab7c500248..f2cf33e9e97e71 100644 --- a/docs/src/components/action/Frame.tsx +++ b/docs/src/components/action/Frame.tsx @@ -36,9 +36,7 @@ const FrameInfo = React.forwardRef(function FrameInfo( borderColor: 'primaryDark.700', borderTop: 0, colorScheme: 'dark', - '* pre, code': { - bgcolor: 'common.black', - }, + overflow: 'clip', ...props.sx, }} /> diff --git a/docs/src/components/action/Item.tsx b/docs/src/components/action/Item.tsx index 4385f5573a84ba..7d391225a73e31 100644 --- a/docs/src/components/action/Item.tsx +++ b/docs/src/components/action/Item.tsx @@ -91,7 +91,9 @@ export default function Item({ p: 2, pr: smallerIconDistance ? 3 : 2, display: 'flex', - alignItems: 'center', + flexDirection: { xs: 'column', sm: 'row' }, + alignItems: { xs: 'start', sm: 'center' }, + gap: { xs: 2, sm: 0.5 }, ...props.sx, }} > diff --git a/docs/src/components/action/NpmCopyButton.tsx b/docs/src/components/action/NpmCopyButton.tsx index e74acf024aae3b..f773a49352c3ae 100644 --- a/docs/src/components/action/NpmCopyButton.tsx +++ b/docs/src/components/action/NpmCopyButton.tsx @@ -13,6 +13,7 @@ const Button = styled('button')(({ theme }) => ({ marginTop: 16, cursor: 'copy', padding: 0, + position: 'relative', display: 'inline-flex', alignItems: 'flex-start', justifyContent: 'center', @@ -34,17 +35,17 @@ const Button = styled('button')(({ theme }) => ({ }), WebkitTapHighlightColor: 'transparent', WebkitFontSmoothing: 'subpixel-antialiased', - color: (theme.vars || theme).palette.grey[600], + color: (theme.vars || theme).palette.text.tertiary, '&:hover, &:focus-visible': { color: (theme.vars || theme).palette.primary.main, '@media (hover: none)': { - color: (theme.vars || theme).palette.grey[600], + color: (theme.vars || theme).palette.text.tertiary, }, }, '& svg': { display: 'inline-block', - position: 'relative', - right: 3, + position: 'absolute', + right: -24, top: 1, opacity: 0, transition: theme.transitions.create('opacity', { diff --git a/docs/src/components/banner/AppHeaderBanner.tsx b/docs/src/components/banner/AppHeaderBanner.tsx index ae83ac840550aa..04377f2d8a5406 100644 --- a/docs/src/components/banner/AppHeaderBanner.tsx +++ b/docs/src/components/banner/AppHeaderBanner.tsx @@ -49,7 +49,7 @@ function getDefaultHiringMessage() { } export default function AppHeaderBanner() { - const showSurveyMessage = true; + const showSurveyMessage = false; const bannerMessage = showSurveyMessage ? getSurveyMessage() : getDefaultHiringMessage(); return FEATURE_TOGGLE.enable_website_banner ? ( diff --git a/docs/src/components/header/HeaderNavBar.tsx b/docs/src/components/header/HeaderNavBar.tsx index 5d53a9b03d7100..a2c3f3fadff065 100644 --- a/docs/src/components/header/HeaderNavBar.tsx +++ b/docs/src/components/header/HeaderNavBar.tsx @@ -69,9 +69,9 @@ const Navigation = styled('nav')(({ theme }) => [ const PRODUCT_IDS = [ 'product-core', 'product-advanced', + 'product-toolpad', 'product-templates', 'product-design', - 'product-toolpad', ]; type ProductSubMenuProps = { @@ -282,29 +282,29 @@ export default function HeaderNavBar() {
  • } - name="Templates" - description="Fully built, out-of-the-box, templates for your application." + href={ROUTES.productToolpad} + icon={} + name="Toolpad" + chip={} + description="Low-code admin builder." />
  • } - name="Design kits" - description="Our components available in your favorite design tool." + href={ROUTES.productTemplates} + icon={} + name="Templates" + description="Fully built, out-of-the-box, templates for your application." />
  • } - name="Toolpad" - chip={} - description="Low-code admin builder." + href={ROUTES.productDesignKits} + icon={} + name="Design Kits" + description="Material UI components in your favorite design tool." />
  • diff --git a/docs/src/components/header/HeaderNavDropdown.tsx b/docs/src/components/header/HeaderNavDropdown.tsx index b48ed4d0a64b44..e625a7443e7fa6 100644 --- a/docs/src/components/header/HeaderNavDropdown.tsx +++ b/docs/src/components/header/HeaderNavDropdown.tsx @@ -71,8 +71,8 @@ const PRODUCTS = [ href: ROUTES.productTemplates, }, { - name: 'Design kits', - description: 'Our components available in your favorite design tool.', + name: 'Design Kits', + description: 'Material UI components in your favorite design tool.', href: ROUTES.productDesignKits, }, { diff --git a/docs/src/components/home/AdvancedShowcase.tsx b/docs/src/components/home/AdvancedShowcase.tsx index 59caeeccbc97ad..56f4fea7edefe9 100644 --- a/docs/src/components/home/AdvancedShowcase.tsx +++ b/docs/src/components/home/AdvancedShowcase.tsx @@ -5,8 +5,7 @@ import Paper from '@mui/material/Paper'; import Typography from '@mui/material/Typography'; import Divider from '@mui/material/Divider'; import ShowcaseContainer from 'docs/src/components/home/ShowcaseContainer'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; -import MarkdownElement from 'docs/src/components/markdown/MarkdownElement'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import XGridGlobalStyles from 'docs/src/components/home/XGridGlobalStyles'; import ProgressBar from 'docs/src/components/x-grid/ProgressBar'; import EditProgress from 'docs/src/components/x-grid/EditProgress'; @@ -1728,12 +1727,7 @@ export default function DataTable() { }, }} > - + } /> diff --git a/docs/src/components/home/CompaniesGrid.tsx b/docs/src/components/home/CompaniesGrid.tsx index 2591dda6a9be02..691f9aefc3e043 100644 --- a/docs/src/components/home/CompaniesGrid.tsx +++ b/docs/src/components/home/CompaniesGrid.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import Grid from '@mui/material/Grid'; +import Grid from '@mui/material/Unstable_Grid2'; import IconImage, { IconImageProps } from 'docs/src/components/icon/IconImage'; export const CORE_CUSTOMERS: Array = [ @@ -189,7 +189,6 @@ export default function CompaniesGrid({ data }: { data: Array }) {data.map((imgProps) => ( {startLine !== undefined && } - + diff --git a/docs/src/components/home/DesignKits.tsx b/docs/src/components/home/DesignKits.tsx index e1e51ea089bc7e..348ffb54fc1fef 100644 --- a/docs/src/components/home/DesignKits.tsx +++ b/docs/src/components/home/DesignKits.tsx @@ -29,10 +29,10 @@ const Image = styled('img')(({ theme }) => ({ objectFit: 'cover', transitionProperty: 'all', transitionDuration: '150ms', - boxShadow: '0px 4px 20px rgba(61, 71, 82, 0.25)', + boxShadow: '0 4px 20px rgba(61, 71, 82, 0.2)', ...theme.applyDarkStyles({ borderColor: (theme.vars || theme).palette.grey[800], - boxShadow: '0px 4px 20px rgba(0, 0, 0, 0.6)', + boxShadow: '0 4px 20px rgba(0, 0, 0, 0.6)', }), })); @@ -40,23 +40,26 @@ const Anchor = styled('a')(({ theme }) => [ { display: 'inline-block', position: 'relative', - transitionProperty: 'all', - transitionDuration: '150ms', + transition: 'all 120ms ease', borderRadius: '50%', border: '1px solid', borderColor: (theme.vars || theme).palette.grey[200], - boxShadow: `0px 2px 12px ${alpha(theme.palette.primary[200], 0.3)}`, + boxShadow: `0 2px 12px ${alpha(theme.palette.primary[200], 0.3)}`, + backgroundColor: '#FFF', '&:hover, &:focus': { borderColor: (theme.vars || theme).palette.primary[300], - boxShadow: `0px 4px 20px ${alpha(theme.palette.primary[400], 0.3)}`, + boxShadow: `0 4px 20px ${alpha(theme.palette.primary[400], 0.3)}`, + backgroundColor: (theme.vars || theme).palette.primary[50], }, } as const, theme.applyDarkStyles({ - borderColor: (theme.vars || theme).palette.primary[900], - boxShadow: `0px 2px 12px ${alpha(theme.palette.primaryDark[800], 0.5)}`, + backgroundColor: alpha(theme.palette.primaryDark[900], 0.8), + borderColor: (theme.vars || theme).palette.primaryDark[600], + boxShadow: `0 2px 12px ${alpha(theme.palette.primaryDark[800], 0.5)}`, '&:hover, &:focus': { + backgroundColor: alpha(theme.palette.primary[900], 0.8), borderColor: (theme.vars || theme).palette.primary[700], - boxShadow: `0 2px 20px 0 ${alpha(theme.palette.primary[800], 0.5)}`, + boxShadow: `0 2px 16px 0 ${alpha(theme.palette.primary[800], 0.5)}`, }, }), ]); @@ -94,18 +97,12 @@ const DesignToolLogo = React.forwardRef< ({ - display: 'flex', - backgroundColor: '#FFF', - p: 2, - borderRadius: '50%', - ...theme.applyDarkStyles({ - backgroundColor: alpha(theme.palette.primary[900], 0.5), - }), - }), + sx={{ + display: 'flex', + p: 2, + borderRadius: '50%', ...(Array.isArray(props.sx) ? props.sx : [props.sx]), - ]} + }} > - + @@ -69,7 +69,7 @@ export default function MaterialDesignDemo(props: CardProps) { zIndex: 2, }} /> - + - + ({ - ...theme.typography.caption, - color: (theme.vars || theme).palette.text.primary, - '& pre': { - backgroundColor: 'hsl(210, 35%, 9%)', // a special, one-off, color tailored for the code blocks using MUI's branding theme blue palette as the starting point. It has a less saturaded color but still maintaining a bit of the blue tint. - color: '#f8f8f2', // fallback color until Prism's theme is loaded - overflow: 'auto', - margin: 0, - WebkitOverflowScrolling: 'touch', // iOS momentum scrolling. - maxWidth: 'calc(100vw - 32px)', - [theme.breakpoints.up('md')]: { - maxWidth: 'calc(100vw - 32px - 16px)', - }, - }, - '& code': { - // Avoid layout jump after hydration (style injected by prism) - ...theme.typography.caption, - fontFamily: theme.typography.fontFamilyCode, - fontWeight: 400, - WebkitFontSmoothing: 'subpixel-antialiased', - // Reset for Safari - // https://github.com/necolas/normalize.css/blob/master/normalize.css#L102 - fontSize: '1em', - }, -})); - -type MarkdownElementProps = { - renderedMarkdown: string; -} & Omit; - -const MarkdownElement = React.forwardRef( - function MarkdownElement(props, ref) { - const { className, renderedMarkdown, ...other } = props; - const more: Record = {}; - - if (typeof renderedMarkdown === 'string') { - // workaround for https://github.com/facebook/react/issues/17170 - // otherwise we could just set `dangerouslySetInnerHTML={undefined}` - more.dangerouslySetInnerHTML = { __html: renderedMarkdown }; - } - - return ; - }, -); - -export default MarkdownElement; diff --git a/docs/src/components/pricing/PricingFAQ.tsx b/docs/src/components/pricing/PricingFAQ.tsx index 58cd45a0601291..380fec80989b25 100644 --- a/docs/src/components/pricing/PricingFAQ.tsx +++ b/docs/src/components/pricing/PricingFAQ.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { styled, alpha } from '@mui/material/styles'; import Box from '@mui/material/Box'; -import Grid from '@mui/material/Grid'; +import Grid from '@mui/material/Unstable_Grid2'; import Link from '@mui/material/Link'; import Paper from '@mui/material/Paper'; import Typography from '@mui/material/Typography'; @@ -272,19 +272,19 @@ export default function PricingFAQ() { Frequently asked questions - + {renderItem(0)} {renderItem(1)} {renderItem(2)} {renderItem(3)} - + {renderItem(4)} {renderItem(5)} {renderItem(6)} {renderItem(7)} - + ({ diff --git a/docs/src/components/pricing/PricingList.tsx b/docs/src/components/pricing/PricingList.tsx index 46eceaabc760a6..3ca9c94cea8a6f 100644 --- a/docs/src/components/pricing/PricingList.tsx +++ b/docs/src/components/pricing/PricingList.tsx @@ -117,7 +117,7 @@ export default function PricingList() { theme.applyDarkStyles({ '& .MuiTab-root': { '&.Mui-selected': { - bgcolor: 'primaryDark.700', + bgcolor: 'primaryDark.800', }, }, }), diff --git a/docs/src/components/pricing/PricingWhatToExpect.tsx b/docs/src/components/pricing/PricingWhatToExpect.tsx index ffeaea5868b4e6..13066ac27238de 100644 --- a/docs/src/components/pricing/PricingWhatToExpect.tsx +++ b/docs/src/components/pricing/PricingWhatToExpect.tsx @@ -36,15 +36,9 @@ export default function PricingWhatToExpect() { }} > - + - + Required quantity @@ -53,6 +47,7 @@ export default function PricingWhatToExpect() { developers contributing changes to the front-end code of the projects that use the software.
    +
    You can learn more about this in{' '}
    - + - + Perpetual license model @@ -93,15 +82,9 @@ export default function PricingWhatToExpect() { - + - + Perpetual vs. Annual license model @@ -118,15 +101,9 @@ export default function PricingWhatToExpect() { - + - + Annual license model @@ -152,15 +129,9 @@ export default function PricingWhatToExpect() { - + - + Maintenance and support @@ -170,21 +141,17 @@ export default function PricingWhatToExpect() { learn more about support {' '} - in the docs. Note that, except for critical issues, such as security flaws, we release - bug fixes and other improvements on top of the latest version, instead of patching older - versions. + in the docs. +
    +
    + Note that, except for critical issues, such as security flaws, we release bug fixes and + other improvements on top of the latest version, instead of patching older versions.
    - + - + Volume discounts @@ -192,6 +159,7 @@ export default function PricingWhatToExpect() { The Pro plan is capped at 10 developers licensed; you do not need to pay for additional licenses for more than 10 developers.
    +
    You can contact sales for a volume discount when licensing over 25 developers under the Premium plan. diff --git a/docs/src/components/productBaseUI/BaseUIComponents.tsx b/docs/src/components/productBaseUI/BaseUIComponents.tsx index dea8227b45d20d..6766fe7b76acea 100644 --- a/docs/src/components/productBaseUI/BaseUIComponents.tsx +++ b/docs/src/components/productBaseUI/BaseUIComponents.tsx @@ -9,6 +9,7 @@ import TabUnselectedRoundedIcon from '@mui/icons-material/TabUnselectedRounded'; import InputRoundedIcon from '@mui/icons-material/InputRounded'; import MenuOpenRoundedIcon from '@mui/icons-material/MenuOpenRounded'; import LinearScaleRoundedIcon from '@mui/icons-material/LinearScaleRounded'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import GradientText from 'docs/src/components/typography/GradientText'; import Item, { Group } from 'docs/src/components/action/Item'; import Highlighter from 'docs/src/components/action/Highlighter'; @@ -18,10 +19,7 @@ import More from 'docs/src/components/action/More'; import Frame from 'docs/src/components/action/Frame'; import ROUTES from 'docs/src/route'; -// switcher icons - -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; -import MarkdownElement from 'docs/src/components/markdown/MarkdownElement'; +// Switcher icons import BaseButtonDemo from './components/BaseButtonDemo'; import BaseMenuDemo from './components/BaseMenuDemo'; import BaseInputDemo from './components/BaseInputDemo'; @@ -164,11 +162,10 @@ export default function BaseUIComponents() { { const result = CODES[demo]; if (typeof result === 'function') { diff --git a/docs/src/components/productBaseUI/BaseUICustomization.tsx b/docs/src/components/productBaseUI/BaseUICustomization.tsx index 797744435b6a22..48ba71e113daad 100644 --- a/docs/src/components/productBaseUI/BaseUICustomization.tsx +++ b/docs/src/components/productBaseUI/BaseUICustomization.tsx @@ -3,9 +3,9 @@ import { styled } from '@mui/system'; import clsx from 'clsx'; import { Switch as SwitchUnstyled } from '@mui/base/Switch'; import { useSwitch, UseSwitchParameters } from '@mui/base/useSwitch'; -import Box from '@mui/material/Box'; import Grid from '@mui/material/Grid'; import Typography from '@mui/material/Typography'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import SvgTwinkle from 'docs/src/icons/SvgTwinkle'; import Section from 'docs/src/layouts/Section'; import Highlighter from 'docs/src/components/action/Highlighter'; @@ -14,8 +14,6 @@ import GradientText from 'docs/src/components/typography/GradientText'; import SectionHeadline from 'docs/src/components/typography/SectionHeadline'; import FlashCode from 'docs/src/components/animation/FlashCode'; import Frame from 'docs/src/components/action/Frame'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; -import MarkdownElement from 'docs/src/components/markdown/MarkdownElement'; const code = ` import clsx from 'clsx'; @@ -302,20 +300,12 @@ export default function BaseUICustomization() { ref={infoRef} sx={{ maxHeight: 450, + position: 'relative', overflow: 'auto', }} > - - - - - - + +
    diff --git a/docs/src/components/productDesignKit/DesignKitDemo.tsx b/docs/src/components/productDesignKit/DesignKitDemo.tsx index 841164afd2a071..72637f25411e37 100644 --- a/docs/src/components/productDesignKit/DesignKitDemo.tsx +++ b/docs/src/components/productDesignKit/DesignKitDemo.tsx @@ -1,11 +1,11 @@ import * as React from 'react'; -import { styled } from '@mui/material/styles'; +import { styled, alpha } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; -import Grid from '@mui/material/Grid'; +import Grid from '@mui/material/Unstable_Grid2'; import Fade from '@mui/material/Fade'; import Typography from '@mui/material/Typography'; -import LaunchRounded from '@mui/icons-material/LaunchRounded'; +import ChevronRightRoundedIcon from '@mui/icons-material/ChevronRightRounded'; import TextFieldsRounded from '@mui/icons-material/TextFieldsRounded'; import WidgetsRounded from '@mui/icons-material/WidgetsRounded'; import ToggleOnRounded from '@mui/icons-material/ToggleOnRounded'; @@ -21,17 +21,176 @@ import { Link } from '@mui/docs/Link'; const DEMOS = ['Components', 'Branding', 'Iconography']; const Image = styled('img')(({ theme }) => ({ - filter: 'drop-shadow(-8px 4px 20px rgba(61, 71, 82, 0.2))', transition: '0.4s', display: 'block', height: 'auto', - borderRadius: '10px', + borderRadius: 6, + border: '1px solid', + borderColor: theme.palette.divider, + filter: `drop-shadow(-2px 4px 6px ${alpha(theme.palette.grey[500], 0.5)})`, ...theme.applyDarkStyles({ - filter: 'drop-shadow(-8px 4px 20px rgba(0, 0, 0, 0.4))', + filter: `drop-shadow(-2px 4px 6px ${alpha(theme.palette.common.black, 0.2)})`, + borderColor: theme.palette.primaryDark[600], }), })); -export default function TemplateDemo() { +interface MaterialFigmaComponentsProps { + fadeIn?: boolean; +} + +export function MaterialFigmaComponents({ fadeIn }: MaterialFigmaComponentsProps) { + return ( + + + theme.applyDarkStyles({ + '&:hover': { + '& img': { + filter: 'drop-shadow(-16px 12px 20px rgba(0, 0, 0, 0.4))', + }, + }, + }), + ]} + > + Material UI Button component variations in the Figma Design Kit. + theme.applyDarkStyles({ + content: `url(/static/branding/design-kits/Button-dark.jpeg)`, + }) + } + /> + Material UI Alert component variations in the Figma Design Kit. + theme.applyDarkStyles({ + content: `url(/static/branding/design-kits/Alert-dark.jpeg)`, + }) + } + /> + Material UI Slider component variations in the Figma Design Kit. + theme.applyDarkStyles({ + content: `url(/static/branding/design-kits/Slider-dark.jpeg)`, + }) + } + /> + + + ); +} + +export function MaterialDesignKitInfo() { + return ( + + + + Available in: + + img': { width: 20, height: 20 } }}> + Figma logo. + Sketch logo. + Adobe XD logo. + + + + We frequently update them to stay up-to-date with the latest release. + + + + + + + ); +} + +export default function DesignKitsDemo() { const [demo, setDemo] = React.useState(DEMOS[0]); const icons = { [DEMOS[0]]: , @@ -41,15 +200,15 @@ export default function TemplateDemo() { return (
    - + - Upgrade your design workflow + Enhance your design workflow } - description="The Design kits contain many of the Material UI components with states, variations, colors, typography, and icons. We frequently update it to sync with the most up-to-date release." + description="The Design Kits contain many of the Material UI components with states, variations, colors, typography, and icons." /> {DEMOS.map((name) => ( @@ -67,102 +226,19 @@ export default function TemplateDemo() { /> - + - - - theme.applyDarkStyles({ - '&:hover': { - '& img': { - filter: 'drop-shadow(-16px 12px 20px rgba(0, 0, 0, 0.4))', - }, - }, - }), - ]} - > - - theme.applyDarkStyles({ - content: `url(/static/branding/design-kits/Button-dark.jpeg)`, - }) - } - /> - - theme.applyDarkStyles({ - content: `url(/static/branding/design-kits/Alert-dark.jpeg)`, - }) - } - /> - - theme.applyDarkStyles({ - content: `url(/static/branding/design-kits/Slider-dark.jpeg)`, - }) - } - /> - - + ({ @@ -179,8 +255,8 @@ export default function TemplateDemo() { ({ @@ -196,47 +272,7 @@ export default function TemplateDemo() { /> - - - - Available for: - - img': { width: 26, height: 26 } }}> - - - - - - - + diff --git a/docs/src/components/productDesignKit/DesignKitFAQ.tsx b/docs/src/components/productDesignKit/DesignKitFAQ.tsx index 5e4f052cc9a4c3..25ab7e0e454d5f 100644 --- a/docs/src/components/productDesignKit/DesignKitFAQ.tsx +++ b/docs/src/components/productDesignKit/DesignKitFAQ.tsx @@ -1,7 +1,6 @@ import * as React from 'react'; import { styled } from '@mui/material/styles'; -import Box from '@mui/material/Box'; -import Grid from '@mui/material/Grid'; +import Grid from '@mui/material/Unstable_Grid2'; import Button from '@mui/material/Button'; import KeyboardArrowRightRounded from '@mui/icons-material/KeyboardArrowRightRounded'; import Paper from '@mui/material/Paper'; @@ -31,18 +30,27 @@ const faqData = [ The number of licenses purchased must correspond to the maximum number of editors working concurrently in a 24 hour period. An editor is somebody contributing changes to the designed - screens that use the UI kits. No licenses are required for viewing the designs. + screens that use the Design Kits. No licenses are required for viewing the designs. ), }, { - summary: 'The UI kit got an update. How do I get it?', + summary: 'The Design Kit got an update. How do I get it?', detail: ( We'll send you an email when a new release is available. You can access the item on the{' '} download page - of your store account. You can find a detailed description of the changes under the - "Changelog" tab on this page. + of your store account and find a detailed description of the changes under + the"Changelog" tab on this page. + + ), + }, + { + summary: 'Is the Material UI Sync plugin paid?', + detail: ( + + No. We're still in alpha mode and rolling out more features progressively, as per your + feedback. We might introduce paid tiers in the future, though. ), }, @@ -64,7 +72,7 @@ const faqData = [ detail: ( We aim to keep feature parity between the Figma, Sketch, and Adobe XD kits where possible. - We have a 50% off coupon for past customers who want to switch between two design tools. + We have a 50% off coupon for past customers who want to switch between them. ), }, @@ -77,7 +85,7 @@ const Accordion = styled(MuiAccordion)(({ theme }) => ({ borderRadius: theme.shape.borderRadius, }, '&:hover': { - boxShadow: '1px 1px 20px 0 rgb(90 105 120 / 20%)', + boxShadow: '1px 1px 8px 0 rgb(90 105 120 / 20%)', }, '&:not(:last-of-type)': { marginBottom: theme.spacing(2), @@ -142,12 +150,12 @@ export default function DesignKitFAQ() { Frequently asked questions - + {renderItem(0)} {renderItem(1)} {renderItem(2)} - + {renderItem(3)} {renderItem(4)} - - - Got any questions unanswered or need more help? - - - + + Got any questions unanswered or need more help? + + From community help to premium business support, we're here to help. + } right={ @@ -69,9 +63,10 @@ export default function TemplateHero() { width: '100%', height: '100%', zIndex: 1, - background: `linear-gradient(90deg, ${ - (theme.vars || theme).palette.primaryDark[900] - } 1%, ${alpha(theme.palette.primaryDark[900], 0.5)})`, + background: `linear-gradient(90deg, ${alpha( + theme.palette.primaryDark[900], + 0.8, + )} 1%, ${alpha(theme.palette.primaryDark[900], 0.1)})`, opacity: 0, ...theme.applyDarkStyles({ opacity: 1, diff --git a/docs/src/components/productDesignKit/DesignKitValues.tsx b/docs/src/components/productDesignKit/DesignKitValues.tsx index 72bca07d667fdf..489f8105933d8d 100644 --- a/docs/src/components/productDesignKit/DesignKitValues.tsx +++ b/docs/src/components/productDesignKit/DesignKitValues.tsx @@ -3,10 +3,11 @@ import Typography from '@mui/material/Typography'; import Grid from '@mui/material/Unstable_Grid2'; import Palette from '@mui/icons-material/Palette'; import LibraryBooks from '@mui/icons-material/LibraryBooks'; +import { InfoCard } from '@mui/docs/InfoCard'; import CodeRounded from '@mui/icons-material/CodeRounded'; import GradientText from 'docs/src/components/typography/GradientText'; import Section from 'docs/src/layouts/Section'; -import { InfoCard } from '@mui/docs/InfoCard'; +import SectionHeadline from 'docs/src/components/typography/SectionHeadline'; const content = [ { @@ -25,21 +26,23 @@ const content = [ icon: , title: 'For developers', description: - 'Effortlessly communicate with designers using the same language around the MUI Core components props and variants.', + 'Effortlessly communicate with designers using the same language around the Material UI components props and variants.', }, ]; -function DesignKitValues() { +export default function DesignKitValues() { return ( -
    - - Collaboration - - - Be more efficient designing and developing with the same - library - - +
    + + Be more efficient designing and developing with the same + library + + } + /> + {content.map(({ icon, title, description }) => ( @@ -49,5 +52,3 @@ function DesignKitValues() {
    ); } - -export default DesignKitValues; diff --git a/docs/src/components/productDesignKit/SyncFeatures.tsx b/docs/src/components/productDesignKit/SyncFeatures.tsx new file mode 100644 index 00000000000000..d2973f10529665 --- /dev/null +++ b/docs/src/components/productDesignKit/SyncFeatures.tsx @@ -0,0 +1,395 @@ +import * as React from 'react'; +import { styled, alpha } from '@mui/material/styles'; +import Box from '@mui/material/Box'; +import Grid from '@mui/material/Unstable_Grid2'; +import Button from '@mui/material/Button'; +import Typography from '@mui/material/Typography'; +import Fade from '@mui/material/Fade'; +import FormatShapesRoundedIcon from '@mui/icons-material/FormatShapesRounded'; +import SvgStorybook from 'docs/src/icons/SvgStorybook'; +import ImagesearchRollerRoundedIcon from '@mui/icons-material/ImagesearchRollerRounded'; +import Section from 'docs/src/layouts/Section'; +import SectionHeadline from 'docs/src/components/typography/SectionHeadline'; +import GradientText from 'docs/src/components/typography/GradientText'; +import Item, { Group } from 'docs/src/components/action/Item'; +import Highlighter from 'docs/src/components/action/Highlighter'; +import Frame from 'docs/src/components/action/Frame'; +import { Link } from '@mui/docs/Link'; + +const Image = styled('img')(({ theme }) => ({ + transition: '0.4s', + display: 'block', + height: 'auto', + borderRadius: 6, + border: '1px solid', + borderColor: theme.palette.divider, + filter: `drop-shadow(-2px 4px 6px ${alpha(theme.palette.grey[500], 0.5)})`, + ...theme.applyDarkStyles({ + filter: `drop-shadow(-2px 4px 6px ${alpha(theme.palette.common.black, 0.2)})`, + borderColor: theme.palette.primaryDark[600], + }), +})); + +export default function ConnectFeatures() { + const [index, setIndex] = React.useState(0); + function getSelectedProps(i: number) { + return { + selected: index === i, + sx: { '& svg': { opacity: index === i ? 1 : 0.5 } }, + }; + } + return ( +
    + + + + The way developers and designers ship faster + + } + description="The Sync plugin is perfect for designing and developing using the Material UI React library and Design Kit." + /> + + setIndex(0)}> + } + title="Theme customization" + description="Generate theme code with custom colors, typography styles, shadows, spacing values, and border-radius." + /> + + setIndex(1)}> + } + title="Component customization" + description="Fully customize a component's design across multiple states and then generate the corresponding theme code." + /> + + setIndex(2)}> + } + title="Preview your changes on Storybook" + description="Quickly visualize all the changes you run through Sync on a built-in Storybook preview instance." + /> + + + + + + + + {index === 0 && ( + + ({ + width: '100%', + height: '100%', + '& img': { + position: 'absolute', + '&:nth-of-type(1)': { + visibility: { xs: 'hidden', sm: 'visible' }, + width: { xs: 240, sm: 600 }, + top: 100, + left: '50%', + transform: 'translate(-40%)', + }, + '&:nth-of-type(2)': { + width: { xs: 240, sm: 560 }, + top: { xs: 100, sm: 40 }, + left: { xs: '60%', sm: '40%' }, + transform: { + xs: 'scale(1.8) translate(-20%)', + sm: 'scale(1) translate(0%)', + }, + }, + }, + '&:hover': { + '& img': { + '&:nth-of-type(2)': { + top: { xs: 100, sm: 60 }, + transform: { + xs: 'scale(1.8) translate(-20%)', + sm: 'scale(1.1) translate(-15%)', + }, + filter: { + xs: 'auto', + sm: `drop-shadow(-16px 12px 20px ${alpha( + theme.palette.grey[600], + 0.5, + )})`, + }, + }, + }, + }, + ...theme.applyDarkStyles({ + '&:hover': { + '& img': { + '&:nth-of-type(2)': { + filter: { + xs: 'auto', + sm: `drop-shadow(-16px 12px 20px ${alpha( + theme.palette.common.black, + 0.8, + )})`, + }, + }, + filter: `drop-shadow(-16px 12px 20px ${alpha( + theme.palette.common.black, + 0.2, + )})`, + }, + }, + }), + })} + > + The Material UI Design Kit for Figma. + theme.applyDarkStyles({ + content: `url(/static/branding/design-kits/sync-base1-dark.png)`, + }) + } + /> + The Material UI Sync plugin displaying theme code. + theme.applyDarkStyles({ + content: `url(/static/branding/design-kits/sync-shot1-dark.png)`, + }) + } + /> + + + )} + {index === 1 && ( + + ({ + width: '100%', + height: '100%', + '& img': { + position: 'absolute', + '&:nth-of-type(1)': { + visibility: { xs: 'hidden', sm: 'visible' }, + width: { xs: 240, sm: 600 }, + top: 100, + left: '50%', + transform: 'translate(-40%)', + }, + '&:nth-of-type(2)': { + width: { xs: 240, sm: 560 }, + top: { xs: 100, sm: 40 }, + left: { xs: '60%', sm: '50%' }, + transform: { + xs: 'scale(1.8) translate(-20%)', + sm: 'none', + }, + }, + }, + '&:hover': { + '& img': { + '&:nth-of-type(2)': { + top: { xs: 100, sm: 60 }, + transform: { + xs: 'scale(1.8) translate(-20%)', + sm: 'scale(1.1) translate(-30%)', + }, + filter: { + xs: 'auto', + sm: `drop-shadow(-16px 12px 20px ${alpha( + theme.palette.grey[600], + 0.5, + )})`, + }, + }, + }, + }, + ...theme.applyDarkStyles({ + '&:hover': { + '& img': { + '&:nth-of-type(2)': { + filter: { + xs: 'auto', + sm: `drop-shadow(-16px 12px 20px ${alpha( + theme.palette.common.black, + 0.8, + )})`, + }, + }, + filter: `drop-shadow(-16px 12px 20px ${alpha( + theme.palette.common.black, + 0.2, + )})`, + }, + }, + }), + })} + > + The Material UI Design Kit for Figma. + theme.applyDarkStyles({ + content: `url(/static/branding/design-kits/sync-base2-dark.png)`, + }) + } + /> + The Material UI Sync plugin displaying theme code. + theme.applyDarkStyles({ + content: `url(/static/branding/design-kits/material-sync-dark.png)`, + }) + } + /> + + + )} + {index === 2 && ( + + ({ + width: '100%', + height: '100%', + '& img': { + position: 'absolute', + '&:nth-of-type(1)': { + visibility: { xs: 'hidden', sm: 'visible' }, + width: { xs: 240, sm: 600 }, + top: 100, + left: '50%', + transform: 'translate(-40%)', + }, + '&:nth-of-type(2)': { + width: { xs: 240, sm: 560 }, + top: { xs: 100, sm: 40 }, + left: { xs: '60%', sm: '40%' }, + transform: { + xs: 'scale(1.8) translate(-20%)', + sm: 'none', + }, + }, + }, + '&:hover': { + '& img': { + '&:nth-of-type(2)': { + top: { xs: 100, sm: 60 }, + transform: { + xs: 'scale(1.8) translate(-20%)', + sm: 'scale(1.1) translate(-25%)', + }, + filter: { + xs: 'auto', + sm: `drop-shadow(-16px 12px 20px ${alpha( + theme.palette.grey[600], + 0.5, + )})`, + }, + }, + }, + }, + ...theme.applyDarkStyles({ + '&:hover': { + '& img': { + '&:nth-of-type(2)': { + filter: { + xs: 'auto', + sm: `drop-shadow(-16px 12px 20px ${alpha( + theme.palette.common.black, + 0.8, + )})`, + }, + }, + filter: `drop-shadow(-16px 12px 20px ${alpha( + theme.palette.common.black, + 0.2, + )})`, + }, + }, + }), + })} + > + The Material UI Design Kit for Figma. + theme.applyDarkStyles({ + content: `url(/static/branding/design-kits/sync-base2-dark.png)`, + }) + } + /> + The Material UI Sync plugin displaying theme code. + theme.applyDarkStyles({ + content: `url(/static/branding/design-kits/sync-shot3-dark.png)`, + }) + } + /> + + + )} + + + + + Get the beta version of Material UI Sync now! + + + There's still a lot to do, and we're looking forward to hearing from all + of you. + + + + + + + + + +
    + ); +} diff --git a/docs/src/components/productMaterial/MaterialComponents.tsx b/docs/src/components/productMaterial/MaterialComponents.tsx index 3abc1df7a2ad0a..08dd1449262faf 100644 --- a/docs/src/components/productMaterial/MaterialComponents.tsx +++ b/docs/src/components/productMaterial/MaterialComponents.tsx @@ -3,7 +3,7 @@ import { Experimental_CssVarsProvider as CssVarsProvider, alpha } from '@mui/mat import Box from '@mui/material/Box'; import Alert from '@mui/material/Alert'; import Button, { buttonClasses } from '@mui/material/Button'; -import Grid from '@mui/material/Grid'; +import Grid from '@mui/material/Unstable_Grid2'; import Stack from '@mui/material/Stack'; import Paper from '@mui/material/Paper'; import Table from '@mui/material/Table'; @@ -29,8 +29,8 @@ import Highlighter from 'docs/src/components/action/Highlighter'; import More from 'docs/src/components/action/More'; import Frame from 'docs/src/components/action/Frame'; import { customTheme } from 'docs/src/components/home/MaterialDesignComponents'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; -import MarkdownElement from 'docs/src/components/markdown/MarkdownElement'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; + import StylingInfo from 'docs/src/components/action/StylingInfo'; import ROUTES from 'docs/src/route'; @@ -118,7 +118,7 @@ export default function MaterialComponents() { return (
    - + - + @@ -290,7 +290,6 @@ export default function MaterialComponents() { minHeight: 220, maxHeight: demo === 'Table' ? 260 : 'none', position: 'relative', - overflow: 'hidden', p: 0, pt: 5, }} @@ -305,12 +304,7 @@ export default function MaterialComponents() { height: '100%', }} > - + ({ diff --git a/docs/src/components/productMaterial/MaterialDesignKits.tsx b/docs/src/components/productMaterial/MaterialDesignKits.tsx index ef65d052dee64a..20cb16e9d070cf 100644 --- a/docs/src/components/productMaterial/MaterialDesignKits.tsx +++ b/docs/src/components/productMaterial/MaterialDesignKits.tsx @@ -1,244 +1,204 @@ import * as React from 'react'; -import { styled } from '@mui/material/styles'; +import { styled, alpha } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; -import Grid from '@mui/material/Grid'; +import Grid from '@mui/material/Unstable_Grid2'; import Fade from '@mui/material/Fade'; import Typography from '@mui/material/Typography'; -import LaunchRounded from '@mui/icons-material/LaunchRounded'; -import TextFieldsRounded from '@mui/icons-material/TextFieldsRounded'; -import WidgetsRounded from '@mui/icons-material/WidgetsRounded'; -import ToggleOnRounded from '@mui/icons-material/ToggleOnRounded'; +import ExtensionRoundedIcon from '@mui/icons-material/ExtensionRounded'; +import DrawRoundedIcon from '@mui/icons-material/DrawRounded'; import Section from 'docs/src/layouts/Section'; import SectionHeadline from 'docs/src/components/typography/SectionHeadline'; import GradientText from 'docs/src/components/typography/GradientText'; import Item, { Group } from 'docs/src/components/action/Item'; import Highlighter from 'docs/src/components/action/Highlighter'; -import More from 'docs/src/components/action/More'; import Frame from 'docs/src/components/action/Frame'; +import { + MaterialDesignKitInfo, + MaterialFigmaComponents, +} from 'docs/src/components/productDesignKit/DesignKitDemo'; import { Link } from '@mui/docs/Link'; -const DEMOS = ['Components', 'Branding', 'Iconography']; - const Image = styled('img')(({ theme }) => ({ - filter: 'drop-shadow(-2px 4px 4px rgba(61, 71, 82, 0.1))', transition: '0.4s', display: 'block', height: 'auto', - borderRadius: '10px', + borderRadius: 6, + border: '1px solid', + borderColor: theme.palette.divider, + filter: `drop-shadow(-2px 4px 6px ${alpha(theme.palette.grey[500], 0.5)})`, ...theme.applyDarkStyles({ - filter: 'drop-shadow(-2px 4px 4px rgba(0, 0, 0, 0.3))', + filter: `drop-shadow(-2px 4px 6px ${alpha(theme.palette.common.black, 0.2)})`, + borderColor: theme.palette.primaryDark[600], }), })); -export default function MaterialDesignKits() { - const [demo, setDemo] = React.useState(DEMOS[0]); - const icons = { - [DEMOS[0]]: , - [DEMOS[1]]: , - [DEMOS[2]]: , - }; +interface MaterialDesignKitsProps { + gradient?: boolean; +} + +export default function MaterialDesignKits({ gradient }: MaterialDesignKitsProps) { + const [customized, setCustomized] = React.useState(true); + return ( -
    +
    - - - - Enhance your design workflow - - } - description="The Design kits contain many of the Material UI components with states, variations, colors, typography, and icons. We frequently update it to sync with the most up-to-date release." - /> - - - {DEMOS.map((name) => ( - setDemo(name)}> - - - ))} - + + + Enhance your design workflow + + } + description="Reach out for the Figma Design Kit and the Sync plugin to bridge the gap between development and design when using Material UI." + /> + + setCustomized(true)}> + } + title="Design Kit" + description="Get many Material UI components with states, variations, colors, typography, and icons on your preferred design tool." + /> + + setCustomized(false)}> + } + title="Sync plugin" + description="Quickly generate a Material UI theme file with token and component customizations done on Figma." + /> + - + - + + ({ + display: !customized ? 'auto' : 'none', + width: '100%', + height: '100%', + '& img': { + position: 'absolute', + '&:nth-of-type(1)': { + visibility: { xs: 'hidden', sm: 'visible' }, + width: { xs: 240, sm: 600 }, + top: 100, left: '50%', - width: { xs: 240, sm: 300 }, - '&:nth-of-type(1)': { - top: 120, - transform: 'translate(-70%)', + transform: 'translate(-40%)', + }, + '&:nth-of-type(2)': { + width: { xs: 240, sm: 560 }, + top: { xs: 100, sm: 40 }, + left: { xs: '60%', sm: '60%' }, + transform: { + xs: 'scale(1.8) translate(-20%)', + sm: 'none', }, + }, + }, + '&:hover': { + '& img': { '&:nth-of-type(2)': { - top: 80, - transform: 'translate(-50%)', - }, - '&:nth-of-type(3)': { - top: 40, - transform: 'translate(-30%)', + top: { xs: 100, sm: 60 }, + transform: { + xs: 'scale(1.8) translate(-20%)', + sm: 'scale(1.1) translate(-30%)', + }, + filter: { + xs: 'auto', + sm: `drop-shadow(-16px 12px 20px ${alpha( + theme.palette.grey[600], + 0.5, + )})`, + }, }, }, + }, + ...theme.applyDarkStyles({ '&:hover': { '& img': { - filter: 'drop-shadow(-16px 12px 20px rgba(61, 71, 82, 0.2))', - '&:nth-of-type(1)': { - top: 0, - transform: 'scale(0.8) translate(-108%) rotateY(30deg)', - }, '&:nth-of-type(2)': { - top: 40, - transform: 'scale(0.8) translate(-54%) rotateY(30deg)', - }, - '&:nth-of-type(3)': { - top: 40, - transform: 'scale(0.8) translate(-0%) rotateY(30deg)', + filter: { + xs: 'auto', + sm: `drop-shadow(-16px 12px 20px ${alpha( + theme.palette.common.black, + 0.8, + )})`, + }, }, + filter: `drop-shadow(-16px 12px 20px ${alpha( + theme.palette.common.black, + 0.2, + )})`, }, }, - }, - (theme) => - theme.applyDarkStyles({ - '&:hover': { - '& img': { - filter: 'drop-shadow(-16px 12px 20px rgba(0, 0, 0, 0.4))', - }, - }, - }), - ]} + }), + })} > theme.applyDarkStyles({ - content: `url(/static/branding/design-kits/Button-dark.jpeg)`, + content: `url(/static/branding/design-kits/sync-base2-dark.png)`, }) } /> theme.applyDarkStyles({ - content: `url(/static/branding/design-kits/Alert-dark.jpeg)`, - }) - } - /> - - theme.applyDarkStyles({ - content: `url(/static/branding/design-kits/Slider-dark.jpeg)`, + content: `url(/static/branding/design-kits/material-sync-dark.png)`, }) } /> - - ({ - width: { sm: 400 }, - position: 'absolute', - left: '50%', - top: '50%', - transform: 'translate(-50%, -50%)', - ...theme.applyDarkStyles({ - content: `url(/static/branding/design-kits/Colors-dark.jpeg)`, - }), - })} - /> - - - ({ - width: { sm: 500 }, - position: 'absolute', - left: '50%', - top: 60, - transform: 'translate(-40%)', - ...theme.applyDarkStyles({ - content: `url(/static/branding/design-kits/Icons-dark.jpeg)`, - }), - })} - /> - - - - - Available for: + {customized ? ( + + ) : ( + + + Get the beta version of Material UI Sync now! + + + There's still a lot to do, and we're looking forward to hearing from all + of you. - img': { width: 26, height: 26 } }}> - - - + + + - - - + + )} diff --git a/docs/src/components/productMaterial/MaterialEnd.tsx b/docs/src/components/productMaterial/MaterialEnd.tsx index be40de0a8cfb73..e3308a4e06a972 100644 --- a/docs/src/components/productMaterial/MaterialEnd.tsx +++ b/docs/src/components/productMaterial/MaterialEnd.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import { alpha } from '@mui/material/styles'; +import Box from '@mui/material/Box'; import Grid from '@mui/material/Unstable_Grid2'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; @@ -14,9 +15,14 @@ import GradientText from 'docs/src/components/typography/GradientText'; import { Link } from '@mui/docs/Link'; import ROUTES from 'docs/src/route'; -export default function MaterialEnd() { +interface MaterialEndProps { + noFaq?: boolean; +} + +export default function MaterialEnd({ noFaq }: MaterialEndProps) { return (
    - - + {noFaq ? ( + @@ -49,44 +56,70 @@ export default function MaterialEnd() { secondaryUrl={ROUTES.freeTemplates} altInstallation="npm install @mui/material @emotion/react @emotion/styled" /> - - - li': { alignItems: 'flex-start' } }}> - - } /> -
    - - Material UI vs. Base UI - - - Material UI implements Google's Material Design whereas Base UI features many - of the same components, but without the Material Design implementation. - -
    -
    - - } /> -
    - - Does it support Material Design 3? - - - The adoption of Material Design 3 is tentatively planned for Material UI v7. See - the{' '} - - the release schedule - {' '} - and follow{' '} - - this GitHub issue - {' '} - for future updates. + + ) : ( + + + + Join our global community -
    -
    -
    + } + description={ + + Material UI wouldn't be possible without our global community of + contributors. Join us today to get help when you need it, and lend a hand when you + can. + + } + /> + +
    + + li': { alignItems: 'flex-start' } }}> + + } /> +
    + + Material UI vs. Base UI + + + Material UI implements Google's Material Design whereas Base UI features + many of the same components, but without the Material Design implementation. + +
    +
    + + } /> +
    + + Does it support Material Design 3? + + + The adoption of Material Design 3 is tentatively planned for Material UI v7. See + the{' '} + + the release schedule + {' '} + and follow{' '} + + this GitHub issue + {' '} + for future updates. + +
    +
    +
    +
    - + )}
    ); } diff --git a/docs/src/components/productMaterial/MaterialStyling.tsx b/docs/src/components/productMaterial/MaterialStyling.tsx index 48897433cb4dc4..4fb48f665fc909 100644 --- a/docs/src/components/productMaterial/MaterialStyling.tsx +++ b/docs/src/components/productMaterial/MaterialStyling.tsx @@ -1,11 +1,12 @@ import * as React from 'react'; import Box from '@mui/material/Box'; -import Grid from '@mui/material/Grid'; +import Grid from '@mui/material/Unstable_Grid2'; import Typography from '@mui/material/Typography'; import DevicesOtherRoundedIcon from '@mui/icons-material/DevicesOtherRounded'; -import ContrastRoundedIcon from '@mui/icons-material/ContrastRounded'; import SwitchAccessShortcutRoundedIcon from '@mui/icons-material/SwitchAccessShortcutRounded'; import DragHandleRounded from '@mui/icons-material/DragHandleRounded'; +import StyleRoundedIcon from '@mui/icons-material/StyleRounded'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import Section from 'docs/src/layouts/Section'; import SectionHeadline from 'docs/src/components/typography/SectionHeadline'; import GradientText from 'docs/src/components/typography/GradientText'; @@ -13,8 +14,7 @@ import Item, { Group } from 'docs/src/components/action/Item'; import Highlighter from 'docs/src/components/action/Highlighter'; import Frame from 'docs/src/components/action/Frame'; import RealEstateCard from 'docs/src/components/showcase/RealEstateCard'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; -import MarkdownElement from 'docs/src/components/markdown/MarkdownElement'; + import FlashCode from 'docs/src/components/animation/FlashCode'; const code = ` @@ -161,7 +161,7 @@ export default function MaterialStyling() { return (
    - + setIndex(0)}> } + icon={} title="Leverage the tokens from your theme" description="Easily use the design tokens defined in your theme for any CSS property out there." /> @@ -195,7 +195,7 @@ export default function MaterialStyling() { - + - - - - - - + + diff --git a/docs/src/components/productMaterial/MaterialTemplates.tsx b/docs/src/components/productMaterial/MaterialTemplates.tsx index 363a98a8f3f9d6..60ddbdc67f29d4 100644 --- a/docs/src/components/productMaterial/MaterialTemplates.tsx +++ b/docs/src/components/productMaterial/MaterialTemplates.tsx @@ -15,7 +15,6 @@ import SectionHeadline from 'docs/src/components/typography/SectionHeadline'; import GradientText from 'docs/src/components/typography/GradientText'; import Item, { Group } from 'docs/src/components/action/Item'; import Highlighter from 'docs/src/components/action/Highlighter'; -import Frame from 'docs/src/components/action/Frame'; import { Link } from '@mui/docs/Link'; import More from 'docs/src/components/action/More'; @@ -30,7 +29,8 @@ export const icons = { export const TEMPLATES = { [DEMOS[0]]: [ { - name: 'Devias Kit Pro - Client & Admin Dashboard', + name: 'Client & Admin Dashboard', + author: 'Devias Kit Pro', src: { light: '/static/branding/store-templates/template-4light.jpg', dark: '/static/branding/store-templates/template-4dark.jpg', @@ -38,7 +38,8 @@ export const TEMPLATES = { href: 'https://mui.com/store/items/devias-kit-pro/', }, { - name: 'Minimal - Client & Admin Dashboard', + name: 'Client & Admin Dashboard', + author: 'Minimal', src: { light: '/static/branding/store-templates/template-1light.jpg', dark: '/static/branding/store-templates/template-1dark.jpg', @@ -46,7 +47,8 @@ export const TEMPLATES = { href: 'https://mui.com/store/items/minimal-dashboard/', }, { - name: 'Berry - React Material Admin Dashboard Template', + name: 'React Material Admin Dashboard Template', + author: 'Berry', src: { light: '/static/branding/store-templates/template-5light.jpg', dark: '/static/branding/store-templates/template-5dark.jpg', @@ -54,7 +56,8 @@ export const TEMPLATES = { href: 'https://mui.com/store/items/berry-react-material-admin/', }, { - name: 'Mira Pro - React Material Admin Dashboard', + name: 'React Material Admin Dashboard', + author: 'Mira Pro', src: { light: '/static/branding/store-templates/template-3light.jpg', dark: '/static/branding/store-templates/template-3dark.jpg', @@ -64,7 +67,8 @@ export const TEMPLATES = { ], [DEMOS[1]]: [ { - name: 'theFront - Multipurpose Template + UI Kit', + name: 'Multipurpose Template + UI Kit', + author: 'theFront', src: { light: '/static/branding/store-templates/template-2light.jpg', dark: '/static/branding/store-templates/template-2dark.jpg', @@ -72,7 +76,8 @@ export const TEMPLATES = { href: 'https://mui.com/store/items/the-front-landing-page/', }, { - name: 'Webbee - Multipurpose landing page UI Kit', + name: 'Multipurpose Landing Page UI Kit', + author: 'Webbe', src: { light: '/static/branding/store-templates/template-6light.jpg', dark: '/static/branding/store-templates/template-6dark.jpg', @@ -82,7 +87,8 @@ export const TEMPLATES = { ], [DEMOS[2]]: [ { - name: 'Bazar Pro - Multipurpose React Ecommerce Template', + name: 'Multipurpose React Ecommerce Template', + author: 'Bazar Pro', src: { light: '/static/branding/store-templates/template-bazar-light.jpg', dark: '/static/branding/store-templates/template-bazar-dark.jpg', @@ -98,16 +104,18 @@ function ActionArea(props: ButtonBaseProps) { {...props} sx={[ (theme) => ({ - width: { xs: 70, sm: 100 }, - height: { xs: 70, sm: 100 }, + width: { xs: 70, sm: 48 }, + height: { xs: 70, sm: 48 }, position: 'absolute', top: 'calc(50% - 50px)', p: 1.5, - color: '#FFF', + color: (theme.vars || theme).palette.primary[500], + bgcolor: '#FFF', + border: '1px solid', + borderColor: (theme.vars || theme).palette.primary[200], borderRadius: '50%', + boxShadow: `0 4px 12px ${alpha(theme.palette.grey[500], 0.2)}`, transition: '0.2s', - backdropFilter: 'blur(4px)', - bgcolor: alpha(theme.palette.primary[500], 0.5), '& > svg': { transition: '0.2s' }, '&.Mui-disabled': { opacity: 0, @@ -115,6 +123,12 @@ function ActionArea(props: ButtonBaseProps) { '&:hover, &:focus': { '& > svg': { fontSize: 28 }, }, + ...theme.applyDarkStyles({ + bgcolor: (theme.vars || theme).palette.primaryDark[900], + borderColor: (theme.vars || theme).palette.primary[900], + color: (theme.vars || theme).palette.primary[300], + boxShadow: `0 4px 12px ${alpha(theme.palette.common.black, 0.2)}`, + }), }), ...(Array.isArray(props.sx) ? props.sx : [props.sx]), ]} @@ -138,7 +152,7 @@ export default function MaterialTemplates() {
    specific use case } - description="A carefully curated collection of gorgeous, fully functional templates, all powered by Material UI." + description="A carefully curated collection of gorgeous, fully functional templates." /> {DEMOS.map((name) => ( @@ -163,147 +177,160 @@ export default function MaterialTemplates() { noLinkStyle /> - - - div': { px: '12%', overflow: 'unset !important' }, - '& .react-swipeable-view-container > div': { - overflow: 'unset !important', - }, + + div': { px: '12%', overflow: 'unset !important' }, + '& .react-swipeable-view-container > div': { + overflow: 'unset !important', + }, + }} + > + setTemplateIndex(index)} > - setTemplateIndex(index)} - > - {templates.map((item, index) => ( - ({ - overflow: 'auto', - borderRadius: 1, - height: { xs: 220, sm: 320, md: 450 }, - backgroundImage: `url(${item.src.light})`, - backgroundSize: 'cover', - backgroundRepeat: 'no-repeat', - border: '1px solid', - borderColor: templateIndex === index ? 'primary.100' : 'divider', - boxShadow: `0px 2px 12px ${alpha(theme.palette.primary[200], 0.3)}`, - transition: '0.6s cubic-bezier(0.15, 0.3, 0.25, 1)', - transform: templateIndex !== index ? 'scale(0.92)' : 'scale(1)', - ...theme.applyDarkStyles({ - backgroundImage: `url(${item.src.dark})`, - borderColor: templateIndex === index ? 'primary.800' : 'divider', - boxShadow: `0px 2px 12px ${alpha(theme.palette.primary[900], 0.5)}`, + {templates.map((item, index) => ( + ({ + overflow: 'auto', + borderRadius: 1, + height: { xs: 220, sm: 320, md: 500 }, + backgroundImage: `url(${item.src.light})`, + backgroundSize: 'cover', + backgroundRepeat: 'no-repeat', + border: '1px solid', + borderColor: templateIndex === index ? 'primary.100' : 'divider', + boxShadow: + templateIndex === index + ? `0px 2px 12px ${alpha(theme.palette.primary[200], 0.3)}` + : undefined, + transition: '0.6s cubic-bezier(0.15, 0.3, 0.25, 1)', + transform: templateIndex !== index ? 'scale(0.92)' : 'scale(1)', + opacity: templateIndex === index ? 1 : 0.2, + ...theme.applyDarkStyles({ + backgroundImage: `url(${item.src.dark})`, + borderColor: templateIndex === index ? 'primary.900' : 'divider', + boxShadow: + templateIndex === index + ? `0px 2px 8px ${alpha(theme.palette.primary[900], 0.4)}` + : undefined, + }), + })} + > + ({ + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + flexDirection: 'column', + gap: 1, + transition: '0.2s', + position: 'absolute', + width: '100%', + height: '100%', + opacity: 0, + top: 0, + left: 0, + bgcolor: alpha(theme.palette.primary[50], 0.6), + backdropFilter: 'blur(4px)', + textDecoration: 'none', + '&:hover, &:focus': { + opacity: 1, + }, + ...theme.applyDarkStyles({ + bgcolor: alpha(theme.palette.primaryDark[900], 0.6), + }), }), - })} + ]} > - + Developed by {templates[templateIndex].author} + + + {templates[templateIndex].name} + + ({ display: 'flex', alignItems: 'center', - justifyContent: 'center', - flexDirection: 'column', - gap: 1, - transition: '0.2s', - position: 'absolute', - width: '100%', - height: '100%', - opacity: 0, - top: 0, - left: 0, - bgcolor: alpha(theme.palette.primary[50], 0.6), - backdropFilter: 'blur(4px)', - textDecoration: 'none', - '&:hover, &:focus': { - opacity: 1, - }, + gap: 0.5, + color: 'primary.500', ...theme.applyDarkStyles({ - bgcolor: alpha(theme.palette.primaryDark[900], 0.6), + color: 'primary.200', }), }), ]} > - ({ - color: 'text.primary', - ...theme.applyDarkStyles({ - color: '#FFF', - }), - }), - ]} - > - {templates[templateIndex].name} - - ({ - display: 'flex', - alignItems: 'center', - gap: 0.5, - color: 'primary.500', - ...theme.applyDarkStyles({ - color: 'primary.100', - }), - }), - ]} - > - Buy now - - - - - ))} - - {templates.length > 1 && ( - - setTemplateIndex((current) => Math.max(0, current - 1))} - sx={{ left: 0, transform: 'translate(-50%)', justifyContent: 'flex-end' }} - > - - - - setTemplateIndex((current) => Math.min(templates.length - 1, current + 1)) - } - sx={{ right: 0, transform: 'translate(50%)', justifyContent: 'flex-start' }} - > - - - - )} - - - + Buy now + + + + + ))} + + {templates.length > 1 && ( + + setTemplateIndex((current) => Math.max(0, current - 1))} + sx={{ left: 0, transform: 'translate(-50%)', justifyContent: 'flex-end' }} + > + + + + setTemplateIndex((current) => Math.min(templates.length - 1, current + 1)) + } + sx={{ right: 0, transform: 'translate(50%)', justifyContent: 'flex-start' }} + > + + + + )} + +
    ); } diff --git a/docs/src/components/productMaterial/MaterialTheming.tsx b/docs/src/components/productMaterial/MaterialTheming.tsx index 01079c893757c9..a0c3560bbaebf1 100644 --- a/docs/src/components/productMaterial/MaterialTheming.tsx +++ b/docs/src/components/productMaterial/MaterialTheming.tsx @@ -1,8 +1,9 @@ import * as React from 'react'; import { Experimental_CssVarsProvider as CssVarsProvider } from '@mui/material/styles'; -import Grid from '@mui/material/Grid'; +import Grid from '@mui/material/Unstable_Grid2'; import Typography from '@mui/material/Typography'; import AutoAwesomeRounded from '@mui/icons-material/AutoAwesomeRounded'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import Section from 'docs/src/layouts/Section'; import SectionHeadline from 'docs/src/components/typography/SectionHeadline'; import GradientText from 'docs/src/components/typography/GradientText'; @@ -11,8 +12,6 @@ import Highlighter from 'docs/src/components/action/Highlighter'; import SvgMaterialDesign from 'docs/src/icons/SvgMaterialDesign'; import Frame from 'docs/src/components/action/Frame'; import PlayerCard from 'docs/src/components/showcase/PlayerCard'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; -import MarkdownElement from 'docs/src/components/markdown/MarkdownElement'; const code = ` - +
    - + - + diff --git a/docs/src/components/productTemplate/TemplateDemo.tsx b/docs/src/components/productTemplate/TemplateDemo.tsx index 6ad9ce04e8491a..28b5edecf1faa0 100644 --- a/docs/src/components/productTemplate/TemplateDemo.tsx +++ b/docs/src/components/productTemplate/TemplateDemo.tsx @@ -3,7 +3,7 @@ import SwipeableViews from 'react-swipeable-views'; import { alpha } from '@mui/material/styles'; import Box from '@mui/material/Box'; import ButtonBase, { ButtonBaseProps } from '@mui/material/ButtonBase'; -import Grid from '@mui/material/Grid'; +import Grid from '@mui/material/Unstable_Grid2'; import Typography from '@mui/material/Typography'; import LaunchRounded from '@mui/icons-material/LaunchRounded'; import KeyboardArrowLeftRounded from '@mui/icons-material/KeyboardArrowLeftRounded'; @@ -59,7 +59,7 @@ export default function TemplateDemo() { return (
    - + specific use case } - description="A collection of 4.5 average rating templates, for multiple use cases, all powered by Material UI components and carefully curated by MUI's team. - " + description="The Material UI collection of templates offers an expanding list of use cases designed to support projects of various types." /> {DEMOS.map((name) => ( @@ -93,7 +92,7 @@ export default function TemplateDemo() { /> - + - - +
    + {templates[templateIndex].name} - - - {templateIndex + 1} / {templates.length} - - - + + Developed by {templates[templateIndex].author} + +
    + + {templateIndex + 1} / {templates.length} +
    diff --git a/docs/src/components/productTemplate/TemplateHero.tsx b/docs/src/components/productTemplate/TemplateHero.tsx index aff549228dac2f..1cb0646dfcea50 100644 --- a/docs/src/components/productTemplate/TemplateHero.tsx +++ b/docs/src/components/productTemplate/TemplateHero.tsx @@ -35,10 +35,10 @@ export default function TemplateHero() { Templates - Fully built Material UI templates + Beautiful and fully built Material UI templates - A collection of 4.5 average rating templates, selected and curated by MUI's team of + A collection of 4.5 average rating templates, selected and curated by Material UI's maintainers to get your projects up and running today. - - ); -} +export default CodeCopyButton; diff --git a/docs/src/modules/components/ComponentLinkHeader.js b/docs/src/modules/components/ComponentLinkHeader.js index ebc8e4cef3e9be..a443a9f82b5742 100644 --- a/docs/src/modules/components/ComponentLinkHeader.js +++ b/docs/src/modules/components/ComponentLinkHeader.js @@ -1,199 +1,5 @@ -import * as React from 'react'; -import PropTypes from 'prop-types'; -import Chip from '@mui/material/Chip'; -import Tooltip from '@mui/material/Tooltip'; -import ChatRounded from '@mui/icons-material/ChatRounded'; -import { styled } from '@mui/material/styles'; -import SketchIcon from 'docs/src/modules/components/SketchIcon'; -import FigmaIcon from 'docs/src/modules/components/FigmaIcon'; -import AdobeXDIcon from 'docs/src/modules/components/AdobeXDIcon'; -import BundleSizeIcon from 'docs/src/modules/components/BundleSizeIcon'; -import W3CIcon from 'docs/src/modules/components/W3CIcon'; -import MaterialDesignIcon from 'docs/src/modules/components/MaterialDesignIcon'; -import { useTranslate } from '@mui/docs/i18n'; +// Backwards compatibility for Toolpad and X. +// TODO: remove when Toolpad and X migrated to `@mui/docs/ComponentLinkHeader` +import { ComponentLinkHeader } from '@mui/docs/ComponentLinkHeader'; -const Root = styled('ul')({ - margin: 0, - padding: 0, - listStyle: 'none', - display: 'flex', - flexWrap: 'wrap', - gap: 8, - '& .MuiChip-root': { - height: 26, - padding: '0 8px', - gap: 6, - '& .MuiChip-label': { padding: 0 }, - '& .MuiChip-iconSmall': { - margin: 0, - fontSize: 14, - }, - }, -}); - -const defaultPackageNames = { - 'material-ui': '@mui/material', - 'joy-ui': '@mui/joy', - 'base-ui': '@mui/base', - system: '@mui/system', -}; - -export default function ComponentLinkHeader(props) { - const { - markdown: { headers }, - design, - } = props; - const t = useTranslate(); - - const packageName = - headers.packageName ?? defaultPackageNames[headers.productId] ?? '@mui/material'; - - return ( - - {headers.githubLabel ? ( -
  • - } - data-ga-event-category="ComponentLinkHeader" - data-ga-event-action="click" - data-ga-event-label={t('githubLabel')} - data-ga-event-split="0.1" - label={t('githubLabel')} - /> -
  • - ) : null} -
  • - - } - data-ga-event-category="ComponentLinkHeader" - data-ga-event-action="click" - data-ga-event-label={t('bundleSize')} - data-ga-event-split="0.1" - label={t('bundleSize')} - /> - -
  • - {headers.waiAria ? ( -
  • - } - data-ga-event-category="ComponentLinkHeader" - data-ga-event-action="click" - data-ga-event-label="WAI-ARIA" - data-ga-event-split="0.1" - label="WAI-ARIA" - /> -
  • - ) : null} - {headers.materialDesign ? ( -
  • - } - data-ga-event-category="ComponentLinkHeader" - data-ga-event-action="click" - data-ga-event-label="Material Design" - data-ga-event-split="0.1" - label="Material Design" - /> -
  • - ) : null} - {design !== false ? ( - -
  • - } - data-ga-event-category="ComponentLinkHeader" - data-ga-event-action="click" - data-ga-event-label="Figma" - data-ga-event-split="0.1" - label="Figma" - /> -
  • - {packageName !== '@mui/joy' ? ( -
  • - } - data-ga-event-category="ComponentLinkHeader" - data-ga-event-action="click" - data-ga-event-label="Adobe XD" - data-ga-event-split="0.1" - label="Adobe" - /> -
  • - ) : null} - {packageName !== '@mui/joy' ? ( -
  • - } - data-ga-event-category="ComponentLinkHeader" - data-ga-event-action="click" - data-ga-event-label="Sketch" - data-ga-event-split="0.1" - label="Sketch" - /> -
  • - ) : null} -
    - ) : null} -
    - ); -} - -ComponentLinkHeader.propTypes = { - design: PropTypes.bool, - markdown: PropTypes.shape({ - headers: PropTypes.object.isRequired, - }).isRequired, -}; +export default ComponentLinkHeader; diff --git a/docs/src/modules/components/ComponentsApiContent.js b/docs/src/modules/components/ComponentsApiContent.js index c089b6302b6783..a31b90d44a99fe 100644 --- a/docs/src/modules/components/ComponentsApiContent.js +++ b/docs/src/modules/components/ComponentsApiContent.js @@ -5,7 +5,7 @@ import kebabCase from 'lodash/kebabCase'; import { useRouter } from 'next/router'; import { exactProp } from '@mui/utils'; import { useTranslate, useUserLanguage } from '@mui/docs/i18n'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import MarkdownElement from 'docs/src/modules/components/MarkdownElement'; import PropertiesSection from 'docs/src/modules/components/ApiPage/sections/PropertiesSection'; import ClassesSection from 'docs/src/modules/components/ApiPage/sections/ClassesSection'; @@ -33,11 +33,13 @@ function Heading(props) { return ( - {getTranslatedHeader(t, hash, text)} - - - - + + {getTranslatedHeader(t, hash, text)} + + + + + ); @@ -148,7 +150,9 @@ export default function ComponentsApiContent(props) { -

    + {imports.length > 1 && ( +

    + )} ({ '& pre': { margin: 0, + marginTop: -1, maxHeight: 'min(68vh, 1000px)', maxWidth: 'initial', borderRadius: 0, + borderBottomLeftRadius: 12, + borderBottomRightRadius: 12, + }, + '& .MuiCode-copy': { + display: 'none', }, })); @@ -348,6 +369,20 @@ const InitialFocus = styled(IconButton)(({ theme }) => ({ pointerEvents: 'none', })); +const selectionOverride = (theme) => ({ + cursor: 'pointer', + '&.base--selected': { + color: (theme.vars || theme).palette.primary[700], + backgroundColor: (theme.vars || theme).palette.primary[50], + borderColor: (theme.vars || theme).palette.primary[200], + ...theme.applyDarkStyles({ + color: (theme.vars || theme).palette.primary[200], + backgroundColor: alpha((theme.vars || theme).palette.primary[900], 0.4), + borderColor: (theme.vars || theme).palette.primary[800], + }), + }, +}); + export default function Demo(props) { const { demo, demoOptions, disableAd, githubLocation, mode } = props; @@ -496,6 +531,32 @@ export default function Demo(props) { liveDemoActive, }); + const [activeTab, setActiveTab] = React.useState(0); + const handleTabChange = (event, newValue) => { + setActiveTab(newValue); + }; + const ownerState = { mounted: true, contained: true }; + + const tabs = React.useMemo(() => { + if (!demoData.relativeModules) { + return [{ module: demoData.module, raw: demoData.raw }]; + } + let demoModule = demoData.module; + if (codeVariant === CODE_VARIANTS.TS && demo.moduleTS) { + demoModule = + demo.moduleTS === demo.module ? demoData.module.replace(/\.js$/, '.tsx') : demo.moduleTS; + } + + return [{ module: demoModule, raw: demoData.raw }, ...demoData.relativeModules]; + }, [ + codeVariant, + demo.moduleTS, + demo.module, + demoData.module, + demoData.raw, + demoData.relativeModules, + ]); + return ( @@ -554,46 +615,67 @@ export default function Demo(props) { - - {/* A limitation from https://github.com/nihgwu/react-runner, + + {demoData.relativeModules && openDemoSource && !editorCode.isPreview ? ( + + {tabs.map((tab, index) => ( + + {tab.module} + + ))} + + ) : null} + + {/* A limitation from https://github.com/nihgwu/react-runner, we can't inject the `window` of the iframe so we need a disableLiveEdit option. */} - {demoOptions.disableLiveEdit ? ( - - ) : ( - { - setEditorCode({ - ...editorCode, - value, - }); - }} - onFocus={() => { - setLiveDemoActive(true); - }} - id={demoSourceId} - language={demoData.sourceLanguage} - copyButtonProps={{ - 'data-ga-event-category': codeOpen ? 'demo-expand' : 'demo', - 'data-ga-event-label': demo.gaLabel, - 'data-ga-event-action': 'copy-click', - }} - > - {debouncedError} - - )} - + {tabs.map((tab, index) => ( + + {demoOptions.disableLiveEdit || index > 0 ? ( + + ) : ( + { + setEditorCode({ + ...editorCode, + value, + }); + }} + onFocus={() => { + setLiveDemoActive(true); + }} + id={demoSourceId} + language={demoData.sourceLanguage} + copyButtonProps={{ + 'data-ga-event-category': codeOpen ? 'demo-expand' : 'demo', + 'data-ga-event-label': demo.gaLabel, + 'data-ga-event-action': 'copy-click', + }} + > + {debouncedError} + + )} + + ))} + + {adVisibility ? : null} )} diff --git a/docs/src/modules/components/DemoEditor.tsx b/docs/src/modules/components/DemoEditor.tsx index a73d74799d6c35..bdee7f8daaa130 100644 --- a/docs/src/modules/components/DemoEditor.tsx +++ b/docs/src/modules/components/DemoEditor.tsx @@ -2,12 +2,12 @@ import * as React from 'react'; import SimpleCodeEditor from 'react-simple-code-editor'; import Box from '@mui/material/Box'; import { NoSsr } from '@mui/base/NoSsr'; -import { styled, useTheme } from '@mui/material/styles'; +import { styled, alpha, useTheme } from '@mui/material/styles'; import prism from '@mui/internal-markdown/prism'; import MarkdownElement from 'docs/src/modules/components/MarkdownElement'; import CodeCopyButton from 'docs/src/modules/components/CodeCopyButton'; import { useTranslate } from '@mui/docs/i18n'; -import { useCodeCopy } from 'docs/src/modules/utils/CodeCopy'; +import { useCodeCopy } from '@mui/docs/CodeCopy'; import { blueDark } from '@mui/docs/branding'; const StyledMarkdownElement = styled(MarkdownElement)(({ theme }) => [ @@ -17,17 +17,20 @@ const StyledMarkdownElement = styled(MarkdownElement)(({ theme }) => [ overflow: 'auto', marginTop: -1, backgroundColor: 'hsl(210, 35%, 9%)', // a special, one-off, color tailored for the code blocks using MUI's branding theme blue palette as the starting point. It has a less saturaded color but still maintaining a bit of the blue tint. - border: `1px solid ${(theme.vars || theme).palette.divider}`, + border: 0, colorScheme: 'dark', '&:hover': { - boxShadow: `0 0 0 3px ${(theme.vars || theme).palette.primary.light}`, + boxShadow: `0 0 0 3px ${alpha((theme.vars || theme).palette.primary[500], 0.5)}`, }, '&:focus-within': { - boxShadow: `0 0 0 2px ${(theme.vars || theme).palette.primary.main}`, + boxShadow: `0 0 0 3px ${alpha((theme.vars || theme).palette.primary[500], 0.8)}`, }, [theme.breakpoints.up('sm')]: { borderRadius: '0 0 12px 12px', }, + ...theme.applyDarkStyles({ + border: `1px solid ${(theme.vars || theme).palette.divider}`, + }), }, '& pre': { // The scroll container needs to be the parent of the editor, overriding: @@ -35,18 +38,10 @@ const StyledMarkdownElement = styled(MarkdownElement)(({ theme }) => [ maxWidth: 'initial', maxHeight: 'initial', }, - }, - theme.applyDarkStyles({ - '& .scrollContainer': { - borderColor: (theme.vars || theme).palette.divider, - '&:hover': { - boxShadow: `0 0 0 3px ${(theme.vars || theme).palette.primaryDark[300]}`, - }, - '&:focus-within': { - boxShadow: `0 0 0 2px ${(theme.vars || theme).palette.primaryDark[400]}`, - }, + '& .MuiCode-copy': { + display: 'none', }, - }), + }, ]) as any; const StyledSimpleCodeEditor = styled(SimpleCodeEditor)(({ theme }) => ({ diff --git a/docs/src/modules/components/DemoToolbar.js b/docs/src/modules/components/DemoToolbar.js index bb057eb447e4a4..8a0e8fbe97a14f 100644 --- a/docs/src/modules/components/DemoToolbar.js +++ b/docs/src/modules/components/DemoToolbar.js @@ -8,7 +8,7 @@ import CheckIcon from '@mui/icons-material/Check'; import Fade from '@mui/material/Fade'; import MDButton from '@mui/material/Button'; import Box from '@mui/material/Box'; -import MDToggleButton, { toggleButtonClasses } from '@mui/material/ToggleButton'; +import MDToggleButton from '@mui/material/ToggleButton'; import MDToggleButtonGroup, { toggleButtonGroupClasses } from '@mui/material/ToggleButtonGroup'; import SvgIcon from '@mui/material/SvgIcon'; import Snackbar from '@mui/material/Snackbar'; @@ -69,23 +69,18 @@ const ToggleButtonGroup = styled(MDToggleButtonGroup)(({ theme }) => [ theme.unstable_sx({ [`& .${toggleButtonGroupClasses.grouped}`]: { '&:not(:first-of-type)': { - marginLeft: 0.8, - borderLeft: '1px solid', - borderLeftColor: 'divider', - borderTopLeftRadius: 999, - borderBottomLeftRadius: 999, + pr: '2px', // a nudge for optical alignment }, '&:not(:last-of-type)': { - borderTopRightRadius: 999, - borderBottomRightRadius: 999, + pl: '2px', // a nudge for optical alignment }, }, }), ]); const Button = styled(MDButton)(({ theme }) => ({ - height: 24, - padding: '5px 8px 6px 8px', // the one-off 5px is for visually centering the text on the button's container + height: 26, + padding: '6px 8px 8px 8px', flexShrink: 0, borderRadius: 999, border: '1px solid', @@ -130,29 +125,15 @@ const MenuItem = styled(MDMenuItem)(({ theme }) => ({ const ToggleButton = styled(MDToggleButton)(({ theme }) => [ theme.unstable_sx({ - padding: theme.spacing(0, 1, 0.1, 1), + height: 26, + width: 38, + p: 0, fontSize: theme.typography.pxToRem(13), - borderColor: 'grey.200', borderRadius: '999px', '&.Mui-disabled': { - opacity: 0.5, + opacity: 0.8, + cursor: 'not-allowed', }, - [`&.${toggleButtonClasses.selected}:hover`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` - : alpha( - theme.palette.primary.main, - theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, - ), - '@media (hover: none)': { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` - : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), - }, - }, - }), - theme.applyDarkStyles({ - borderColor: theme.palette.primaryDark[700], }), ]); @@ -281,6 +262,31 @@ function useToolbar(controlRefs, options = {}) { }; } +function copyWithRelativeModules(raw, relativeModules) { + if (relativeModules) { + relativeModules.forEach(({ module, raw: content }) => { + // remove exports from relative module + content = content.replace(/export( )*(default)*( )*\w+;|export default|export/gm, ''); + // replace import statement with relative module content + // the module might be imported with or without extension, so we need to cover all cases + // E.g.: /import .* from '(.\/top100Films.js|.\/top100Films)';/ + const extensions = ['', '.js', '.jsx', '.ts', '.tsx', '.css', '.json']; + const patterns = extensions + .map((ext) => { + if (module.endsWith(ext)) { + return module.replace(ext, ''); + } + return ''; + }) + .filter(Boolean) + .join('|'); + const importPattern = new RegExp(`import .* from '(${patterns})';`); + raw = raw.replace(importPattern, content); + }); + } + return copy(raw); +} + export default function DemoToolbar(props) { const { codeOpen, @@ -332,9 +338,10 @@ export default function DemoToolbar(props) { const handleSnackbarClose = () => { setSnackbarOpen(false); }; + const handleCopyClick = async () => { try { - await copy(demoData.raw); + await copyWithRelativeModules(demoData.raw, demoData.relativeModules); setSnackbarMessage(t('copiedSource')); setSnackbarOpen(true); } finally { @@ -499,7 +506,7 @@ export default function DemoToolbar(props) { )} - + {hasNonSystemDemos && ( )} diff --git a/docs/src/modules/components/DemoToolbarRoot.ts b/docs/src/modules/components/DemoToolbarRoot.ts index 984115f71f2f7d..8632ce1ad77bfa 100644 --- a/docs/src/modules/components/DemoToolbarRoot.ts +++ b/docs/src/modules/components/DemoToolbarRoot.ts @@ -11,11 +11,13 @@ const DemoToolbarRoot = styled('div', { { display: 'none', [theme.breakpoints.up('sm')]: { + top: 0, + maxHeight: 50, display: 'block', - border: `1px solid ${(theme.vars || theme).palette.divider}`, marginTop: demoOptions.bg === 'inline' ? theme.spacing(1) : -1, - top: 0, padding: theme.spacing(0.5, 1), + border: `1px solid ${(theme.vars || theme).palette.divider}`, + borderTopWidth: demoOptions.bg === 'inline' ? 1 : 0, backgroundColor: alpha(theme.palette.grey[50], 0.2), borderRadius: openDemoSource ? 0 : '0 0 12px 12px', transition: theme.transitions.create('border-radius'), diff --git a/docs/src/modules/components/Head.tsx b/docs/src/modules/components/Head.tsx index 7366a2ce2fd8ff..884ecea4b08879 100644 --- a/docs/src/modules/components/Head.tsx +++ b/docs/src/modules/components/Head.tsx @@ -6,7 +6,9 @@ import { useUserLanguage, useTranslate } from '@mui/docs/i18n'; import { pathnameToLanguage } from 'docs/src/modules/utils/helpers'; // #major-version-switch -const HOST = 'https://mui.com'; +const HOST = process.env.PULL_REQUEST_ID + ? `https://deploy-preview-${process.env.PULL_REQUEST_ID}--${process.env.NETLIFY_SITE_NAME}.netlify.app` + : 'https://mui.com'; interface HeadProps { card?: string; diff --git a/docs/src/modules/components/HighlightedCode.js b/docs/src/modules/components/HighlightedCode.js index ca7a8458fa1034..16848d1f2cfac8 100644 --- a/docs/src/modules/components/HighlightedCode.js +++ b/docs/src/modules/components/HighlightedCode.js @@ -1,52 +1,5 @@ -import * as React from 'react'; -import PropTypes from 'prop-types'; -import prism from '@mui/internal-markdown/prism'; -import { NoSsr } from '@mui/base/NoSsr'; -import MarkdownElement from 'docs/src/modules/components/MarkdownElement'; -import CodeCopyButton from 'docs/src/modules/components/CodeCopyButton'; -import { useCodeCopy } from 'docs/src/modules/utils/CodeCopy'; - -const HighlightedCode = React.forwardRef(function HighlightedCode(props, ref) { - const { - copyButtonHidden = false, - copyButtonProps, - code, - language, - component: Component = MarkdownElement, - ...other - } = props; - const renderedCode = React.useMemo(() => { - return prism(code.trim(), language); - }, [code, language]); - const handlers = useCodeCopy(); - - return ( - -

    - {copyButtonHidden ? null : ( - - - - )} -
    -          
    -        
    -
    - - ); -}); - -HighlightedCode.propTypes = { - code: PropTypes.string.isRequired, - component: PropTypes.elementType, - copyButtonHidden: PropTypes.bool, - copyButtonProps: PropTypes.object, - language: PropTypes.string.isRequired, - sx: PropTypes.object, -}; +// Backwards compatibility for Toolpad and X. +// TODO: remove when Toolpad and X migrated to `@mui/docs/HighlightedCode` +import { HighlightedCode } from '@mui/docs/HighlightedCode'; export default HighlightedCode; diff --git a/docs/src/modules/components/HighlightedCode.test.js b/docs/src/modules/components/HighlightedCode.test.js index 05f7f1b627a523..60ccf9b7c04ff4 100644 --- a/docs/src/modules/components/HighlightedCode.test.js +++ b/docs/src/modules/components/HighlightedCode.test.js @@ -3,7 +3,7 @@ import { expect } from 'chai'; import { createRenderer } from '@mui-internal/test-utils'; import { ThemeProvider, createTheme } from '@mui/material/styles'; import { getDesignTokens } from '@mui/docs/branding'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; describe('HighlightedCode', () => { const { render } = createRenderer(); diff --git a/docs/src/modules/components/HighlightedCodeWithTabs.tsx b/docs/src/modules/components/HighlightedCodeWithTabs.tsx index 7372011ff47f06..27242449152c99 100644 --- a/docs/src/modules/components/HighlightedCodeWithTabs.tsx +++ b/docs/src/modules/components/HighlightedCodeWithTabs.tsx @@ -7,22 +7,35 @@ import { Tab as TabBase } from '@mui/base/Tab'; import useLocalStorageState from '@mui/utils/useLocalStorageState'; import HighlightedCode from './HighlightedCode'; -const TabList = styled(TabsListBase)(({ theme }) => ({ - padding: 6, +export const CodeTabList = styled(TabsListBase)<{ + ownerState: { mounted: boolean; contained?: boolean }; +}>(({ theme, ownerState }) => ({ + padding: ownerState?.contained ? theme.spacing(1.5, 1) : theme.spacing(1), display: 'flex', - border: '1px solid', - borderColor: (theme.vars || theme).palette.primaryDark[700], - backgroundColor: (theme.vars || theme).palette.primaryDark[900], - borderTopLeftRadius: (theme.vars || theme).shape.borderRadius, - borderTopRightRadius: (theme.vars || theme).shape.borderRadius, + gap: theme.spacing(0.5), + borderLeft: '1px solid', + borderRight: '1px solid', + borderTop: ownerState?.contained ? 'none' : '1px solid', + borderBottom: ownerState?.contained ? 'none' : '1px solid', + borderTopLeftRadius: ownerState?.contained ? 0 : (theme.vars || theme).shape.borderRadius, + borderTopRightRadius: ownerState?.contained ? 0 : (theme.vars || theme).shape.borderRadius, + borderColor: ownerState?.contained + ? (theme.vars || theme).palette.divider + : (theme.vars || theme).palette.primaryDark[700], + backgroundColor: ownerState?.contained + ? alpha(theme.palette.grey[50], 0.2) + : (theme.vars || theme).palette.primaryDark[900], ...theme.applyDarkStyles({ - backgroundColor: alpha(theme.palette.primaryDark[800], 0.5), + backgroundColor: alpha(theme.palette.primaryDark[800], 0.2), }), })); -const TabPanel = styled(TabPanelBase)<{ ownerState: { mounted: boolean } }>(({ ownerState }) => ({ +export const CodeTabPanel = styled(TabPanelBase)<{ + ownerState: { mounted: boolean; contained?: boolean }; +}>(({ ownerState }) => ({ + marginTop: ownerState?.contained ? -1 : 0, '& pre': { - marginTop: -1, + marginTop: ownerState?.contained ? 0 : -1, borderTopLeftRadius: 0, borderTopRightRadius: 0, '& code': { @@ -31,46 +44,59 @@ const TabPanel = styled(TabPanelBase)<{ ownerState: { mounted: boolean } }>(({ o }, })); -const Tab = styled(TabBase)<{ ownerState: { mounted: boolean } }>(({ theme, ownerState }) => - theme.unstable_sx({ - p: 0.8, - border: 'none', - bgcolor: 'transparent', - color: (theme.vars || theme).palette.grey[500], - fontSize: theme.typography.pxToRem(12), - fontWeight: theme.typography.fontWeightSemiBold, - fontFamily: theme.typography.fontFamilyCode, - outline: 'none', - minWidth: 52, - cursor: 'pointer', - borderRadius: '8px', - position: 'relative', - '&:not(:first-of-type)': { - marginLeft: 0.5, - }, - ...(ownerState.mounted && { - '&.base--selected': { - color: '#FFF', - '&::after': { - content: "''", - position: 'absolute', - left: 0, - bottom: '-6px', - height: 2, - width: '100%', - bgcolor: (theme.vars || theme).palette.primary.light, - }, +export const CodeTab = styled(TabBase)<{ ownerState: { mounted: boolean; contained?: boolean } }>( + ({ theme, ownerState }) => + theme.unstable_sx({ + height: 26, + p: '0 8px 2px 8px', + border: ownerState?.contained ? '1px solid transparent' : 'none', + bgcolor: 'transparent', + color: ownerState?.contained + ? (theme.vars || theme).palette.text.tertiary + : (theme.vars || theme).palette.grey[500], + fontSize: theme.typography.pxToRem(ownerState?.contained ? 13 : 12), + fontFamily: ownerState?.contained + ? theme.typography.fontFamily + : theme.typography.fontFamilyCode, + fontWeight: ownerState?.contained + ? theme.typography.fontWeightMedium + : theme.typography.fontWeightBold, + lineHeight: 1.2, + outline: 'none', + minWidth: 52, + cursor: 'pointer', + borderRadius: 99, + position: 'relative', + transition: ownerState?.contained ? 'background, color, 100ms ease' : 'unset', + '&:hover': { + backgroundColor: (theme.vars || theme).palette.divider, }, + '&:focus-visible': { + outline: '3px solid', + outlineOffset: '1px', + outlineColor: (theme.vars || theme).palette.primary.light, + }, + ...(!ownerState?.contained && { + '&:hover': { + backgroundColor: alpha(theme.palette.primaryDark[500], 0.5), + color: (theme.vars || theme).palette.grey[400], + }, + ...(ownerState.mounted && { + '&.base--selected': { + color: '#FFF', + '&::after': { + content: "''", + position: 'absolute', + left: 0, + bottom: '-8px', + height: 2, + width: '100%', + bgcolor: (theme.vars || theme).palette.primary.light, + }, + }, + }), + }), }), - '&:hover': { - backgroundColor: alpha(theme.palette.primaryDark[500], 0.5), - }, - '&:focus-visible': { - outline: '2px solid', - outlineOffset: '-2px', - outlineColor: (theme.vars || theme).palette.primary.light, - }, - }), ); type TabsConfig = { @@ -88,6 +114,8 @@ export default function HighlightedCodeWithTabs( const { tabs, storageKey } = props; const availableTabs = React.useMemo(() => tabs.map(({ tab }) => tab), [tabs]); const [activeTab, setActiveTab] = useLocalStorageState(storageKey ?? null, availableTabs[0]); + // During hydration, activeTab is null, default to first value. + const defaultizedActiveTab = activeTab ?? availableTabs[0]; const [mounted, setMounted] = React.useState(false); @@ -101,22 +129,22 @@ export default function HighlightedCodeWithTabs( const ownerState = { mounted }; return ( - - + + {tabs.map(({ tab }) => ( - + {tab} - + ))} - + {tabs.map(({ tab, language, code }) => ( - + - + ))} ); diff --git a/docs/src/modules/components/HooksApiContent.js b/docs/src/modules/components/HooksApiContent.js index ded5a05f01e5fa..54f14253876081 100644 --- a/docs/src/modules/components/HooksApiContent.js +++ b/docs/src/modules/components/HooksApiContent.js @@ -5,7 +5,7 @@ import kebabCase from 'lodash/kebabCase'; import { exactProp } from '@mui/utils'; import { useTranslate, useUserLanguage } from '@mui/docs/i18n'; import PropertiesSection from 'docs/src/modules/components/ApiPage/sections/PropertiesSection'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import MarkdownElement from 'docs/src/modules/components/MarkdownElement'; import { DEFAULT_API_LAYOUT_STORAGE_KEYS } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; @@ -27,11 +27,13 @@ function Heading(props) { return ( - {getTranslatedHeader(t, hash, text)} - - - - + + {getTranslatedHeader(t, hash, text)} + + + + + ); @@ -72,7 +74,9 @@ export default function HooksApiContent(props) { -

    + {imports.length > 1 && ( +

    + )} {Object.keys(parameters).length > 0 ? ( { let equal = true; diff --git a/docs/src/modules/components/JoyVariablesDemo.tsx b/docs/src/modules/components/JoyVariablesDemo.tsx index 2d4392d3059bf3..fe4fb76e37d8ef 100644 --- a/docs/src/modules/components/JoyVariablesDemo.tsx +++ b/docs/src/modules/components/JoyVariablesDemo.tsx @@ -12,7 +12,7 @@ import FormHelperText from '@mui/joy/FormHelperText'; import Input, { inputClasses } from '@mui/joy/Input'; import ReplayRoundedIcon from '@mui/icons-material/ReplayRounded'; import KeyboardArrowDown from '@mui/icons-material/KeyboardArrowDown'; -import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; +import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { BrandingProvider } from '@mui/docs/branding'; interface DataItem { diff --git a/docs/src/modules/components/MarkdownDocs.js b/docs/src/modules/components/MarkdownDocs.js index 9d12aef4dad2c5..5d1dc61a55b3c8 100644 --- a/docs/src/modules/components/MarkdownDocs.js +++ b/docs/src/modules/components/MarkdownDocs.js @@ -54,6 +54,10 @@ export default function MarkdownDocs(props) { return ( item.text !== 'API'); + const demosToc = localizedDoc.toc; function createHookTocEntry(hookName, sectionName, hookProps = {}) { const hookPropToc = []; @@ -243,6 +243,10 @@ export default function MarkdownDocsV2(props) { return ( 0 ? 1 : 0), - ) + .slice(i) .map((renderedMarkdownOrDemo, index) => ( ({ - ...lightTheme.typography.body1, - lineHeight: 1.6, // Increased compared to the 1.5 default to make the docs easier to read. - color: `var(--muidocs-palette-text-primary, ${lightTheme.palette.text.primary})`, - '& :focus-visible': { - outline: `3px solid ${alpha(lightTheme.palette.primary[500], 0.5)}`, - outlineOffset: 2, - }, - '& strong': { - color: `var(--muidocs-palette-text-primary, ${lightTheme.palette.text.primary})`, - }, - wordBreak: 'break-word', - '& pre': { - lineHeight: 1.5, // Developers like when the code is dense. - margin: theme.spacing(2, 'auto'), - padding: theme.spacing(2), - backgroundColor: 'hsl(210, 35%, 9%)', // a special, one-off, color tailored for the code blocks using MUI's branding theme blue palette as the starting point. It has a less saturaded color but still maintaining a bit of the blue tint. - color: 'hsl(60, 30%, 96%)', - colorScheme: 'dark', - borderRadius: `var(--muidocs-shape-borderRadius, ${ - theme.shape?.borderRadius ?? lightTheme.shape.borderRadius - }px)`, - border: '1px solid', - borderColor: `var(--muidocs-palette-primaryDark-700, ${lightTheme.palette.primaryDark[700]})`, - overflow: 'auto', - WebkitOverflowScrolling: 'touch', - fontSize: lightTheme.typography.pxToRem(13), - maxWidth: 'calc(100vw - 32px)', - maxHeight: '400px', - [lightTheme.breakpoints.up('md')]: { - maxWidth: 'calc(100vw - 32px - 16px)', - }, - }, - '& code': { - ...lightTheme.typography.body2, - fontFamily: lightTheme.typography.fontFamilyCode, - fontWeight: 400, - WebkitFontSmoothing: 'subpixel-antialiased', - }, - '& pre > code': { - // Reset for Safari - // https://github.com/necolas/normalize.css/blob/master/normalize.css#L102 - fontSize: 'inherit', - }, - // inline code block - '& :not(pre) > code': { - padding: '2px 4px', - color: `var(--muidocs-palette-text-primary, ${lightTheme.palette.text.primary})`, - backgroundColor: `var(--muidocs-palette-grey-50, ${lightTheme.palette.grey[50]})`, - border: '1px solid', - borderColor: `var(--muidocs-palette-grey-200, ${lightTheme.palette.grey[200]})`, - borderRadius: 6, - fontSize: lightTheme.typography.pxToRem(13), - direction: 'ltr /*! @noflip */', - boxDecorationBreak: 'clone', - }, - '& h1': { - ...lightTheme.typography.h3, - fontSize: lightTheme.typography.pxToRem(36), - fontFamily: `"Graphik", ${lightTheme.typography.fontFamilySystem}`, - margin: '10px 0', - color: `var(--muidocs-palette-primaryDark-900, ${lightTheme.palette.primaryDark[900]})`, - fontWeight: 600, - letterSpacing: -0.2, - }, - '& .description': { - ...lightTheme.typography.subtitle1, - fontWeight: 400, - margin: '0 0 24px', - }, - '& .component-tabs': { - margin: '0 0 40px', - }, - '& h2': { - ...lightTheme.typography.h5, - fontFamily: `"Graphik", ${lightTheme.typography.fontFamilySystem}`, - fontSize: theme.typography.pxToRem(26), - fontWeight: lightTheme.typography.fontWeightSemiBold, - color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, - margin: '40px 0 4px', - }, - '& h3': { - ...lightTheme.typography.h6, - fontFamily: `"Graphik", ${lightTheme.typography.fontFamilySystem}`, - fontSize: theme.typography.pxToRem(20), - fontWeight: lightTheme.typography.fontWeightSemiBold, - color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, - margin: '24px 0 4px', - }, - '& h4': { - ...lightTheme.typography.subtitle1, - fontFamily: `"Graphik", ${lightTheme.typography.fontFamilySystem}`, - fontWeight: lightTheme.typography.fontWeightSemiBold, - color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, - margin: '20px 0 6px', - }, - '& h5': { - ...lightTheme.typography.subtitle2, - fontFamily: `"Graphik", ${lightTheme.typography.fontFamilySystem}`, - fontWeight: lightTheme.typography.fontWeightSemiBold, - color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, - margin: '20px 0 8px', - }, - '& p': { - marginTop: 0, - marginBottom: 16, - color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, - }, - '& ul, & ol': { - paddingLeft: 30, - marginTop: 0, - marginBottom: 16, - '& ul, & ol': { - marginBottom: 6, - }, - }, - '& h1, & h2, & h3, & h4': { - display: 'flex', - alignItems: 'center', - gap: 6, - '& code': { - fontSize: 'inherit', - lineHeight: 'inherit', - // Remove scroll on small screens. - wordBreak: 'break-all', - }, - '& .anchor-link': { - // To prevent the link to get the focus. - display: 'inline-flex', - alignItems: 'center', - visibility: 'hidden', - }, - '& a:not(.anchor-link):hover': { - color: 'currentColor', - border: 'none', - boxShadow: '0 1px 0 0 currentColor', - textDecoration: 'none', - }, - '& .anchor-link, & .comment-link': { - padding: 0, - cursor: 'pointer', - alignItems: 'center', - justifyContent: 'center', - flexShrink: 0, - textAlign: 'center', - marginLeft: 4, - height: 26, - width: 26, - backgroundColor: `var(--muidocs-palette-primary-50, ${lightTheme.palette.grey[50]})`, - color: `var(--muidocs-palette-grey-600, ${lightTheme.palette.grey[600]})`, - border: '1px solid', - borderColor: `var(--muidocs-palette-divider, ${lightTheme.palette.divider})`, - borderRadius: 8, - '&:hover': { - backgroundColor: alpha(lightTheme.palette.primary[100], 0.4), - borderColor: `var(--muidocs-palette-primary-100, ${lightTheme.palette.primary[100]})`, - color: `var(--muidocs-palette-primary-main, ${lightTheme.palette.primary.main})`, - }, - '& svg': { - height: 14, - width: 14, - fill: 'currentColor', - pointerEvents: 'none', - verticalAlign: 'middle', - }, - }, - '&:hover .anchor-link': { - visibility: 'visible', - }, - '& .comment-link': { - display: 'none', // So we can have the comment button opt-in. - marginLeft: 'auto', - transition: theme.transitions.create('opacity', { - duration: theme.transitions.duration.shortest, - }), - '& svg': { - fill: 'currentColor', - marginRight: 1.5, - }, - }, - }, - '& h1 code, & h2 code, & h3 code': { - color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, - }, - '& h1 code': { - fontWeight: lightTheme.typography.fontWeightSemiBold, - }, - '& h2 code': { - fontSize: lightTheme.typography.pxToRem(24), - fontWeight: lightTheme.typography.fontWeightSemiBold, - }, - '& h3 code': { - fontSize: lightTheme.typography.pxToRem(18), - }, - '& table': { - // Trade display table for scroll overflow - display: 'block', - wordBreak: 'normal', - overflowX: 'auto', - WebkitOverflowScrolling: 'touch', - borderCollapse: 'collapse', - marginBottom: '20px', - borderSpacing: 0, - '& .prop-name, & .prop-type, & .prop-default, & .slot-name, & .slot-defaultClass, & .slot-default': - { - fontWeight: 400, - fontFamily: lightTheme.typography.fontFamilyCode, - WebkitFontSmoothing: 'subpixel-antialiased', - fontSize: lightTheme.typography.pxToRem(13), - }, - '& .required': { - color: '#006500', - }, - '& .optional': { - color: '#45529f', - }, - '& .prop-type, & .slot-defaultClass': { - color: '#932981', - }, - '& .prop-default, & .slot-default': { - borderBottom: `1px dotted var(--muidocs-palette-divider, ${lightTheme.palette.divider})`, - }, - }, - '& td': { - ...theme.typography.body2, - borderBottom: `1px solid var(--muidocs-palette-divider, ${lightTheme.palette.divider})`, - paddingRight: 20, - paddingTop: 16, - paddingBottom: 16, - color: `var(--muidocs-palette-text-secondary, ${lightTheme.palette.text.secondary})`, - }, - '& td code': { - lineHeight: 1.6, - }, - '& th': { - fontSize: theme.typography.pxToRem(14), - lineHeight: theme.typography.pxToRem(24), - fontWeight: 500, - color: `var(--muidocs-palette-text-primary, ${lightTheme.palette.text.primary})`, - whiteSpace: 'pre', - borderBottom: `1px solid var(--muidocs-palette-divider, ${lightTheme.palette.divider})`, - paddingRight: 20, - paddingTop: 12, - paddingBottom: 12, - }, - '& blockquote': { - position: 'relative', - padding: '0 16px', - margin: 0, - borderLeft: '1.5px solid', - borderColor: `var(--muidocs-palette-grey-200, ${lightTheme.palette.grey[200]})`, - '& p': { - fontSize: theme.typography.pxToRem(12.5), - fontFamily: lightTheme.typography.fontFamilyCode, - fontWeight: lightTheme.typography.fontWeightMedium, - lineHeight: theme.typography.pxToRem(24), - textIndent: 20, - }, - '&::before': { - position: 'absolute', - // eslint-disable-next-line material-ui/straight-quotes - content: '"“"', - color: `var(--muidocs-palette-grey-300, ${lightTheme.palette.grey[300]})`, - fontSize: '2.5rem', - top: 8, - marginLeft: -6, - lineHeight: 0.5, - }, - }, - '& .MuiCallout-root': { - display: 'flex', - gap: 12, - padding: '16px', - margin: '16px 0', - border: '1px solid', - color: `var(--muidocs-palette-text-secondary, ${lightTheme.palette.text.secondary})`, - borderColor: `var(--muidocs-palette-grey-100, ${lightTheme.palette.grey[100]})`, - borderRadius: `var(--muidocs-shape-borderRadius, ${ - theme.shape?.borderRadius ?? lightTheme.shape.borderRadius - }px)`, - '& > code': { - height: 'fit-content', - backgroundColor: `var(--muidocs-palette-grey-100, ${lightTheme.palette.grey[100]})`, - borderColor: `var(--muidocs-palette-grey-300, ${lightTheme.palette.grey[300]})`, - }, - '& .MuiCallout-content': { - minWidth: 0, // Allows content to shrink. Useful when callout contains code block - flexGrow: 1, - '& > p:last-child, & > ul:last-child': { - // Avoid margin on last child - marginBottom: 0, - }, - '& .MuiCode-root': { - '& > pre': { - margin: 0, - marginTop: 4, - }, - }, - '& > ul': { - // Because of the gap left by the icon, we visually need less padding - paddingLeft: 22, - }, - }, - '& > svg': { - marginTop: 2, - width: 20, - height: 20, - flexShrink: 0, - }, - '& > ul, & > p': { - '&:last-child': { - margin: 0, - }, - }, - '& ul, li, p': { - color: 'inherit', - }, - '&.MuiCallout-error': { - color: `var(--muidocs-palette-error-900, ${lightTheme.palette.error[900]})`, - backgroundColor: `var(--muidocs-palette-error-50, ${lightTheme.palette.error[50]})`, - borderColor: `var(--muidocs-palette-error-100, ${lightTheme.palette.error[100]})`, - '& strong': { - color: `var(--muidocs-palette-error-800, ${lightTheme.palette.error[800]})`, - }, - '& > svg': { - fill: `var(--muidocs-palette-error-500, ${lightTheme.palette.error[600]})`, - }, - '& a': { - color: `var(--muidocs-palette-error-800, ${lightTheme.palette.error[800]})`, - textDecorationColor: alpha(lightTheme.palette.error.main, 0.4), - '&:hover': { - textDecorationColor: 'inherit', - }, - }, - }, - '&.MuiCallout-info': { - color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, - backgroundColor: `var(--muidocs-palette-grey-50, ${lightTheme.palette.grey[50]})`, - borderColor: `var(--muidocs-palette-grey-100, ${lightTheme.palette.grey[100]})`, - '& strong': { - color: `var(--muidocs-palette-primary-800, ${lightTheme.palette.primary[800]})`, - }, - '& > svg': { - fill: `var(--muidocs-palette-grey-600, ${lightTheme.palette.grey[600]})`, - }, - }, - '&.MuiCallout-success': { - color: `var(--muidocs-palette-success-900, ${lightTheme.palette.success[900]})`, - backgroundColor: `var(--muidocs-palette-success-50, ${lightTheme.palette.success[50]})`, - borderColor: `var(--muidocs-palette-success-100, ${lightTheme.palette.success[100]})`, - '& strong': { - color: `var(--muidocs-palette-success-900, ${lightTheme.palette.success[900]})`, - }, - '& > svg': { - fill: `var(--muidocs-palette-success-600, ${lightTheme.palette.success[600]})`, - }, - '& a': { - color: `var(--muidocs-palette-success-900, ${lightTheme.palette.success[900]})`, - textDecorationColor: alpha(lightTheme.palette.success.main, 0.4), - '&:hover': { - textDecorationColor: 'inherit', - }, - }, - }, - '&.MuiCallout-warning': { - color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, - backgroundColor: alpha(lightTheme.palette.warning[50], 0.5), - borderColor: alpha(lightTheme.palette.warning[700], 0.15), - '& strong': { - color: `var(--muidocs-palette-warning-800, ${lightTheme.palette.warning[800]})`, - }, - '& > svg': { - fill: `var(--muidocs-palette-warning-600, ${lightTheme.palette.warning[600]})`, - }, - '& a': { - color: `var(--muidocs-palette-warning-800, ${lightTheme.palette.warning[800]})`, - textDecorationColor: alpha(lightTheme.palette.warning.main, 0.4), - '&:hover': { - textDecorationColor: 'inherit', - }, - }, - }, - }, - '& a[target="_blank"]::after': { - content: '""', - maskImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' focusable='false' aria-hidden='true' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M6 6v2h8.59L5 17.59 6.41 19 16 9.41V18h2V6z'%3E%3C/path%3E%3C/svg%3E")`, - display: 'inline-flex', - width: '1em', - height: '1em', - color: 'inherit', - backgroundColor: 'currentColor', - transform: 'translate(0, 2px)', - transition: 'transform 0.3s cubic-bezier(0.1, 0.8, 0.3, 1)', // bounce effect - opacity: 0.8, - }, - '& a[target="_blank"]:hover::after': { - opacity: 1, - transform: 'translate(1px, 0)', - }, - '& a.remove-link-arrow::after': { - // Allows to remove link arrows for images - display: 'none', - }, - '& .Ad-root a::after': { - // Remove link arrow for ads - display: 'none', - }, - '& a, & a code': { - // Style taken from the Link component - color: `var(--muidocs-palette-primary-600, ${lightTheme.palette.primary[600]})`, - fontWeight: theme.typography.fontWeightMedium, - textDecoration: 'underline', - textDecorationColor: alpha(lightTheme.palette.primary.main, 0.4), - '&:hover': { - textDecorationColor: 'inherit', - }, - }, - '& a code': { - color: darken(lightTheme.palette.primary.main, 0.2), - }, - '& img, & video': { - // Use !important so that inline style on or

    - *
    ...
    - * - *
    - */ -export function useCodeCopy(): any { - const rootNode = React.useContext(CodeBlockContext); - return { - onMouseEnter: (event: React.MouseEvent) => { - rootNode.current = event.currentTarget as HTMLDivElement; - }, - onMouseLeave: (event: React.MouseEvent) => { - if (rootNode.current === event.currentTarget) { - (rootNode.current.querySelector('.MuiCode-copy') as null | HTMLButtonElement)?.blur(); - rootNode.current = null; - } - }, - onFocus: (event: React.MouseEvent) => { - rootNode.current = event.currentTarget as HTMLDivElement; - }, - onBlur: (event: React.FocusEvent) => { - if (rootNode.current === event.currentTarget) { - rootNode.current = null; - } - }, - }; -} - -function InitCodeCopy() { - const rootNode = React.useContext(CodeBlockContext); - const router = useRouter(); - React.useEffect(() => { - let key = 'Ctrl + '; - if (typeof window !== 'undefined') { - const macOS = window.navigator.platform.toUpperCase().indexOf('MAC') >= 0; - if (macOS) { - key = '⌘'; - } - } - const codeRoots = document.getElementsByClassName( - 'MuiCode-root', - ) as HTMLCollectionOf; - - if (codeRoots !== null) { - const listeners: Array<() => void> = []; - Array.from(codeRoots).forEach((elm) => { - const handleMouseEnter = () => { - rootNode.current = elm; - }; - - elm.addEventListener('mouseenter', handleMouseEnter); - listeners.push(() => elm.removeEventListener('mouseenter', handleMouseEnter)); - - const handleMouseLeave = () => { - if (rootNode.current === elm) { - (rootNode.current.querySelector('.MuiCode-copy') as null | HTMLButtonElement)?.blur(); - rootNode.current = null; - } - }; - elm.addEventListener('mouseleave', handleMouseLeave); - listeners.push(() => elm.removeEventListener('mouseleave', handleMouseLeave)); - - const handleFocusin = () => { - // use `focusin` because it bubbles from the copy button - rootNode.current = elm; - }; - elm.addEventListener('focusin', handleFocusin); - listeners.push(() => elm.removeEventListener('focusin', handleFocusin)); - - const handleFocusout = () => { - // use `focusout` because it bubbles from the copy button - if (rootNode.current === elm) { - rootNode.current = null; - } - }; - elm.addEventListener('focusout', handleFocusout); - listeners.push(() => elm.removeEventListener('focusout', handleFocusout)); - - async function handleClick(event: MouseEvent) { - const trigger = event.currentTarget as HTMLButtonElement; - const pre = (event.currentTarget as Element)?.previousElementSibling as Element; - const textNode = trigger.childNodes[0]; - textNode.nodeValue = textNode.textContent?.replace('Copy', 'Copied') || null; - trigger.dataset.copied = 'true'; - setTimeout(() => { - if (trigger) { - textNode.nodeValue = textNode.textContent?.replace('Copied', 'Copy') || null; - delete trigger.dataset.copied; - } - }, 2000); - try { - if (pre.textContent) { - await copy(pre.textContent); - } - // eslint-disable-next-line no-empty - } catch (error) {} - } - - const btn = elm.querySelector('.MuiCode-copy') as HTMLButtonElement | null; - if (btn) { - const keyNode = btn.querySelector('.MuiCode-copyKeypress')?.childNodes[1]; - if (!keyNode) { - // skip the logic if the btn is not generated from the markdown. - return; - } - keyNode.textContent = keyNode?.textContent?.replace('$key', key) || null; - btn.addEventListener('click', handleClick); - listeners.push(() => btn.removeEventListener('click', handleClick)); - } - }); - - return () => { - listeners.forEach((removeEventListener) => { - removeEventListener(); - }); - }; - } - - return undefined; - }, [rootNode, router.pathname]); - return null; -} - -function hasNativeSelection(element: HTMLTextAreaElement) { - if (window.getSelection()?.toString()) { - return true; - } - - // window.getSelection() returns an empty string in Firefox for selections inside a form element. - // See: https://bugzilla.mozilla.org/show_bug.cgi?id=85686. - // Instead, we can use element.selectionStart that is only defined on form elements. - if (element && (element.selectionEnd || 0) - (element.selectionStart || 0) > 0) { - return true; - } - - return false; -} - -interface CodeCopyProviderProps { - children: React.ReactNode; -} - -/** - * Place at the page level. It will check the keydown event and try to initiate copy click if rootNode exist. - * Any code block inside the tree can set the rootNode when mouse enter to leverage keyboard copy. - */ -export function CodeCopyProvider({ children }: CodeCopyProviderProps) { - const rootNode = React.useRef(null); - React.useEffect(() => { - document.addEventListener('keydown', (event) => { - if (!rootNode.current) { - return; - } - - // Skip if user is highlighting a text. - if (hasNativeSelection(event.target as HTMLTextAreaElement)) { - return; - } - - // Skip if it's not a copy keyboard event - if ( - !( - (event.ctrlKey || event.metaKey) && - event.key.toLowerCase() === 'c' && - !event.shiftKey && - !event.altKey - ) - ) { - return; - } - - const copyBtn = rootNode.current.querySelector('.MuiCode-copy') as HTMLButtonElement; - const initialEventAction = copyBtn.getAttribute('data-ga-event-action'); - // update the 'data-ga-event-action' on the button to track keyboard interaction - copyBtn.dataset.gaEventAction = - initialEventAction?.replace('click', 'keyboard') || 'copy-keyboard'; - copyBtn.click(); // let the GA setup in GoogleAnalytics.js do the job - copyBtn.dataset.gaEventAction = initialEventAction!; // reset the 'data-ga-event-action' back to initial - }); - }, []); - return ( - - - {children} - - ); -} +export * from '@mui/docs/CodeCopy'; diff --git a/docs/src/modules/utils/useClipboardCopy.ts b/docs/src/modules/utils/useClipboardCopy.ts index dd0b3b618b8e3e..817efb527c4c30 100644 --- a/docs/src/modules/utils/useClipboardCopy.ts +++ b/docs/src/modules/utils/useClipboardCopy.ts @@ -1,32 +1,5 @@ -import * as React from 'react'; -import clipboardCopy from 'clipboard-copy'; +// Backwards compatibility for Toolpad and X. +// TODO: remove when Toolpad and X migrated to `@mui/docs/CodeCopy` +import { useClipboardCopy } from '@mui/docs/CodeCopy'; -export default function useClipboardCopy() { - const [isCopied, setIsCopied] = React.useState(false); - const timeout = React.useRef>(); - const mounted = React.useRef(false); - - React.useEffect(() => { - mounted.current = true; - return () => { - mounted.current = false; - }; - }, []); - - const copy = async (text: string) => { - try { - setIsCopied(true); - clearTimeout(timeout.current); - timeout.current = setTimeout(() => { - if (mounted) { - setIsCopied(false); - } - }, 1200); - await clipboardCopy(text); - } catch (error) { - // ignore error - } - }; - - return { copy, isCopied }; -} +export default useClipboardCopy; diff --git a/docs/src/pages/premium-themes/onepirate/modules/components/Snackbar.tsx b/docs/src/pages/premium-themes/onepirate/modules/components/Snackbar.tsx index e27855541ec2ec..bb4231a7725f94 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/components/Snackbar.tsx +++ b/docs/src/pages/premium-themes/onepirate/modules/components/Snackbar.tsx @@ -6,7 +6,7 @@ import Slide from '@mui/material/Slide'; import CloseIcon from '@mui/icons-material/Close'; import InfoIcon from '@mui/icons-material/Info'; import IconButton from '@mui/material/IconButton'; -import { TransitionProps } from '@mui/material/transitions/transition'; +import { TransitionProps } from '@mui/material/transitions'; const styles = ({ theme }: { theme: Theme }) => ({ diff --git a/docs/src/route.ts b/docs/src/route.ts index b4a0c5828de3a9..03911cc4e5645a 100644 --- a/docs/src/route.ts +++ b/docs/src/route.ts @@ -49,7 +49,7 @@ const ROUTES = { // Tree View doc pages treeViewOverview: '/x/react-tree-view/', // Toolpad pages - toolpadDocs: '/toolpad/getting-started/', + toolpadDocs: '/toolpad/studio/getting-started/', toolpadStudioDocs: '/toolpad/studio/getting-started', // External pages rssFeed: '/feed/blog/rss.xml', diff --git a/docs/translations/api-docs/chip/chip.json b/docs/translations/api-docs/chip/chip.json index fddc50bdb23a05..719f2b5e502068 100644 --- a/docs/translations/api-docs/chip/chip.json +++ b/docs/translations/api-docs/chip/chip.json @@ -79,6 +79,11 @@ "conditions": "onClick and color=\"secondary\" is defined or clickable={true}", "deprecationInfo": "Combine the .MuiChip-clickable and .MuiChip-colorSecondary classes instead. How to migrate" }, + "colorDefault": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "color=\"default\"" + }, "colorError": { "description": "Styles applied to {{nodeName}} if {{conditions}}.", "nodeName": "the root element", diff --git a/docs/translations/api-docs/form-control-label/form-control-label.json b/docs/translations/api-docs/form-control-label/form-control-label.json index 9cee865af30cbe..4e95f4509846fd 100644 --- a/docs/translations/api-docs/form-control-label/form-control-label.json +++ b/docs/translations/api-docs/form-control-label/form-control-label.json @@ -24,6 +24,7 @@ "description": "If true, the label will indicate that the input is required." }, "slotProps": { "description": "The props used for each slot inside." }, + "slots": { "description": "The components used for each slot inside." }, "sx": { "description": "The system prop that allows defining system overrides as well as additional CSS styles." }, @@ -69,5 +70,8 @@ "conditions": "required={true}" }, "root": { "description": "Styles applied to the root element." } + }, + "slotDescriptions": { + "typography": "The component that renders the label. This is unused if disableTypography is true." } } diff --git a/docs/translations/api-docs/pagination-item/pagination-item.json b/docs/translations/api-docs/pagination-item/pagination-item.json index de26e46725f5d8..1dd3b9dbcba2f4 100644 --- a/docs/translations/api-docs/pagination-item/pagination-item.json +++ b/docs/translations/api-docs/pagination-item/pagination-item.json @@ -16,9 +16,8 @@ "selected": { "description": "If true the pagination item is selected." }, "shape": { "description": "The shape of the pagination item." }, "size": { "description": "The size of the component." }, - "slots": { - "description": "The components used for each slot inside.
    This prop is an alias for the components prop, which will be deprecated in the future." - }, + "slotProps": { "description": "The props used for each slot inside." }, + "slots": { "description": "The components used for each slot inside." }, "sx": { "description": "The system prop that allows defining system overrides as well as additional CSS styles." }, @@ -122,5 +121,6 @@ "conditions": "variant=\"text\" and color=\"secondary\"", "deprecationInfo": "Combine the .MuiPaginationItem-text and .MuiPaginationItem-colorSecondary classes instead. How to migrate." } - } + }, + "slotDescriptions": { "first": "", "last": "", "next": "", "previous": "" } } diff --git a/docs/translations/api-docs/step-connector/step-connector.json b/docs/translations/api-docs/step-connector/step-connector.json index 87eacce62772ef..650f2fd5e5c8dd 100644 --- a/docs/translations/api-docs/step-connector/step-connector.json +++ b/docs/translations/api-docs/step-connector/step-connector.json @@ -35,13 +35,15 @@ "line": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the line element" }, "lineHorizontal": { "description": "Styles applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the root element", - "conditions": "orientation=\"horizontal\"" + "nodeName": "the line element", + "conditions": "orientation=\"horizontal\"", + "deprecationInfo": "Combine the .MuiStepConnector-horizontal and .MuiStepConnector-line classes instead. How to migrate" }, "lineVertical": { "description": "Styles applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the root element", - "conditions": "orientation=\"vertical\"" + "nodeName": "the line element", + "conditions": "orientation=\"vertical\"", + "deprecationInfo": "Combine the .MuiStepConnector-vertical and .MuiStepConnector-line classes instead. How to migrate" }, "root": { "description": "Styles applied to the root element." }, "vertical": { diff --git a/docs/translations/api-docs/step-label/step-label.json b/docs/translations/api-docs/step-label/step-label.json index 7a68d574ce6f9d..7c281a6e0eec06 100644 --- a/docs/translations/api-docs/step-label/step-label.json +++ b/docs/translations/api-docs/step-label/step-label.json @@ -67,5 +67,8 @@ "conditions": "orientation=\"vertical\"" } }, - "slotDescriptions": { "label": "The component that renders the label." } + "slotDescriptions": { + "label": "The component that renders the label.", + "stepIcon": "The component to render in place of the StepIcon." + } } diff --git a/docs/translations/translations.json b/docs/translations/translations.json index 98890158834ba8..110ffd7366beeb 100644 --- a/docs/translations/translations.json +++ b/docs/translations/translations.json @@ -281,6 +281,9 @@ "/material-ui/discover-more/backers": "Sponsors and Backers", "/material-ui/discover-more/vision": "Vision", "/material-ui/discover-more/changelog": "Changelog", + "/material-ui/design-resources": "Design resources", + "/material-ui/design-resources/material-ui-for-figma": "Figma Design Kit", + "/material-ui/design-resources/material-ui-sync": "Figma Sync plugin", "https://mui.com/store/?utm_source=docs&utm_medium=referral&utm_campaign=sidenav": "Template store", "/joy-ui/getting-started-group": "Getting started", "/joy-ui/getting-started": "Overview", diff --git a/examples/pigment-css-nextjs-ts/package.json b/examples/pigment-css-nextjs-ts/package.json index f0cbed14e0dc94..b2579629a61906 100644 --- a/examples/pigment-css-nextjs-ts/package.json +++ b/examples/pigment-css-nextjs-ts/package.json @@ -10,13 +10,13 @@ "post-update": "echo \"codesandbox preview only, need an update\" && pnpm update --latest" }, "dependencies": { - "@pigment-css/react": "next", + "@pigment-css/react": "latest", "react": "latest", "react-dom": "latest", "next": "latest" }, "devDependencies": { - "@pigment-css/nextjs-plugin": "next", + "@pigment-css/nextjs-plugin": "latest", "@types/node": "latest", "@types/react": "latest", "@types/react-dom": "latest", diff --git a/examples/pigment-css-remix-ts/package.json b/examples/pigment-css-remix-ts/package.json index 21fbee6451ff9d..fed2f6e7b85591 100644 --- a/examples/pigment-css-remix-ts/package.json +++ b/examples/pigment-css-remix-ts/package.json @@ -10,7 +10,7 @@ "typecheck": "tsc" }, "dependencies": { - "@pigment-css/react": "next", + "@pigment-css/react": "latest", "@remix-run/node": "latest", "@remix-run/react": "latest", "@remix-run/serve": "latest", @@ -19,7 +19,7 @@ "react-dom": "^18.2.0" }, "devDependencies": { - "@pigment-css/vite-plugin": "next", + "@pigment-css/vite-plugin": "latest", "@remix-run/dev": "latest", "@types/react": "latest", "@types/react-dom": "latest", diff --git a/examples/pigment-css-vite-ts/package.json b/examples/pigment-css-vite-ts/package.json index a4691ef62945f3..8b61ac52d46cb2 100644 --- a/examples/pigment-css-vite-ts/package.json +++ b/examples/pigment-css-vite-ts/package.json @@ -9,12 +9,12 @@ "preview": "vite preview" }, "dependencies": { - "@pigment-css/react": "next", + "@pigment-css/react": "latest", "react": "latest", "react-dom": "latest" }, "devDependencies": { - "@pigment-css/vite-plugin": "next", + "@pigment-css/vite-plugin": "latest", "@types/react": "latest", "@types/react-dom": "latest", "@vitejs/plugin-react": "latest", diff --git a/netlify/edge-functions/og-image.tsx b/netlify/edge-functions/og-image.tsx new file mode 100644 index 00000000000000..d1c4a05a055d30 --- /dev/null +++ b/netlify/edge-functions/og-image.tsx @@ -0,0 +1,268 @@ +import React from 'https://esm.sh/react@18.2.0'; +// eslint-disable-next-line import/extensions +import { ImageResponse } from 'https://deno.land/x/og_edge/mod.ts'; + +const MAX_AUTHORS = 5; +export default async function handler(req: Request) { + const params = new URL(req.url).searchParams; + const title = params.get('title'); + const authors = params.get('authors'); + const product = params.get('product'); + const description = params.get('description'); + + const parsedAuthors = + authors && + authors + .split(',') + .map((author) => { + const [name, github] = author.split('@'); + return { name: name.trim(), github: github.trim() }; + }) + .filter(({ name, github }) => name && github); + + const withAuthors = parsedAuthors && parsedAuthors.length > 0; + let starCount = 0; + + return new ImageResponse( + ( +
    +
    +
    + + + + +
    +

    + {product} +

    +
    +
    + {title && + title.split('\\n').map((line) => ( +

    + {line.split('*').flatMap((text, index) => { + if (index > 0) { + starCount += 1; + } + + const isBlue = starCount % 2 === 1; + return text.split(' ').map((word) => ( + 0 ? 15 : 0, + }} + > + {word} + + )); + })} +

    + ))} + {description && ( +

    + {description} +

    + )} +
    +
    + {withAuthors && + parsedAuthors.slice(0, MAX_AUTHORS).map(({ name, github }) => { + return ( +
    +
    + +
    +
    + + {name} + + + @{github} + +
    +
    + ); + })} +
    +
    +
    + ), + { + width: 1280, + height: 640, + // debug: true, + fonts: [ + { + name: 'IBM Plex Sans', + data: await fetch('https://fonts.cdnfonts.com/s/15449/IBMPlexSans-Medium.woff').then( + (a) => a.arrayBuffer(), + ), + weight: 500, + style: 'normal', + }, + { + name: 'General Sans', + data: await fetch('https://fonts.cdnfonts.com/s/85793/GeneralSans-Semibold.woff').then( + (a) => a.arrayBuffer(), + ), + weight: 600, + style: 'normal', + }, + { + name: 'General Sans', + data: await fetch('https://fonts.cdnfonts.com/s/85793/GeneralSans-Bold.woff').then((a) => + a.arrayBuffer(), + ), + weight: 700, + style: 'normal', + }, + ], + // Manage the caching + headers: { + // Cache control is already done by the package (https://github.com/ascorbic/og-edge/blob/d533ef878801d7f808eb004f254e782ec6ba1e3c/mod.ts#L233-L240) + 'Netlify-Vary': 'query', + }, + }, + ); +} +export const config = { + cache: 'manual', + path: '/edge-functions/og-image', +}; diff --git a/package.json b/package.json index ba58c416b28879..31f1876ba23581 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mui/monorepo", - "version": "6.0.0-alpha.2", + "version": "6.0.0-alpha.5", "private": true, "scripts": { "preinstall": "npx only-allow pnpm", @@ -10,8 +10,6 @@ "build": "lerna run build --ignore docs", "build:public": "lerna run --no-private build", "build:ci": "lerna run build --ignore docs --concurrency 8 --skip-nx-cache", - "build:zero": "lerna run --scope \"@pigmentcss/*\" build", - "clean:zero": "pnpm --filter \"@pigmentcss/*\" clean", "build:codesandbox": "NODE_OPTIONS=\"--max_old_space_size=4096\" lerna run --concurrency 8 --scope \"@mui/*\" --scope \"@mui-internal/*\" --no-private build", "release:version": "lerna version --no-changelog --no-push --no-git-tag-version --no-private --force-publish=@mui/core-downloads-tracker", "release:build": "lerna run --concurrency 8 --no-private build --skip-nx-cache", @@ -55,9 +53,8 @@ "test": "node scripts/test.mjs", "tc": "node test/cli.js", "test:extended": "pnpm eslint && pnpm typescript && pnpm test:coverage", - "test:pigment-css-react:ci": "pnpm nx run @pigment-css/react:test:ci", - "test:coverage": "cross-env NODE_ENV=test BABEL_ENV=coverage nyc --reporter=text mocha 'packages/**/*.test.{js,ts,tsx}' 'docs/**/*.test.{js,ts,tsx}' --exclude 'packages/pigment-css-react/**/*.test.{js,ts,tsx}' && pnpm test:pigment-css-react", - "test:coverage:ci": "cross-env NODE_ENV=test BABEL_ENV=coverage nyc --reporter=lcov mocha 'packages/**/*.test.{js,ts,tsx}' 'docs/**/*.test.{js,ts,tsx}' --exclude 'packages/pigment-css-react/**/*.test.{js,ts,tsx}' && pnpm test:pigment-css-react:ci", + "test:coverage": "cross-env NODE_ENV=test BABEL_ENV=coverage nyc --reporter=text mocha 'packages/**/*.test.{js,ts,tsx}' 'docs/**/*.test.{js,ts,tsx}'", + "test:coverage:ci": "cross-env NODE_ENV=test BABEL_ENV=coverage nyc --reporter=lcov mocha 'packages/**/*.test.{js,ts,tsx}' 'docs/**/*.test.{js,ts,tsx}'", "test:coverage:html": "cross-env NODE_ENV=test BABEL_ENV=coverage nyc --reporter=html mocha 'packages/**/*.test.{js,ts,tsx}' 'docs/**/*.test.{js,ts,tsx}'", "test:e2e": "cross-env NODE_ENV=production pnpm test:e2e:build && concurrently --success first --kill-others \"pnpm test:e2e:run\" \"pnpm test:e2e:server\"", "test:e2e:build": "webpack --config test/e2e/webpack.config.js", @@ -74,23 +71,22 @@ "test:regressions:run": "mocha --config test/regressions/.mocharc.js --delay 'test/regressions/**/*.test.js'", "test:regressions:server": "serve test/regressions -p 5001", "test:umd": "node packages/mui-material/test/umd/run.js", - "test:unit": "cross-env NODE_ENV=test mocha 'packages/**/*.test.{js,ts,tsx}' 'docs/**/*.test.{js,ts,tsx}' --exclude 'packages/pigment-css-react/**/*.test.{js,ts,tsx}' && pnpm test:pigment-css-react:ci", + "test:unit": "cross-env NODE_ENV=test mocha 'packages/**/*.test.{js,ts,tsx}' 'docs/**/*.test.{js,ts,tsx}'", "test:argos": "node ./scripts/pushArgos.mjs", "typescript": "lerna run --no-bail --parallel typescript", "typescript:ci": "lerna run --concurrency 3 --no-bail --no-sort typescript", "validate-declarations": "tsx scripts/validateTypescriptDeclarations.mts", - "generate-codeowners": "node scripts/generateCodeowners.mjs", - "watch:zero": "nx run-many -t watch --projects=\"@pigmentcss/*\" --parallel" + "generate-codeowners": "node scripts/generateCodeowners.mjs" }, "dependencies": { "@googleapis/sheets": "^5.0.5", - "@slack/bolt": "^3.17.1", + "@slack/bolt": "^3.18.0", "@netlify/functions": "^2.6.0", "execa": "^8.0.1", - "google-auth-library": "^9.7.0" + "google-auth-library": "^9.9.0" }, "devDependencies": { - "@argos-ci/core": "^1.5.5", + "@argos-ci/core": "^2.1.0", "@babel/cli": "^7.24.1", "@babel/core": "^7.24.4", "@babel/node": "^7.23.9", @@ -98,7 +94,6 @@ "@babel/plugin-proposal-object-rest-spread": "^7.20.7", "@babel/plugin-proposal-private-methods": "^7.18.6", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", - "@babel/plugin-transform-object-assign": "^7.24.1", "@babel/plugin-transform-react-constant-elements": "^7.24.1", "@babel/plugin-transform-runtime": "^7.24.3", "@babel/preset-env": "^7.24.4", @@ -114,10 +109,10 @@ "@mui/joy": "workspace:*", "@mui/material": "workspace:^", "@mui/utils": "workspace:^", - "@pigment-css/react": "workspace:^", - "@next/eslint-plugin-next": "^14.1.4", + "@next/eslint-plugin-next": "^14.2.3", "@octokit/rest": "^20.1.0", - "@playwright/test": "1.43.0", + "@pigment-css/react": "^0.0.9", + "@playwright/test": "1.43.1", "@types/enzyme": "^3.10.18", "@types/fs-extra": "^11.0.4", "@types/lodash": "^4.17.0", @@ -131,7 +126,7 @@ "babel-loader": "^9.1.3", "babel-plugin-istanbul": "^6.1.1", "babel-plugin-macros": "^3.1.0", - "babel-plugin-module-resolver": "^5.0.0", + "babel-plugin-module-resolver": "^5.0.2", "babel-plugin-optimize-clsx": "^2.6.2", "babel-plugin-react-remove-properties": "^0.3.0", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", @@ -153,9 +148,9 @@ "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsx-a11y": "^6.7.1", "eslint-plugin-material-ui": "workspace:^", - "eslint-plugin-mocha": "^10.4.1", + "eslint-plugin-mocha": "^10.4.3", "eslint-plugin-react": "^7.34.1", - "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-hooks": "^4.6.2", "fast-glob": "^3.3.2", "fs-extra": "^11.2.0", "globby": "^14.0.1", @@ -169,7 +164,7 @@ "karma-webpack": "^5.0.0", "lerna": "^8.1.2", "lodash": "^4.17.21", - "markdownlint-cli2": "^0.12.1", + "markdownlint-cli2": "^0.13.0", "mocha": "^10.4.0", "nx": "^17.3.2", "nyc": "^15.1.0", @@ -180,20 +175,19 @@ "process": "^0.11.10", "raw-loader": "4.0.2", "rimraf": "^5.0.5", - "serve": "^14.2.1", + "serve": "^14.2.3", "stylelint": "^15.11.0", "stylelint-config-standard": "^34.0.0", "stylelint-processor-styled-components": "^1.10.0", "terser-webpack-plugin": "^5.3.10", - "tsup": "^8.0.2", - "tsx": "^4.7.2", - "typescript": "^5.4.4", - "webpack": "^5.90.3", - "webpack-bundle-analyzer": "^4.10.1", + "tsx": "^4.7.3", + "typescript": "^5.4.5", + "webpack": "^5.91.0", + "webpack-bundle-analyzer": "^4.10.2", "webpack-cli": "^5.1.4", "yargs": "^17.7.2" }, - "packageManager": "pnpm@8.15.6", + "packageManager": "pnpm@8.15.7", "resolutions": { "@babel/core": "^7.24.4", "@babel/code-frame": "^7.24.2", @@ -209,12 +203,12 @@ "@babel/preset-typescript": "^7.24.1", "@babel/runtime": "^7.24.4", "@babel/types": "^7.24.0", - "@definitelytyped/header-parser": "^0.2.8", + "@definitelytyped/header-parser": "^0.2.9", "@definitelytyped/typescript-versions": "^0.1.1", - "@definitelytyped/utils": "^0.1.5", + "@definitelytyped/utils": "^0.1.6", "@types/node": "^18.19.31", "@types/react": "18.2.55", - "@types/react-dom": "18.2.19", + "@types/react-dom": "18.3.0", "cross-fetch": "^4.0.0" }, "nyc": { diff --git a/packages-internal/docs-utils/package.json b/packages-internal/docs-utils/package.json index a0bf7c1cc79fdc..a5ab0c508a862d 100644 --- a/packages-internal/docs-utils/package.json +++ b/packages-internal/docs-utils/package.json @@ -1,6 +1,6 @@ { "name": "@mui/internal-docs-utils", - "version": "1.0.5", + "version": "1.0.6", "author": "MUI Team", "description": "Utilities for MUI docs. This is an internal package not meant for general use.", "main": "./build/index.js", @@ -22,7 +22,7 @@ }, "dependencies": { "rimraf": "^5.0.5", - "typescript": "^5.4.4" + "typescript": "^5.4.5" }, "publishConfig": { "access": "public" diff --git a/packages-internal/scripts/package.json b/packages-internal/scripts/package.json index d68d07740cbdec..f8459dc41fc169 100644 --- a/packages-internal/scripts/package.json +++ b/packages-internal/scripts/package.json @@ -1,6 +1,6 @@ { "name": "@mui/internal-scripts", - "version": "1.0.5", + "version": "1.0.6", "author": "MUI Team", "description": "Utilities supporting MUI libraries build and docs generation. This is an internal package not meant for general use.", "main": "build/index.js", @@ -33,7 +33,7 @@ "@mui/internal-docs-utils": "workspace:^", "doctrine": "^3.0.0", "lodash": "^4.17.21", - "typescript": "^5.4.4", + "typescript": "^5.4.5", "uuid": "^9.0.1" }, "devDependencies": { diff --git a/packages/api-docs-builder-core/baseUi/generateBaseUiApiPages.ts b/packages/api-docs-builder-core/baseUi/generateBaseUiApiPages.ts index fc5fc499e42cff..e8933b54b1f190 100644 --- a/packages/api-docs-builder-core/baseUi/generateBaseUiApiPages.ts +++ b/packages/api-docs-builder-core/baseUi/generateBaseUiApiPages.ts @@ -9,7 +9,7 @@ export async function generateBaseUIApiPages() { await Promise.all( findPagesMarkdown().map(async (markdown) => { const markdownContent = fs.readFileSync(markdown.filename, 'utf8'); - const markdownHeaders = getHeaders(markdownContent) as any; + const markdownHeaders = getHeaders(markdownContent); const pathnameTokens = markdown.pathname.split('/'); const productName = pathnameTokens[1]; const componentName = pathnameTokens[3]; diff --git a/packages/api-docs-builder-core/baseUi/getBaseUiComponentInfo.ts b/packages/api-docs-builder-core/baseUi/getBaseUiComponentInfo.ts index b3d8ba5c182530..3bd8a8271d17d2 100644 --- a/packages/api-docs-builder-core/baseUi/getBaseUiComponentInfo.ts +++ b/packages/api-docs-builder-core/baseUi/getBaseUiComponentInfo.ts @@ -24,12 +24,12 @@ export function getBaseUiDemos(name: string, filename?: string) { }) .map((markdown) => { const markdownContent = fs.readFileSync(markdown.filename, 'utf8'); - const markdownHeaders = getHeaders(markdownContent) as any; + const markdownHeaders = getHeaders(markdownContent); return { ...markdown, markdownContent, - components: markdownHeaders.components as string[], + components: markdownHeaders.components, }; }); diff --git a/packages/api-docs-builder-core/joyUi/getJoyUiComponentInfo.ts b/packages/api-docs-builder-core/joyUi/getJoyUiComponentInfo.ts index 6e93feb97b55eb..83de2d69f6176f 100644 --- a/packages/api-docs-builder-core/joyUi/getJoyUiComponentInfo.ts +++ b/packages/api-docs-builder-core/joyUi/getJoyUiComponentInfo.ts @@ -68,12 +68,12 @@ export function getJoyUiComponentInfo(filename: string): ComponentInfo { getDemos: () => { const allMarkdowns = findPagesMarkdown().map((markdown) => { const markdownContent = fs.readFileSync(markdown.filename, 'utf8'); - const markdownHeaders = getHeaders(markdownContent) as any; + const markdownHeaders = getHeaders(markdownContent); return { ...markdown, markdownContent, - components: markdownHeaders.components as string[], + components: markdownHeaders.components, }; }); return allMarkdowns diff --git a/packages/api-docs-builder-core/materialUi/getMaterialUiComponentInfo.ts b/packages/api-docs-builder-core/materialUi/getMaterialUiComponentInfo.ts index be080b01e268a9..3090b60d23053a 100644 --- a/packages/api-docs-builder-core/materialUi/getMaterialUiComponentInfo.ts +++ b/packages/api-docs-builder-core/materialUi/getMaterialUiComponentInfo.ts @@ -51,12 +51,12 @@ export function getMaterialUiComponentInfo(filename: string): ComponentInfo { getDemos: () => { const allMarkdowns = findPagesMarkdown().map((markdown) => { const markdownContent = fs.readFileSync(markdown.filename, 'utf8'); - const markdownHeaders = getHeaders(markdownContent) as any; + const markdownHeaders = getHeaders(markdownContent); return { ...markdown, markdownContent, - components: markdownHeaders.components as string[], + components: markdownHeaders.components, }; }); return allMarkdowns diff --git a/packages/api-docs-builder-core/muiSystem/getSystemComponentInfo.ts b/packages/api-docs-builder-core/muiSystem/getSystemComponentInfo.ts index 7ae097a4ffc2eb..4d8b8a580c8424 100644 --- a/packages/api-docs-builder-core/muiSystem/getSystemComponentInfo.ts +++ b/packages/api-docs-builder-core/muiSystem/getSystemComponentInfo.ts @@ -65,12 +65,12 @@ export function getSystemComponentInfo(filename: string): ComponentInfo { }) .map((markdown) => { const markdownContent = fs.readFileSync(markdown.filename, 'utf8'); - const markdownHeaders = getHeaders(markdownContent) as any; + const markdownHeaders = getHeaders(markdownContent); return { ...markdown, markdownContent, - components: markdownHeaders.components as string[], + components: markdownHeaders.components, }; }); return allMarkdowns diff --git a/packages/api-docs-builder-core/package.json b/packages/api-docs-builder-core/package.json index a111b120ec6679..1897564ff22376 100644 --- a/packages/api-docs-builder-core/package.json +++ b/packages/api-docs-builder-core/package.json @@ -21,6 +21,6 @@ "@types/sinon": "^10.0.20", "chai": "^4.4.1", "sinon": "^15.2.0", - "typescript": "^5.4.4" + "typescript": "^5.4.5" } } diff --git a/packages/api-docs-builder/ApiBuilders/HookApiBuilder.ts b/packages/api-docs-builder/ApiBuilders/HookApiBuilder.ts index f02e5e6d9de344..2f48f39bc9d73f 100644 --- a/packages/api-docs-builder/ApiBuilders/HookApiBuilder.ts +++ b/packages/api-docs-builder/ApiBuilders/HookApiBuilder.ts @@ -482,7 +482,7 @@ const extractInfoFromType = async ( * @param filename The filename where its defined (to infer the package) * @returns an array of import command */ -const getHookImports = (name: string, filename: string) => { +const defaultGetHookImports = (name: string, filename: string) => { const githubPath = toGitHubPath(filename); const rootImportPath = githubPath.replace( /\/packages\/mui(?:-(.+?))?\/src\/.*/, @@ -552,6 +552,8 @@ export default async function generateHookApi( if (annotatedDescriptionMatch !== null) { reactApi.description = reactApi.description.slice(0, annotatedDescriptionMatch.index).trim(); } + + const { getHookImports = defaultGetHookImports } = projectSettings; reactApi.filename = filename; reactApi.name = name; reactApi.imports = getHookImports(name, filename); diff --git a/packages/api-docs-builder/ProjectSettings.ts b/packages/api-docs-builder/ProjectSettings.ts index 2ba937f0a4e9b2..3ae895666b561e 100644 --- a/packages/api-docs-builder/ProjectSettings.ts +++ b/packages/api-docs-builder/ProjectSettings.ts @@ -74,9 +74,13 @@ export interface ProjectSettings { */ importTranslationPagesDirectory?: string; /** - * Returns an array of import commands used for the API page header. + * Returns an array of import commands used for the component API page header. */ getComponentImports?: (name: string, filename: string) => string[]; + /** + * Returns an array of import commands used for the hook API page header. + */ + getHookImports?: (name: string, filename: string) => string[]; /** * Settings to configure props definition tests. */ diff --git a/packages/api-docs-builder/package.json b/packages/api-docs-builder/package.json index 835fefbb459dec..1a4bd930e38a08 100644 --- a/packages/api-docs-builder/package.json +++ b/packages/api-docs-builder/package.json @@ -22,7 +22,7 @@ "react-docgen": "^5.4.3", "recast": "^0.23.6", "remark": "^13.0.0", - "typescript": "^5.4.4", + "typescript": "^5.4.5", "unist-util-visit": "^2.0.3" }, "devDependencies": { diff --git a/packages/api-docs-builder/utils/parseTest.ts b/packages/api-docs-builder/utils/parseTest.ts index 14d2c70c9939cb..082eb0df2d12fe 100644 --- a/packages/api-docs-builder/utils/parseTest.ts +++ b/packages/api-docs-builder/utils/parseTest.ts @@ -3,9 +3,6 @@ import * as babel from '@babel/core'; import { readFile } from 'fs-extra'; import glob from 'fast-glob'; -const workspaceRoot = path.join(__dirname, '../../../'); -const babelConfigPath = path.join(workspaceRoot, 'babel.config.js'); - function getTestFilesNames(filepath: string) { return glob.sync( path @@ -18,15 +15,14 @@ function getTestFilesNames(filepath: string) { ); } -async function parseWithConfig(filename: string, configFilePath: string) { +async function parseWithConfig(filename: string) { const source = await readFile(filename, { encoding: 'utf8' }); const partialConfig = babel.loadPartialConfig({ - configFile: configFilePath, filename, }); if (partialConfig === null) { - throw new Error(`Could not load a babel config for ${filename} located at ${configFilePath}.`); + throw new Error(`Could not load a babel config for ${filename}.`); } return babel.parseAsync(source, partialConfig.options); @@ -139,15 +135,19 @@ export default async function parseTest(componentFilename: string): Promise = null; - // eslint-disable-next-line no-restricted-syntax - for await (const testFilename of testFilenames) { - if (descriptor === null) { - const babelParseResult = await parseWithConfig(testFilename, babelConfigPath); - if (babelParseResult === null) { - throw new Error(`Could not parse ${testFilename}.`); + try { + // eslint-disable-next-line no-restricted-syntax + for await (const testFilename of testFilenames) { + if (descriptor === null) { + const babelParseResult = await parseWithConfig(testFilename); + if (babelParseResult === null) { + throw new Error(`Could not parse ${testFilename}.`); + } + descriptor = findConformanceDescriptor(babelParseResult); } - descriptor = findConformanceDescriptor(babelParseResult); } + } catch (error) { + console.error(error); } const result: ParseResult = { diff --git a/packages/eslint-plugin-material-ui/package.json b/packages/eslint-plugin-material-ui/package.json index 39cbd86a6a0709..f8c30dc71efafc 100644 --- a/packages/eslint-plugin-material-ui/package.json +++ b/packages/eslint-plugin-material-ui/package.json @@ -8,7 +8,7 @@ "emoji-regex": "^10.3.0" }, "devDependencies": { - "@types/eslint": "^8.56.7", + "@types/eslint": "^8.56.10", "@typescript-eslint/parser": "^6.21.0", "eslint": "^8.57.0" }, diff --git a/packages/feedback/package.json b/packages/feedback/package.json index 0fdc0f95914824..90a16f422848c3 100644 --- a/packages/feedback/package.json +++ b/packages/feedback/package.json @@ -25,6 +25,6 @@ "claudia": "^5.14.1" }, "optionalDependencies": { - "aws-sdk": "^2.1589.0" + "aws-sdk": "^2.1609.0" } } diff --git a/packages/markdown/index.d.ts b/packages/markdown/index.d.ts index a5f9e850f5fe43..dc73e31e7a0d53 100644 --- a/packages/markdown/index.d.ts +++ b/packages/markdown/index.d.ts @@ -12,7 +12,24 @@ export function createRender(context: { ignoreLanguagePages: (path: string) => boolean; }): (markdown: string) => string; -export function getHeaders(markdown: string): Record; +export interface MarkdownHeaders { + packageName?: string; + productId: string; + githubLabel?: string; + waiAria?: string; + materialDesign?: string; + components: string[]; + hooks?: string[]; + slug?: string; + title?: string; + description?: string; + image?: string; + tags?: string[]; + authors?: string[]; + date?: string; +} + +export function getHeaders(markdown: string): MarkdownHeaders; export function getTitle(markdown: string): string; diff --git a/packages/markdown/loader.js b/packages/markdown/loader.js index 2c70b31176dabc..f6ebfec5290245 100644 --- a/packages/markdown/loader.js +++ b/packages/markdown/loader.js @@ -1,4 +1,4 @@ -const { promises: fs, readdirSync } = require('fs'); +const { promises: fs, readdirSync, statSync } = require('fs'); const path = require('path'); const prepareMarkdown = require('./prepareMarkdown'); const extractImports = require('./extractImports'); @@ -19,7 +19,7 @@ function upperCaseFirst(string) { * @example moduleIDToJSIdentifier('../Box-new.js') === '$$$BoxNewJs' */ function moduleIDToJSIdentifier(moduleID) { - const delimiter = /(\.|-|\/|:)/; + const delimiter = /(@|\.|-|\/|:)/; return moduleID .split(delimiter) .filter((part) => !delimiter.test(part)) @@ -127,6 +127,7 @@ module.exports = async function demoLoader() { const demoModuleIDs = new Set(); const componentModuleIDs = new Set(); const nonEditableDemos = new Set(); + const relativeModules = new Map(); const demoNames = Array.from( new Set( docs.en.rendered @@ -142,6 +143,63 @@ module.exports = async function demoLoader() { ), ); + /** + * @param {*} demoName + * @param {*} moduleFilepath + * @param {*} variant + * @param {*} importModuleID + * @example detectRelativeImports('ComboBox.js', '', JS', './top100Films') => relativeModules.set('ComboBox.js', new Map([['./top100Films.js', ['JS']]])) + */ + function detectRelativeImports(demoName, moduleFilepath, variant, importModuleID) { + if (importModuleID.startsWith('.')) { + let relativeModuleFilename = importModuleID; + const demoMap = relativeModules.get(demoName); + // If the moduleID does not end with an extension, or ends with an unsupported extension (e.g. ".styling") we need to resolve it + // Fastest way to get a file extension, see: https://stackoverflow.com/a/12900504/ + const importType = importModuleID.slice( + (Math.max(0, importModuleID.lastIndexOf('.')) || Infinity) + 1, + ); + const supportedTypes = ['js', 'jsx', 'ts', 'tsx', 'css', 'json']; + if (!importType || !supportedTypes.includes(importType)) { + // If the demo is a JS demo, we can assume that the relative import is either + // a `.js` or a `.jsx` file, with `.js` taking precedence over `.jsx` + // likewise for TS demos, with `.ts` taking precedence over `.tsx` + const extensions = + variant === 'JS' ? ['.js', '.jsx', '.ts', '.tsx'] : ['.ts', '.tsx', '.js', '.jsx']; + const extension = extensions.find((ext) => { + try { + return statSync(path.join(moduleFilepath, '..', `${importModuleID}${ext}`)); + } catch (error) { + // If the file does not exist, we return false and continue to the next extension + return false; + } + }); + if (!extension) { + throw new Error( + [ + `You are trying to import a module "${importModuleID}" in the demo "${demoName}" that could not be resolved.`, + `Please make sure that one of the following file exists:`, + ...extensions.map((ext) => `- ${importModuleID}${ext}`), + ].join('\n'), + ); + } else { + relativeModuleFilename = `${importModuleID}${extension}`; + } + } + + if (!demoMap) { + relativeModules.set(demoName, new Map([[relativeModuleFilename, [variant]]])); + } else { + const variantArray = demoMap.get(relativeModuleFilename); + if (variantArray) { + variantArray.push(variant); + } else { + demoMap.set(relativeModuleFilename, [variant]); + } + } + } + } + await Promise.all( demoNames.map(async (demoName) => { const multipleDemoVersionsUsed = !demoName.endsWith('.js'); @@ -168,11 +226,14 @@ module.exports = async function demoLoader() { raw: await fs.readFile(moduleFilepath, { encoding: 'utf8' }), }; demoModuleIDs.add(moduleID); + // Skip non-editable demos if (!nonEditableDemos.has(demoName)) { - extractImports(demos[demoName].raw).forEach((importModuleID) => - importedModuleIDs.add(importModuleID), - ); + extractImports(demos[demoName].raw).forEach((importModuleID) => { + // detect relative import + detectRelativeImports(demoName, moduleFilepath, 'JS', importModuleID); + importedModuleIDs.add(importModuleID); + }); } if (multipleDemoVersionsUsed) { @@ -343,10 +404,69 @@ module.exports = async function demoLoader() { // But this leads to building both demo version i.e. more build time. demos[demoName].moduleTS = this.mode === 'production' ? moduleID : moduleTS; demos[demoName].rawTS = rawTS; + + // Extract relative imports from the TypeScript version + // of demos which have relative imports in the JS version + if (relativeModules.has(demoName)) { + extractImports(demos[demoName].rawTS).forEach((importModuleID) => { + detectRelativeImports(demoName, moduleTSFilepath, 'TS', importModuleID); + importedModuleIDs.add(importModuleID); + }); + } + demoModuleIDs.add(demos[demoName].moduleTS); } catch (error) { // TS version of the demo doesn't exist. This is fine. } + + /* Map over relative import module IDs and resolve them + * while grouping by demo variant + * From: + * relativeModules: { 'ComboBox.js' => + * { './top100Films.js' => ['JS', 'TS'] } + * } + * To: + * demos["ComboBox.js"].relativeModules = { + * JS: [{ module: './top100Films.js', raw: '...' }], + * TS: [{ module: './top100Films.js', raw: '...' }] + * } + * } + */ + + if (relativeModules.has(demoName)) { + if (!demos[demoName].relativeModules) { + demos[demoName].relativeModules = {}; + } + + await Promise.all( + Array.from(relativeModules.get(demoName)).map(async ([relativeModuleID, variants]) => { + let raw = ''; + try { + raw = await fs.readFile(path.join(path.dirname(moduleFilepath), relativeModuleID), { + encoding: 'utf8', + }); + } catch { + throw new Error( + `Could not find a module for the relative import "${relativeModuleID}" in the demo "${demoName}"`, + ); + } + + const moduleData = { module: relativeModuleID, raw }; + const modules = demos[demoName].relativeModules; + + variants.forEach((variant) => { + if (modules[variant]) { + // Avoid duplicates + if (!modules[variant].some((elem) => elem.module === relativeModuleID)) { + modules[variant].push(moduleData); + } + } else { + modules[variant] = [moduleData]; + } + }); + }), + ); + } }), ); @@ -365,7 +485,9 @@ module.exports = async function demoLoader() { ); componentNames.forEach((componentName) => { - const moduleID = path.join(this.rootContext, 'src', componentName).replace(/\\/g, '/'); + const moduleID = componentName.startsWith('@mui/docs/') + ? componentName + : path.join(this.rootContext, 'src', componentName).replace(/\\/g, '/'); components[moduleID] = componentName; componentModuleIDs.add(moduleID); diff --git a/packages/markdown/package.json b/packages/markdown/package.json index 9d6cef39b4b224..a26692062dc126 100644 --- a/packages/markdown/package.json +++ b/packages/markdown/package.json @@ -1,6 +1,6 @@ { "name": "@mui/internal-markdown", - "version": "1.0.2", + "version": "1.0.3", "author": "MUI Team", "description": "MUI markdown parser. This is an internal package not meant for general use.", "main": "./index.js", diff --git a/packages/markdown/parseMarkdown.js b/packages/markdown/parseMarkdown.js index a9848f583dce47..874f48b1241582 100644 --- a/packages/markdown/parseMarkdown.js +++ b/packages/markdown/parseMarkdown.js @@ -364,11 +364,7 @@ function createRender(context) { } return [ - ``, - headingHtml, - ``, - '', - '', + `${headingHtml}`, ``, diff --git a/packages/markdown/parseMarkdown.test.js b/packages/markdown/parseMarkdown.test.js index 20cf39596a17ab..c168296bb9841c 100644 --- a/packages/markdown/parseMarkdown.test.js +++ b/packages/markdown/parseMarkdown.test.js @@ -295,9 +295,9 @@ authors: ).to.equal( [ `

    Accordion

    `, - `

    Basic features 🧪

    `, - `

    Using slots and slotProps

    `, - `

    Specific example

    `, + `

    Basic features 🧪

    `, + `

    Using slots and slotProps

    `, + `

    Specific example

    `, ].join(''), ); diff --git a/packages/markdown/prepareMarkdown.js b/packages/markdown/prepareMarkdown.js index caaa61d0fbbd97..878bdea7e768db 100644 --- a/packages/markdown/prepareMarkdown.js +++ b/packages/markdown/prepareMarkdown.js @@ -110,7 +110,7 @@ This unstyled version of the component is the ideal choice for heavy customizati `); } - if (headers.components.length > 0) { + if (headers.components.length > 0 && headers.productId !== 'base-ui') { contents.push(` ## API diff --git a/packages/mui-babel-macros/MuiError.macro.d.ts b/packages/mui-babel-macros/MuiError.macro.d.ts index 53d894b2241058..54293408e59b1a 100644 --- a/packages/mui-babel-macros/MuiError.macro.d.ts +++ b/packages/mui-babel-macros/MuiError.macro.d.ts @@ -1,3 +1,3 @@ export default class MuiError { - constructor(message: string); + constructor(message: string, ...args: string[]); } diff --git a/packages/mui-babel-macros/package.json b/packages/mui-babel-macros/package.json index 2cc41924b72c25..56390a6c12784c 100644 --- a/packages/mui-babel-macros/package.json +++ b/packages/mui-babel-macros/package.json @@ -1,6 +1,6 @@ { "name": "@mui/internal-babel-macros", - "version": "1.0.2", + "version": "1.0.3", "author": "MUI Team", "description": "MUI Babel macros. This is an internal package not meant for general use.", "main": "./MuiError.macro.js", diff --git a/packages/mui-base/package.json b/packages/mui-base/package.json index 51006729c675fa..95c7be4f0a94cc 100644 --- a/packages/mui-base/package.json +++ b/packages/mui-base/package.json @@ -1,6 +1,6 @@ { "name": "@mui/base", - "version": "5.0.0-beta.42", + "version": "5.0.0-beta.43", "private": false, "author": "MUI Team", "description": "Base UI is a library of headless ('unstyled') React components and low-level hooks. You gain complete control over your app's CSS and accessibility features.", @@ -27,8 +27,7 @@ "url": "https://opencollective.com/mui-org" }, "scripts": { - "build": "pnpm build:legacy && pnpm build:modern && pnpm build:node && pnpm build:stable && pnpm build:types && pnpm build:copy-files", - "build:legacy": "node ../../scripts/build.mjs legacy", + "build": "pnpm build:modern && pnpm build:node && pnpm build:stable && pnpm build:types && pnpm build:copy-files", "build:modern": "node ../../scripts/build.mjs modern", "build:node": "node ../../scripts/build.mjs node", "build:stable": "node ../../scripts/build.mjs stable", @@ -46,19 +45,19 @@ "@mui/types": "workspace:^", "@mui/utils": "workspace:^", "@popperjs/core": "^2.11.8", - "clsx": "^2.1.0", + "clsx": "^2.1.1", "prop-types": "^15.8.1" }, "devDependencies": { "@mui-internal/test-utils": "workspace:^", "@mui/internal-babel-macros": "workspace:^", "@mui/types": "workspace:^", - "@testing-library/react": "^14.2.2", + "@testing-library/react": "^14.3.1", "@testing-library/user-event": "^14.5.2", "@types/chai": "^4.3.14", "@types/prop-types": "^15.7.12", "@types/react": "18.2.55", - "@types/react-dom": "18.2.19", + "@types/react-dom": "18.3.0", "@types/sinon": "^10.0.20", "chai": "^4.4.1", "fast-glob": "^3.3.2", diff --git a/packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx b/packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx index a66407f984ac5e..23799d01516409 100644 --- a/packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx +++ b/packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx @@ -65,6 +65,7 @@ const TextareaAutosize = React.forwardRef(function TextareaAutosize( const { current: isControlled } = React.useRef(value != null); const inputRef = React.useRef(null); const handleRef = useForkRef(forwardedRef, inputRef); + const heightRef = React.useRef(null); const shadowRef = React.useRef(null); const calculateTextareaStyles = React.useCallback(() => { @@ -130,8 +131,12 @@ const TextareaAutosize = React.forwardRef(function TextareaAutosize( return; } + const outerHeightStyle = textareaStyles.outerHeightStyle; const input = inputRef.current!; - input.style.height = `${textareaStyles.outerHeightStyle}px`; + if (heightRef.current !== outerHeightStyle) { + heightRef.current = outerHeightStyle; + input.style.height = `${outerHeightStyle}px`; + } input.style.overflow = textareaStyles.overflowing ? 'hidden' : ''; }, [calculateTextareaStyles]); diff --git a/packages/mui-base/src/useAutocomplete/useAutocomplete.js b/packages/mui-base/src/useAutocomplete/useAutocomplete.js index 344b2cce0efe0f..45caa7dd2123dc 100644 --- a/packages/mui-base/src/useAutocomplete/useAutocomplete.js +++ b/packages/mui-base/src/useAutocomplete/useAutocomplete.js @@ -10,11 +10,8 @@ import { } from '@mui/utils'; // https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript -// Give up on IE11 support for this feature function stripDiacritics(string) { - return typeof string.normalize !== 'undefined' - ? string.normalize('NFD').replace(/[\u0300-\u036f]/g, '') - : string; + return string.normalize('NFD').replace(/[\u0300-\u036f]/g, ''); } export function createFilterOptions(config = {}) { @@ -56,17 +53,6 @@ export function createFilterOptions(config = {}) { }; } -// To replace with .findIndex() once we stop IE11 support. -function findIndex(array, comp) { - for (let i = 0; i < array.length; i += 1) { - if (comp(array[i])) { - return i; - } - } - - return -1; -} - const defaultFilterOptions = createFilterOptions(); // Number of options to jump in list box when `Page Up` and `Page Down` keys are used. @@ -498,7 +484,7 @@ export function useAutocomplete(props) { const previousHighlightedOption = previousProps.filteredOptions[highlightedIndexRef.current]; if (previousHighlightedOption) { - return findIndex(filteredOptions, (option) => { + return filteredOptions.findIndex((option) => { return getOptionLabel(option) === getOptionLabel(previousHighlightedOption); }); } @@ -539,12 +525,12 @@ export function useAutocomplete(props) { if ( multiple && currentOption && - findIndex(value, (val) => isOptionEqualToValue(currentOption, val)) !== -1 + value.findIndex((val) => isOptionEqualToValue(currentOption, val)) !== -1 ) { return; } - const itemIndex = findIndex(filteredOptions, (optionItem) => + const itemIndex = filteredOptions.findIndex((optionItem) => isOptionEqualToValue(optionItem, valueItem), ); if (itemIndex === -1) { @@ -685,7 +671,7 @@ export function useAutocomplete(props) { } } - const itemIndex = findIndex(newValue, (valueItem) => isOptionEqualToValue(option, valueItem)); + const itemIndex = newValue.findIndex((valueItem) => isOptionEqualToValue(option, valueItem)); if (itemIndex === -1) { newValue.push(option); diff --git a/packages/mui-base/src/useSnackbar/useSnackbar.ts b/packages/mui-base/src/useSnackbar/useSnackbar.ts index d2d73cf641af1f..4b9de6ad0754bb 100644 --- a/packages/mui-base/src/useSnackbar/useSnackbar.ts +++ b/packages/mui-base/src/useSnackbar/useSnackbar.ts @@ -44,8 +44,7 @@ export function useSnackbar(parameters: UseSnackbarParameters = {}): UseSnackbar */ function handleKeyDown(nativeEvent: KeyboardEvent) { if (!nativeEvent.defaultPrevented) { - // IE11, Edge (prior to using Blink?) use 'Esc' - if (nativeEvent.key === 'Escape' || nativeEvent.key === 'Esc') { + if (nativeEvent.key === 'Escape') { // not calling `preventDefault` since we don't know if people may ignore this event e.g. a permanently open snackbar onClose?.(nativeEvent, 'escapeKeyDown'); } diff --git a/packages/mui-codemod/README.md b/packages/mui-codemod/README.md index b37418902a5182..604a054a6e8ac0 100644 --- a/packages/mui-codemod/README.md +++ b/packages/mui-codemod/README.md @@ -858,6 +858,29 @@ npx @mui/codemod@next deprecations/chip-classes npx @mui/codemod@next deprecations/divider-props ``` +#### `form-control-label-props` + +```diff + +``` + +```diff + MuiFormControlLabel: { + defaultProps: { +- componentsProps={{ typography: typographyProps }} ++ slotProps={{ typography: typographyProps }} + }, + }, +``` + +```bash +npx @mui/codemod@next deprecations/form-control-label-props + +``` + #### `pagination-item-classes` JS transforms: @@ -922,6 +945,28 @@ CSS transforms: npx @mui/codemod@next deprecations/pagination-item-classes ``` +#### `pagination-item-props` + +```diff + +``` + +```diff + MuiPaginationItem: { + defaultProps: { +- components: { first: FirstIcon, last: LastIcon, next: NextIcon, previous: PreviousIcons } ++ slots: { first: FirstIcon, last: LastIcon, next: NextIcon, previous: PreviousIcons } + }, + }, +``` + +```bash +npx @mui/codemod@next deprecations/pagination-item-props +``` + #### `slider-props` ```diff @@ -991,14 +1036,22 @@ npx @mui/codemod@latest deprecations/toggle-button-group-classes ``` ```diff MuiStepLabel: { defaultProps: { -- componentsProps={{ label: labelProps }} -+ slotProps={{ label: labelProps }} +- componentsProps:{ label: labelProps } ++ slotProps:{ label: labelProps } +- StepIconComponent:StepIconComponent ++ slots:{ stepIcon: StepIconComponent } +- StepIconProps:StepIconProps ++ slotProps:{ stepIcon: StepIconProps } }, }, ``` @@ -1008,8 +1061,180 @@ npx @mui/codemod@latest deprecations/step-label-props ``` +#### `step-connector-classes` + +JS transforms: + +```diff + import { stepConnectorClasses } from '@mui/material/StepConnector'; + + MuiStepConnector: { + styleOverrides: { + root: { +- [`& .${stepConnectorClasses.lineHorizontal}`]: { ++ [`&.${stepConnectorClasses.horizontal} > .${stepConnectorClasses.line}`]: { + color: 'red', + }, +- [`& .${stepConnectorClasses.lineVertical}`]: { ++ [`&.${stepConnectorClasses.vertical} > .${stepConnectorClasses.line}`]: { + color: 'red', + }, + }, + }, + }, +``` + +CSS transforms: + +```diff +- .MuiStepConnector-lineHorizontal ++.MuiStepConnector-horizontal > .MuiStepConnector-line +- .MuiStepConnector-lineVertical ++.MuiStepConnector-vertical > .MuiStepConnector-line +``` + +```bash +npx @mui/codemod@next deprecations/step-connector-classes +``` + ### v6.0.0 +#### `theme-v6` + +```bash +npx @mui/codemod@next v6.0.0/theme-v6 +``` + +Update the theme creation from `@mui/system@v5` to be compatible with `@pigment-css/react`. + +- replace palette mode conditional with `theme.applyStyles()` +- replace `ownerState` with `variants` +- move theme variants to the root slot + +```diff + createTheme({ + components: { + MuiButton: { +- variants: [ +- { +- props: { color: 'primary' }, +- style: { +- color: 'red', +- }, +- }, +- ], + styleOverrides: { +- root: ({ theme, ownerState }) => ({ ++ root: ({ theme }) => ({ + ...ownerState.variant === 'contained' && { + backgroundColor: alpha(theme.palette.primary.main, 0.8), + ...theme.palette.mode === 'dark' && { + backgroundColor: alpha(theme.palette.primary.light, 0.9), + } + }, ++ variants: [ ++ { ++ prop: { variant: 'contained' }, ++ style: { ++ backgroundColor: alpha(theme.palette.primary.main, 0.8), ++ }, ++ }, ++ { ++ prop: { variant: 'contained' }, ++ style: { ++ ...theme.applyStyles('dark', { ++ backgroundColor: alpha(theme.palette.primary.light, 0.9), ++ }) ++ }, ++ }, ++ { ++ prop: { color: 'primary' }, ++ style: { ++ color: 'red', ++ }, ++ }, ++ ], + }) + } + } + } + }) +``` + +#### `styled-v6` + +```bash +npx @mui/codemod@next v6.0.0/styled-v6 +``` + +Updates the usage of `styled` from `@mui/system@v5` to be compatible with `@pigment-css/react`. + +This codemod transforms the styles based on props to `variants` by looking for `styled` calls: + +```diff + styled('div')(({ theme, disabled }) => ({ + color: theme.palette.primary.main, +- ...(disabled && { +- opacity: 0.5, +- }), ++ variants: [ ++ { ++ prop: 'disabled', ++ style: { ++ opacity: 0.5, ++ }, ++ }, ++ ], + })); +``` + +This codemod can handle complex styles with spread operators, ternary operators, and nested objects. + +However, it has some **limitations**: + +- It does not transform dynamic values as shown below: + + ```js + const ResizableContainer = styled('div')(({ ownerState, theme }) => ({ + width: ownerState.width ?? '100%', + height: ownerState.height ?? '100%', + })); + ``` + + You need to manually declare a CSS variable and set the values using inline styles: + + ```js + // ✅ Recommended way + const ResizableContainer = styled('div')({ + width: 'var(--ResizableContainer-width, 100%)', + height: 'var(--ResizableContainer-height, 100%)', + }); + ``` + +- It does not transform dynamic reference from the theme, for example color palette. + + ```js + const Test = styled('div')(({ ownerState, theme }) => ({ + backgroundColor: (theme.vars || theme).palette[ownerState.color]?.main, + })); + ``` + + You need to manually iterate the theme object and create `variants` for each color. + + ```js + // ✅ Recommended way + const Test = styled('div')(({ theme }) => ({ + variants: Object.entries(theme.palette) + .filter(([color, value]) => value.main) + .map(([color, value]) => ({ + props: { color }, + style: { + backgroundColor: value.main, + }, + })), + })); + ``` + ### v5.0.0 #### `base-use-named-exports` diff --git a/packages/mui-codemod/package.json b/packages/mui-codemod/package.json index d66dcb477c1f67..c092fc37e951a9 100644 --- a/packages/mui-codemod/package.json +++ b/packages/mui-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@mui/codemod", - "version": "6.0.0-alpha.1", + "version": "6.0.0-alpha.5", "bin": "./codemod.js", "private": false, "author": "MUI Team", @@ -33,7 +33,7 @@ "@babel/core": "^7.24.4", "@babel/runtime": "^7.24.4", "@babel/traverse": "^7.24.1", - "jscodeshift": "^0.13.1", + "jscodeshift": "^0.15.2", "jscodeshift-add-imports": "^1.0.10", "postcss": "^8.4.38", "postcss-cli": "^8.3.1", @@ -41,7 +41,7 @@ }, "devDependencies": { "@types/chai": "^4.3.14", - "@types/jscodeshift": "0.11.5", + "@types/jscodeshift": "0.11.11", "chai": "^4.4.1" }, "sideEffects": false, diff --git a/packages/mui-codemod/src/deprecations/accordion-props/accordion-props.js b/packages/mui-codemod/src/deprecations/accordion-props/accordion-props.js index dddc01c2288104..386de541096490 100644 --- a/packages/mui-codemod/src/deprecations/accordion-props/accordion-props.js +++ b/packages/mui-codemod/src/deprecations/accordion-props/accordion-props.js @@ -1,6 +1,5 @@ -import findComponentJSX from '../../util/findComponentJSX'; -import assignObject from '../../util/assignObject'; -import appendAttribute from '../../util/appendAttribute'; +import movePropIntoSlots from '../utils/movePropIntoSlots'; +import movePropIntoSlotProps from '../utils/movePropIntoSlotProps'; /** * @param {import('jscodeshift').FileInfo} file @@ -11,84 +10,18 @@ export default function transformer(file, api, options) { const root = j(file.source); const printOptions = options.printOptions; - findComponentJSX(j, { root, componentName: 'Accordion' }, (elementPath) => { - let index = elementPath.node.openingElement.attributes.findIndex( - (attr) => attr.type === 'JSXAttribute' && attr.name.name === 'TransitionComponent', - ); - if (index !== -1) { - const removed = elementPath.node.openingElement.attributes.splice(index, 1); - let hasNode = false; - elementPath.node.openingElement.attributes.forEach((attr) => { - if (attr.name?.name === 'slots') { - hasNode = true; - assignObject(j, { - target: attr, - key: 'transition', - expression: removed[0].value.expression, - }); - } - }); - if (!hasNode) { - appendAttribute(j, { - target: elementPath.node, - attributeName: 'slots', - expression: j.objectExpression([ - j.objectProperty(j.identifier('transition'), removed[0].value.expression), - ]), - }); - } - } - - index = elementPath.node.openingElement.attributes.findIndex( - (attr) => attr.type === 'JSXAttribute' && attr.name.name === 'TransitionProps', - ); - if (index !== -1) { - const removed = elementPath.node.openingElement.attributes.splice(index, 1); - let hasNode = false; - elementPath.node.openingElement.attributes.forEach((attr) => { - if (attr.name?.name === 'slotProps') { - hasNode = true; - assignObject(j, { - target: attr, - key: 'transition', - expression: removed[0].value.expression, - }); - } - }); - if (!hasNode) { - appendAttribute(j, { - target: elementPath.node, - attributeName: 'slotProps', - expression: j.objectExpression([ - j.objectProperty(j.identifier('transition'), removed[0].value.expression), - ]), - }); - } - } - }); - - root.find(j.ObjectProperty, { key: { name: 'TransitionComponent' } }).forEach((path) => { - if (path.parent?.parent?.parent?.parent?.node.key?.name === 'MuiAccordion') { - path.replace( - j.property( - 'init', - j.identifier('slots'), - j.objectExpression([j.objectProperty(j.identifier('transition'), path.node.value)]), - ), - ); - } + movePropIntoSlots(j, { + root, + componentName: 'Accordion', + propName: 'TransitionComponent', + slotName: 'transition', }); - root.find(j.ObjectProperty, { key: { name: 'TransitionProps' } }).forEach((path) => { - if (path.parent?.parent?.parent?.parent?.node.key?.name === 'MuiAccordion') { - path.replace( - j.property( - 'init', - j.identifier('slotProps'), - j.objectExpression([j.objectProperty(j.identifier('transition'), path.node.value)]), - ), - ); - } + movePropIntoSlotProps(j, { + root, + componentName: 'Accordion', + propName: 'TransitionProps', + slotName: 'transition', }); return root.toSource(printOptions); diff --git a/packages/mui-codemod/src/deprecations/accordion-props/test-cases/actual.js b/packages/mui-codemod/src/deprecations/accordion-props/test-cases/actual.js index 20ac7fa81a3bb8..9f6a4672656efd 100644 --- a/packages/mui-codemod/src/deprecations/accordion-props/test-cases/actual.js +++ b/packages/mui-codemod/src/deprecations/accordion-props/test-cases/actual.js @@ -23,6 +23,8 @@ import { Accordion as MyAccordion } from '@mui/material'; ...outerSlotProps, }} />; +; +; // should skip non MUI components ; +; +; // should skip non MUI components { - const index = elementPath.node.openingElement.attributes.findIndex( - (attr) => attr.type === 'JSXAttribute' && attr.name.name === 'imgProps', - ); - if (index !== -1) { - const removed = elementPath.node.openingElement.attributes.splice(index, 1); - let hasNode = false; - elementPath.node.openingElement.attributes.forEach((attr) => { - if (attr.name?.name === 'slotProps') { - hasNode = true; - assignObject(j, { - target: attr, - key: 'img', - expression: removed[0].value.expression, - }); - } - }); - if (!hasNode) { - appendAttribute(j, { - target: elementPath.node, - attributeName: 'slotProps', - expression: j.objectExpression([ - j.objectProperty(j.identifier('img'), removed[0].value.expression), - ]), - }); - } - } - }); - - root.find(j.ObjectProperty, { key: { name: 'imgProps' } }).forEach((path) => { - if (path.parent?.parent?.parent?.parent?.node.key?.name === 'MuiAvatar') { - path.replace( - j.property( - 'init', - j.identifier('slotProps'), - j.objectExpression([j.objectProperty(j.identifier('img'), path.node.value)]), - ), - ); - } + movePropIntoSlotProps(j, { + root, + componentName: 'Avatar', + propName: 'imgProps', + slotName: 'img', }); return root.toSource(printOptions); diff --git a/packages/mui-codemod/src/deprecations/avatar-props/test-cases/actual.js b/packages/mui-codemod/src/deprecations/avatar-props/test-cases/actual.js index e553aae667fd1a..541efaabed3e79 100644 --- a/packages/mui-codemod/src/deprecations/avatar-props/test-cases/actual.js +++ b/packages/mui-codemod/src/deprecations/avatar-props/test-cases/actual.js @@ -13,6 +13,16 @@ import { Avatar as MyAvatar } from '@mui/material'; onLoad: () => {}, }} />; + {}, + }} + slotProps={{ + img: { + onError: () => {}, + }, + }} +/>; // should skip non MUI components ; + {}, + }, + + ...{ + onError: () => {}, + } + }, + }} />; // should skip non MUI components {}, + }, + slotProps: { + img: { + onError: () => {}, + }, + }, + }, + }, +}); diff --git a/packages/mui-codemod/src/deprecations/avatar-props/test-cases/theme.expected.js b/packages/mui-codemod/src/deprecations/avatar-props/test-cases/theme.expected.js index a4ac9d4cf5fccb..f1b14e5af41789 100644 --- a/packages/mui-codemod/src/deprecations/avatar-props/test-cases/theme.expected.js +++ b/packages/mui-codemod/src/deprecations/avatar-props/test-cases/theme.expected.js @@ -6,6 +6,24 @@ fn({ onError: () => {}, onLoad: () => {}, } + }, + }, + }, +}); + +fn({ + MuiAvatar: { + defaultProps: { + slotProps: { + img: { + ...{ + onLoad: () => {}, + }, + + ...{ + onError: () => {}, + } + }, } }, }, diff --git a/packages/mui-codemod/src/deprecations/backdrop-props/backdrop-props.js b/packages/mui-codemod/src/deprecations/backdrop-props/backdrop-props.js index c444dfc97b1004..d462ae49ed5b1f 100644 --- a/packages/mui-codemod/src/deprecations/backdrop-props/backdrop-props.js +++ b/packages/mui-codemod/src/deprecations/backdrop-props/backdrop-props.js @@ -1,6 +1,4 @@ -import findComponentJSX from '../../util/findComponentJSX'; -import assignObject from '../../util/assignObject'; -import appendAttribute from '../../util/appendAttribute'; +import movePropIntoSlots from '../utils/movePropIntoSlots'; /** * @param {import('jscodeshift').FileInfo} file @@ -11,73 +9,11 @@ export default function transformer(file, api, options) { const root = j(file.source); const printOptions = options.printOptions; - findComponentJSX(j, { root, componentName: 'Backdrop' }, (elementPath) => { - const index = elementPath.node.openingElement.attributes.findIndex( - (attr) => attr.type === 'JSXAttribute' && attr.name.name === 'TransitionComponent', - ); - - if (index !== -1) { - const removed = elementPath.node.openingElement.attributes.splice(index, 1); - let hasNode = false; - elementPath.node.openingElement.attributes.forEach((attr) => { - if (attr.name?.name === 'slots') { - hasNode = true; - assignObject(j, { - target: attr, - key: 'transition', - expression: removed[0].value.expression, - }); - } - }); - - if (!hasNode) { - appendAttribute(j, { - target: elementPath.node, - attributeName: 'slots', - expression: j.objectExpression([ - j.objectProperty(j.identifier('transition'), removed[0].value.expression), - ]), - }); - } - } - }); - - root.find(j.ObjectProperty, { key: { name: 'TransitionComponent' } }).forEach((path) => { - if (path.parent?.parent?.parent?.parent?.node.key?.name === 'MuiBackdrop') { - const { properties: defaultPropsProperties } = path.parent.value; - - const existingSlots = defaultPropsProperties.find((prop) => prop.key.name === 'slots'); - const slots = existingSlots - ? existingSlots.value.properties.reduce((acc, prop) => { - return { ...acc, [prop.key.name]: prop.value }; - }, {}) - : {}; - - const transitionComponent = - defaultPropsProperties.find((prop) => prop.key.name === 'TransitionComponent') ?? {}; - - const updatedSlots = j.objectExpression( - Object.entries({ - transition: transitionComponent?.value, - ...slots, - }).map(([slot, value]) => { - return j.objectProperty(j.identifier(slot), value); - }), - ); - - if (existingSlots) { - existingSlots.value = updatedSlots; - path.prune(); - } else { - path.replace( - j.property( - 'init', - j.identifier('slots'), - j.objectExpression([j.objectProperty(j.identifier('transition'), path.node.value)]), - ), - ); - } - } + movePropIntoSlots(j, { + root, + componentName: 'Backdrop', + propName: 'TransitionComponent', + slotName: 'transition', }); return root.toSource(printOptions); diff --git a/packages/mui-codemod/src/deprecations/backdrop-props/backdrop-props.test.js b/packages/mui-codemod/src/deprecations/backdrop-props/backdrop-props.test.js index 4d825b0076014a..13949c52396b08 100644 --- a/packages/mui-codemod/src/deprecations/backdrop-props/backdrop-props.test.js +++ b/packages/mui-codemod/src/deprecations/backdrop-props/backdrop-props.test.js @@ -31,7 +31,7 @@ describe('@mui/codemod', () => { const actual = transform( { source: read('./test-cases/theme.actual.js') }, { jscodeshift }, - { printOptions: { trailingComma: true } }, + {}, ); const expected = read('./test-cases/theme.expected.js'); diff --git a/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/actual.js b/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/actual.js index 8cca730fda99e4..00edff06a072ce 100644 --- a/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/actual.js +++ b/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/actual.js @@ -8,17 +8,18 @@ import { Backdrop as MyBackdrop } from '@mui/material'; slots={{ root: 'div', }} - slotProps={{ - root: { className: 'foo' }, - }} />; ; +; // should skip non MUI components diff --git a/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/expected.js b/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/expected.js index ca22506cedab88..60b85e0d7b2556 100644 --- a/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/expected.js +++ b/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/expected.js @@ -11,17 +11,16 @@ import { Backdrop as MyBackdrop } from '@mui/material'; slots={{ root: 'div', transition: CustomTransition - }} - slotProps={{ - root: { className: 'foo' }, }} />; ; +; // should skip non MUI components ; diff --git a/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/theme.actual.js b/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/theme.actual.js index a8e62bd3583647..8488ea0176baaa 100644 --- a/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/theme.actual.js +++ b/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/theme.actual.js @@ -16,3 +16,15 @@ fn({ }, }, }); + +fn({ + MuiBackdrop: { + defaultProps: { + TransitionComponent: ComponentTransition, + slots: { + root: 'div', + transition: SlotTransition + }, + }, + }, +}); diff --git a/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/theme.expected.js b/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/theme.expected.js index ccc52bc558129d..46e9175ad5fdab 100644 --- a/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/theme.expected.js +++ b/packages/mui-codemod/src/deprecations/backdrop-props/test-cases/theme.expected.js @@ -2,8 +2,8 @@ fn({ MuiBackdrop: { defaultProps: { slots: { - transition: CustomTransition, - }, + transition: CustomTransition + } }, }, }); @@ -12,9 +12,20 @@ fn({ MuiBackdrop: { defaultProps: { slots: { - transition: CustomTransition, root: 'div', - }, + transition: CustomTransition + } + }, + }, +}); + +fn({ + MuiBackdrop: { + defaultProps: { + slots: { + root: 'div', + transition: SlotTransition + } }, }, }); diff --git a/packages/mui-codemod/src/deprecations/form-control-label-props/form-control-label-props.js b/packages/mui-codemod/src/deprecations/form-control-label-props/form-control-label-props.js new file mode 100644 index 00000000000000..5d49fa5c50dbad --- /dev/null +++ b/packages/mui-codemod/src/deprecations/form-control-label-props/form-control-label-props.js @@ -0,0 +1,15 @@ +import replaceComponentsWithSlots from '../utils/replaceComponentsWithSlots'; + +/** + * @param {import('jscodeshift').FileInfo} file + * @param {import('jscodeshift').API} api + */ +export default function transformer(file, api, options) { + const j = api.jscodeshift; + const root = j(file.source); + const printOptions = options.printOptions; + + replaceComponentsWithSlots(j, { root, componentName: 'FormControlLabel' }); + + return root.toSource(printOptions); +} diff --git a/packages/mui-codemod/src/deprecations/form-control-label-props/form-control-label-props.test.js b/packages/mui-codemod/src/deprecations/form-control-label-props/form-control-label-props.test.js new file mode 100644 index 00000000000000..6092d772500eb2 --- /dev/null +++ b/packages/mui-codemod/src/deprecations/form-control-label-props/form-control-label-props.test.js @@ -0,0 +1,53 @@ +import path from 'path'; +import { expect } from 'chai'; +import { jscodeshift } from '../../../testUtils'; +import transform from './form-control-label-props'; +import readFile from '../../util/readFile'; + +function read(fileName) { + return readFile(path.join(__dirname, fileName)); +} + +describe('@mui/codemod', () => { + describe('deprecations', () => { + describe('form-control-label-props', () => { + it('transforms props as needed', () => { + const actual = transform({ source: read('./test-cases/actual.js') }, { jscodeshift }, {}); + + const expected = read('./test-cases/expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform({ source: read('./test-cases/expected.js') }, { jscodeshift }, {}); + + const expected = read('./test-cases/expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + + describe('[theme] form-control-label-props', () => { + it('transforms props as needed', () => { + const actual = transform( + { source: read('./test-cases/theme.actual.js') }, + { jscodeshift }, + { printOptions: { trailingComma: false } }, + ); + + const expected = read('./test-cases/theme.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform( + { source: read('./test-cases/theme.expected.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/theme.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + }); +}); diff --git a/packages/mui-codemod/src/deprecations/form-control-label-props/index.js b/packages/mui-codemod/src/deprecations/form-control-label-props/index.js new file mode 100644 index 00000000000000..a6f42614343fcc --- /dev/null +++ b/packages/mui-codemod/src/deprecations/form-control-label-props/index.js @@ -0,0 +1 @@ +export { default } from './form-control-label-props'; diff --git a/packages/mui-codemod/src/deprecations/form-control-label-props/test-cases/actual.js b/packages/mui-codemod/src/deprecations/form-control-label-props/test-cases/actual.js new file mode 100644 index 00000000000000..e3f03f8768844f --- /dev/null +++ b/packages/mui-codemod/src/deprecations/form-control-label-props/test-cases/actual.js @@ -0,0 +1,8 @@ +import FormControlLabel from '@mui/material/FormControlLabel'; + +; +; diff --git a/packages/mui-codemod/src/deprecations/form-control-label-props/test-cases/expected.js b/packages/mui-codemod/src/deprecations/form-control-label-props/test-cases/expected.js new file mode 100644 index 00000000000000..b1a509848396d7 --- /dev/null +++ b/packages/mui-codemod/src/deprecations/form-control-label-props/test-cases/expected.js @@ -0,0 +1,9 @@ +import FormControlLabel from '@mui/material/FormControlLabel'; + +; +; diff --git a/packages/mui-codemod/src/deprecations/form-control-label-props/test-cases/theme.actual.js b/packages/mui-codemod/src/deprecations/form-control-label-props/test-cases/theme.actual.js new file mode 100644 index 00000000000000..4cadf31b19f0b9 --- /dev/null +++ b/packages/mui-codemod/src/deprecations/form-control-label-props/test-cases/theme.actual.js @@ -0,0 +1,16 @@ +fn({ + MuiFormControlLabel: { + defaultProps: { + componentsProps: { typography: componentsTypographyProps }, + }, + }, +}); + +fn({ + MuiFormControlLabel: { + defaultProps: { + componentsProps: { typography: componentsTypographyProps }, + slotProps: { typography: slotsTypographyProps }, + }, + }, +}); diff --git a/packages/mui-codemod/src/deprecations/form-control-label-props/test-cases/theme.expected.js b/packages/mui-codemod/src/deprecations/form-control-label-props/test-cases/theme.expected.js new file mode 100644 index 00000000000000..289ec8a0cbd3c4 --- /dev/null +++ b/packages/mui-codemod/src/deprecations/form-control-label-props/test-cases/theme.expected.js @@ -0,0 +1,22 @@ +fn({ + MuiFormControlLabel: { + defaultProps: { + slotProps: { + typography: componentsTypographyProps + } + }, + }, +}); + +fn({ + MuiFormControlLabel: { + defaultProps: { + slotProps: { + typography: { + ...componentsTypographyProps, + ...slotsTypographyProps + } + } + }, + }, +}); diff --git a/packages/mui-codemod/src/deprecations/pagination-item-props/index.js b/packages/mui-codemod/src/deprecations/pagination-item-props/index.js new file mode 100644 index 00000000000000..7999d2c6792651 --- /dev/null +++ b/packages/mui-codemod/src/deprecations/pagination-item-props/index.js @@ -0,0 +1 @@ +export { default } from './pagination-item-props'; diff --git a/packages/mui-codemod/src/deprecations/pagination-item-props/pagination-item-props.js b/packages/mui-codemod/src/deprecations/pagination-item-props/pagination-item-props.js new file mode 100644 index 00000000000000..252aabc0e816e5 --- /dev/null +++ b/packages/mui-codemod/src/deprecations/pagination-item-props/pagination-item-props.js @@ -0,0 +1,15 @@ +import replaceComponentsWithSlots from '../utils/replaceComponentsWithSlots'; + +/** + * @param {import('jscodeshift').FileInfo} file + * @param {import('jscodeshift').API} api + */ +export default function transformer(file, api, options) { + const j = api.jscodeshift; + const root = j(file.source); + const printOptions = options.printOptions; + + replaceComponentsWithSlots(j, { root, componentName: 'PaginationItem' }); + + return root.toSource(printOptions); +} diff --git a/packages/mui-codemod/src/deprecations/pagination-item-props/pagination-item-props.test.js b/packages/mui-codemod/src/deprecations/pagination-item-props/pagination-item-props.test.js new file mode 100644 index 00000000000000..4d7cd4fe412d44 --- /dev/null +++ b/packages/mui-codemod/src/deprecations/pagination-item-props/pagination-item-props.test.js @@ -0,0 +1,53 @@ +import path from 'path'; +import { expect } from 'chai'; +import { jscodeshift } from '../../../testUtils'; +import transform from './pagination-item-props'; +import readFile from '../../util/readFile'; + +function read(fileName) { + return readFile(path.join(__dirname, fileName)); +} + +describe('@mui/codemod', () => { + describe('deprecations', () => { + describe('pagination-item-props', () => { + it('transforms props as needed', () => { + const actual = transform({ source: read('./test-cases/actual.js') }, { jscodeshift }, {}); + + const expected = read('./test-cases/expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform({ source: read('./test-cases/expected.js') }, { jscodeshift }, {}); + + const expected = read('./test-cases/expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + + describe('[theme] pagination-item-props', () => { + it('transforms props as needed', () => { + const actual = transform( + { source: read('./test-cases/theme.actual.js') }, + { jscodeshift }, + { printOptions: { trailingComma: false } }, + ); + + const expected = read('./test-cases/theme.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform( + { source: read('./test-cases/theme.expected.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/theme.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + }); +}); diff --git a/packages/mui-codemod/src/deprecations/pagination-item-props/test-cases/actual.js b/packages/mui-codemod/src/deprecations/pagination-item-props/test-cases/actual.js new file mode 100644 index 00000000000000..08076e26561737 --- /dev/null +++ b/packages/mui-codemod/src/deprecations/pagination-item-props/test-cases/actual.js @@ -0,0 +1,12 @@ +import PaginationItem from '@mui/material/PaginationItem'; + +; +; diff --git a/packages/mui-codemod/src/deprecations/pagination-item-props/test-cases/expected.js b/packages/mui-codemod/src/deprecations/pagination-item-props/test-cases/expected.js new file mode 100644 index 00000000000000..c5b0e3adaf46ed --- /dev/null +++ b/packages/mui-codemod/src/deprecations/pagination-item-props/test-cases/expected.js @@ -0,0 +1,10 @@ +import PaginationItem from '@mui/material/PaginationItem'; + +; +; diff --git a/packages/mui-codemod/src/deprecations/pagination-item-props/test-cases/theme.actual.js b/packages/mui-codemod/src/deprecations/pagination-item-props/test-cases/theme.actual.js new file mode 100644 index 00000000000000..dd9d86c3f0143f --- /dev/null +++ b/packages/mui-codemod/src/deprecations/pagination-item-props/test-cases/theme.actual.js @@ -0,0 +1,27 @@ +fn({ + MuiPaginationItem: { + defaultProps: { + components: { + first: componentFirst, + last: componentLast, + next: componentNext, + previous: componentPrevious, + }, + }, + }, +}); + +fn({ + MuiPaginationItem: { + defaultProps: { + components: { + first: componentFirst, + last: componentLast, + }, + slots: { + next: slotNext, + previous: slotPrevious, + }, + }, + }, +}); diff --git a/packages/mui-codemod/src/deprecations/pagination-item-props/test-cases/theme.expected.js b/packages/mui-codemod/src/deprecations/pagination-item-props/test-cases/theme.expected.js new file mode 100644 index 00000000000000..b98b57f7bf9c72 --- /dev/null +++ b/packages/mui-codemod/src/deprecations/pagination-item-props/test-cases/theme.expected.js @@ -0,0 +1,25 @@ +fn({ + MuiPaginationItem: { + defaultProps: { + slots: { + first: componentFirst, + last: componentLast, + next: componentNext, + previous: componentPrevious + } + }, + }, +}); + +fn({ + MuiPaginationItem: { + defaultProps: { + slots: { + first: componentFirst, + last: componentLast, + next: slotNext, + previous: slotPrevious + } + }, + }, +}); diff --git a/packages/mui-codemod/src/deprecations/step-connector-classes/index.js b/packages/mui-codemod/src/deprecations/step-connector-classes/index.js new file mode 100644 index 00000000000000..c4b340dac5ae6d --- /dev/null +++ b/packages/mui-codemod/src/deprecations/step-connector-classes/index.js @@ -0,0 +1 @@ +export { default } from './step-connector-classes'; diff --git a/packages/mui-codemod/src/deprecations/step-connector-classes/postcss-plugin.js b/packages/mui-codemod/src/deprecations/step-connector-classes/postcss-plugin.js new file mode 100644 index 00000000000000..71e512e0678a8c --- /dev/null +++ b/packages/mui-codemod/src/deprecations/step-connector-classes/postcss-plugin.js @@ -0,0 +1,33 @@ +const classes = [ + { + deprecatedClass: ' .MuiStepConnector-lineHorizontal', + replacementSelector: '.MuiStepConnector-horizontal > .MuiStepConnector-line', + }, + { + deprecatedClass: ' .MuiStepConnector-lineVertical', + replacementSelector: '.MuiStepConnector-vertical > .MuiStepConnector-line', + }, +]; + +const plugin = () => { + return { + postcssPlugin: `Replace deperecated StepConnector classes with new classes`, + Rule(rule) { + const { selector } = rule; + + classes.forEach(({ deprecatedClass, replacementSelector }) => { + const selectorRegex = new RegExp(`${deprecatedClass}$`); + + if (selector.match(selectorRegex)) { + rule.selector = selector.replace(selectorRegex, replacementSelector); + } + }); + }, + }; +}; +plugin.postcss = true; + +module.exports = { + plugin, + classes, +}; diff --git a/packages/mui-codemod/src/deprecations/step-connector-classes/postcss.config.js b/packages/mui-codemod/src/deprecations/step-connector-classes/postcss.config.js new file mode 100644 index 00000000000000..23bebc1125be6e --- /dev/null +++ b/packages/mui-codemod/src/deprecations/step-connector-classes/postcss.config.js @@ -0,0 +1,5 @@ +const { plugin } = require('./postcss-plugin'); + +module.exports = { + plugins: [plugin], +}; diff --git a/packages/mui-codemod/src/deprecations/step-connector-classes/step-connector-classes.js b/packages/mui-codemod/src/deprecations/step-connector-classes/step-connector-classes.js new file mode 100644 index 00000000000000..00f08a6c9b49f9 --- /dev/null +++ b/packages/mui-codemod/src/deprecations/step-connector-classes/step-connector-classes.js @@ -0,0 +1,127 @@ +import { classes } from './postcss-plugin'; + +/** + * @param {import('jscodeshift').FileInfo} file + * @param {import('jscodeshift').API} api + */ +export default function transformer(file, api, options) { + const j = api.jscodeshift; + const root = j(file.source); + const printOptions = options.printOptions; + classes.forEach(({ deprecatedClass, replacementSelector }) => { + const replacementSelectorPrefix = '&'; + root + .find(j.ImportDeclaration) + .filter((path) => path.node.source.value.match(/^@mui\/material\/StepConnector$/)) + .forEach((path) => { + path.node.specifiers.forEach((specifier) => { + if ( + specifier.type === 'ImportSpecifier' && + specifier.imported.name === 'stepConnectorClasses' + ) { + const deprecatedAtomicClass = deprecatedClass.replace( + `${deprecatedClass.split('-')[0]}-`, + '', + ); + root + .find(j.MemberExpression, { + object: { name: specifier.local.name }, + property: { name: deprecatedAtomicClass }, + }) + .forEach((memberExpression) => { + const parent = memberExpression.parentPath.parentPath.value; + if (parent.type === j.TemplateLiteral.name) { + const memberExpressionIndex = parent.expressions.findIndex( + (expression) => expression === memberExpression.value, + ); + const precedingTemplateElement = parent.quasis[memberExpressionIndex]; + const atomicClasses = replacementSelector + .replaceAll('MuiStepConnector-', '') + .replaceAll(replacementSelectorPrefix, '') + .replaceAll(' > ', '') + .split('.') + .filter(Boolean); + + if ( + precedingTemplateElement.value.raw.endsWith( + deprecatedClass.startsWith(' ') + ? `${replacementSelectorPrefix} .` + : `${replacementSelectorPrefix}.`, + ) + ) { + const atomicClassesArgs = [ + memberExpressionIndex, + 1, + ...atomicClasses.map((atomicClass) => + j.memberExpression( + memberExpression.value.object, + j.identifier(atomicClass), + ), + ), + ]; + parent.expressions.splice(...atomicClassesArgs); + + if (replacementSelector.includes(' > ')) { + const quasisArgs = [ + memberExpressionIndex, + 1, + j.templateElement( + { + raw: precedingTemplateElement.value.raw.replace(' ', ''), + cooked: precedingTemplateElement.value.cooked.replace(' ', ''), + }, + false, + ), + j.templateElement({ raw: ' > .', cooked: ' > .' }, false), + ]; + + if (atomicClasses.length === 3) { + quasisArgs.splice( + 3, + 0, + j.templateElement({ raw: '.', cooked: '.' }, false), + ); + } + + parent.quasis.splice(...quasisArgs); + } else { + parent.quasis.splice( + memberExpressionIndex, + 1, + j.templateElement( + { + raw: precedingTemplateElement.value.raw, + cooked: precedingTemplateElement.value.cooked, + }, + false, + ), + + j.templateElement({ raw: '.', cooked: '.' }, false), + ); + } + } + } + }); + } + }); + }); + + const selectorRegex = new RegExp(`${replacementSelectorPrefix}${deprecatedClass}$`); + root + .find( + j.Literal, + (literal) => typeof literal.value === 'string' && literal.value.match(selectorRegex), + ) + .forEach((path) => { + path.replace( + j.literal( + path.value.value.replace( + selectorRegex, + `${replacementSelectorPrefix}${replacementSelector}`, + ), + ), + ); + }); + }); + return root.toSource(printOptions); +} diff --git a/packages/mui-codemod/src/deprecations/step-connector-classes/step-connector-classes.test.js b/packages/mui-codemod/src/deprecations/step-connector-classes/step-connector-classes.test.js new file mode 100644 index 00000000000000..ea3ace7ef9d7e4 --- /dev/null +++ b/packages/mui-codemod/src/deprecations/step-connector-classes/step-connector-classes.test.js @@ -0,0 +1,78 @@ +import path from 'path'; +import { expect } from 'chai'; +import postcss from 'postcss'; +import { jscodeshift } from '../../../testUtils'; +import jsTransform from './step-connector-classes'; +import { plugin as postcssPlugin } from './postcss-plugin'; +import readFile from '../../util/readFile'; + +function read(fileName) { + return readFile(path.join(__dirname, fileName)); +} + +const postcssProcessor = postcss([postcssPlugin]); + +describe('@mui/codemod', () => { + describe('deprecations', () => { + describe('step-connector-classes', () => { + describe('js-transform', () => { + it('transforms props as needed', () => { + const actual = jsTransform( + { source: read('./test-cases/actual.js') }, + { jscodeshift }, + { printOptions: { quote: 'double', trailingComma: true } }, + ); + + const expected = read('./test-cases/expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = jsTransform( + { source: read('./test-cases/expected.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + + describe('css-transform', () => { + it('transforms classes as needed', async () => { + const actual = await postcssProcessor.process(read('./test-cases/actual.css'), { + from: undefined, + }); + + const expected = read('./test-cases/expected.css'); + expect(actual.css).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', async () => { + const actual = await postcssProcessor.process(read('./test-cases/expected.css'), { + from: undefined, + }); + + const expected = read('./test-cases/expected.css'); + expect(actual.css).to.equal(expected, 'The transformed version should be correct'); + }); + }); + + describe('test-cases', () => { + it('should not be the same', () => { + const actualJS = read('./test-cases/actual.js'); + const expectedJS = read('./test-cases/expected.js'); + expect(actualJS).not.to.equal(expectedJS, 'The actual and expected should be different'); + + const actualCSS = read('./test-cases/actual.css'); + const expectedCSS = read('./test-cases/expected.css'); + expect(actualCSS).not.to.equal( + expectedCSS, + 'The actual and expected should be different', + ); + }); + }); + }); + }); +}); diff --git a/packages/mui-codemod/src/deprecations/step-connector-classes/test-cases/actual.css b/packages/mui-codemod/src/deprecations/step-connector-classes/test-cases/actual.css new file mode 100644 index 00000000000000..a6803c62d2dd52 --- /dev/null +++ b/packages/mui-codemod/src/deprecations/step-connector-classes/test-cases/actual.css @@ -0,0 +1,7 @@ +.MuiStepConnector-root .MuiStepConnector-lineHorizontal { + color: red; +} + +.MuiStepConnector-root .MuiStepConnector-lineVertical { + color: red; +} diff --git a/packages/mui-codemod/src/deprecations/step-connector-classes/test-cases/actual.js b/packages/mui-codemod/src/deprecations/step-connector-classes/test-cases/actual.js new file mode 100644 index 00000000000000..2a3d38d0081cbf --- /dev/null +++ b/packages/mui-codemod/src/deprecations/step-connector-classes/test-cases/actual.js @@ -0,0 +1,6 @@ +import { stepConnectorClasses } from '@mui/material/StepConnector'; + +('& .MuiStepConnector-lineHorizontal'); +('& .MuiStepConnector-lineVertical'); +`& .${stepConnectorClasses.lineHorizontal}`; +`& .${stepConnectorClasses.lineVertical}`; diff --git a/packages/mui-codemod/src/deprecations/step-connector-classes/test-cases/expected.css b/packages/mui-codemod/src/deprecations/step-connector-classes/test-cases/expected.css new file mode 100644 index 00000000000000..e57ec5b0540422 --- /dev/null +++ b/packages/mui-codemod/src/deprecations/step-connector-classes/test-cases/expected.css @@ -0,0 +1,7 @@ +.MuiStepConnector-root.MuiStepConnector-horizontal > .MuiStepConnector-line { + color: red; +} + +.MuiStepConnector-root.MuiStepConnector-vertical > .MuiStepConnector-line { + color: red; +} diff --git a/packages/mui-codemod/src/deprecations/step-connector-classes/test-cases/expected.js b/packages/mui-codemod/src/deprecations/step-connector-classes/test-cases/expected.js new file mode 100644 index 00000000000000..5779ddf485b802 --- /dev/null +++ b/packages/mui-codemod/src/deprecations/step-connector-classes/test-cases/expected.js @@ -0,0 +1,6 @@ +import { stepConnectorClasses } from '@mui/material/StepConnector'; + +("&.MuiStepConnector-horizontal > .MuiStepConnector-line"); +("&.MuiStepConnector-vertical > .MuiStepConnector-line"); +`&.${stepConnectorClasses.horizontal} > .${stepConnectorClasses.line}`; +`&.${stepConnectorClasses.vertical} > .${stepConnectorClasses.line}`; diff --git a/packages/mui-codemod/src/deprecations/step-label-props/step-label-props.js b/packages/mui-codemod/src/deprecations/step-label-props/step-label-props.js index d71fbba3a84810..b2fec09fa3b826 100644 --- a/packages/mui-codemod/src/deprecations/step-label-props/step-label-props.js +++ b/packages/mui-codemod/src/deprecations/step-label-props/step-label-props.js @@ -1,4 +1,6 @@ import replaceComponentsWithSlots from '../utils/replaceComponentsWithSlots'; +import movePropIntoSlots from '../utils/movePropIntoSlots'; +import movePropIntoSlotProps from '../utils/movePropIntoSlotProps'; /** * @param {import('jscodeshift').FileInfo} file @@ -11,5 +13,19 @@ export default function transformer(file, api, options) { replaceComponentsWithSlots(j, { root, componentName: 'StepLabel' }); + movePropIntoSlots(j, { + root, + componentName: 'StepLabel', + propName: 'StepIconComponent', + slotName: 'stepIcon', + }); + + movePropIntoSlotProps(j, { + root, + componentName: 'StepLabel', + propName: 'StepIconProps', + slotName: 'stepIcon', + }); + return root.toSource(printOptions); } diff --git a/packages/mui-codemod/src/deprecations/step-label-props/test-cases/actual.js b/packages/mui-codemod/src/deprecations/step-label-props/test-cases/actual.js index 9caf4e5a411080..20a1428f7b1598 100644 --- a/packages/mui-codemod/src/deprecations/step-label-props/test-cases/actual.js +++ b/packages/mui-codemod/src/deprecations/step-label-props/test-cases/actual.js @@ -6,3 +6,15 @@ import StepLabel from '@mui/material/StepLabel'; slotProps={{ label: slotLabelProps }} componentsProps={{ label: componentsLabelProps }} />; +; +; +; diff --git a/packages/mui-codemod/src/deprecations/step-label-props/test-cases/expected.js b/packages/mui-codemod/src/deprecations/step-label-props/test-cases/expected.js index b26c217086b36d..3dfec474599baf 100644 --- a/packages/mui-codemod/src/deprecations/step-label-props/test-cases/expected.js +++ b/packages/mui-codemod/src/deprecations/step-label-props/test-cases/expected.js @@ -7,3 +7,29 @@ import StepLabel from '@mui/material/StepLabel'; ...componentsLabelProps, ...slotLabelProps } }} />; +; +; +; diff --git a/packages/mui-codemod/src/deprecations/step-label-props/test-cases/theme.actual.js b/packages/mui-codemod/src/deprecations/step-label-props/test-cases/theme.actual.js index 4f68c1fe687871..68624f70881f49 100644 --- a/packages/mui-codemod/src/deprecations/step-label-props/test-cases/theme.actual.js +++ b/packages/mui-codemod/src/deprecations/step-label-props/test-cases/theme.actual.js @@ -14,3 +14,23 @@ fn({ }, }, }); + +fn({ + MuiStepLabel: { + defaultProps: { + StepIconComponent: StepIconComponent, + StepIconProps: StepIconProps, + }, + }, +}); + +fn({ + MuiStepLabel: { + defaultProps: { + componentsProps: { label: componentsLabelProps }, + slotProps: { label: slotLabelProps }, + StepIconComponent: StepIconComponent, + StepIconProps: StepIconProps, + }, + }, +}); diff --git a/packages/mui-codemod/src/deprecations/step-label-props/test-cases/theme.expected.js b/packages/mui-codemod/src/deprecations/step-label-props/test-cases/theme.expected.js index c8874c72137cab..3919652d47b97d 100644 --- a/packages/mui-codemod/src/deprecations/step-label-props/test-cases/theme.expected.js +++ b/packages/mui-codemod/src/deprecations/step-label-props/test-cases/theme.expected.js @@ -20,3 +20,36 @@ fn({ }, }, }); + +fn({ + MuiStepLabel: { + defaultProps: { + slots: { + stepIcon: StepIconComponent + }, + + slotProps: { + stepIcon: StepIconProps + } + }, + }, +}); + +fn({ + MuiStepLabel: { + defaultProps: { + slotProps: { + label: { + ...componentsLabelProps, + ...slotLabelProps + }, + + stepIcon: StepIconProps + }, + + slots: { + stepIcon: StepIconComponent + } + }, + }, +}); diff --git a/packages/mui-codemod/src/deprecations/utils/movePropIntoSlotProps.js b/packages/mui-codemod/src/deprecations/utils/movePropIntoSlotProps.js new file mode 100644 index 00000000000000..2e09e3d1d021cc --- /dev/null +++ b/packages/mui-codemod/src/deprecations/utils/movePropIntoSlotProps.js @@ -0,0 +1,111 @@ +import findComponentJSX from '../../util/findComponentJSX'; +import findComponentDefaultProps from '../../util/findComponentDefaultProps'; +import assignObject from '../../util/assignObject'; +import appendAttribute from '../../util/appendAttribute'; + +function moveJsxPropIntoSlotProps(j, element, propName, slotName) { + const propIndex = element.openingElement.attributes.findIndex( + (attr) => attr.type === 'JSXAttribute' && attr.name.name === propName, + ); + + if (propIndex !== -1) { + const removedValue = element.openingElement.attributes.splice(propIndex, 1)[0].value.expression; + let hasSlotProps = false; + element.openingElement.attributes.forEach((attr) => { + if (attr.name?.name === 'slotProps') { + hasSlotProps = true; + const slots = attr.value.expression; + const slotIndex = slots.properties.findIndex((prop) => prop?.key?.name === slotName); + if (slotIndex === -1) { + assignObject(j, { + target: attr, + key: slotName, + expression: removedValue, + }); + } else { + const slotPropsSlotValue = slots.properties.splice(slotIndex, 1)[0].value; + assignObject(j, { + target: attr, + key: slotName, + expression: j.objectExpression([ + j.spreadElement(removedValue), + j.spreadElement(slotPropsSlotValue), + ]), + }); + } + } + }); + + if (!hasSlotProps) { + appendAttribute(j, { + target: element, + attributeName: 'slotProps', + expression: j.objectExpression([j.objectProperty(j.identifier(slotName), removedValue)]), + }); + } + } +} + +function moveDefaultPropsPropIntoslotProps(j, defaultPropsPathCollection, propName, slotName) { + defaultPropsPathCollection.find(j.ObjectProperty, { key: { name: propName } }).forEach((path) => { + const removedValue = path.value.value; + const defaultProps = path.parent.value; + + let hasSlotProps = false; + defaultProps.properties.forEach((property) => { + if (property.key?.name === 'slotProps') { + hasSlotProps = true; + const slotIndex = property.value.properties.findIndex( + (prop) => prop?.key?.name === slotName, + ); + if (slotIndex === -1) { + property.value.properties.push(j.objectProperty(j.identifier(slotName), removedValue)); + } else { + const slotPropsSlotValue = property.value.properties.splice(slotIndex, 1)[0].value; + property.value.properties.push( + j.objectProperty( + j.identifier(slotName), + j.objectExpression([ + j.spreadElement(removedValue), + j.spreadElement(slotPropsSlotValue), + ]), + ), + ); + } + } + }); + + if (!hasSlotProps) { + defaultProps.properties.push( + j.objectProperty( + j.identifier('slotProps'), + j.objectExpression([j.objectProperty(j.identifier(slotName), removedValue)]), + ), + ); + } + + path.prune(); + }); +} + +/** + * Moves prop into slotProps. + * If the slotProps prop exists, it will merge the prop into the slotProps. + * If there are duplicated values, the values will be spread. + * + * @param {import('jscodeshift')} j + * @param {{ root: import('jscodeshift').Collection; componentName: string, propName: string, slotName: string }} options + * + * @example => + */ +export default function movePropIntoSlotProps(j, options) { + const { root, componentName, propName, slotName } = options; + + findComponentJSX(j, { root, componentName }, (elementPath) => { + moveJsxPropIntoSlotProps(j, elementPath.node, propName, slotName); + }); + + const defaultPropsPathCollection = findComponentDefaultProps(j, { root, componentName }); + + moveDefaultPropsPropIntoslotProps(j, defaultPropsPathCollection, propName, slotName); +} diff --git a/packages/mui-codemod/src/deprecations/utils/movePropIntoSlots.js b/packages/mui-codemod/src/deprecations/utils/movePropIntoSlots.js new file mode 100644 index 00000000000000..9910853c3b4949 --- /dev/null +++ b/packages/mui-codemod/src/deprecations/utils/movePropIntoSlots.js @@ -0,0 +1,91 @@ +import findComponentJSX from '../../util/findComponentJSX'; +import findComponentDefaultProps from '../../util/findComponentDefaultProps'; +import assignObject from '../../util/assignObject'; +import appendAttribute from '../../util/appendAttribute'; + +function moveJsxPropIntoSlots(j, element, propName, slotName) { + const index = element.openingElement.attributes.findIndex( + (attr) => attr.type === 'JSXAttribute' && attr.name.name === propName, + ); + + if (index !== -1) { + const removedValue = element.openingElement.attributes.splice(index, 1)[0].value.expression; + let hasSlots = false; + element.openingElement.attributes.forEach((attr) => { + if (attr.name?.name === 'slots') { + hasSlots = true; + const slotIndex = attr.value.expression.properties.findIndex( + (prop) => prop?.key?.name === slotName, + ); + if (slotIndex === -1) { + assignObject(j, { + target: attr, + key: slotName, + expression: removedValue, + }); + } + } + }); + + if (!hasSlots) { + appendAttribute(j, { + target: element, + attributeName: 'slots', + expression: j.objectExpression([j.objectProperty(j.identifier(slotName), removedValue)]), + }); + } + } +} + +function moveDefaultPropsPropIntoSlots(j, defaultPropsPathCollection, propName, slotName) { + defaultPropsPathCollection.find(j.ObjectProperty, { key: { name: propName } }).forEach((path) => { + const removedValue = path.value.value; + const defaultProps = path.parent.value; + + let hasSlots = false; + defaultProps.properties.forEach((property) => { + if (property.key?.name === 'slots') { + hasSlots = true; + const slots = property.value; + const slotIndex = slots.properties.findIndex((prop) => prop?.key?.name === slotName); + if (slotIndex === -1) { + slots.properties.push(j.objectProperty(j.identifier(slotName), removedValue)); + } + } + }); + + if (!hasSlots) { + defaultProps.properties.push( + j.property( + 'init', + j.identifier('slots'), + j.objectExpression([j.objectProperty(j.identifier(slotName), removedValue)]), + ), + ); + } + + path.prune(); + }); +} + +/** + * Moves prop into slots. + * If the slots prop exists, it will add the prop to the slots. + * If there are duplicated values, the slots values will be used. + * + * @param {import('jscodeshift')} j + * @param {{ root: import('jscodeshift').Collection; componentName: string, propName: string, slotName: string }} options + * + * @example => + */ +export default function movePropIntoSlots(j, options) { + const { root, componentName, propName, slotName } = options; + + findComponentJSX(j, { root, componentName }, (elementPath) => { + moveJsxPropIntoSlots(j, elementPath.node, propName, slotName); + }); + + const defaultPropsPathCollection = findComponentDefaultProps(j, { root, componentName }); + + moveDefaultPropsPropIntoSlots(j, defaultPropsPathCollection, propName, slotName); +} diff --git a/packages/mui-codemod/src/util/getReturnExpression.js b/packages/mui-codemod/src/util/getReturnExpression.js new file mode 100644 index 00000000000000..b14830121fa4f5 --- /dev/null +++ b/packages/mui-codemod/src/util/getReturnExpression.js @@ -0,0 +1,14 @@ +/** + * @param {import('ast-types').namedTypes.ArrowFunctionExpression | import('ast-types').namedTypes.FunctionExpression} node + */ +export default function getReturnExpression(node) { + let body = node.body; + if (body === 'BlockStatement') { + body = body.body; + } + + if (Array.isArray(body)) { + return body.find((statement) => statement.type === 'ReturnStatement')?.argument; + } + return body; +} diff --git a/packages/mui-codemod/src/util/migrateToVariants.js b/packages/mui-codemod/src/util/migrateToVariants.js new file mode 100644 index 00000000000000..c8508c67b2f2d9 --- /dev/null +++ b/packages/mui-codemod/src/util/migrateToVariants.js @@ -0,0 +1,581 @@ +const MAX_DEPTH = 20; +/** + * + * @param {import('jscodeshift').API['j']} j + * @param {any[]} styles + */ +export default function migrateToVariants(j, styles) { + function createBuildStyle(key, upperBuildStyle, applyStylesMode) { + if (applyStylesMode) { + upperBuildStyle = (styleExpression) => + j.objectExpression([ + j.spreadElement( + j.callExpression( + j.memberExpression(j.identifier('theme'), j.identifier('applyStyles')), + [j.stringLiteral(applyStylesMode), styleExpression], + ), + ), + ]); + } + return function buildStyle(styleExpression) { + if (key) { + if (key.type === 'Identifier' || key.type === 'StringLiteral') { + return upperBuildStyle(j.objectExpression([j.objectProperty(key, styleExpression)])); + } + if (key.type === 'TemplateLiteral' || key.type === 'CallExpression') { + return upperBuildStyle( + j.objectExpression([ + { + ...j.objectProperty(key, styleExpression), + computed: true, + }, + ]), + ); + } + } + return upperBuildStyle ? upperBuildStyle(styleExpression) : styleExpression; + }; + } + + /** + * + * @param {import('ast-types').namedTypes.MemberExpression | import('ast-types').namedTypes.Identifier} node + */ + function getIdentifierKey(node) { + if (node.type === 'MemberExpression') { + return node.property; + } + return node; + } + + /** + * + * @param {import('ast-types').namedTypes.UnaryExpression | import('ast-types').namedTypes.MemberExpression | import('ast-types').namedTypes.Identifier} node + */ + function getObjectKey(node) { + let tempNode = { ...node }; + while (tempNode.type === 'UnaryExpression') { + tempNode = tempNode.argument; + } + while (tempNode.type === 'MemberExpression') { + tempNode = tempNode.object; + } + return tempNode; + } + + /** + * + * @param {import('ast-types').namedTypes.ObjectExpression} objectExpression + * @param {import('ast-types').namedTypes.BinaryExpression} addtional + */ + function objectToArrowFunction(objectExpression, addtional) { + const paramKeys = new Set(); + let left; + objectExpression.properties.forEach((prop, index) => { + paramKeys.add(prop.key.name); + const result = j.binaryExpression('===', prop.key, prop.value); + if (index === 0) { + left = result; + } else { + left = j.logicalExpression('&&', left, result); + } + }); + if (addtional) { + paramKeys.add(getObjectKey(addtional.left).name); + } + return buildArrowFunctionAST( + paramKeys, + addtional ? j.logicalExpression('&&', left, addtional) : left, + ); + } + + /** + * + * @param {import('ast-types').namedTypes.Identifier | import('ast-types').namedTypes.BinaryExpression | import('ast-types').namedTypes.UnaryExpression | import('ast-types').namedTypes.MemberExpression} node + */ + function inverseBinaryExpression(node) { + if (node.type === 'Identifier' || node.type === 'MemberExpression') { + return j.unaryExpression('!', node); + } + if (node.operator === '===') { + return { ...node, operator: '!==' }; + } + if (node.operator === '!==') { + return { ...node, operator: '===' }; + } + if (node.operator === '!') { + if (node.argument?.operator === '!') { + return node.argument; + } + return j.unaryExpression('!', node); + } + return node; + } + + /** + * + * @param {import('ast-types').namedTypes.ObjectExpression} node + */ + function removeProperty(parentNode, child) { + if (parentNode) { + if (parentNode.type === 'ObjectExpression') { + parentNode.properties = parentNode.properties.filter( + (prop) => prop !== child && prop.value !== child, + ); + } + } + } + + function buildObjectAST(jsObject) { + const result = j.objectExpression([]); + Object.entries(jsObject).forEach(([key, value]) => { + result.properties.push(j.objectProperty(j.identifier(key), value)); + }); + return result; + } + + function buildArrowFunctionAST(params, body) { + return j.arrowFunctionExpression( + [ + j.objectPattern( + [...params].map((k) => ({ + ...j.objectProperty(j.identifier(k), j.identifier(k)), + shorthand: true, + })), + ), + ], + body, + ); + } + + /** + * + * @param {{ properties: any[] }} node + * @param {Record} modeStyles + */ + function appendPaletteModeStyles(node, modeStyles) { + Object.entries(modeStyles).forEach(([mode, objectStyles]) => { + node.properties.push( + j.spreadElement( + j.callExpression(j.memberExpression(j.identifier('theme'), j.identifier('applyStyles')), [ + j.stringLiteral(mode), + Array.isArray(objectStyles) ? j.objectExpression(objectStyles) : objectStyles, + ]), + ), + ); + }); + } + + /** + * + * @param {import('ast-types').namedTypes.LogicalExpression | import('ast-types').namedTypes.BinaryExpression | import('ast-types').namedTypes.UnaryExpression | import('ast-types').namedTypes.MemberExpression} node + */ + function buildProps(node) { + const properties = []; + const variables = new Set(); + let isAllEqual = true; + let tempNode = { ...node }; + function assignProperties(_node) { + if (_node.type === 'BinaryExpression') { + variables.add(getObjectKey(_node.left).name); + if (_node.operator === '===') { + properties.push(j.objectProperty(getIdentifierKey(_node.left), _node.right)); + } else { + isAllEqual = false; + } + } + if (_node.type === 'MemberExpression' || _node.type === 'Identifier') { + isAllEqual = false; + variables.add(getObjectKey(_node).name); + } + if (_node.type === 'UnaryExpression') { + isAllEqual = false; + if (_node.argument.type === 'UnaryExpression') { + // handle `!!variable` + variables.add(getObjectKey(_node.argument.argument).name); + } else { + // handle `!variable` + variables.add(getObjectKey(_node.argument).name); + } + } + } + let counter = 0; + if (tempNode.type !== 'LogicalExpression') { + assignProperties(tempNode); + } else { + while (tempNode.type === 'LogicalExpression' && counter < MAX_DEPTH) { + counter += 1; + if (tempNode.operator !== '&&') { + isAllEqual = false; + } + + assignProperties(tempNode.right); + if (tempNode.left.type !== 'LogicalExpression') { + assignProperties(tempNode.left); + break; + } + + tempNode = { ...tempNode.left }; + } + } + + if (!isAllEqual) { + return buildArrowFunctionAST(variables, node); + } + return j.objectExpression(properties); + } + + function mergeProps(parentProps, currentProps) { + if (parentProps.type === 'ObjectExpression' && currentProps.type === 'ObjectExpression') { + return j.objectExpression([...parentProps.properties, ...currentProps.properties]); + } + const parentArrow = + parentProps.type === 'ObjectExpression' ? objectToArrowFunction(parentProps) : parentProps; + const currentArrow = + currentProps.type === 'ObjectExpression' ? objectToArrowFunction(currentProps) : currentProps; + const variables = new Set(); + [...parentArrow.params[0].properties, ...currentArrow.params[0].properties].forEach((param) => { + variables.add(param.key.name); + }); + return buildArrowFunctionAST( + variables, + j.logicalExpression('&&', parentArrow.body, currentArrow.body), + ); + } + + function isThemePaletteMode(node) { + return ( + node.type === 'MemberExpression' && + node.object.type === 'MemberExpression' && + node.object.object.name === 'theme' && + node.object.property.name === 'palette' && + node.property.name === 'mode' + ); + } + + // 2. Find logical spread expressions to convert to variants + styles.forEach((style) => { + const parameters = new Set(); + style.params.forEach((param) => { + if (param.type === 'ObjectPattern') { + param.properties.forEach((prop) => { + parameters.add(prop.key.name); + }); + } + }); + const variants = []; + + if (style.body.type === 'LogicalExpression') { + if ( + style.params[0] && + style.params[0].type === 'ObjectPattern' && + style.params[0].properties.some((prop) => prop.key.name !== 'theme') + ) { + // case: ({ theme, ownerState }) => ownerState.variant === 'regular' && theme.mixins.toolbar + style.body = j.objectExpression([ + j.objectProperty( + j.identifier('variants'), + j.arrayExpression([ + j.objectExpression([ + j.objectProperty(j.identifier('props'), buildProps(style.body.left)), + j.objectProperty(j.identifier('style'), style.body.right), + ]), + ]), + ), + ]); + } + } else if (style.body.type === 'ConditionalExpression') { + // skip ConditionalExpression + } else { + let objectExpression = style.body; + let counter = 0; + while (objectExpression.type !== 'ObjectExpression' && counter < MAX_DEPTH) { + counter += 1; + if (objectExpression.type === 'BlockStatement') { + objectExpression = objectExpression.body.find( + (item) => item.type === 'ReturnStatement', + ).argument; + } + } + + recurseObjectExpression({ node: objectExpression, buildStyle: createBuildStyle() }); + + if (variants.length) { + objectExpression.properties.push( + j.objectProperty( + j.identifier('variants'), + j.arrayExpression( + variants.filter((variant) => { + const props = variant.properties.find((prop) => prop.key.name === 'props'); + const styleVal = variant.properties.find((prop) => prop.key.name === 'style'); + return ( + props && + styleVal && + (!styleVal.value.properties || styleVal.value.properties.length > 0) && + (props.value.type === 'ArrowFunctionExpression' || + props.value.properties.length > 0) + ); + }), + ), + ), + ); + } + } + + function recurseObjectExpression(data) { + if (data.node.type === 'ObjectExpression') { + const modeStyles = {}; // to collect styles from `theme.palette.mode === '...'` + data.node.properties.forEach((prop) => { + if (prop.type === 'ObjectProperty') { + recurseObjectExpression({ + ...data, + node: prop.value, + parentNode: data.node, + key: prop.key, + buildStyle: createBuildStyle(prop.key, data.buildStyle), + replaceValue: (newValue) => { + prop.value = newValue; + }, + modeStyles, + }); + } else { + recurseObjectExpression({ + ...data, + node: prop, + parentNode: data.node, + buildStyle: createBuildStyle(prop.key, data.buildStyle), + }); + } + }); + appendPaletteModeStyles(data.node, modeStyles); + } + if (data.node.type === 'SpreadElement') { + if (data.node.argument.type === 'LogicalExpression') { + const paramName = + data.node.argument.left.type === 'BinaryExpression' + ? getObjectKey(data.node.argument.left.left)?.name + : getObjectKey(data.node.argument.left)?.name; + if (paramName === 'theme' && data.node.argument.left.right.type === 'StringLiteral') { + if (data.node.argument.right.type === 'ObjectExpression') { + const mode = data.node.argument.left.right.value; + data.node.argument.right.properties.forEach((prop) => { + if (prop.type === 'ObjectProperty') { + recurseObjectExpression({ + ...data, + node: prop.value, + parentNode: data.node.argument.right, + key: prop.key, + buildStyle: createBuildStyle(prop.key, data.buildStyle, mode), + replaceValue: (newValue) => { + prop.value = newValue; + }, + }); + } else { + recurseObjectExpression({ + ...data, + node: prop, + parentNode: data.node.argument.right, + buildStyle: createBuildStyle(prop.key, data.buildStyle, mode), + }); + } + }); + appendPaletteModeStyles(data.parentNode, { + [mode]: data.node.argument.right, + }); + } + removeProperty(data.parentNode, data.node); + return; + } + if (paramName && !parameters.has(paramName)) { + return; + } + + const scopeProps = buildProps(data.node.argument.left); + const variant = { + props: data.props ? mergeProps(data.props, scopeProps) : scopeProps, + style: data.node.argument.right, + }; + + const lastLength = variants.push({}); // preserve the order of the recursive calls + + const modeStyles = {}; // to collect styles from `theme.palette.mode === '...'` + if (variant.style.type === 'ObjectExpression') { + variant.style.properties.forEach((prop) => { + if (prop.type === 'ObjectProperty') { + recurseObjectExpression({ + ...data, + node: prop.value, + parentNode: variant.style, + props: variant.props, + key: prop.key, + buildStyle: createBuildStyle(prop.key, data.buildStyle), + replaceValue: (newValue) => { + prop.value = newValue; + }, + modeStyles, + }); + } else { + recurseObjectExpression({ + ...data, + node: prop, + parentNode: variant.style, + props: variant.props, + buildStyle: createBuildStyle(prop.key, data.buildStyle), + }); + } + }); + } + appendPaletteModeStyles(variant.style, modeStyles); + variant.style = data.buildStyle(variant.style); + variants[lastLength - 1] = buildObjectAST(variant); + removeProperty(data.parentNode, data.node); + } + if (data.node.argument.type === 'ConditionalExpression') { + recurseObjectExpression({ + ...data, + node: data.node.argument, + parentNode: data.node, + }); + removeProperty(data.parentNode, data.node); + } + } + if (data.node.type === 'ConditionalExpression') { + if ( + data.node.test.type === 'BinaryExpression' || + data.node.test.type === 'UnaryExpression' || + data.node.test.type === 'Identifier' || + data.node.test.type === 'MemberExpression' + ) { + let leftName = getObjectKey(data.node.test)?.name; + if (data.node.test.left) { + leftName = getObjectKey(data.node.test.left)?.name; + } + if (data.node.test.argument) { + leftName = getObjectKey(data.node.test.argument)?.name; + } + if (parameters.has(leftName) && leftName !== 'theme') { + let props = buildProps(data.node.test); + if (data.props) { + props = mergeProps(data.props, props); + } + const styleVal = data.buildStyle(data.node.consequent); + const variant = { + props, + style: styleVal, + }; + variants.push(buildObjectAST(variant)); + + // create another variant with inverted condition + let props2 = buildProps(inverseBinaryExpression(data.node.test)); + if (data.props) { + props2 = mergeProps(data.props, props2); + } + const styleVal2 = data.buildStyle(data.node.alternate); + const variant2 = { + props: props2, + style: styleVal2, + }; + variants.push(buildObjectAST(variant2)); + if (data.parentNode?.type === 'ObjectExpression') { + removeProperty(data.parentNode, data.node); + } + } + if ( + leftName === 'theme' && + data.parentNode?.type === 'ObjectExpression' && + data.node.test?.type === 'BinaryExpression' && + isThemePaletteMode(data.node.test.left) + ) { + if ( + data.node.consequent.type !== 'ObjectExpression' && + data.node.alternate.type !== 'ObjectExpression' + ) { + if (data.modeStyles) { + if (!data.modeStyles[data.node.test.right.value]) { + data.modeStyles[data.node.test.right.value] = []; + } + data.modeStyles[data.node.test.right.value].push( + j.objectProperty(data.key, data.node.consequent), + ); + } + data.replaceValue?.(data.node.alternate); + } + } + } + } + if (data.node.type === 'TemplateLiteral') { + if (data.parentNode?.type === 'ObjectExpression') { + const modeStyles = {}; + data.node.expressions.forEach((expression, index) => { + recurseObjectExpression({ + ...data, + node: expression, + parentNode: data.parentNode, + buildStyle: createBuildStyle(data.key, data.buildStyle), + replaceValue: (newValue) => { + data.node.expressions[index] = newValue; + }, + modeStyles, + }); + }); + if (data.modeStyles) { + Object.entries(modeStyles).forEach(([mode, objectStyles]) => { + const clonedNode = { + ...data.node, + expressions: data.node.expressions.map((expression) => ({ ...expression })), + }; + clonedNode.expressions = objectStyles.map((item) => item.value); + + if (!data.modeStyles[mode]) { + data.modeStyles[mode] = []; + } + data.modeStyles[mode].push(j.objectProperty(data.key, clonedNode)); + }); + } + } + } + if ( + data.key && + data.key.type === 'Identifier' && + data.node.type === 'MemberExpression' && + data.node.object.type === 'ObjectExpression' && + parameters.has(getObjectKey(data.node.property).name) + ) { + data.node.object.properties.forEach((prop) => { + variants.push( + buildObjectAST({ + props: j.objectExpression([ + j.objectProperty( + getIdentifierKey(data.node.property), + j.stringLiteral(prop.key.name), + ), + ]), + style: data.buildStyle(prop.value), + }), + ); + }); + removeProperty(data.parentNode, data.node); + } + } + + style.params.forEach((param) => { + if (param.type === 'ObjectPattern') { + param.properties = param.properties.filter((prop) => prop.key.name === 'theme'); + } + }); + + if (style.body.type === 'ObjectExpression') { + // Remove empty `...theme.applyStyles('...', {})` + style.body.properties = style.body.properties.filter((prop) => { + if ( + prop.argument?.callee?.object?.name === 'theme' && + typeof prop.argument?.arguments[0]?.value === 'string' && + !prop.argument?.arguments?.[1]?.properties?.length + ) { + return false; + } + return true; + }); + } + }); +} diff --git a/packages/mui-codemod/src/v5.0.0/base-remove-unstyled-suffix.js b/packages/mui-codemod/src/v5.0.0/base-remove-unstyled-suffix.js index 6d773a08c0f639..6c3e45094df4ec 100644 --- a/packages/mui-codemod/src/v5.0.0/base-remove-unstyled-suffix.js +++ b/packages/mui-codemod/src/v5.0.0/base-remove-unstyled-suffix.js @@ -10,14 +10,13 @@ export default function transformer(file, api) { .find(j.ImportDeclaration) .filter(({ node }) => { const sourceVal = node.source.value; - if (sourceVal.startsWith('@mui/base')) { - node.source.value = sourceVal.replace(/unstyled/im, ''); - node.source.raw = sourceVal.replace(/unstyled/im, ''); - } - return sourceVal.startsWith('@mui/base'); }) .forEach((path) => { + const sourceVal = path.node.source.value; + if (sourceVal.startsWith('@mui/base')) { + path.node.source = j.stringLiteral(sourceVal.replace(/unstyled/im, '')); + } const specifiers = []; path.node.specifiers.forEach((elementNode) => { const importedName = elementNode.imported?.name || ''; diff --git a/packages/mui-codemod/src/v5.0.0/box-sx-prop.test/expected.js b/packages/mui-codemod/src/v5.0.0/box-sx-prop.test/expected.js index 1c5cb573310c52..0a58fec3d56e84 100644 --- a/packages/mui-codemod/src/v5.0.0/box-sx-prop.test/expected.js +++ b/packages/mui-codemod/src/v5.0.0/box-sx-prop.test/expected.js @@ -4,7 +4,7 @@ import Button from '@material-ui/core/Button'; export default function BoxComponent(props) { return ( - - + ) ); } diff --git a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/eighth.expected.js b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/eighth.expected.js index 65cd75818c0c89..95c31a25fe07e3 100644 --- a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/eighth.expected.js +++ b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/eighth.expected.js @@ -115,7 +115,7 @@ export default function Cart() { }); }; return ( - + ( @@ -208,6 +208,6 @@ export default function Cart() { - + ) ); } \ No newline at end of file diff --git a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/eleventh.expected.js b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/eleventh.expected.js index 8fb90973ad75f7..71e28fcea2d4e3 100644 --- a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/eleventh.expected.js +++ b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/eleventh.expected.js @@ -29,9 +29,9 @@ export default function Page() { return ( - + (

    -
    +
    ) ); } \ No newline at end of file diff --git a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/fifth.expected.js b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/fifth.expected.js index 493cbe51da0472..093020d104b1d2 100644 --- a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/fifth.expected.js +++ b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/fifth.expected.js @@ -62,7 +62,7 @@ function SellHero() { return ( - + ( Sell themes @@ -87,7 +87,7 @@ function SellHero() {
    - + ) ); } diff --git a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/first.expected.js b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/first.expected.js index c919a8c97db252..5169edb4b7cd3a 100644 --- a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/first.expected.js +++ b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/first.expected.js @@ -180,7 +180,7 @@ class AppAppBar extends React.Component { const { menuOpen } = this.state; return ( - + (
    @@ -237,7 +237,7 @@ class AppAppBar extends React.Component {
    )} -
    +
    ) ); } } diff --git a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/fourth.expected.js b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/fourth.expected.js index cc59b1db8d5abd..714539faff3696 100644 --- a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/fourth.expected.js +++ b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/fourth.expected.js @@ -31,10 +31,10 @@ const StyledCard = styled(Card)(function getStyles( export const MyCard = ((props) => { const { } = props; return ( - + ( - + ) ); }); diff --git a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/nineth.expected.js b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/nineth.expected.js index 8661d681bbb3e8..b2d000ea40311c 100644 --- a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/nineth.expected.js +++ b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/nineth.expected.js @@ -29,9 +29,9 @@ export default function Page() { return ( - + (

    -
    +
    ) ); } \ No newline at end of file diff --git a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/second.expected.js b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/second.expected.js index 30eb0ee2541889..0a5f0311b364c4 100644 --- a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/second.expected.js +++ b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/second.expected.js @@ -63,7 +63,7 @@ function AffiliatesHero() { return ( - + ( Affiliate Program @@ -85,7 +85,7 @@ function AffiliatesHero() { - + ) ); } diff --git a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/seventh.expected.js b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/seventh.expected.js index 2715106e6ff16a..2a9c9e35f18226 100644 --- a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/seventh.expected.js +++ b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/seventh.expected.js @@ -86,7 +86,7 @@ function Iframe(props) { }, []); return ( - + ( {loaded === false ? (
    @@ -109,7 +109,7 @@ function Iframe(props) { frameBorder="0" {...props} /> - + ) ); } diff --git a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/third.expected.js b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/third.expected.js index bd072a096a31d8..5525352eb6dfa0 100644 --- a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/third.expected.js +++ b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/third.expected.js @@ -27,10 +27,10 @@ const StyledCard = styled(Card)(( export const MyCard = ((props) => { const { } = props; return ( - + ( - + ) ); }); diff --git a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles.expected.tsx b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles.expected.tsx index 63e961a28eff28..3ac787c22c4308 100644 --- a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles.expected.tsx +++ b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles.expected.tsx @@ -19,7 +19,7 @@ const Root = styled('div')(( const MyComponent = (props) => { - return ; + return (); }; export default MyComponent; \ No newline at end of file diff --git a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles1.expected.tsx b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles1.expected.tsx index 31d6cef054510c..55073749924256 100644 --- a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles1.expected.tsx +++ b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles1.expected.tsx @@ -19,7 +19,7 @@ const Root = styled('div')(( const MyComponent = (props) => { const { } = props; - return ; + return (); }; export default (MyComponent); \ No newline at end of file diff --git a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles2.expected.tsx b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles2.expected.tsx index 7c5a2d26246fc7..6b84c2a5f090ad 100644 --- a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles2.expected.tsx +++ b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles2.expected.tsx @@ -15,7 +15,7 @@ const Root = styled('div')({ const MyComponent = (props) => { const { } = props; - return ; + return (); }; export default (MyComponent); \ No newline at end of file diff --git a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles3.expected.tsx b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles3.expected.tsx index d40f46b983f2ce..cbede67798b670 100644 --- a/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles3.expected.tsx +++ b/packages/mui-codemod/src/v5.0.0/jss-to-styled.test/withCreateStyles3.expected.tsx @@ -15,7 +15,7 @@ const Root = styled('div')({ const MyComponent = (props) => { - return ; + return (); }; export default MyComponent; \ No newline at end of file diff --git a/packages/mui-codemod/src/v5.0.0/jss-to-tss-react.test/expected-typescript-docs-example-params.tsx b/packages/mui-codemod/src/v5.0.0/jss-to-tss-react.test/expected-typescript-docs-example-params.tsx index 11951ce8c1a7c0..af3bb81e8b8343 100644 --- a/packages/mui-codemod/src/v5.0.0/jss-to-tss-react.test/expected-typescript-docs-example-params.tsx +++ b/packages/mui-codemod/src/v5.0.0/jss-to-tss-react.test/expected-typescript-docs-example-params.tsx @@ -1,12 +1,13 @@ import { makeStyles } from 'tss-react/mui'; const useStyles = makeStyles<{color: 'primary' | 'secondary', padding: number}, 'child' | 'small'>({name: 'App'})((theme, { color, padding }, classes) => ({ - root: { + root: ({ padding: padding, + [`&:hover .${classes.child}`]: { backgroundColor: theme.palette[color].main, } - }, + }), small: {}, child: { border: '1px solid black', @@ -28,7 +29,7 @@ function App({classes: classesProp}: {classes?: any}) { }); return ( -
    + (
    The Background take the primary theme color when the mouse hovers the parent.
    @@ -36,7 +37,7 @@ function App({classes: classesProp}: {classes?: any}) { The Background take the primary theme color when the mouse hovers the parent. I am smaller than the other child.
    -
    +
    ) ); } diff --git a/packages/mui-codemod/src/v5.0.0/jss-to-tss-react.test/expected-typescript-docs-example.tsx b/packages/mui-codemod/src/v5.0.0/jss-to-tss-react.test/expected-typescript-docs-example.tsx index b906d0c65b7665..495a6f1c8853a7 100644 --- a/packages/mui-codemod/src/v5.0.0/jss-to-tss-react.test/expected-typescript-docs-example.tsx +++ b/packages/mui-codemod/src/v5.0.0/jss-to-tss-react.test/expected-typescript-docs-example.tsx @@ -22,7 +22,7 @@ const useStyles = makeStyles()((theme, _params, classes function App() { const { classes, cx } = useStyles(); return ( -
    + (
    Background turns red when the mouse hovers over the parent.
    @@ -30,7 +30,7 @@ function App() { Background turns red when the mouse hovers over the parent. I am smaller than the other child.
    -
    + ) ); } diff --git a/packages/mui-codemod/src/v5.0.0/preset-safe.test/expected.js b/packages/mui-codemod/src/v5.0.0/preset-safe.test/expected.js index 511a87bcb82936..d65e32b346d5aa 100644 --- a/packages/mui-codemod/src/v5.0.0/preset-safe.test/expected.js +++ b/packages/mui-codemod/src/v5.0.0/preset-safe.test/expected.js @@ -87,7 +87,7 @@ const Header = () => { const classes = useStyles(); const { dark, setDark } = React.useContext(DarkContext); return ( - + ( 👋 Hello @@ -110,7 +110,7 @@ const Header = () => { onChange={(event, checked) => setDark(checked)} /> - + ) ); }; @@ -119,7 +119,7 @@ function App() { const handleClose = () => setOpen(false); const { setDark } = React.useContext(DarkContext); const classes = useStyles(); - return <> + return (<>
    @@ -173,7 +173,7 @@ function App() { - ; + ); } const withThemeProvider = (Component) => (props) => { @@ -188,7 +188,7 @@ const withThemeProvider = (Component) => (props) => { [dark], ); return ( - + ( @@ -196,7 +196,7 @@ const withThemeProvider = (Component) => (props) => { - + ) ); }; diff --git a/packages/mui-codemod/src/v5.0.0/styled-engine-provider.test/mui-theme-provider.expected.js b/packages/mui-codemod/src/v5.0.0/styled-engine-provider.test/mui-theme-provider.expected.js index 107f5814aa1f23..6826808eedbe0d 100644 --- a/packages/mui-codemod/src/v5.0.0/styled-engine-provider.test/mui-theme-provider.expected.js +++ b/packages/mui-codemod/src/v5.0.0/styled-engine-provider.test/mui-theme-provider.expected.js @@ -5,7 +5,7 @@ import Page from './pages'; const App = () => { return ( - + ( @@ -13,7 +13,7 @@ const App = () => { - + ) ); }; diff --git a/packages/mui-codemod/src/v5.0.0/styled-engine-provider.test/theme-provider.expected.js b/packages/mui-codemod/src/v5.0.0/styled-engine-provider.test/theme-provider.expected.js index ce27802818f1fc..b727b543d2728d 100644 --- a/packages/mui-codemod/src/v5.0.0/styled-engine-provider.test/theme-provider.expected.js +++ b/packages/mui-codemod/src/v5.0.0/styled-engine-provider.test/theme-provider.expected.js @@ -6,11 +6,11 @@ import Page from './pages'; const App = () => { return ( - + ( - + ) ); }; diff --git a/packages/mui-codemod/src/v5.0.0/theme-provider.test/core-import.expected.js b/packages/mui-codemod/src/v5.0.0/theme-provider.test/core-import.expected.js index 15925ec0af83d1..0f5322c1c02a6e 100644 --- a/packages/mui-codemod/src/v5.0.0/theme-provider.test/core-import.expected.js +++ b/packages/mui-codemod/src/v5.0.0/theme-provider.test/core-import.expected.js @@ -2,8 +2,8 @@ import { createTheme, ThemeProvider, Theme } from '@material-ui/core'; function App() { return ( - + (
    - + ) ); } diff --git a/packages/mui-codemod/src/v5.0.0/theme-provider.test/expected.js b/packages/mui-codemod/src/v5.0.0/theme-provider.test/expected.js index 21b87540236096..c90abfb69000d1 100644 --- a/packages/mui-codemod/src/v5.0.0/theme-provider.test/expected.js +++ b/packages/mui-codemod/src/v5.0.0/theme-provider.test/expected.js @@ -2,8 +2,8 @@ import { createTheme, ThemeProvider, Theme } from '@material-ui/core/styles'; function App() { return ( - + (
    - + ) ); } diff --git a/packages/mui-codemod/src/v5.0.0/variant-prop.test/expected.js b/packages/mui-codemod/src/v5.0.0/variant-prop.test/expected.js index e668c182c28d65..7b38552e579f7b 100644 --- a/packages/mui-codemod/src/v5.0.0/variant-prop.test/expected.js +++ b/packages/mui-codemod/src/v5.0.0/variant-prop.test/expected.js @@ -11,7 +11,7 @@ const Select2 = () => ; export default function TextFieldComponent(props) { return ( -
    + (
    @@ -33,10 +33,9 @@ export default function TextFieldComponent(props) { - -
    +
    ) ); } diff --git a/packages/mui-codemod/src/v6.0.0/styled/index.js b/packages/mui-codemod/src/v6.0.0/styled/index.js new file mode 100644 index 00000000000000..b848cbfe4e9d99 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/index.js @@ -0,0 +1 @@ +export { default } from './styled-v6'; diff --git a/packages/mui-codemod/src/v6.0.0/styled/styled-v6.js b/packages/mui-codemod/src/v6.0.0/styled/styled-v6.js new file mode 100644 index 00000000000000..269e75f07407df --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/styled-v6.js @@ -0,0 +1,101 @@ +import migrateToVariants from '../../util/migrateToVariants'; + +/** + * @param {import('jscodeshift').FileInfo} file + * @param {import('jscodeshift').API} api + */ +export default function styledV6(file, api, options) { + const j = api.jscodeshift; + const root = j(file.source); + const printOptions = options.printOptions; + + let shouldTransform = false; + + root.find(j.CallExpression).forEach((path) => { + const styles = []; + let args = []; + + // styled('div')(...arguments) + if ( + path.node.callee.type === 'Identifier' && + path.node.callee.name === 'styled' && + path.parentPath.node.type === 'CallExpression' + ) { + args = path.parentPath.node.arguments; + } + + // styled.div(...arguments) + if ( + path.node.callee.type === 'MemberExpression' && + path.node.callee.object.type === 'Identifier' && + path.node.callee.object.name === 'styled' + ) { + args = path.node.arguments; + } + + // 1. collecting styles that should be tranformed + args.forEach((arg) => { + if ( + arg.type === 'ArrowFunctionExpression' && + arg.params[0] && + arg.params[0].type === 'ObjectPattern' + ) { + styles.push(arg); + } + }); + + if (!shouldTransform && styles.length > 0) { + shouldTransform = true; + } + + migrateToVariants(j, styles); + + // Replace arrow function with object expression if the arg properties is empty + args.forEach((arg, index) => { + if ( + arg.type === 'ArrowFunctionExpression' && + arg.params[0] && + arg.params[0].type === 'ObjectPattern' && + arg.params[0].properties.length === 0 + ) { + if (arg.body.type === 'ObjectExpression') { + args[index] = arg.body; + } + if (arg.body.type === 'BlockStatement') { + const returnStatement = arg.body.body.find((item) => item.type === 'ReturnStatement'); + if (returnStatement) { + args[index] = returnStatement.argument; + } + } + } + }); + }); + + const transformed = root.toSource(printOptions); + + if (shouldTransform) { + // recast adds extra newlines that we don't want, https://github.com/facebook/jscodeshift/issues/249 + // need to remove them manually + const lines = []; + let isInStyled = false; + transformed.split('\n').forEach((line, index, array) => { + if (!isInStyled) { + lines.push(line); + } else if ( + line !== '' || + (line === '' && array[index + 1] && array[index + 1].includes('return')) + ) { + if (line.match(/^}\)+(\({}\)|\(\))?;?$/) || line.match(/^\);?$/)) { + isInStyled = false; + } + lines.push(line); + } + if (line.includes('styled.') || line.includes('styled(')) { + isInStyled = true; + } + }); + return lines.join('\n'); + } + + return transformed; +} diff --git a/packages/mui-codemod/src/v6.0.0/styled/styled-v6.test.js b/packages/mui-codemod/src/v6.0.0/styled/styled-v6.test.js new file mode 100644 index 00000000000000..7dee2d833d463f --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/styled-v6.test.js @@ -0,0 +1,181 @@ +import path from 'path'; +import { expect } from 'chai'; +import { jscodeshift } from '../../../testUtils'; +import transform from './styled-v6'; +import readFile from '../../util/readFile'; + +function read(fileName) { + return readFile(path.join(__dirname, fileName)); +} + +describe('@mui/codemod', () => { + describe('v6.0.0', () => { + describe('basic styled-v6', () => { + it('transforms props as needed', () => { + const actual = transform( + { source: read('./test-cases/BasicStyled.actual.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/BasicStyled.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform( + { source: read('./test-cases/BasicStyled.expected.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/BasicStyled.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + + describe('logical styled-v6', () => { + it('transforms props as needed', () => { + const actual = transform( + { source: read('./test-cases/LogicalStyled.actual.js') }, + { jscodeshift }, + { printOptions: { trailingComma: false } }, + ); + + const expected = read('./test-cases/LogicalStyled.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform( + { source: read('./test-cases/LogicalStyled.expected.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/LogicalStyled.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + + describe('nested spread styled-v6', () => { + it('transforms props as needed', () => { + const actual = transform( + { source: read('./test-cases/NestedSpread.actual.js') }, + { jscodeshift }, + { printOptions: { trailingComma: false } }, + ); + + const expected = read('./test-cases/NestedSpread.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform( + { source: read('./test-cases/NestedSpread.expected.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/NestedSpread.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + + describe('object map styled-v6', () => { + it('transforms props as needed', () => { + const actual = transform( + { source: read('./test-cases/ObjectMap.actual.js') }, + { jscodeshift }, + { printOptions: { trailingComma: false } }, + ); + + const expected = read('./test-cases/ObjectMap.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform( + { source: read('./test-cases/ObjectMap.expected.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/ObjectMap.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + + describe('conditional styled-v6', () => { + it('transforms props as needed', () => { + const actual = transform( + { source: read('./test-cases/ConditionalStyled.actual.js') }, + { jscodeshift }, + { printOptions: { trailingComma: false } }, + ); + + const expected = read('./test-cases/ConditionalStyled.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform( + { source: read('./test-cases/ConditionalStyled.expected.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/ConditionalStyled.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + + describe('theme palette mode styled-v6', () => { + it('transforms props as needed', () => { + const actual = transform( + { source: read('./test-cases/ThemePaletteMode.actual.js') }, + { jscodeshift }, + { printOptions: { trailingComma: false } }, + ); + + const expected = read('./test-cases/ThemePaletteMode.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform( + { source: read('./test-cases/ThemePaletteMode.expected.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/ThemePaletteMode.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + + describe('theme palette mode and variants styled-v6', () => { + it('transforms props as needed', () => { + const actual = transform( + { source: read('./test-cases/VariantAndModeStyled.actual.js') }, + { jscodeshift }, + { printOptions: { trailingComma: false } }, + ); + + const expected = read('./test-cases/VariantAndModeStyled.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform( + { source: read('./test-cases/VariantAndModeStyled.expected.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/VariantAndModeStyled.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + }); +}); diff --git a/packages/mui-codemod/src/v6.0.0/styled/test-cases/BasicStyled.actual.js b/packages/mui-codemod/src/v6.0.0/styled/test-cases/BasicStyled.actual.js new file mode 100644 index 00000000000000..a6d9713613d6c1 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/test-cases/BasicStyled.actual.js @@ -0,0 +1,84 @@ +const FormHelperTextRoot = styled('p')(({ theme, ownerState, disabled }) => ({ + color: (theme.vars || theme).palette.text.secondary, + ...theme.typography.caption, + textAlign: 'left', + [`&.${formHelperTextClasses.disabled}`]: { + color: (theme.vars || theme).palette.text.disabled, + }, + ...(ownerState.size === 'small' && { + marginTop: 4, + }), + ...(ownerState.size === 'small' && + ownerState.variant === 'contained' && { + marginTop: 6, + }), + ...(ownerState.size === 'small' && + ownerState.variant === 'contained' && + disabled && { + marginTop: 6, + }), + ...(ownerState.size !== 'small' && { + marginBottom: 4, + }), + ...(ownerState.size !== 'small' && + ownerState.variant !== 'contained' && + !disabled && { + marginBottom: 6, + }), + ...(ownerState.contained && { + marginLeft: 14, + marginRight: 14, + }), + ...(!ownerState.contained && { + marginTop: 14, + marginBottom: 14, + }), + ...(!!ownerState.disabled && { + opacity: 0.5, + }), +})); + +const Component = styled.div(({ theme, ownerState }) => ({ + ...theme.typography.caption, + ...(ownerState.size === 'small' && { + marginTop: (theme.vars || theme).spacing(1), + }), +})); + +const ImageListRoot = styled('ul')(({ ownerState }) => { + return { + display: 'grid', + overflowY: 'auto', + listStyle: 'none', + padding: 0, + // Add iOS momentum scrolling for iOS < 13.0 + WebkitOverflowScrolling: 'touch', + ...(ownerState.variant === 'masonry' && { + display: 'block', + }), + }; +}); + +const ImageListItemRoot = styled('li')(({ ownerState }) => ({ + display: 'block', + position: 'relative', + [`& .${imageListItemClasses.img}`]: { + objectFit: 'cover', + width: '100%', + height: '100%', + display: 'block', + ...(ownerState.variant === 'standard' && { + height: 'auto', + flexGrow: 1, + }), + '&:hover': { + '&[data-shape="circular"]': { + borderRadius: '50%', + ...(ownerState.variant === 'unique' && { + height: 'auto', + flexGrow: 1, + }), + }, + }, + }, +})); diff --git a/packages/mui-codemod/src/v6.0.0/styled/test-cases/BasicStyled.expected.js b/packages/mui-codemod/src/v6.0.0/styled/test-cases/BasicStyled.expected.js new file mode 100644 index 00000000000000..6024e33fe6b402 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/test-cases/BasicStyled.expected.js @@ -0,0 +1,160 @@ +const FormHelperTextRoot = styled('p')(({ + theme +}) => ({ + color: (theme.vars || theme).palette.text.secondary, + ...theme.typography.caption, + textAlign: 'left', + [`&.${formHelperTextClasses.disabled}`]: { + color: (theme.vars || theme).palette.text.disabled, + }, + variants: [{ + props: { + size: 'small' + }, + style: { + marginTop: 4, + } + }, { + props: { + variant: 'contained', + size: 'small' + }, + style: { + marginTop: 6, + } + }, { + props: ( + { + disabled, + ownerState + } + ) => ownerState.size === 'small' && + ownerState.variant === 'contained' && + disabled, + style: { + marginTop: 6, + } + }, { + props: ( + { + ownerState + } + ) => ownerState.size !== 'small', + style: { + marginBottom: 4, + } + }, { + props: ( + { + disabled, + ownerState + } + ) => ownerState.size !== 'small' && + ownerState.variant !== 'contained' && + !disabled, + style: { + marginBottom: 6, + } + }, { + props: ( + { + ownerState + } + ) => ownerState.contained, + style: { + marginLeft: 14, + marginRight: 14, + } + }, { + props: ( + { + ownerState + } + ) => !ownerState.contained, + style: { + marginTop: 14, + marginBottom: 14, + } + }, { + props: ( + { + ownerState + } + ) => !!ownerState.disabled, + style: { + opacity: 0.5, + } + }] +})); + +const Component = styled.div(({ + theme +}) => ({ + ...theme.typography.caption, + variants: [{ + props: { + size: 'small' + }, + style: { + marginTop: (theme.vars || theme).spacing(1), + } + }] +})); + +const ImageListRoot = styled('ul')({ + display: 'grid', + overflowY: 'auto', + listStyle: 'none', + padding: 0, + // Add iOS momentum scrolling for iOS < 13.0 + WebkitOverflowScrolling: 'touch', + variants: [{ + props: { + variant: 'masonry' + }, + style: { + display: 'block', + } + }] +}); + +const ImageListItemRoot = styled('li')(({ + display: 'block', + position: 'relative', + [`& .${imageListItemClasses.img}`]: { + objectFit: 'cover', + width: '100%', + height: '100%', + display: 'block', + '&:hover': { + '&[data-shape="circular"]': { + borderRadius: '50%' + }, + } + }, + variants: [{ + props: { + variant: 'standard' + }, + style: { + [`& .${imageListItemClasses.img}`]: { + height: 'auto', + flexGrow: 1, + } + } + }, { + props: { + variant: 'unique' + }, + style: { + [`& .${imageListItemClasses.img}`]: { + '&:hover': { + '&[data-shape="circular"]': { + height: 'auto', + flexGrow: 1, + } + } + } + } + }] +})); diff --git a/packages/mui-codemod/src/v6.0.0/styled/test-cases/ConditionalStyled.actual.js b/packages/mui-codemod/src/v6.0.0/styled/test-cases/ConditionalStyled.actual.js new file mode 100644 index 00000000000000..284ff75cbd4d8b --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/test-cases/ConditionalStyled.actual.js @@ -0,0 +1,152 @@ +const LinearProgressBar1 = styled('span', { + name: 'MuiLinearProgress', + slot: 'Bar1', + overridesResolver: (props, styles) => { + const { ownerState } = props; + + return [ + styles.bar, + styles[`barColor${capitalize(ownerState.color)}`], + (ownerState.variant === 'indeterminate' || ownerState.variant === 'query') && + styles.bar1Indeterminate, + ownerState.variant === 'determinate' && styles.bar1Determinate, + ownerState.variant === 'buffer' && styles.bar1Buffer, + ]; + }, +})(({ ownerState, theme }) => ({ + ...(ownerState.variant === 'buffer' && { + backgroundColor: + ownerState.color !== 'normal' + ? 'currentColor' + : (theme.vars || theme).palette[ownerState.color].light, + '&:hover': { + ...(ownerState.color !== 'inherit' + ? { + backgroundColor: (theme.vars || theme).palette[ownerState.color].dark, + } + : { + backgroundColor: 'currentColor', + }), + }, + }), + ...(ownerState.variant !== 'buffer' && { + backgroundColor: + ownerState.color === 'inherit' + ? 'currentColor' + : (theme.vars || theme).palette[ownerState.color].main, + }), +})); + +const ExpandMore = styled((props) => { + const { expand, ...other } = props; + return ; +})(({ theme, expand }) => ({ + transform: !expand ? 'rotate(0deg)' : 'rotate(180deg)', + marginLeft: 'auto', + transition: theme.transitions.create('transform', { + duration: theme.transitions.duration.shortest, + }), +})); + +const Main = styled('main', { + shouldForwardProp: (prop) => prop !== 'disableToc', +})(({ disableToc, theme }) => ({ + minHeight: '100vh', + display: 'grid', + width: '100%', + ...(disableToc + ? { + [theme.breakpoints.up('md')]: { + marginRight: TOC_WIDTH / 2, + }, + } + : { + [theme.breakpoints.up('md')]: { + gridTemplateColumns: `1fr ${TOC_WIDTH}px`, + }, + }), + '& .markdown-body .comment-link': { + display: 'flex', + }, +})); + +const StyledAppContainer = styled(AppContainer, { + shouldForwardProp: (prop) => prop !== 'disableAd' && prop !== 'hasTabs' && prop !== 'disableToc', +})(({ disableAd, hasTabs, disableToc, theme }) => { + return { + position: 'relative', + // By default, a grid item cannot be smaller than the size of its content. + // https://stackoverflow.com/questions/43311943/prevent-content-from-expanding-grid-items + minWidth: 0, + ...(disableToc + ? { + // 105ch ≈ 930px + maxWidth: `calc(105ch + ${TOC_WIDTH / 2}px)`, + } + : { + // We're mostly hosting text content so max-width by px does not make sense considering font-size is system-adjustable. + fontFamily: 'Arial', + // 105ch ≈ 930px + maxWidth: '105ch', + }), + ...(!disableAd && { + ...(hasTabs + ? { + '&& .component-tabs .MuiTabs-root': { + // 40px matches MarkdownElement h2 margin-top. + marginBottom: `calc(${theme.spacing(AD_MARGIN_TOP)} + ${AD_HEIGHT_MOBILE}px + 40px)`, + [theme.breakpoints.up('sm')]: { + marginBottom: `calc(${theme.spacing(AD_MARGIN_TOP)} + ${AD_HEIGHT}px + 40px)`, + }, + }, + '&& .component-tabs.ad .MuiTabs-root': { + marginBottom: 0, + }, + } + : { + '&& .description': { + marginBottom: theme.spacing(AD_MARGIN_BOTTOM), + paddingBottom: `calc(${theme.spacing(AD_MARGIN_TOP)} + ${AD_HEIGHT_MOBILE}px)`, + [theme.breakpoints.up('sm')]: { + paddingBottom: `calc(${theme.spacing(AD_MARGIN_TOP)} + ${AD_HEIGHT}px)`, + }, + }, + '&& .description.ad': { + paddingBottom: 0, + marginBottom: 0, + }, + }), + }), + [theme.breakpoints.up('lg')]: { + paddingLeft: '60px', + paddingRight: '60px', + }, + }; +}); + +const DialogContentRoot = styled('div', { + name: 'MuiDialogContent', + slot: 'Root', + overridesResolver: (props, styles) => { + const { ownerState } = props; + + return [styles.root, ownerState.dividers && styles.dividers]; + }, +})(({ theme, ownerState }) => ({ + flex: '1 1 auto', + // Add iOS momentum scrolling for iOS < 13.0 + WebkitOverflowScrolling: 'touch', + overflowY: 'auto', + padding: '20px 24px', + ...(ownerState.dividers + ? { + padding: '16px 24px', + borderTop: `1px solid ${(theme.vars || theme).palette.divider}`, + borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, + } + : { + [`.${dialogTitleClasses.root} + &`]: { + paddingTop: 0, + }, + }), +})); diff --git a/packages/mui-codemod/src/v6.0.0/styled/test-cases/ConditionalStyled.expected.js b/packages/mui-codemod/src/v6.0.0/styled/test-cases/ConditionalStyled.expected.js new file mode 100644 index 00000000000000..94648e44467afd --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/test-cases/ConditionalStyled.expected.js @@ -0,0 +1,273 @@ +const LinearProgressBar1 = styled('span', { + name: 'MuiLinearProgress', + slot: 'Bar1', + overridesResolver: (props, styles) => { + const { ownerState } = props; + + return [ + styles.bar, + styles[`barColor${capitalize(ownerState.color)}`], + (ownerState.variant === 'indeterminate' || ownerState.variant === 'query') && + styles.bar1Indeterminate, + ownerState.variant === 'determinate' && styles.bar1Determinate, + ownerState.variant === 'buffer' && styles.bar1Buffer, + ]; + }, +})(({ + theme +}) => ({ + variants: [{ + props: { + variant: 'buffer' + }, + style: { + '&:hover': {} + } + }, { + props: ( + { + variant, + ownerState + } + ) => variant === 'buffer' && ownerState.color !== 'normal', + style: { + backgroundColor: 'currentColor' + } + }, { + props: { + variant: 'buffer', + color: 'normal' + }, + style: { + backgroundColor: (theme.vars || theme).palette[ownerState.color].light + } + }, { + props: ( + { + variant, + ownerState + } + ) => variant === 'buffer' && ownerState.color !== 'inherit', + style: { + '&:hover': { + backgroundColor: (theme.vars || theme).palette[ownerState.color].dark, + } + } + }, { + props: { + variant: 'buffer', + color: 'inherit' + }, + style: { + '&:hover': { + backgroundColor: 'currentColor', + } + } + }, { + props: ( + { + ownerState, + color + } + ) => ownerState.variant !== 'buffer' && color === 'inherit', + style: { + backgroundColor: 'currentColor' + } + }, { + props: ( + { + ownerState + } + ) => ownerState.variant !== 'buffer' && ownerState.color !== 'inherit', + style: { + backgroundColor: (theme.vars || theme).palette[ownerState.color].main + } + }] +})); + +const ExpandMore = styled((props) => { + const { expand, ...other } = props; + return ; +})(({ + theme +}) => ({ + marginLeft: 'auto', + transition: theme.transitions.create('transform', { + duration: theme.transitions.duration.shortest, + }), + variants: [{ + props: ( + { + expand + } + ) => !expand, + style: { + transform: 'rotate(0deg)' + } + }, { + props: ( + { + expand + } + ) => !!expand, + style: { + transform: 'rotate(180deg)' + } + }], +})); + +const Main = styled('main', { + shouldForwardProp: (prop) => prop !== 'disableToc', +})(({ + theme +}) => ({ + minHeight: '100vh', + display: 'grid', + width: '100%', + '& .markdown-body .comment-link': { + display: 'flex', + }, + variants: [{ + props: ( + { + disableToc + } + ) => disableToc, + style: { + [theme.breakpoints.up('md')]: { + marginRight: TOC_WIDTH / 2, + }, + } + }, { + props: ( + { + disableToc + } + ) => !disableToc, + style: { + [theme.breakpoints.up('md')]: { + gridTemplateColumns: `1fr ${TOC_WIDTH}px`, + }, + } + }] +})); + +const StyledAppContainer = styled(AppContainer, { + shouldForwardProp: (prop) => prop !== 'disableAd' && prop !== 'hasTabs' && prop !== 'disableToc', +})(({ + theme +}) => { + return { + position: 'relative', + // By default, a grid item cannot be smaller than the size of its content. + // https://stackoverflow.com/questions/43311943/prevent-content-from-expanding-grid-items + minWidth: 0, + [theme.breakpoints.up('lg')]: { + paddingLeft: '60px', + paddingRight: '60px', + }, + variants: [{ + props: ( + { + disableToc + } + ) => disableToc, + style: { + // 105ch ≈ 930px + maxWidth: `calc(105ch + ${TOC_WIDTH / 2}px)`, + } + }, { + props: ( + { + disableToc + } + ) => !disableToc, + style: { + // We're mostly hosting text content so max-width by px does not make sense considering font-size is system-adjustable. + fontFamily: 'Arial', + // 105ch ≈ 930px + maxWidth: '105ch', + } + }, { + props: ( + { + disableAd, + hasTabs + } + ) => !disableAd && hasTabs, + style: { + '&& .component-tabs .MuiTabs-root': { + // 40px matches MarkdownElement h2 margin-top. + marginBottom: `calc(${theme.spacing(AD_MARGIN_TOP)} + ${AD_HEIGHT_MOBILE}px + 40px)`, + [theme.breakpoints.up('sm')]: { + marginBottom: `calc(${theme.spacing(AD_MARGIN_TOP)} + ${AD_HEIGHT}px + 40px)`, + }, + }, + '&& .component-tabs.ad .MuiTabs-root': { + marginBottom: 0, + }, + } + }, { + props: ( + { + disableAd, + hasTabs + } + ) => !disableAd && !hasTabs, + style: { + '&& .description': { + marginBottom: theme.spacing(AD_MARGIN_BOTTOM), + paddingBottom: `calc(${theme.spacing(AD_MARGIN_TOP)} + ${AD_HEIGHT_MOBILE}px)`, + [theme.breakpoints.up('sm')]: { + paddingBottom: `calc(${theme.spacing(AD_MARGIN_TOP)} + ${AD_HEIGHT}px)`, + }, + }, + '&& .description.ad': { + paddingBottom: 0, + marginBottom: 0, + }, + } + }] + }; +}); + +const DialogContentRoot = styled('div', { + name: 'MuiDialogContent', + slot: 'Root', + overridesResolver: (props, styles) => { + const { ownerState } = props; + + return [styles.root, ownerState.dividers && styles.dividers]; + }, +})(({ + theme +}) => ({ + flex: '1 1 auto', + // Add iOS momentum scrolling for iOS < 13.0 + WebkitOverflowScrolling: 'touch', + overflowY: 'auto', + padding: '20px 24px', + variants: [{ + props: ( + { + ownerState + } + ) => ownerState.dividers, + style: { + padding: '16px 24px', + borderTop: `1px solid ${(theme.vars || theme).palette.divider}`, + borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, + } + }, { + props: ( + { + ownerState + } + ) => !ownerState.dividers, + style: { + [`.${dialogTitleClasses.root} + &`]: { + paddingTop: 0, + }, + } + }] +})); diff --git a/packages/mui-codemod/src/v6.0.0/styled/test-cases/LogicalStyled.actual.js b/packages/mui-codemod/src/v6.0.0/styled/test-cases/LogicalStyled.actual.js new file mode 100644 index 00000000000000..1c19e8f6cfcbd6 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/test-cases/LogicalStyled.actual.js @@ -0,0 +1,17 @@ +const ToolbarRoot = styled('div', { + name: 'MuiToolbar', + slot: 'Root', + overridesResolver: (props, styles) => { + const { ownerState } = props; + + return [styles.root, !ownerState.disableGutters && styles.gutters, styles[ownerState.variant]]; + }, +})( + ({ theme, ownerState }) => ownerState.variant === 'regular' && theme.mixins.toolbar, + ({ theme, ownerState }) => ownerState.variant !== 'regular' && theme.mixins.toolbar2, + ({ theme, ownerState, disabled }) => + ownerState.variant === 'regular' && disabled && theme.mixins.toolbar3, + ({ theme, ownerState, disabled }) => + ownerState.variant !== 'regular' && !disabled && theme.mixins.toolbar4, + ({ theme }) => theme.vars && theme.mixins.toolbar5, +); diff --git a/packages/mui-codemod/src/v6.0.0/styled/test-cases/LogicalStyled.expected.js b/packages/mui-codemod/src/v6.0.0/styled/test-cases/LogicalStyled.expected.js new file mode 100644 index 00000000000000..f5f59ecd6d0be0 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/test-cases/LogicalStyled.expected.js @@ -0,0 +1,61 @@ +const ToolbarRoot = styled('div', { + name: 'MuiToolbar', + slot: 'Root', + overridesResolver: (props, styles) => { + const { ownerState } = props; + + return [styles.root, !ownerState.disableGutters && styles.gutters, styles[ownerState.variant]]; + }, +})( + ({ + theme + }) => ({ + variants: [{ + props: { + variant: 'regular' + }, + style: theme.mixins.toolbar + }] + }), + ({ + theme + }) => ({ + variants: [{ + props: ( + { + ownerState + } + ) => ownerState.variant !== 'regular', + style: theme.mixins.toolbar2 + }] + }), + ({ + theme + }) => + ({ + variants: [{ + props: ( + { + disabled, + ownerState + } + ) => ownerState.variant === 'regular' && disabled, + style: theme.mixins.toolbar3 + }] + }), + ({ + theme + }) => + ({ + variants: [{ + props: ( + { + disabled, + ownerState + } + ) => ownerState.variant !== 'regular' && !disabled, + style: theme.mixins.toolbar4 + }] + }), + ({ theme }) => theme.vars && theme.mixins.toolbar5, +); diff --git a/packages/mui-codemod/src/v6.0.0/styled/test-cases/NestedSpread.actual.js b/packages/mui-codemod/src/v6.0.0/styled/test-cases/NestedSpread.actual.js new file mode 100644 index 00000000000000..7b8c87c9cdb595 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/test-cases/NestedSpread.actual.js @@ -0,0 +1,46 @@ +const Component = styled('div')(({ theme, ownerState }) => { + const palette = (theme.vars || theme).palette?.[ownerState.color]; + return { + overflow: 'visible', // Explicitly set the default value to solve a bug on IE11. + color: (theme.vars || theme).palette.action.active, + transition: theme.transitions.create('background-color', { + duration: theme.transitions.duration.shortest, + }), + ...(!ownerState.disableRipple && { + '&:hover': { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.action.activeChannel} / ${theme.vars.palette.action.hoverOpacity})` + : alpha(theme.palette.action.active, theme.palette.action.hoverOpacity), + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: 'transparent', + }, + }, + }), + ...(ownerState.edge === 'start' && { + marginLeft: ownerState.size === 'small' ? -3 : -12, + }), + ...(ownerState.edge === 'end' && { + marginRight: ownerState.size === 'small' ? -3 : -12, + }), + ...(ownerState.color !== 'inherit' && + ownerState.color !== 'default' && { + color: palette?.main, + ...(!ownerState.disableRipple && { + '&:hover': { + // The codemod won't handle this case when the variable is not declared in the style argument. + // In this case, the `palette` create a new variable in the style argument. + ...(palette && { + backgroundColor: theme.vars + ? `rgba(${palette.mainChannel} / ${theme.vars.palette.action.hoverOpacity})` + : alpha(palette.main, theme.palette.action.hoverOpacity), + }), + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: 'transparent', + }, + }, + }), + }), + }; +}); diff --git a/packages/mui-codemod/src/v6.0.0/styled/test-cases/NestedSpread.expected.js b/packages/mui-codemod/src/v6.0.0/styled/test-cases/NestedSpread.expected.js new file mode 100644 index 00000000000000..36aec722aa4883 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/test-cases/NestedSpread.expected.js @@ -0,0 +1,99 @@ +const Component = styled('div')(({ + theme +}) => { + const palette = (theme.vars || theme).palette?.[ownerState.color]; + return { + // Explicitly set the default value to solve a bug on IE11. + overflow: 'visible', + color: (theme.vars || theme).palette.action.active, + transition: theme.transitions.create('background-color', { + duration: theme.transitions.duration.shortest, + }), + variants: [{ + props: ( + { + ownerState + } + ) => !ownerState.disableRipple, + style: { + '&:hover': { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.action.activeChannel} / ${theme.vars.palette.action.hoverOpacity})` + : alpha(theme.palette.action.active, theme.palette.action.hoverOpacity), + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: 'transparent', + }, + }, + } + }, { + props: { + edge: 'start', + size: 'small' + }, + style: { + marginLeft: -3 + } + }, { + props: ( + { + edge, + ownerState + } + ) => edge === 'start' && ownerState.size !== 'small', + style: { + marginLeft: -12 + } + }, { + props: { + edge: 'end', + size: 'small' + }, + style: { + marginRight: -3 + } + }, { + props: ( + { + edge, + ownerState + } + ) => edge === 'end' && ownerState.size !== 'small', + style: { + marginRight: -12 + } + }, { + props: ( + { + ownerState + } + ) => ownerState.color !== 'inherit' && + ownerState.color !== 'default', + style: { + color: palette?.main + } + }, { + props: ( + { + ownerState + } + ) => ownerState.color !== 'inherit' && + ownerState.color !== 'default' && !ownerState.disableRipple, + style: { + '&:hover': { + // The codemod won't handle this case when the variable is not declared in the style argument. + // In this case, the `palette` create a new variable in the style argument. + ...(palette && { + backgroundColor: theme.vars + ? `rgba(${palette.mainChannel} / ${theme.vars.palette.action.hoverOpacity})` + : alpha(palette.main, theme.palette.action.hoverOpacity), + }), + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: 'transparent', + }, + }, + } + }] + }; +}); diff --git a/packages/mui-codemod/src/v6.0.0/styled/test-cases/ObjectMap.actual.js b/packages/mui-codemod/src/v6.0.0/styled/test-cases/ObjectMap.actual.js new file mode 100644 index 00000000000000..2460dfd28078e7 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/test-cases/ObjectMap.actual.js @@ -0,0 +1,29 @@ +const IconRoot = styled('span')(({ theme, ownerState }) => ({ + userSelect: 'none', + width: '1em', + height: '1em', + // Chrome fix for https://bugs.chromium.org/p/chromium/issues/detail?id=820541 + // To remove at some point. + overflow: 'hidden', + display: 'inline-block', // allow overflow hidden to take action + textAlign: 'center', // support non-square icon + flexShrink: 0, + fontSize: { + inherit: 'inherit', + small: theme.typography.pxToRem(20), + medium: theme.typography.pxToRem(24), + large: theme.typography.pxToRem(36), + }[ownerState.fontSize], + // TODO v5 deprecate, v6 remove for sx + color: { + primary: (theme.vars || theme).palette.primary.main, + secondary: (theme.vars || theme).palette.secondary.main, + info: (theme.vars || theme).palette.info.main, + success: (theme.vars || theme).palette.success.main, + warning: (theme.vars || theme).palette.warning.main, + action: (theme.vars || theme).palette.action.active, + error: (theme.vars || theme).palette.error.main, + disabled: (theme.vars || theme).palette.action.disabled, + inherit: undefined, + }[ownerState.color], +})); diff --git a/packages/mui-codemod/src/v6.0.0/styled/test-cases/ObjectMap.expected.js b/packages/mui-codemod/src/v6.0.0/styled/test-cases/ObjectMap.expected.js new file mode 100644 index 00000000000000..e4e787da2443ff --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/test-cases/ObjectMap.expected.js @@ -0,0 +1,107 @@ +const IconRoot = styled('span')(({ + theme +}) => ({ + userSelect: 'none', + width: '1em', + height: '1em', + // Chrome fix for https://bugs.chromium.org/p/chromium/issues/detail?id=820541 + // To remove at some point. + overflow: 'hidden', + // allow overflow hidden to take action + display: 'inline-block', + // support non-square icon + textAlign: 'center', + flexShrink: 0, + variants: [{ + props: { + fontSize: "inherit" + }, + style: { + fontSize: 'inherit' + } + }, { + props: { + fontSize: "small" + }, + style: { + fontSize: theme.typography.pxToRem(20) + } + }, { + props: { + fontSize: "medium" + }, + style: { + fontSize: theme.typography.pxToRem(24) + } + }, { + props: { + fontSize: "large" + }, + style: { + fontSize: theme.typography.pxToRem(36) + } + }, { + props: { + color: "primary" + }, + style: { + color: (theme.vars || theme).palette.primary.main + } + }, { + props: { + color: "secondary" + }, + style: { + color: (theme.vars || theme).palette.secondary.main + } + }, { + props: { + color: "info" + }, + style: { + color: (theme.vars || theme).palette.info.main + } + }, { + props: { + color: "success" + }, + style: { + color: (theme.vars || theme).palette.success.main + } + }, { + props: { + color: "warning" + }, + style: { + color: (theme.vars || theme).palette.warning.main + } + }, { + props: { + color: "action" + }, + style: { + color: (theme.vars || theme).palette.action.active + } + }, { + props: { + color: "error" + }, + style: { + color: (theme.vars || theme).palette.error.main + } + }, { + props: { + color: "disabled" + }, + style: { + color: (theme.vars || theme).palette.action.disabled + } + }, { + props: { + color: "inherit" + }, + style: { + color: undefined + } + }] +})); diff --git a/packages/mui-codemod/src/v6.0.0/styled/test-cases/ThemePaletteMode.actual.js b/packages/mui-codemod/src/v6.0.0/styled/test-cases/ThemePaletteMode.actual.js new file mode 100644 index 00000000000000..14f35faf74a0ef --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/test-cases/ThemePaletteMode.actual.js @@ -0,0 +1,58 @@ +const Test = styled('div')(({ theme }) => ({ + color: theme.palette.mode === 'dark' ? theme.palette.primary.light : theme.palette.primary.main, + background: `linear-gradient(45deg, ${theme.palette.mode === 'dark' ? theme.palette.primary[400] : theme.palette.primary[600]} 30%, ${theme.palette.mode === 'dark' ? theme.palette.primary[200] : theme.palette.primary[500]} 90%})`, +})); + +const StyledPopper = styled(Popper)(({ theme }) => ({ + border: `1px solid ${theme.palette.mode === 'light' ? '#e1e4e8' : '#30363d'}`, + boxShadow: `0 8px 24px ${ + theme.palette.mode === 'light' ? 'rgba(149, 157, 165, 0.2)' : 'rgb(1, 4, 9)' + }`, + borderRadius: 6, + width: 300, + zIndex: theme.zIndex.modal, + fontSize: 13, + color: theme.palette.mode === 'light' ? '#24292e' : '#c9d1d9', + backgroundColor: theme.palette.mode === 'light' ? '#fff' : '#1c2128', +})); + +const AntSwitch = styled(Switch)(({ theme }) => ({ + width: 28, + height: 16, + padding: 0, + display: 'flex', + '&:active': { + '& .MuiSwitch-thumb': { + width: 15, + }, + '& .MuiSwitch-switchBase.Mui-checked': { + transform: 'translateX(9px)', + }, + }, + '& .MuiSwitch-switchBase': { + padding: 2, + '&.Mui-checked': { + transform: 'translateX(12px)', + color: '#fff', + '& + .MuiSwitch-track': { + opacity: 1, + backgroundColor: theme.palette.mode === 'dark' ? '#177ddc' : '#1890ff', + }, + }, + }, + '& .MuiSwitch-thumb': { + boxShadow: '0 2px 4px 0 rgb(0 35 11 / 20%)', + width: 12, + height: 12, + borderRadius: 6, + transition: theme.transitions.create(['width'], { + duration: 200, + }), + }, + '& .MuiSwitch-track': { + borderRadius: 16 / 2, + opacity: 1, + backgroundColor: theme.palette.mode === 'dark' ? 'rgba(255,255,255,.35)' : 'rgba(0,0,0,.25)', + boxSizing: 'border-box', + }, +})); diff --git a/packages/mui-codemod/src/v6.0.0/styled/test-cases/ThemePaletteMode.expected.js b/packages/mui-codemod/src/v6.0.0/styled/test-cases/ThemePaletteMode.expected.js new file mode 100644 index 00000000000000..1e852ec767882c --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/test-cases/ThemePaletteMode.expected.js @@ -0,0 +1,74 @@ +const Test = styled('div')(({ theme }) => ({ + color: theme.palette.primary.main, + background: `linear-gradient(45deg, ${theme.palette.primary[600]} 30%, ${theme.palette.primary[500]} 90%})`, + ...theme.applyStyles("dark", { + color: theme.palette.primary.light, + background: `linear-gradient(45deg, ${theme.palette.primary[400]} 30%, ${theme.palette.primary[200]} 90%})` + }) +})); + +const StyledPopper = styled(Popper)(({ theme }) => ({ + border: `1px solid ${'#30363d'}`, + boxShadow: `0 8px 24px ${ + 'rgb(1, 4, 9)' + }`, + borderRadius: 6, + width: 300, + zIndex: theme.zIndex.modal, + fontSize: 13, + color: '#c9d1d9', + backgroundColor: '#1c2128', + ...theme.applyStyles("light", { + border: `1px solid ${'#e1e4e8'}`, + boxShadow: `0 8px 24px ${'rgba(149, 157, 165, 0.2)'}`, + color: '#24292e', + backgroundColor: '#fff' + }) +})); + +const AntSwitch = styled(Switch)(({ theme }) => ({ + width: 28, + height: 16, + padding: 0, + display: 'flex', + '&:active': { + '& .MuiSwitch-thumb': { + width: 15, + }, + '& .MuiSwitch-switchBase.Mui-checked': { + transform: 'translateX(9px)', + }, + }, + '& .MuiSwitch-switchBase': { + padding: 2, + '&.Mui-checked': { + transform: 'translateX(12px)', + color: '#fff', + '& + .MuiSwitch-track': { + opacity: 1, + backgroundColor: '#1890ff', + ...theme.applyStyles("dark", { + backgroundColor: '#177ddc' + }) + }, + }, + }, + '& .MuiSwitch-thumb': { + boxShadow: '0 2px 4px 0 rgb(0 35 11 / 20%)', + width: 12, + height: 12, + borderRadius: 6, + transition: theme.transitions.create(['width'], { + duration: 200, + }), + }, + '& .MuiSwitch-track': { + borderRadius: 16 / 2, + opacity: 1, + backgroundColor: 'rgba(0,0,0,.25)', + boxSizing: 'border-box', + ...theme.applyStyles("dark", { + backgroundColor: 'rgba(255,255,255,.35)' + }) + }, +})); diff --git a/packages/mui-codemod/src/v6.0.0/styled/test-cases/VariantAndModeStyled.actual.js b/packages/mui-codemod/src/v6.0.0/styled/test-cases/VariantAndModeStyled.actual.js new file mode 100644 index 00000000000000..de31de9a2d874e --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/test-cases/VariantAndModeStyled.actual.js @@ -0,0 +1,7 @@ +const Component = styled.div(({ theme, ownerState }) => ({ + ...theme.typography.caption, + ...(ownerState.size === 'small' && { + marginTop: (theme.vars || theme).spacing(1), + color: theme.palette.mode === 'dark' ? theme.palette.primary.light : theme.palette.primary.main, + }), +})); diff --git a/packages/mui-codemod/src/v6.0.0/styled/test-cases/VariantAndModeStyled.expected.js b/packages/mui-codemod/src/v6.0.0/styled/test-cases/VariantAndModeStyled.expected.js new file mode 100644 index 00000000000000..52780f9917f951 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/styled/test-cases/VariantAndModeStyled.expected.js @@ -0,0 +1,17 @@ +const Component = styled.div(({ + theme +}) => ({ + ...theme.typography.caption, + variants: [{ + props: { + size: 'small' + }, + style: { + marginTop: (theme.vars || theme).spacing(1), + color: theme.palette.primary.main, + ...theme.applyStyles("dark", { + color: theme.palette.primary.light + }) + } + }] +})); diff --git a/packages/mui-codemod/src/v6.0.0/theme-v6/index.js b/packages/mui-codemod/src/v6.0.0/theme-v6/index.js new file mode 100644 index 00000000000000..109bf88c72774c --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/theme-v6/index.js @@ -0,0 +1 @@ +export { default } from './theme-v6'; diff --git a/packages/mui-codemod/src/v6.0.0/theme-v6/test-cases/basicTheme.actual.js b/packages/mui-codemod/src/v6.0.0/theme-v6/test-cases/basicTheme.actual.js new file mode 100644 index 00000000000000..05d986c8e991e3 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/theme-v6/test-cases/basicTheme.actual.js @@ -0,0 +1,513 @@ +export default function getCheckoutTheme(mode) { + return { + ...getDesignTokens(mode), + components: { + MuiAlert: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: 10, + backgroundColor: orange[100], + color: theme.palette.text.primary, + border: `1px solid ${alpha(orange[300], 0.5)}`, + '& .MuiAlert-icon': { + color: orange[500], + }, + ...(theme.palette.mode === 'dark' && { + backgroundColor: `${alpha(orange[900], 0.5)}`, + border: `1px solid ${alpha(orange[800], 0.5)}`, + }), + }), + }, + }, + MuiButtonBase: { + defaultProps: { + disableTouchRipple: true, + disableRipple: true, + }, + styleOverrides: { + root: { + boxSizing: 'border-box', + transition: 'all 100ms ease', + '&:focus-visible': { + outline: `3px solid ${alpha(brand[400], 0.5)}`, + outlineOffset: '2px', + }, + }, + }, + }, + MuiButton: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + boxShadow: 'none', + borderRadius: theme.shape.borderRadius, + textTransform: 'none', + ...(ownerState.size === 'small' && { + height: '2rem', // 32px + padding: '0 0.5rem', + }), + ...(ownerState.size === 'medium' && { + height: '2.5rem', // 40px + }), + ...(ownerState.variant === 'contained' && + ownerState.color === 'primary' && { + color: 'white', + backgroundColor: brand[300], + backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, + boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, + border: `1px solid ${brand[500]}`, + '&:hover': { + backgroundColor: brand[700], + boxShadow: 'none', + }, + '&:active': { + backgroundColor: brand[700], + boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + }, + }), + ...(ownerState.variant === 'outlined' && { + color: brand[700], + backgroundColor: alpha(brand[300], 0.1), + borderColor: alpha(brand[200], 0.8), + boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, + '&:hover': { + backgroundColor: alpha(brand[300], 0.2), + borderColor: alpha(brand[300], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[300], 0.3), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, + backgroundImage: 'none', + }, + }), + ...(ownerState.variant === 'outlined' && + ownerState.color === 'secondary' && { + backgroundColor: alpha(gray[300], 0.1), + borderColor: alpha(gray[300], 0.5), + color: gray[700], + '&:hover': { + backgroundColor: alpha(gray[300], 0.3), + borderColor: alpha(gray[300], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(gray[300], 0.4), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, + backgroundImage: 'none', + }, + }), + ...(ownerState.variant === 'text' && + ownerState.color === 'primary' && { + color: brand[700], + '&:hover': { + backgroundColor: alpha(brand[300], 0.3), + }, + }), + ...(ownerState.variant === 'text' && + ownerState.color === 'info' && { + color: gray[700], + '&:hover': { + backgroundColor: alpha(gray[300], 0.3), + }, + }), + ...(theme.palette.mode === 'dark' && { + ...(ownerState.variant === 'outlined' && { + color: brand[200], + backgroundColor: alpha(brand[600], 0.1), + borderColor: alpha(brand[600], 0.6), + boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(brand[700], 0.2), + borderColor: alpha(brand[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + ...(ownerState.variant === 'text' && + ownerState.color === 'info' && { + color: gray[200], + '&:hover': { + backgroundColor: alpha(gray[700], 0.3), + }, + }), + ...(ownerState.variant === 'outlined' && + ownerState.color === 'secondary' && { + color: gray[300], + backgroundColor: alpha(gray[600], 0.1), + borderColor: alpha(gray[700], 0.5), + boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(gray[700], 0.2), + borderColor: alpha(gray[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(gray[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundImage: 'none', + }, + }), + ...(ownerState.variant === 'text' && + ownerState.color === 'primary' && { + color: brand[200], + '&:hover': { + backgroundColor: alpha(brand[700], 0.3), + }, + }), + }), + }), + }, + }, + MuiCard: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + transition: 'all 100ms ease', + backgroundColor: gray[50], + borderRadius: theme.shape.borderRadius, + border: `1px solid ${alpha(gray[200], 0.5)}`, + boxShadow: 'none', + ...(ownerState.variant === 'outlined' && { + border: `1px solid ${gray[200]}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, + }), + ...(theme.palette.mode === 'dark' && { + backgroundColor: alpha(gray[800], 0.6), + border: `1px solid ${alpha(gray[700], 0.3)}`, + ...(ownerState.variant === 'outlined' && { + border: `1px solid ${alpha(gray[700], 0.4)}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, ${gray[900]}, ${alpha(gray[800], 0.5)})`, + }), + }), + }), + }, + }, + MuiCheckbox: { + defaultProps: { + disableRipple: true, + icon: , + checkedIcon: , + }, + styleOverrides: { + root: ({ theme }) => ({ + margin: 10, + height: 16, + width: 16, + borderRadius: 5, + border: '1px solid ', + borderColor: alpha(gray[300], 0.8), + boxShadow: '0 0 0 1.5px hsla(210, 0%, 0%, 0.04) inset', + transition: 'border-color 120ms ease-in', + backgroundColor: alpha(gray[100], 0.4), + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focusVisible': { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '2px', + borderColor: brand[400], + }, + '&.Mui-checked': { + color: 'white', + backgroundColor: brand[500], + borderColor: brand[500], + boxShadow: `none`, + '&:hover': { + backgroundColor: brand[600], + }, + }, + ...(theme.palette.mode === 'dark' && { + borderColor: alpha(gray[700], 0.5), + boxShadow: '0 0 0 1.5px hsl(210, 0%, 0%) inset', + backgroundColor: alpha(gray[900], 0.8), + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focusVisible': { + borderColor: brand[400], + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '2px', + }, + }), + }), + }, + }, + MuiDivider: { + styleOverrides: { + root: ({ theme }) => ({ + borderColor: `${alpha(gray[200], 0.8)}`, + ...(theme.palette.mode === 'dark' && { + borderColor: `${alpha(gray[700], 0.4)}`, + }), + }), + }, + }, + MuiFormLabel: { + styleOverrides: { + root: ({ theme }) => ({ + typography: theme.typography.caption, + marginBottom: 8, + }), + }, + }, + MuiIconButton: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + ...(ownerState.size === 'small' && { + height: '2rem', + width: '2rem', + }), + ...(ownerState.size === 'medium' && { + height: '2.5rem', + width: '2.5rem', + }), + color: brand[500], + '&:hover': { + backgroundColor: alpha(brand[300], 0.3), + borderColor: brand[200], + }, + ...(theme.palette.mode === 'dark' && { + color: brand[200], + '&:hover': { + backgroundColor: alpha(brand[600], 0.3), + borderColor: brand[700], + }, + }), + }), + }, + }, + MuiInputBase: { + styleOverrides: { + root: { + border: 'none', + }, + }, + }, + MuiLink: { + defaultProps: { + underline: 'none', + }, + styleOverrides: { + root: ({ theme }) => ({ + color: brand[700], + fontWeight: 500, + position: 'relative', + textDecoration: 'none', + '&::before': { + content: '""', + position: 'absolute', + width: 0, + height: '1px', + bottom: 0, + left: 0, + backgroundColor: brand[200], + opacity: 0.7, + transition: 'width 0.3s ease, opacity 0.3s ease', + }, + '&:hover::before': { + width: '100%', + opacity: 1, + }, + '&:focus-visible': { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '4px', + borderRadius: '2px', + }, + ...(theme.palette.mode === 'dark' && { + color: brand[200], + }), + }), + }, + }, + MuiOutlinedInput: { + styleOverrides: { + notchedOutline: { + border: 'none', + }, + input: { + paddingLeft: 10, + }, + root: ({ theme, ownerState }) => ({ + 'input:-webkit-autofill': { + WebkitBoxShadow: `0 0 0 1000px ${brand[100]} inset, 0 0 0 1px ${brand[200]}`, + maxHeight: '4px', + borderRadius: '8px', + }, + '& .MuiInputBase-input': { + fontSize: '1rem', + '&::placeholder': { + opacity: 0.7, + color: gray[500], + }, + }, + boxSizing: 'border-box', + flexGrow: 1, + height: '40px', + borderRadius: theme.shape.borderRadius, + border: '1px solid', + borderColor: alpha(gray[300], 0.8), + boxShadow: '0 0 0 1.5px hsla(210, 0%, 0%, 0.02) inset', + transition: 'border-color 120ms ease-in', + backgroundColor: alpha(gray[100], 0.4), + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '2px', + borderColor: brand[400], + }, + ...(ownerState.color === 'error' && { + borderColor: red[200], + color: red[500], + '& + .MuiFormHelperText-root': { + color: red[500], + }, + }), + ...(theme.palette.mode === 'dark' && { + 'input:-webkit-autofill': { + WebkitBoxShadow: `0 0 0 1000px ${brand[900]} inset, 0 0 0 1px ${brand[600]}`, + maxHeight: '6px', + borderRadius: '8px', + }, + '& .MuiInputBase-input': { + fontSize: '1rem', + '&::placeholder': { + opacity: 1, + color: gray[500], + }, + }, + borderColor: alpha(gray[700], 0.5), + boxShadow: '0 0 0 1.5px hsl(210, 0%, 0%) inset', + backgroundColor: alpha(gray[900], 0.8), + transition: 'border-color 120ms ease-in', + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + borderColor: brand[400], + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '2px', + }, + ...(ownerState.color === 'error' && { + borderColor: red[700], + color: red[300], + '& + .MuiFormHelperText-root': { + color: red[300], + }, + }), + }), + }), + }, + }, + MuiPaper: { + defaultProps: { + elevation: 0, + }, + }, + MuiStack: { + defaultProps: { + useFlexGap: true, + }, + }, + MuiStepConnector: { + styleOverrides: { + line: ({ theme }) => ({ + borderTop: '1px solid', + borderColor: theme.palette.divider, + flex: 1, + borderRadius: '99px', + }), + }, + }, + MuiStepIcon: { + variants: [ + { + props: { completed: true }, + style: () => ({ + width: 12, + height: 12, + }), + }, + ], + styleOverrides: { + root: ({ theme }) => ({ + color: 'transparent', + border: `1px solid ${gray[400]}`, + width: 12, + height: 12, + borderRadius: '50%', + '& text': { + display: 'none', + }, + '&.Mui-active': { + border: 'none', + color: theme.palette.primary.main, + }, + '&.Mui-completed': { + border: 'none', + color: theme.palette.success.main, + }, + ...(theme.palette.mode === 'dark' && { + border: `1px solid ${gray[700]}`, + '&.Mui-active': { + border: 'none', + color: theme.palette.primary.light, + }, + '&.Mui-completed': { + border: 'none', + color: theme.palette.success.light, + }, + }), + }), + }, + }, + MuiStepLabel: { + styleOverrides: { + label: ({ theme }) => ({ + '&.Mui-completed': { + opacity: 0.6, + ...(theme.palette.mode === 'dark' && { opacity: 0.5 }), + }, + }), + }, + }, + MuiToggleButtonGroup: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: theme.shape.borderRadius, + boxShadow: `0 1px 2px hsla(210, 0%, 0%, 0.05), 0 2px 12px ${alpha(brand[200], 0.5)}`, + '& .Mui-selected': { + color: brand[500], + }, + ...(theme.palette.mode === 'dark' && { + '& .Mui-selected': { + color: 'hsl(0, 0%, 100%)', + }, + boxShadow: `0 0 0 1px hsla(210, 0%, 0%, 0.5), 0 2px 12px ${alpha(brand[700], 0.5)}`, + }), + }), + }, + }, + MuiToggleButton: { + styleOverrides: { + root: ({ theme }) => ({ + padding: '12px 16px', + textTransform: 'none', + borderRadius: theme.shape.borderRadius, + fontWeight: 500, + ...(theme.palette.mode === 'dark' && { + color: gray[400], + '&.Mui-selected': { color: brand[300] }, + }), + }), + }, + }, + }, + }; +} diff --git a/packages/mui-codemod/src/v6.0.0/theme-v6/test-cases/basicTheme.expected.js b/packages/mui-codemod/src/v6.0.0/theme-v6/test-cases/basicTheme.expected.js new file mode 100644 index 00000000000000..72d8d0a1d226bd --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/theme-v6/test-cases/basicTheme.expected.js @@ -0,0 +1,603 @@ +export default function getCheckoutTheme(mode) { + return { + ...getDesignTokens(mode), + components: { + MuiAlert: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: 10, + backgroundColor: orange[100], + color: theme.palette.text.primary, + border: `1px solid ${alpha(orange[300], 0.5)}`, + '& .MuiAlert-icon': { + color: orange[500], + }, + ...theme.applyStyles("dark", { + backgroundColor: `${alpha(orange[900], 0.5)}`, + border: `1px solid ${alpha(orange[800], 0.5)}`, + }), + }), + }, + }, + MuiButtonBase: { + defaultProps: { + disableTouchRipple: true, + disableRipple: true, + }, + styleOverrides: { + root: { + boxSizing: 'border-box', + transition: 'all 100ms ease', + '&:focus-visible': { + outline: `3px solid ${alpha(brand[400], 0.5)}`, + outlineOffset: '2px', + }, + }, + }, + }, + MuiButton: { + styleOverrides: { + root: ({ + theme + }) => ({ + boxShadow: 'none', + borderRadius: theme.shape.borderRadius, + textTransform: 'none', + variants: [{ + props: { + size: 'small' + }, + style: { + height: '2rem', // 32px + padding: '0 0.5rem', + } + }, { + props: { + size: 'medium' + }, + style: { + height: '2.5rem', // 40px + } + }, { + props: { + color: 'primary', + variant: 'contained' + }, + style: { + color: 'white', + backgroundColor: brand[300], + backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, + boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, + border: `1px solid ${brand[500]}`, + '&:hover': { + backgroundColor: brand[700], + boxShadow: 'none', + }, + '&:active': { + backgroundColor: brand[700], + boxShadow: `inset 0 2.5px 0 ${alpha(brand[700], 0.4)}`, + }, + } + }, { + props: { + variant: 'outlined' + }, + style: { + color: brand[700], + backgroundColor: alpha(brand[300], 0.1), + borderColor: alpha(brand[200], 0.8), + boxShadow: `inset 0 2px ${alpha(brand[50], 0.5)}, inset 0 -2px ${alpha(brand[200], 0.2)}`, + '&:hover': { + backgroundColor: alpha(brand[300], 0.2), + borderColor: alpha(brand[300], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[300], 0.3), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[400], 0.2)}`, + backgroundImage: 'none', + }, + } + }, { + props: { + color: 'secondary', + variant: 'outlined' + }, + style: { + backgroundColor: alpha(gray[300], 0.1), + borderColor: alpha(gray[300], 0.5), + color: gray[700], + '&:hover': { + backgroundColor: alpha(gray[300], 0.3), + borderColor: alpha(gray[300], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(gray[300], 0.4), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[400], 0.2)}`, + backgroundImage: 'none', + }, + } + }, { + props: { + color: 'primary', + variant: 'text' + }, + style: { + color: brand[700], + '&:hover': { + backgroundColor: alpha(brand[300], 0.3), + }, + } + }, { + props: { + color: 'info', + variant: 'text' + }, + style: { + color: gray[700], + '&:hover': { + backgroundColor: alpha(gray[300], 0.3), + }, + } + }, { + props: { + variant: 'outlined' + }, + style: { + ...theme.applyStyles("dark", { + color: brand[200], + backgroundColor: alpha(brand[600], 0.1), + borderColor: alpha(brand[600], 0.6), + boxShadow: `inset 0 2.5px ${alpha(brand[400], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(brand[700], 0.2), + borderColor: alpha(brand[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(brand[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(brand[900], 0.4)}`, + backgroundImage: 'none', + }, + }) + } + }, { + props: { + color: 'info', + variant: 'text' + }, + style: { + ...theme.applyStyles("dark", { + color: gray[200], + '&:hover': { + backgroundColor: alpha(gray[700], 0.3), + }, + }) + } + }, { + props: { + color: 'secondary', + variant: 'outlined' + }, + style: { + ...theme.applyStyles("dark", { + color: gray[300], + backgroundColor: alpha(gray[600], 0.1), + borderColor: alpha(gray[700], 0.5), + boxShadow: `inset 0 2.5px ${alpha(gray[600], 0.1)}, inset 0 -2px ${alpha(gray[900], 0.5)}`, + '&:hover': { + backgroundColor: alpha(gray[700], 0.2), + borderColor: alpha(gray[700], 0.5), + boxShadow: 'none', + }, + '&:active': { + backgroundColor: alpha(gray[800], 0.2), + boxShadow: `inset 0 2.5px 0 ${alpha(gray[900], 0.4)}`, + backgroundImage: 'none', + }, + }) + } + }, { + props: { + color: 'primary', + variant: 'text' + }, + style: { + ...theme.applyStyles("dark", { + color: brand[200], + '&:hover': { + backgroundColor: alpha(brand[700], 0.3), + }, + }) + } + }] + }), + }, + }, + MuiCard: { + styleOverrides: { + root: ({ + theme + }) => ({ + transition: 'all 100ms ease', + backgroundColor: gray[50], + borderRadius: theme.shape.borderRadius, + border: `1px solid ${alpha(gray[200], 0.5)}`, + boxShadow: 'none', + ...theme.applyStyles("dark", { + backgroundColor: alpha(gray[800], 0.6), + border: `1px solid ${alpha(gray[700], 0.3)}` + }), + variants: [{ + props: { + variant: 'outlined' + }, + style: { + border: `1px solid ${gray[200]}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, hsl(0, 0%, 100%), ${gray[50]})`, + } + }, { + props: { + variant: 'outlined' + }, + style: { + ...theme.applyStyles("dark", { + border: `1px solid ${alpha(gray[700], 0.4)}`, + boxShadow: 'none', + background: `linear-gradient(to bottom, ${gray[900]}, ${alpha(gray[800], 0.5)})`, + }) + } + }] + }), + }, + }, + MuiCheckbox: { + defaultProps: { + disableRipple: true, + icon: , + checkedIcon: , + }, + styleOverrides: { + root: ({ theme }) => ({ + margin: 10, + height: 16, + width: 16, + borderRadius: 5, + border: '1px solid ', + borderColor: alpha(gray[300], 0.8), + boxShadow: '0 0 0 1.5px hsla(210, 0%, 0%, 0.04) inset', + transition: 'border-color 120ms ease-in', + backgroundColor: alpha(gray[100], 0.4), + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focusVisible': { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '2px', + borderColor: brand[400], + }, + '&.Mui-checked': { + color: 'white', + backgroundColor: brand[500], + borderColor: brand[500], + boxShadow: `none`, + '&:hover': { + backgroundColor: brand[600], + }, + }, + ...theme.applyStyles("dark", { + borderColor: alpha(gray[700], 0.5), + boxShadow: '0 0 0 1.5px hsl(210, 0%, 0%) inset', + backgroundColor: alpha(gray[900], 0.8), + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focusVisible': { + borderColor: brand[400], + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '2px', + }, + }), + }), + }, + }, + MuiDivider: { + styleOverrides: { + root: ({ theme }) => ({ + borderColor: `${alpha(gray[200], 0.8)}`, + ...theme.applyStyles("dark", { + borderColor: `${alpha(gray[700], 0.4)}`, + }), + }), + }, + }, + MuiFormLabel: { + styleOverrides: { + root: ({ theme }) => ({ + typography: theme.typography.caption, + marginBottom: 8, + }), + }, + }, + MuiIconButton: { + styleOverrides: { + root: ({ + theme + }) => ({ + color: brand[500], + '&:hover': { + backgroundColor: alpha(brand[300], 0.3), + borderColor: brand[200], + }, + ...theme.applyStyles("dark", { + color: brand[200], + '&:hover': { + backgroundColor: alpha(brand[600], 0.3), + borderColor: brand[700], + }, + }), + variants: [{ + props: { + size: 'small' + }, + style: { + height: '2rem', + width: '2rem', + } + }, { + props: { + size: 'medium' + }, + style: { + height: '2.5rem', + width: '2.5rem', + } + }] + }), + }, + }, + MuiInputBase: { + styleOverrides: { + root: { + border: 'none', + }, + }, + }, + MuiLink: { + defaultProps: { + underline: 'none', + }, + styleOverrides: { + root: ({ theme }) => ({ + color: brand[700], + fontWeight: 500, + position: 'relative', + textDecoration: 'none', + '&::before': { + content: '""', + position: 'absolute', + width: 0, + height: '1px', + bottom: 0, + left: 0, + backgroundColor: brand[200], + opacity: 0.7, + transition: 'width 0.3s ease, opacity 0.3s ease', + }, + '&:hover::before': { + width: '100%', + opacity: 1, + }, + '&:focus-visible': { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '4px', + borderRadius: '2px', + }, + ...theme.applyStyles("dark", { + color: brand[200], + }), + }), + }, + }, + MuiOutlinedInput: { + styleOverrides: { + notchedOutline: { + border: 'none', + }, + input: { + paddingLeft: 10, + }, + root: ({ + theme + }) => ({ + 'input:-webkit-autofill': { + WebkitBoxShadow: `0 0 0 1000px ${brand[100]} inset, 0 0 0 1px ${brand[200]}`, + maxHeight: '4px', + borderRadius: '8px', + }, + '& .MuiInputBase-input': { + fontSize: '1rem', + '&::placeholder': { + opacity: 0.7, + color: gray[500], + }, + }, + boxSizing: 'border-box', + flexGrow: 1, + height: '40px', + borderRadius: theme.shape.borderRadius, + border: '1px solid', + borderColor: alpha(gray[300], 0.8), + boxShadow: '0 0 0 1.5px hsla(210, 0%, 0%, 0.02) inset', + transition: 'border-color 120ms ease-in', + backgroundColor: alpha(gray[100], 0.4), + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '2px', + borderColor: brand[400], + }, + ...theme.applyStyles("dark", { + 'input:-webkit-autofill': { + WebkitBoxShadow: `0 0 0 1000px ${brand[900]} inset, 0 0 0 1px ${brand[600]}`, + maxHeight: '6px', + borderRadius: '8px', + }, + '& .MuiInputBase-input': { + fontSize: '1rem', + '&::placeholder': { + opacity: 1, + color: gray[500], + }, + }, + borderColor: alpha(gray[700], 0.5), + boxShadow: '0 0 0 1.5px hsl(210, 0%, 0%) inset', + backgroundColor: alpha(gray[900], 0.8), + transition: 'border-color 120ms ease-in', + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + borderColor: brand[400], + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '2px', + } + }), + variants: [{ + props: { + color: 'error' + }, + style: { + borderColor: red[200], + color: red[500], + '& + .MuiFormHelperText-root': { + color: red[500], + }, + } + }, { + props: { + color: 'error' + }, + style: { + ...theme.applyStyles("dark", { + borderColor: red[700], + color: red[300], + '& + .MuiFormHelperText-root': { + color: red[300], + }, + }) + } + }] + }), + }, + }, + MuiPaper: { + defaultProps: { + elevation: 0, + }, + }, + MuiStack: { + defaultProps: { + useFlexGap: true, + }, + }, + MuiStepConnector: { + styleOverrides: { + line: ({ theme }) => ({ + borderTop: '1px solid', + borderColor: theme.palette.divider, + flex: 1, + borderRadius: '99px', + }), + }, + }, + MuiStepIcon: { + styleOverrides: { + root: ({ theme }) => ({ + color: 'transparent', + border: `1px solid ${gray[400]}`, + width: 12, + height: 12, + borderRadius: '50%', + '& text': { + display: 'none', + }, + '&.Mui-active': { + border: 'none', + color: theme.palette.primary.main, + }, + '&.Mui-completed': { + border: 'none', + color: theme.palette.success.main, + }, + ...theme.applyStyles("dark", { + border: `1px solid ${gray[700]}`, + '&.Mui-active': { + border: 'none', + color: theme.palette.primary.light, + }, + '&.Mui-completed': { + border: 'none', + color: theme.palette.success.light, + }, + }), + variants: [ + { + props: { completed: true }, + style: ({ + width: 12, + height: 12 + }), + }, + ] + }), + } + }, + MuiStepLabel: { + styleOverrides: { + label: ({ theme }) => ({ + '&.Mui-completed': { + opacity: 0.6, + ...theme.applyStyles("dark", { opacity: 0.5 }), + }, + }), + }, + }, + MuiToggleButtonGroup: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: theme.shape.borderRadius, + boxShadow: `0 1px 2px hsla(210, 0%, 0%, 0.05), 0 2px 12px ${alpha(brand[200], 0.5)}`, + '& .Mui-selected': { + color: brand[500], + }, + ...theme.applyStyles("dark", { + '& .Mui-selected': { + color: 'hsl(0, 0%, 100%)', + }, + boxShadow: `0 0 0 1px hsla(210, 0%, 0%, 0.5), 0 2px 12px ${alpha(brand[700], 0.5)}`, + }), + }), + }, + }, + MuiToggleButton: { + styleOverrides: { + root: ({ theme }) => ({ + padding: '12px 16px', + textTransform: 'none', + borderRadius: theme.shape.borderRadius, + fontWeight: 500, + ...theme.applyStyles("dark", { + color: gray[400], + '&.Mui-selected': { color: brand[300] }, + }), + }), + }, + }, + }, + }; +} diff --git a/packages/mui-codemod/src/v6.0.0/theme-v6/test-cases/themeVariants.actual.js b/packages/mui-codemod/src/v6.0.0/theme-v6/test-cases/themeVariants.actual.js new file mode 100644 index 00000000000000..bdd99e5b12c3d4 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/theme-v6/test-cases/themeVariants.actual.js @@ -0,0 +1,56 @@ +export default function getCheckoutTheme(mode) { + return { + ...getDesignTokens(mode), + components: { + MuiStepIcon: { + variants: [ + { + props: { completed: true }, + style: () => ({ + width: 12, + height: 12, + }), + }, + ], + styleOverrides: { + root: ({ theme, ownerState }) => ({ + color: 'transparent', + border: `1px solid ${gray[400]}`, + width: 12, + height: 12, + borderRadius: '50%', + '& text': { + display: 'none', + }, + '&.Mui-active': { + border: 'none', + color: theme.palette.primary.main, + }, + '&.Mui-completed': { + border: 'none', + color: theme.palette.success.main, + }, + ...(ownerState.size === 'large' && { + width: 20, + height: 20, + }), + ...(theme.palette.mode === 'dark' && { + border: `1px solid ${gray[700]}`, + '&.Mui-active': { + border: 'none', + color: theme.palette.primary.light, + }, + '&.Mui-completed': { + border: 'none', + color: theme.palette.success.light, + }, + ...(ownerState.variant === 'shadow' && { + boxShadow: theme.shadows[2], + }), + }), + }), + }, + }, + }, + }; +} diff --git a/packages/mui-codemod/src/v6.0.0/theme-v6/test-cases/themeVariants.expected.js b/packages/mui-codemod/src/v6.0.0/theme-v6/test-cases/themeVariants.expected.js new file mode 100644 index 00000000000000..8f5660247befd8 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/theme-v6/test-cases/themeVariants.expected.js @@ -0,0 +1,66 @@ +export default function getCheckoutTheme(mode) { + return { + ...getDesignTokens(mode), + components: { + MuiStepIcon: { + styleOverrides: { + root: ({ + theme + }) => ({ + color: 'transparent', + border: `1px solid ${gray[400]}`, + width: 12, + height: 12, + borderRadius: '50%', + '& text': { + display: 'none', + }, + '&.Mui-active': { + border: 'none', + color: theme.palette.primary.main, + }, + '&.Mui-completed': { + border: 'none', + color: theme.palette.success.main, + }, + ...theme.applyStyles("dark", { + border: `1px solid ${gray[700]}`, + '&.Mui-active': { + border: 'none', + color: theme.palette.primary.light, + }, + '&.Mui-completed': { + border: 'none', + color: theme.palette.success.light, + } + }), + variants: [{ + props: { + size: 'large' + }, + style: { + width: 20, + height: 20, + } + }, { + props: { + variant: 'shadow' + }, + style: { + ...theme.applyStyles("dark", { + boxShadow: theme.shadows[2], + }) + } + }, { + props: { completed: true }, + style: ({ + width: 12, + height: 12 + }), + }] + }), + } + }, + }, + }; +} diff --git a/packages/mui-codemod/src/v6.0.0/theme-v6/theme-v6.js b/packages/mui-codemod/src/v6.0.0/theme-v6/theme-v6.js new file mode 100644 index 00000000000000..00b08bad9afdd9 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/theme-v6/theme-v6.js @@ -0,0 +1,106 @@ +import getReturnExpression from '../../util/getReturnExpression'; +import migrateToVariants from '../../util/migrateToVariants'; + +/** + * @param {import('jscodeshift').FileInfo} file + * @param {import('jscodeshift').API} api + */ +export default function styledV6(file, api, options) { + const j = api.jscodeshift; + const root = j(file.source); + const printOptions = options.printOptions; + + let shouldTransform = false; + + root.find(j.ArrowFunctionExpression).forEach((path) => { + const styles = []; + let args = []; + + if (path.parent.parent.parent.get('key', 'name').value === 'styleOverrides') { + args = [path.node]; + } + + // 1. collecting styles that should be tranformed + args.forEach((arg) => { + if ( + arg.type === 'ArrowFunctionExpression' && + arg.params[0] && + arg.params[0].type === 'ObjectPattern' + ) { + styles.push(arg); + } + }); + + if (!shouldTransform && styles.length > 0) { + shouldTransform = true; + } + + migrateToVariants(j, styles); + + if (path.parent.get('key', 'name').value === 'root') { + const componentTheme = path.parent.parent.parent.parent.get('properties'); + if (componentTheme.node.type === 'ObjectExpression') { + componentTheme.node.properties.forEach((prop) => { + if (prop.key.name === 'variants') { + prop.value.elements = prop.value.elements.map((element) => { + const styleIndex = element.properties.findIndex( + (styleProp) => + styleProp.type === 'ObjectProperty' && styleProp.key.name === 'style', + ); + if ( + styleIndex !== -1 && + element.properties[styleIndex].value.type !== 'ObjectExpression' + ) { + element.properties[styleIndex].value = getReturnExpression( + element.properties[styleIndex].value, + ); + } + return element; + }); + const stylesNode = getReturnExpression(path.node); + const variantsNode = stylesNode?.properties.find( + (styleProp) => + styleProp.type === 'ObjectProperty' && styleProp.key.name === 'variants', + ); + if (variantsNode) { + variantsNode.value.elements.push(...prop.value.elements); + } else { + stylesNode.properties.push(j.property('init', j.identifier('variants'), prop.value)); + } + } + }); + componentTheme.node.properties = componentTheme.node.properties.filter( + (prop) => prop.key.name !== 'variants', + ); + } + } + }); + + const transformed = root.toSource(printOptions); + + if (shouldTransform) { + // recast adds extra newlines that we don't want, https://github.com/facebook/jscodeshift/issues/249 + // need to remove them manually + const lines = []; + let isInStyled = false; + let spaceMatch; + transformed.split('\n').forEach((line) => { + if (!isInStyled) { + lines.push(line); + } else if (line !== '') { + if (spaceMatch && line.match(/^\s+/)?.[0] === spaceMatch?.[0]) { + isInStyled = false; + spaceMatch = null; + } + lines.push(line); + } + if (line.includes('styleOverrides')) { + isInStyled = true; + spaceMatch = line.match(/^\s+/); + } + }); + return lines.join('\n'); + } + + return transformed; +} diff --git a/packages/mui-codemod/src/v6.0.0/theme-v6/theme-v6.test.js b/packages/mui-codemod/src/v6.0.0/theme-v6/theme-v6.test.js new file mode 100644 index 00000000000000..57ecbada5bfcde --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/theme-v6/theme-v6.test.js @@ -0,0 +1,61 @@ +import path from 'path'; +import { expect } from 'chai'; +import { jscodeshift } from '../../../testUtils'; +import transform from './theme-v6'; +import readFile from '../../util/readFile'; + +function read(fileName) { + return readFile(path.join(__dirname, fileName)); +} + +describe('@mui/codemod', () => { + describe('v6.0.0 - theme-v6', () => { + describe('styleOverrides', () => { + it('transforms props as needed', () => { + const actual = transform( + { source: read('./test-cases/basicTheme.actual.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/basicTheme.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform( + { source: read('./test-cases/basicTheme.expected.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/basicTheme.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + + describe('theme variants to root slot', () => { + it('transforms props as needed', () => { + const actual = transform( + { source: read('./test-cases/themeVariants.actual.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/themeVariants.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform( + { source: read('./test-cases/themeVariants.expected.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/themeVariants.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + }); +}); diff --git a/packages/mui-core-downloads-tracker/package.json b/packages/mui-core-downloads-tracker/package.json index a2aa0d9631db7b..4463a508ba8623 100644 --- a/packages/mui-core-downloads-tracker/package.json +++ b/packages/mui-core-downloads-tracker/package.json @@ -1,6 +1,6 @@ { "name": "@mui/core-downloads-tracker", - "version": "6.0.0-alpha.2", + "version": "6.0.0-alpha.5", "private": false, "author": "MUI Team", "description": "Internal package to track number of downloads of our design system libraries", diff --git a/packages/mui-docs/package.json b/packages/mui-docs/package.json index 54f3b4c83f9a47..5542fa3f0211b3 100644 --- a/packages/mui-docs/package.json +++ b/packages/mui-docs/package.json @@ -1,6 +1,6 @@ { "name": "@mui/docs", - "version": "6.0.0-alpha.2", + "version": "6.0.0-alpha.5", "private": false, "author": "MUI Team", "description": "MUI Docs - Documentation building blocks.", @@ -23,8 +23,7 @@ }, "homepage": "https://github.com/mui/material-ui/tree/master/packages/mui-docs", "scripts": { - "build": "pnpm build:legacy && pnpm build:modern && pnpm build:node && pnpm build:stable && pnpm build:types && pnpm build:copy-files", - "build:legacy": "node ../../scripts/build.mjs legacy", + "build": "pnpm build:modern && pnpm build:node && pnpm build:stable && pnpm build:types && pnpm build:copy-files", "build:modern": "echo 'Skip modern build'", "build:node": "node ../../scripts/build.mjs node", "build:stable": "node ../../scripts/build.mjs stable", @@ -36,7 +35,9 @@ }, "dependencies": { "@babel/runtime": "^7.24.4", - "clsx": "^2.1.0", + "@mui/internal-markdown": "workspace:^", + "clipboard-copy": "^4.0.1", + "clsx": "^2.1.1", "nprogress": "^0.2.0", "prop-types": "^15.8.1" }, diff --git a/packages/mui-docs/src/CodeCopy/CodeCopy.tsx b/packages/mui-docs/src/CodeCopy/CodeCopy.tsx new file mode 100644 index 00000000000000..f39c1adb147380 --- /dev/null +++ b/packages/mui-docs/src/CodeCopy/CodeCopy.tsx @@ -0,0 +1,199 @@ +import * as React from 'react'; +import { useRouter } from 'next/router'; +import clipboardCopy from 'clipboard-copy'; + +const CodeBlockContext = React.createContext>({ + current: null, +}); + +/** + * How to use: spread the handlers to the .MuiCode-root + * + * The html structure should be: + *
    + *
    ...
    + * + *
    + */ +export function useCodeCopy(): React.HTMLAttributes { + const rootNode = React.useContext(CodeBlockContext); + return { + onMouseEnter: (event) => { + rootNode.current = event.currentTarget; + }, + onMouseLeave: (event) => { + if (rootNode.current === event.currentTarget) { + (rootNode.current.querySelector('.MuiCode-copy') as null | HTMLButtonElement)?.blur(); + rootNode.current = null; + } + }, + onFocus: (event) => { + rootNode.current = event.currentTarget; + }, + onBlur: (event) => { + if (rootNode.current === event.currentTarget) { + rootNode.current = null; + } + }, + }; +} + +function InitCodeCopy() { + const rootNode = React.useContext(CodeBlockContext); + const router = useRouter(); + React.useEffect(() => { + let key = 'Ctrl + '; + if (typeof window !== 'undefined') { + const macOS = window.navigator.platform.toUpperCase().indexOf('MAC') >= 0; + if (macOS) { + key = '⌘'; + } + } + const codeRoots = document.getElementsByClassName( + 'MuiCode-root', + ) as HTMLCollectionOf; + + if (codeRoots !== null) { + const listeners: Array<() => void> = []; + Array.from(codeRoots).forEach((elm) => { + const handleMouseEnter = () => { + rootNode.current = elm; + }; + + elm.addEventListener('mouseenter', handleMouseEnter); + listeners.push(() => elm.removeEventListener('mouseenter', handleMouseEnter)); + + const handleMouseLeave = () => { + if (rootNode.current === elm) { + (rootNode.current.querySelector('.MuiCode-copy') as null | HTMLButtonElement)?.blur(); + rootNode.current = null; + } + }; + elm.addEventListener('mouseleave', handleMouseLeave); + listeners.push(() => elm.removeEventListener('mouseleave', handleMouseLeave)); + + const handleFocusin = () => { + // use `focusin` because it bubbles from the copy button + rootNode.current = elm; + }; + elm.addEventListener('focusin', handleFocusin); + listeners.push(() => elm.removeEventListener('focusin', handleFocusin)); + + const handleFocusout = () => { + // use `focusout` because it bubbles from the copy button + if (rootNode.current === elm) { + rootNode.current = null; + } + }; + elm.addEventListener('focusout', handleFocusout); + listeners.push(() => elm.removeEventListener('focusout', handleFocusout)); + + async function handleClick(event: MouseEvent) { + const trigger = event.currentTarget as HTMLButtonElement; + const pre = (event.currentTarget as Element)?.previousElementSibling as Element; + const textNode = trigger.childNodes[0]; + textNode.nodeValue = textNode.textContent?.replace('Copy', 'Copied') || null; + trigger.dataset.copied = 'true'; + setTimeout(() => { + if (trigger) { + textNode.nodeValue = textNode.textContent?.replace('Copied', 'Copy') || null; + delete trigger.dataset.copied; + } + }, 2000); + try { + if (pre.textContent) { + await clipboardCopy(pre.textContent); + } + // eslint-disable-next-line no-empty + } catch (error) {} + } + + const btn = elm.querySelector('.MuiCode-copy') as HTMLButtonElement | null; + if (btn) { + const keyNode = btn.querySelector('.MuiCode-copyKeypress')?.childNodes[1]; + if (!keyNode) { + // skip the logic if the btn is not generated from the markdown. + return; + } + keyNode.textContent = keyNode?.textContent?.replace('$key', key) || null; + btn.addEventListener('click', handleClick); + listeners.push(() => btn.removeEventListener('click', handleClick)); + } + }); + + return () => { + listeners.forEach((removeEventListener) => { + removeEventListener(); + }); + }; + } + + return undefined; + }, [rootNode, router.pathname]); + return null; +} + +function hasNativeSelection(element: HTMLTextAreaElement) { + if (window.getSelection()?.toString()) { + return true; + } + + // window.getSelection() returns an empty string in Firefox for selections inside a form element. + // See: https://bugzilla.mozilla.org/show_bug.cgi?id=85686. + // Instead, we can use element.selectionStart that is only defined on form elements. + if (element && (element.selectionEnd || 0) - (element.selectionStart || 0) > 0) { + return true; + } + + return false; +} + +interface CodeCopyProviderProps { + children: React.ReactNode; +} + +/** + * Place at the page level. It will check the keydown event and try to initiate copy click if rootNode exist. + * Any code block inside the tree can set the rootNode when mouse enter to leverage keyboard copy. + */ +export function CodeCopyProvider({ children }: CodeCopyProviderProps) { + const rootNode = React.useRef(null); + React.useEffect(() => { + document.addEventListener('keydown', (event) => { + if (!rootNode.current) { + return; + } + + // Skip if user is highlighting a text. + if (hasNativeSelection(event.target as HTMLTextAreaElement)) { + return; + } + + // Skip if it's not a copy keyboard event + if ( + !( + (event.ctrlKey || event.metaKey) && + event.key.toLowerCase() === 'c' && + !event.shiftKey && + !event.altKey + ) + ) { + return; + } + + const copyBtn = rootNode.current.querySelector('.MuiCode-copy') as HTMLButtonElement; + const initialEventAction = copyBtn.getAttribute('data-ga-event-action'); + // update the 'data-ga-event-action' on the button to track keyboard interaction + copyBtn.dataset.gaEventAction = + initialEventAction?.replace('click', 'keyboard') || 'copy-keyboard'; + copyBtn.click(); // let the GA setup in GoogleAnalytics.js do the job + copyBtn.dataset.gaEventAction = initialEventAction!; // reset the 'data-ga-event-action' back to initial + }); + }, []); + return ( + + + {children} + + ); +} diff --git a/packages/mui-docs/src/CodeCopy/CodeCopyButton.tsx b/packages/mui-docs/src/CodeCopy/CodeCopyButton.tsx new file mode 100644 index 00000000000000..648e479a504399 --- /dev/null +++ b/packages/mui-docs/src/CodeCopy/CodeCopyButton.tsx @@ -0,0 +1,41 @@ +import * as React from 'react'; +import ContentCopyRoundedIcon from '@mui/icons-material/ContentCopyRounded'; +import LibraryAddCheckRoundedIcon from '@mui/icons-material/LibraryAddCheckRounded'; +import useClipboardCopy from './useClipboardCopy'; + +export interface CodeCopyButtonProps { + code: string; +} + +export function CodeCopyButton(props: CodeCopyButtonProps) { + const { code, ...other } = props; + const { copy, isCopied } = useClipboardCopy(); + // This component is designed to be wrapped in NoSsr + const macOS = window.navigator.platform.toUpperCase().indexOf('MAC') >= 0; + const key = macOS ? '⌘' : 'Ctrl + '; + + return ( +
    + +
    + ); +} diff --git a/packages/mui-docs/src/CodeCopy/index.tsx b/packages/mui-docs/src/CodeCopy/index.tsx new file mode 100644 index 00000000000000..074604ad8bfd26 --- /dev/null +++ b/packages/mui-docs/src/CodeCopy/index.tsx @@ -0,0 +1,3 @@ +export * from './CodeCopy'; +export * from './CodeCopyButton'; +export { default as useClipboardCopy } from './useClipboardCopy'; diff --git a/packages/mui-docs/src/CodeCopy/useClipboardCopy.ts b/packages/mui-docs/src/CodeCopy/useClipboardCopy.ts new file mode 100644 index 00000000000000..9979a455775ae5 --- /dev/null +++ b/packages/mui-docs/src/CodeCopy/useClipboardCopy.ts @@ -0,0 +1,25 @@ +import * as React from 'react'; +import clipboardCopy from 'clipboard-copy'; + +export default function useClipboardCopy() { + const [isCopied, setIsCopied] = React.useState(false); + const timeout = React.useRef>(); + + React.useEffect( + () => () => { + clearTimeout(timeout.current); + }, + [], + ); + + const copy = async (text: string) => { + await clipboardCopy(text); + setIsCopied(true); + clearTimeout(timeout.current); + timeout.current = setTimeout(() => { + setIsCopied(false); + }, 1200); + }; + + return { copy, isCopied }; +} diff --git a/packages/mui-docs/src/ComponentLinkHeader/ComponentLinkHeader.tsx b/packages/mui-docs/src/ComponentLinkHeader/ComponentLinkHeader.tsx new file mode 100644 index 00000000000000..50e1a7f705af88 --- /dev/null +++ b/packages/mui-docs/src/ComponentLinkHeader/ComponentLinkHeader.tsx @@ -0,0 +1,199 @@ +import * as React from 'react'; +import Chip from '@mui/material/Chip'; +import Tooltip from '@mui/material/Tooltip'; +import ChatRounded from '@mui/icons-material/ChatRounded'; +import { styled } from '@mui/material/styles'; +import { MarkdownHeaders } from '@mui/internal-markdown'; +import SketchIcon from '../svgIcons/SketchIcon'; +import FigmaIcon from '../svgIcons/FigmaIcon'; +import AdobeXDIcon from '../svgIcons/AdobeXDIcon'; +import BundleSizeIcon from '../svgIcons/BundleSizeIcon'; +import W3CIcon from '../svgIcons/W3CIcon'; +import MaterialDesignIcon from '../svgIcons/MaterialDesignIcon'; +import { useTranslate } from '../i18n'; + +const Root = styled('ul')({ + margin: 0, + padding: 0, + listStyle: 'none', + display: 'flex', + flexWrap: 'wrap', + gap: 8, + '& .MuiChip-root': { + height: 26, + padding: '0 8px', + gap: 6, + '& .MuiChip-label': { padding: 0 }, + '& .MuiChip-iconSmall': { + margin: 0, + fontSize: 14, + }, + }, +}); + +const defaultPackageNames: Record = { + 'material-ui': '@mui/material', + 'joy-ui': '@mui/joy', + 'base-ui': '@mui/base', + system: '@mui/system', +}; + +export interface ComponentLinkHeaderProps { + design?: boolean; + markdown: { + headers: MarkdownHeaders; + }; +} + +export function ComponentLinkHeader(props: ComponentLinkHeaderProps) { + const { + markdown: { headers }, + design, + } = props; + const t = useTranslate(); + + const packageName = + headers.packageName ?? defaultPackageNames[headers.productId] ?? '@mui/material'; + + return ( + + {headers.githubLabel ? ( +
  • + } + data-ga-event-category="ComponentLinkHeader" + data-ga-event-action="click" + data-ga-event-label={t('githubLabel')} + data-ga-event-split="0.1" + label={t('githubLabel')} + /> +
  • + ) : null} +
  • + + } + data-ga-event-category="ComponentLinkHeader" + data-ga-event-action="click" + data-ga-event-label={t('bundleSize')} + data-ga-event-split="0.1" + label={t('bundleSize')} + /> + +
  • + {headers.waiAria ? ( +
  • + } + data-ga-event-category="ComponentLinkHeader" + data-ga-event-action="click" + data-ga-event-label="WAI-ARIA" + data-ga-event-split="0.1" + label="WAI-ARIA" + /> +
  • + ) : null} + {headers.materialDesign ? ( +
  • + } + data-ga-event-category="ComponentLinkHeader" + data-ga-event-action="click" + data-ga-event-label="Material Design" + data-ga-event-split="0.1" + label="Material Design" + /> +
  • + ) : null} + {design === false ? null : ( + +
  • + } + data-ga-event-category="ComponentLinkHeader" + data-ga-event-action="click" + data-ga-event-label="Figma" + data-ga-event-split="0.1" + label="Figma" + /> +
  • + {packageName === '@mui/joy' ? null : ( + +
  • + } + data-ga-event-category="ComponentLinkHeader" + data-ga-event-action="click" + data-ga-event-label="Adobe XD" + data-ga-event-split="0.1" + label="Adobe" + /> +
  • +
  • + } + data-ga-event-category="ComponentLinkHeader" + data-ga-event-action="click" + data-ga-event-label="Sketch" + data-ga-event-split="0.1" + label="Sketch" + /> +
  • +
    + )} +
    + )} +
    + ); +} diff --git a/packages/mui-docs/src/ComponentLinkHeader/index.ts b/packages/mui-docs/src/ComponentLinkHeader/index.ts new file mode 100644 index 00000000000000..755708982255a7 --- /dev/null +++ b/packages/mui-docs/src/ComponentLinkHeader/index.ts @@ -0,0 +1,2 @@ +export * from './ComponentLinkHeader'; +export { ComponentLinkHeader as default } from './ComponentLinkHeader'; diff --git a/packages/mui-docs/src/HighlightedCode/HighlightedCode.tsx b/packages/mui-docs/src/HighlightedCode/HighlightedCode.tsx new file mode 100644 index 00000000000000..2f88f0d09476b5 --- /dev/null +++ b/packages/mui-docs/src/HighlightedCode/HighlightedCode.tsx @@ -0,0 +1,75 @@ +import * as React from 'react'; +import prism from '@mui/internal-markdown/prism'; +import { NoSsr } from '@mui/base/NoSsr'; +import { ButtonProps } from '@mui/material/Button'; +import { SxProps, styled } from '@mui/material/styles'; +import { useCodeCopy, CodeCopyButton } from '../CodeCopy'; +import { MarkdownElement } from '../MarkdownElement'; + +const Pre = styled('pre')(({ theme }) => ({ + margin: 0, + color: 'hsl(60deg 30% 96.08%)', // fallback color until Prism's theme is loaded + WebkitOverflowScrolling: 'touch', // iOS momentum scrolling. + maxWidth: 'calc(100vw - 32px)', + [theme.breakpoints.up('md')]: { + maxWidth: 'calc(100vw - 32px - 16px)', + }, + '& code': { + // Avoid layout jump after hydration (style injected by Prism) + ...theme.typography.caption, + fontFamily: theme.typography.fontFamilyCode, + fontWeight: 400, + WebkitFontSmoothing: 'subpixel-antialiased', + // Reset for Safari + // https://github.com/necolas/normalize.css/blob/master/normalize.css#L102 + }, +})); + +export interface HighlightedCodeProps { + code: string; + copyButtonHidden?: boolean; + copyButtonProps?: ButtonProps; + language: string; + parentComponent?: React.ElementType; + preComponent?: React.ElementType; + plainStyle?: boolean; + sx?: SxProps; +} + +export const HighlightedCode = React.forwardRef( + function HighlightedCode(props, ref) { + const { + copyButtonHidden = false, + copyButtonProps, + code, + language, + plainStyle, + parentComponent: Component = plainStyle ? 'div' : MarkdownElement, + preComponent: PreComponent = plainStyle ? Pre : 'pre', + ...other + } = props; + const renderedCode = React.useMemo(() => { + return prism(code.trim(), language); + }, [code, language]); + const handlers = useCodeCopy(); + + return ( + +
    + {copyButtonHidden ? null : ( + + + + )} + + + +
    +
    + ); + }, +); diff --git a/packages/mui-docs/src/HighlightedCode/index.tsx b/packages/mui-docs/src/HighlightedCode/index.tsx new file mode 100644 index 00000000000000..c348a40cdaa7c2 --- /dev/null +++ b/packages/mui-docs/src/HighlightedCode/index.tsx @@ -0,0 +1 @@ +export * from './HighlightedCode'; diff --git a/packages/mui-docs/src/InfoCard/InfoCard.tsx b/packages/mui-docs/src/InfoCard/InfoCard.tsx index 754a22b43e5c77..56ec11e1f94486 100644 --- a/packages/mui-docs/src/InfoCard/InfoCard.tsx +++ b/packages/mui-docs/src/InfoCard/InfoCard.tsx @@ -23,11 +23,11 @@ export function GlowingIconContainer({ icon }: GlowingIconContainerProps) { border: '1px solid', borderColor: 'primary.200', bgcolor: 'primary.50', - boxShadow: `0px 1px 6px 0px ${alpha(theme.palette.primary[500], 0.2)}, 0px 2px 12px 0px rgba(234, 237, 241, 0.3) inset`, + boxShadow: `0px 0 0 2px ${alpha(theme.palette.primary[500], 0.1)}, 0px 2px 12px 0px rgba(234, 237, 241, 0.3) inset`, ...theme.applyDarkStyles({ borderColor: alpha(theme.palette.primary[400], 0.25), - bgcolor: alpha(theme.palette.primary[900], 0.25), - boxShadow: `0 2px 6px 0 ${alpha(theme.palette.primary[600], 0.3)}, 0px 2px 12px 0px rgba(0, 0, 0, 0.25) inset`, + bgcolor: alpha(theme.palette.primary[900], 0.4), + boxShadow: `0 0 0 2px ${alpha(theme.palette.primary[600], 0.1)}, 0px 2px 12px 0px rgba(0, 0, 0, 0.25) inset`, }), })} > diff --git a/packages/mui-docs/src/MarkdownElement/MarkdownElement.tsx b/packages/mui-docs/src/MarkdownElement/MarkdownElement.tsx new file mode 100644 index 00000000000000..b95280444c9c0a --- /dev/null +++ b/packages/mui-docs/src/MarkdownElement/MarkdownElement.tsx @@ -0,0 +1,831 @@ +import * as React from 'react'; +import clsx from 'clsx'; +import { alpha, darken, styled } from '@mui/material/styles'; +import { brandingDarkTheme as darkTheme, brandingLightTheme as lightTheme } from '../branding'; + +const Root = styled('div')( + ({ theme }) => ({ + ...lightTheme.typography.body1, + lineHeight: 1.6, // Increased compared to the 1.5 default to make the docs easier to read. + color: `var(--muidocs-palette-text-primary, ${lightTheme.palette.text.primary})`, + '& :focus-visible': { + outline: `3px solid ${alpha(lightTheme.palette.primary[500], 0.5)}`, + outlineOffset: 2, + }, + '& strong': { + color: `var(--muidocs-palette-text-primary, ${lightTheme.palette.text.primary})`, + }, + wordBreak: 'break-word', + '& pre': { + lineHeight: 1.5, // Developers like when the code is dense. + margin: theme.spacing(2, 'auto'), + padding: theme.spacing(2), + backgroundColor: 'hsl(210, 35%, 9%)', // a special, one-off, color tailored for the code blocks using MUI's branding theme blue palette as the starting point. It has a less saturaded color but still maintaining a bit of the blue tint. + color: 'hsl(60, 30%, 96%)', + colorScheme: 'dark', + borderRadius: `var(--muidocs-shape-borderRadius, ${ + theme.shape?.borderRadius ?? lightTheme.shape.borderRadius + }px)`, + border: '1px solid', + borderColor: `var(--muidocs-palette-primaryDark-700, ${lightTheme.palette.primaryDark[700]})`, + overflow: 'auto', + WebkitOverflowScrolling: 'touch', + fontSize: lightTheme.typography.pxToRem(13), + maxWidth: 'calc(100vw - 32px)', + maxHeight: '400px', + [lightTheme.breakpoints.up('md')]: { + maxWidth: 'calc(100vw - 32px - 16px)', + }, + }, + '& code': { + ...lightTheme.typography.body2, + fontFamily: lightTheme.typography.fontFamilyCode, + fontWeight: 400, + WebkitFontSmoothing: 'subpixel-antialiased', + }, + '& pre > code': { + // Reset for Safari + // https://github.com/necolas/normalize.css/blob/master/normalize.css#L102 + fontSize: 'inherit', + }, + // inline code block + '& :not(pre) > code': { + padding: '2px 4px', + color: `var(--muidocs-palette-text-primary, ${lightTheme.palette.text.primary})`, + backgroundColor: `var(--muidocs-palette-grey-50, ${lightTheme.palette.grey[50]})`, + border: '1px solid', + borderColor: `var(--muidocs-palette-grey-200, ${lightTheme.palette.grey[200]})`, + borderRadius: 6, + fontSize: lightTheme.typography.pxToRem(13), + direction: 'ltr /*! @noflip */', + boxDecorationBreak: 'clone', + }, + '& h1': { + ...lightTheme.typography.h3, + fontSize: lightTheme.typography.pxToRem(36), + fontFamily: `"General Sans", ${lightTheme.typography.fontFamilySystem}`, + margin: '10px 0', + color: `var(--muidocs-palette-primaryDark-900, ${lightTheme.palette.primaryDark[900]})`, + fontWeight: 600, + letterSpacing: -0.2, + }, + '& .description': { + ...lightTheme.typography.subtitle1, + fontWeight: 400, + margin: '0 0 24px', + }, + '& .component-tabs': { + margin: '0 0 40px', + }, + '& h2': { + ...lightTheme.typography.h5, + fontFamily: `"General Sans", ${lightTheme.typography.fontFamilySystem}`, + fontSize: theme.typography.pxToRem(26), + fontWeight: lightTheme.typography.fontWeightSemiBold, + color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, + margin: '40px 0 4px', + }, + '& h3': { + ...lightTheme.typography.h6, + fontFamily: `"General Sans", ${lightTheme.typography.fontFamilySystem}`, + fontSize: theme.typography.pxToRem(20), + fontWeight: lightTheme.typography.fontWeightSemiBold, + color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, + margin: '24px 0 4px', + }, + '& h4': { + ...lightTheme.typography.subtitle1, + fontFamily: `"General Sans", ${lightTheme.typography.fontFamilySystem}`, + fontWeight: lightTheme.typography.fontWeightSemiBold, + color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, + margin: '20px 0 6px', + }, + '& h5': { + ...lightTheme.typography.subtitle2, + fontFamily: `"General Sans", ${lightTheme.typography.fontFamilySystem}`, + fontWeight: lightTheme.typography.fontWeightSemiBold, + color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, + margin: '20px 0 8px', + }, + '& p': { + marginTop: 0, + marginBottom: 16, + color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, + }, + '& ul, & ol': { + paddingLeft: 30, + marginTop: 0, + marginBottom: 16, + '& ul, & ol': { + marginBottom: 6, + }, + }, + '& h1, & h2, & h3, & h4': { + display: 'flex', + alignItems: 'center', + gap: 6, + '& code': { + fontSize: 'inherit', + lineHeight: 'inherit', + // Remove scroll on small screens. + wordBreak: 'break-all', + }, + '& .title-link-to-anchor': { + color: 'inherit', + textDecoration: 'none', + position: 'relative', + display: 'flex', + alignItems: 'center', + }, + '& .anchor-icon': { + // To prevent the link to get the focus. + display: 'inline-flex', + alignItems: 'center', + visibility: 'hidden', + }, + '& a:not(.title-link-to-anchor):hover': { + color: 'currentColor', + border: 'none', + boxShadow: '0 1px 0 0 currentColor', + textDecoration: 'none', + }, + '& .anchor-icon, & .comment-link': { + padding: 0, + cursor: 'pointer', + alignItems: 'center', + justifyContent: 'center', + flexShrink: 0, + textAlign: 'center', + marginLeft: 8, + height: 26, + width: 26, + backgroundColor: `var(--muidocs-palette-primary-50, ${lightTheme.palette.grey[50]})`, + color: `var(--muidocs-palette-grey-600, ${lightTheme.palette.grey[600]})`, + border: '1px solid', + borderColor: `var(--muidocs-palette-divider, ${lightTheme.palette.divider})`, + borderRadius: 8, + '&:hover': { + backgroundColor: alpha(lightTheme.palette.primary[100], 0.4), + borderColor: `var(--muidocs-palette-primary-100, ${lightTheme.palette.primary[100]})`, + color: `var(--muidocs-palette-primary-main, ${lightTheme.palette.primary.main})`, + }, + '& svg': { + height: 14, + width: 14, + fill: 'currentColor', + pointerEvents: 'none', + verticalAlign: 'middle', + }, + }, + '&:hover .anchor-icon': { + visibility: 'visible', + }, + '& .comment-link': { + display: 'none', // So we can have the comment button opt-in. + marginLeft: 'auto', + transition: theme.transitions.create('opacity', { + duration: theme.transitions.duration.shortest, + }), + '& svg': { + fill: 'currentColor', + marginRight: 1.5, + }, + }, + }, + '& h1 code, & h2 code, & h3 code': { + color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, + }, + '& h1 code': { + fontWeight: lightTheme.typography.fontWeightSemiBold, + }, + '& h2 code': { + fontSize: lightTheme.typography.pxToRem(24), + fontWeight: lightTheme.typography.fontWeightSemiBold, + }, + '& h3 code': { + fontSize: lightTheme.typography.pxToRem(18), + }, + '& table': { + // Trade display table for scroll overflow + display: 'block', + wordBreak: 'normal', + overflowX: 'auto', + WebkitOverflowScrolling: 'touch', + borderCollapse: 'collapse', + marginBottom: '20px', + borderSpacing: 0, + '& .prop-name, & .prop-type, & .prop-default, & .slot-name, & .slot-defaultClass, & .slot-default': + { + fontWeight: 400, + fontFamily: lightTheme.typography.fontFamilyCode, + WebkitFontSmoothing: 'subpixel-antialiased', + fontSize: lightTheme.typography.pxToRem(13), + }, + '& .required': { + color: '#006500', + }, + '& .optional': { + color: '#45529f', + }, + '& .prop-type, & .slot-defaultClass': { + color: '#932981', + }, + '& .prop-default, & .slot-default': { + borderBottom: `1px dotted var(--muidocs-palette-divider, ${lightTheme.palette.divider})`, + }, + }, + '& td': { + ...theme.typography.body2, + borderBottom: `1px solid var(--muidocs-palette-divider, ${lightTheme.palette.divider})`, + paddingRight: 20, + paddingTop: 16, + paddingBottom: 16, + color: `var(--muidocs-palette-text-secondary, ${lightTheme.palette.text.secondary})`, + }, + '& td code': { + lineHeight: 1.6, + }, + '& th': { + fontSize: theme.typography.pxToRem(14), + lineHeight: theme.typography.pxToRem(24), + fontWeight: 500, + color: `var(--muidocs-palette-text-primary, ${lightTheme.palette.text.primary})`, + whiteSpace: 'pre', + borderBottom: `1px solid var(--muidocs-palette-divider, ${lightTheme.palette.divider})`, + paddingRight: 20, + paddingTop: 12, + paddingBottom: 12, + }, + '& blockquote': { + position: 'relative', + padding: '0 16px', + margin: 0, + borderLeft: '1.5px solid', + borderColor: `var(--muidocs-palette-grey-200, ${lightTheme.palette.grey[200]})`, + '& p': { + fontSize: theme.typography.pxToRem(12.5), + fontFamily: lightTheme.typography.fontFamilyCode, + fontWeight: lightTheme.typography.fontWeightMedium, + lineHeight: theme.typography.pxToRem(24), + textIndent: 20, + }, + '&::before': { + position: 'absolute', + // eslint-disable-next-line material-ui/straight-quotes + content: '"“"', + color: `var(--muidocs-palette-grey-300, ${lightTheme.palette.grey[300]})`, + fontSize: '2.5rem', + top: 8, + marginLeft: -6, + lineHeight: 0.5, + }, + }, + '& .MuiCallout-root': { + display: 'flex', + gap: 12, + padding: '16px', + margin: '16px 0', + border: '1px solid', + color: `var(--muidocs-palette-text-secondary, ${lightTheme.palette.text.secondary})`, + borderColor: `var(--muidocs-palette-grey-100, ${lightTheme.palette.grey[100]})`, + borderRadius: `var(--muidocs-shape-borderRadius, ${ + theme.shape?.borderRadius ?? lightTheme.shape.borderRadius + }px)`, + '& > code': { + height: 'fit-content', + backgroundColor: `var(--muidocs-palette-grey-100, ${lightTheme.palette.grey[100]})`, + borderColor: `var(--muidocs-palette-grey-300, ${lightTheme.palette.grey[300]})`, + }, + '& .MuiCallout-content': { + minWidth: 0, // Allows content to shrink. Useful when callout contains code block + flexGrow: 1, + '& > p:last-child, & > ul:last-child': { + // Avoid margin on last child + marginBottom: 0, + }, + '& .MuiCode-root': { + '& > pre': { + margin: 0, + marginTop: 4, + }, + }, + '& > ul': { + // Because of the gap left by the icon, we visually need less padding + paddingLeft: 22, + }, + }, + '& > svg': { + marginTop: 2, + width: 20, + height: 20, + flexShrink: 0, + }, + '& > ul, & > p': { + '&:last-child': { + margin: 0, + }, + }, + '& ul, li, p': { + color: 'inherit', + }, + '&.MuiCallout-error': { + color: `var(--muidocs-palette-error-900, ${lightTheme.palette.error[900]})`, + backgroundColor: `var(--muidocs-palette-error-50, ${lightTheme.palette.error[50]})`, + borderColor: `var(--muidocs-palette-error-100, ${lightTheme.palette.error[100]})`, + '& strong': { + color: `var(--muidocs-palette-error-800, ${lightTheme.palette.error[800]})`, + }, + '& > svg': { + fill: `var(--muidocs-palette-error-500, ${lightTheme.palette.error[600]})`, + }, + '& a': { + color: `var(--muidocs-palette-error-800, ${lightTheme.palette.error[800]})`, + textDecorationColor: alpha(lightTheme.palette.error.main, 0.4), + '&:hover': { + textDecorationColor: 'inherit', + }, + }, + }, + '&.MuiCallout-info': { + color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, + backgroundColor: `var(--muidocs-palette-grey-50, ${lightTheme.palette.grey[50]})`, + borderColor: `var(--muidocs-palette-grey-100, ${lightTheme.palette.grey[100]})`, + '& strong': { + color: `var(--muidocs-palette-primary-800, ${lightTheme.palette.primary[800]})`, + }, + '& > svg': { + fill: `var(--muidocs-palette-grey-600, ${lightTheme.palette.grey[600]})`, + }, + }, + '&.MuiCallout-success': { + color: `var(--muidocs-palette-success-900, ${lightTheme.palette.success[900]})`, + backgroundColor: `var(--muidocs-palette-success-50, ${lightTheme.palette.success[50]})`, + borderColor: `var(--muidocs-palette-success-100, ${lightTheme.palette.success[100]})`, + '& strong': { + color: `var(--muidocs-palette-success-900, ${lightTheme.palette.success[900]})`, + }, + '& > svg': { + fill: `var(--muidocs-palette-success-600, ${lightTheme.palette.success[600]})`, + }, + '& a': { + color: `var(--muidocs-palette-success-900, ${lightTheme.palette.success[900]})`, + textDecorationColor: alpha(lightTheme.palette.success.main, 0.4), + '&:hover': { + textDecorationColor: 'inherit', + }, + }, + }, + '&.MuiCallout-warning': { + color: `var(--muidocs-palette-grey-900, ${lightTheme.palette.grey[900]})`, + backgroundColor: alpha(lightTheme.palette.warning[50], 0.5), + borderColor: alpha(lightTheme.palette.warning[700], 0.15), + '& strong': { + color: `var(--muidocs-palette-warning-800, ${lightTheme.palette.warning[800]})`, + }, + '& > svg': { + fill: `var(--muidocs-palette-warning-600, ${lightTheme.palette.warning[600]})`, + }, + '& a': { + color: `var(--muidocs-palette-warning-800, ${lightTheme.palette.warning[800]})`, + textDecorationColor: alpha(lightTheme.palette.warning.main, 0.4), + '&:hover': { + textDecorationColor: 'inherit', + }, + }, + }, + }, + '& a[target="_blank"]::after': { + content: '""', + maskImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' focusable='false' aria-hidden='true' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M6 6v2h8.59L5 17.59 6.41 19 16 9.41V18h2V6z'%3E%3C/path%3E%3C/svg%3E")`, + display: 'inline-flex', + width: '1em', + height: '1em', + color: 'inherit', + backgroundColor: 'currentColor', + transform: 'translate(0, 2px)', + transition: 'transform 0.3s cubic-bezier(0.1, 0.8, 0.3, 1)', // bounce effect + opacity: 0.8, + }, + '& a[target="_blank"]:hover::after': { + opacity: 1, + transform: 'translate(1px, 0)', + }, + '& a.remove-link-arrow::after': { + // Allows to remove link arrows for images + display: 'none', + }, + '& .Ad-root a::after': { + // Remove link arrow for ads + display: 'none', + }, + '& a:not(.title-link-to-anchor), & a:not(.title-link-to-anchor) code': { + // Style taken from the Link component + color: `var(--muidocs-palette-primary-600, ${lightTheme.palette.primary[600]})`, + fontWeight: theme.typography.fontWeightMedium, + textDecoration: 'underline', + textDecorationColor: alpha(lightTheme.palette.primary.main, 0.4), + '&:hover': { + textDecorationColor: 'inherit', + }, + }, + '& a code': { + color: darken(lightTheme.palette.primary.main, 0.04), + }, + '& a:not(.title-link-to-anchor) code': { + color: darken(lightTheme.palette.primary.main, 0.2), + }, + '& img, & video': { + // Use !important so that inline style on or