From 262d09da53b3f600032732372ba4d29a8a63bfef Mon Sep 17 00:00:00 2001 From: Bharat Kashyap Date: Wed, 3 Apr 2024 17:47:47 +0530 Subject: [PATCH 01/13] feat: Rebase onto `next` --- .../components/autocomplete/ComboBox.js | 129 +------------ .../components/autocomplete/ComboBox.tsx | 129 +------------ .../components/autocomplete/top100Films.js | 129 +++++++++++++ docs/src/modules/components/Demo.js | 182 ++++++++++++++---- docs/src/modules/components/DemoEditor.tsx | 21 +- docs/src/modules/components/DemoToolbar.js | 20 +- .../components/HighlightedCodeWithTabs.tsx | 134 +++++++------ .../src/modules/components/MarkdownElement.js | 2 +- .../modules/components/RichMarkdownElement.js | 5 +- packages/markdown/loader.js | 122 ++++++++++-- .../mui-docs/src/branding/brandingTheme.ts | 4 +- 11 files changed, 490 insertions(+), 387 deletions(-) create mode 100644 docs/data/material/components/autocomplete/top100Films.js diff --git a/docs/data/material/components/autocomplete/ComboBox.js b/docs/data/material/components/autocomplete/ComboBox.js index 4e515937746cb4..ceeb0eb96834a4 100644 --- a/docs/data/material/components/autocomplete/ComboBox.js +++ b/docs/data/material/components/autocomplete/ComboBox.js @@ -1,6 +1,7 @@ import * as React from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; export default function ComboBox() { return ( @@ -13,131 +14,3 @@ export default function ComboBox() { /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { label: 'The Shawshank Redemption', year: 1994 }, - { label: 'The Godfather', year: 1972 }, - { label: 'The Godfather: Part II', year: 1974 }, - { label: 'The Dark Knight', year: 2008 }, - { label: '12 Angry Men', year: 1957 }, - { label: "Schindler's List", year: 1993 }, - { label: 'Pulp Fiction', year: 1994 }, - { - label: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { label: 'The Good, the Bad and the Ugly', year: 1966 }, - { label: 'Fight Club', year: 1999 }, - { - label: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - label: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { label: 'Forrest Gump', year: 1994 }, - { label: 'Inception', year: 2010 }, - { - label: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { label: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { label: 'Goodfellas', year: 1990 }, - { label: 'The Matrix', year: 1999 }, - { label: 'Seven Samurai', year: 1954 }, - { - label: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { label: 'City of God', year: 2002 }, - { label: 'Se7en', year: 1995 }, - { label: 'The Silence of the Lambs', year: 1991 }, - { label: "It's a Wonderful Life", year: 1946 }, - { label: 'Life Is Beautiful', year: 1997 }, - { label: 'The Usual Suspects', year: 1995 }, - { label: 'Léon: The Professional', year: 1994 }, - { label: 'Spirited Away', year: 2001 }, - { label: 'Saving Private Ryan', year: 1998 }, - { label: 'Once Upon a Time in the West', year: 1968 }, - { label: 'American History X', year: 1998 }, - { label: 'Interstellar', year: 2014 }, - { label: 'Casablanca', year: 1942 }, - { label: 'City Lights', year: 1931 }, - { label: 'Psycho', year: 1960 }, - { label: 'The Green Mile', year: 1999 }, - { label: 'The Intouchables', year: 2011 }, - { label: 'Modern Times', year: 1936 }, - { label: 'Raiders of the Lost Ark', year: 1981 }, - { label: 'Rear Window', year: 1954 }, - { label: 'The Pianist', year: 2002 }, - { label: 'The Departed', year: 2006 }, - { label: 'Terminator 2: Judgment Day', year: 1991 }, - { label: 'Back to the Future', year: 1985 }, - { label: 'Whiplash', year: 2014 }, - { label: 'Gladiator', year: 2000 }, - { label: 'Memento', year: 2000 }, - { label: 'The Prestige', year: 2006 }, - { label: 'The Lion King', year: 1994 }, - { label: 'Apocalypse Now', year: 1979 }, - { label: 'Alien', year: 1979 }, - { label: 'Sunset Boulevard', year: 1950 }, - { - label: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { label: 'The Great Dictator', year: 1940 }, - { label: 'Cinema Paradiso', year: 1988 }, - { label: 'The Lives of Others', year: 2006 }, - { label: 'Grave of the Fireflies', year: 1988 }, - { label: 'Paths of Glory', year: 1957 }, - { label: 'Django Unchained', year: 2012 }, - { label: 'The Shining', year: 1980 }, - { label: 'WALL·E', year: 2008 }, - { label: 'American Beauty', year: 1999 }, - { label: 'The Dark Knight Rises', year: 2012 }, - { label: 'Princess Mononoke', year: 1997 }, - { label: 'Aliens', year: 1986 }, - { label: 'Oldboy', year: 2003 }, - { label: 'Once Upon a Time in America', year: 1984 }, - { label: 'Witness for the Prosecution', year: 1957 }, - { label: 'Das Boot', year: 1981 }, - { label: 'Citizen Kane', year: 1941 }, - { label: 'North by Northwest', year: 1959 }, - { label: 'Vertigo', year: 1958 }, - { - label: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { label: 'Reservoir Dogs', year: 1992 }, - { label: 'Braveheart', year: 1995 }, - { label: 'M', year: 1931 }, - { label: 'Requiem for a Dream', year: 2000 }, - { label: 'Amélie', year: 2001 }, - { label: 'A Clockwork Orange', year: 1971 }, - { label: 'Like Stars on Earth', year: 2007 }, - { label: 'Taxi Driver', year: 1976 }, - { label: 'Lawrence of Arabia', year: 1962 }, - { label: 'Double Indemnity', year: 1944 }, - { - label: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { label: 'Amadeus', year: 1984 }, - { label: 'To Kill a Mockingbird', year: 1962 }, - { label: 'Toy Story 3', year: 2010 }, - { label: 'Logan', year: 2017 }, - { label: 'Full Metal Jacket', year: 1987 }, - { label: 'Dangal', year: 2016 }, - { label: 'The Sting', year: 1973 }, - { label: '2001: A Space Odyssey', year: 1968 }, - { label: "Singin' in the Rain", year: 1952 }, - { label: 'Toy Story', year: 1995 }, - { label: 'Bicycle Thieves', year: 1948 }, - { label: 'The Kid', year: 1921 }, - { label: 'Inglourious Basterds', year: 2009 }, - { label: 'Snatch', year: 2000 }, - { label: '3 Idiots', year: 2009 }, - { label: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/ComboBox.tsx b/docs/data/material/components/autocomplete/ComboBox.tsx index 4e515937746cb4..ceeb0eb96834a4 100644 --- a/docs/data/material/components/autocomplete/ComboBox.tsx +++ b/docs/data/material/components/autocomplete/ComboBox.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; export default function ComboBox() { return ( @@ -13,131 +14,3 @@ export default function ComboBox() { /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { label: 'The Shawshank Redemption', year: 1994 }, - { label: 'The Godfather', year: 1972 }, - { label: 'The Godfather: Part II', year: 1974 }, - { label: 'The Dark Knight', year: 2008 }, - { label: '12 Angry Men', year: 1957 }, - { label: "Schindler's List", year: 1993 }, - { label: 'Pulp Fiction', year: 1994 }, - { - label: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { label: 'The Good, the Bad and the Ugly', year: 1966 }, - { label: 'Fight Club', year: 1999 }, - { - label: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - label: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { label: 'Forrest Gump', year: 1994 }, - { label: 'Inception', year: 2010 }, - { - label: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { label: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { label: 'Goodfellas', year: 1990 }, - { label: 'The Matrix', year: 1999 }, - { label: 'Seven Samurai', year: 1954 }, - { - label: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { label: 'City of God', year: 2002 }, - { label: 'Se7en', year: 1995 }, - { label: 'The Silence of the Lambs', year: 1991 }, - { label: "It's a Wonderful Life", year: 1946 }, - { label: 'Life Is Beautiful', year: 1997 }, - { label: 'The Usual Suspects', year: 1995 }, - { label: 'Léon: The Professional', year: 1994 }, - { label: 'Spirited Away', year: 2001 }, - { label: 'Saving Private Ryan', year: 1998 }, - { label: 'Once Upon a Time in the West', year: 1968 }, - { label: 'American History X', year: 1998 }, - { label: 'Interstellar', year: 2014 }, - { label: 'Casablanca', year: 1942 }, - { label: 'City Lights', year: 1931 }, - { label: 'Psycho', year: 1960 }, - { label: 'The Green Mile', year: 1999 }, - { label: 'The Intouchables', year: 2011 }, - { label: 'Modern Times', year: 1936 }, - { label: 'Raiders of the Lost Ark', year: 1981 }, - { label: 'Rear Window', year: 1954 }, - { label: 'The Pianist', year: 2002 }, - { label: 'The Departed', year: 2006 }, - { label: 'Terminator 2: Judgment Day', year: 1991 }, - { label: 'Back to the Future', year: 1985 }, - { label: 'Whiplash', year: 2014 }, - { label: 'Gladiator', year: 2000 }, - { label: 'Memento', year: 2000 }, - { label: 'The Prestige', year: 2006 }, - { label: 'The Lion King', year: 1994 }, - { label: 'Apocalypse Now', year: 1979 }, - { label: 'Alien', year: 1979 }, - { label: 'Sunset Boulevard', year: 1950 }, - { - label: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { label: 'The Great Dictator', year: 1940 }, - { label: 'Cinema Paradiso', year: 1988 }, - { label: 'The Lives of Others', year: 2006 }, - { label: 'Grave of the Fireflies', year: 1988 }, - { label: 'Paths of Glory', year: 1957 }, - { label: 'Django Unchained', year: 2012 }, - { label: 'The Shining', year: 1980 }, - { label: 'WALL·E', year: 2008 }, - { label: 'American Beauty', year: 1999 }, - { label: 'The Dark Knight Rises', year: 2012 }, - { label: 'Princess Mononoke', year: 1997 }, - { label: 'Aliens', year: 1986 }, - { label: 'Oldboy', year: 2003 }, - { label: 'Once Upon a Time in America', year: 1984 }, - { label: 'Witness for the Prosecution', year: 1957 }, - { label: 'Das Boot', year: 1981 }, - { label: 'Citizen Kane', year: 1941 }, - { label: 'North by Northwest', year: 1959 }, - { label: 'Vertigo', year: 1958 }, - { - label: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { label: 'Reservoir Dogs', year: 1992 }, - { label: 'Braveheart', year: 1995 }, - { label: 'M', year: 1931 }, - { label: 'Requiem for a Dream', year: 2000 }, - { label: 'Amélie', year: 2001 }, - { label: 'A Clockwork Orange', year: 1971 }, - { label: 'Like Stars on Earth', year: 2007 }, - { label: 'Taxi Driver', year: 1976 }, - { label: 'Lawrence of Arabia', year: 1962 }, - { label: 'Double Indemnity', year: 1944 }, - { - label: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { label: 'Amadeus', year: 1984 }, - { label: 'To Kill a Mockingbird', year: 1962 }, - { label: 'Toy Story 3', year: 2010 }, - { label: 'Logan', year: 2017 }, - { label: 'Full Metal Jacket', year: 1987 }, - { label: 'Dangal', year: 2016 }, - { label: 'The Sting', year: 1973 }, - { label: '2001: A Space Odyssey', year: 1968 }, - { label: "Singin' in the Rain", year: 1952 }, - { label: 'Toy Story', year: 1995 }, - { label: 'Bicycle Thieves', year: 1948 }, - { label: 'The Kid', year: 1921 }, - { label: 'Inglourious Basterds', year: 2009 }, - { label: 'Snatch', year: 2000 }, - { label: '3 Idiots', year: 2009 }, - { label: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/top100Films.js b/docs/data/material/components/autocomplete/top100Films.js new file mode 100644 index 00000000000000..3226dcbc8ba7f3 --- /dev/null +++ b/docs/data/material/components/autocomplete/top100Films.js @@ -0,0 +1,129 @@ +// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top +const top100Films = [ + { label: 'The Shawshank Redemption', year: 1994 }, + { label: 'The Godfather', year: 1972 }, + { label: 'The Godfather: Part II', year: 1974 }, + { label: 'The Dark Knight', year: 2008 }, + { label: '12 Angry Men', year: 1957 }, + { label: "Schindler's List", year: 1993 }, + { label: 'Pulp Fiction', year: 1994 }, + { + label: 'The Lord of the Rings: The Return of the King', + year: 2003, + }, + { label: 'The Good, the Bad and the Ugly', year: 1966 }, + { label: 'Fight Club', year: 1999 }, + { + label: 'The Lord of the Rings: The Fellowship of the Ring', + year: 2001, + }, + { + label: 'Star Wars: Episode V - The Empire Strikes Back', + year: 1980, + }, + { label: 'Forrest Gump', year: 1994 }, + { label: 'Inception', year: 2010 }, + { + label: 'The Lord of the Rings: The Two Towers', + year: 2002, + }, + { label: "One Flew Over the Cuckoo's Nest", year: 1975 }, + { label: 'Goodfellas', year: 1990 }, + { label: 'The Matrix', year: 1999 }, + { label: 'Seven Samurai', year: 1954 }, + { + label: 'Star Wars: Episode IV - A New Hope', + year: 1977, + }, + { label: 'City of God', year: 2002 }, + { label: 'Se7en', year: 1995 }, + { label: 'The Silence of the Lambs', year: 1991 }, + { label: "It's a Wonderful Life", year: 1946 }, + { label: 'Life Is Beautiful', year: 1997 }, + { label: 'The Usual Suspects', year: 1995 }, + { label: 'Léon: The Professional', year: 1994 }, + { label: 'Spirited Away', year: 2001 }, + { label: 'Saving Private Ryan', year: 1998 }, + { label: 'Once Upon a Time in the West', year: 1968 }, + { label: 'American History X', year: 1998 }, + { label: 'Interstellar', year: 2014 }, + { label: 'Casablanca', year: 1942 }, + { label: 'City Lights', year: 1931 }, + { label: 'Psycho', year: 1960 }, + { label: 'The Green Mile', year: 1999 }, + { label: 'The Intouchables', year: 2011 }, + { label: 'Modern Times', year: 1936 }, + { label: 'Raiders of the Lost Ark', year: 1981 }, + { label: 'Rear Window', year: 1954 }, + { label: 'The Pianist', year: 2002 }, + { label: 'The Departed', year: 2006 }, + { label: 'Terminator 2: Judgment Day', year: 1991 }, + { label: 'Back to the Future', year: 1985 }, + { label: 'Whiplash', year: 2014 }, + { label: 'Gladiator', year: 2000 }, + { label: 'Memento', year: 2000 }, + { label: 'The Prestige', year: 2006 }, + { label: 'The Lion King', year: 1994 }, + { label: 'Apocalypse Now', year: 1979 }, + { label: 'Alien', year: 1979 }, + { label: 'Sunset Boulevard', year: 1950 }, + { + label: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', + year: 1964, + }, + { label: 'The Great Dictator', year: 1940 }, + { label: 'Cinema Paradiso', year: 1988 }, + { label: 'The Lives of Others', year: 2006 }, + { label: 'Grave of the Fireflies', year: 1988 }, + { label: 'Paths of Glory', year: 1957 }, + { label: 'Django Unchained', year: 2012 }, + { label: 'The Shining', year: 1980 }, + { label: 'WALL·E', year: 2008 }, + { label: 'American Beauty', year: 1999 }, + { label: 'The Dark Knight Rises', year: 2012 }, + { label: 'Princess Mononoke', year: 1997 }, + { label: 'Aliens', year: 1986 }, + { label: 'Oldboy', year: 2003 }, + { label: 'Once Upon a Time in America', year: 1984 }, + { label: 'Witness for the Prosecution', year: 1957 }, + { label: 'Das Boot', year: 1981 }, + { label: 'Citizen Kane', year: 1941 }, + { label: 'North by Northwest', year: 1959 }, + { label: 'Vertigo', year: 1958 }, + { + label: 'Star Wars: Episode VI - Return of the Jedi', + year: 1983, + }, + { label: 'Reservoir Dogs', year: 1992 }, + { label: 'Braveheart', year: 1995 }, + { label: 'M', year: 1931 }, + { label: 'Requiem for a Dream', year: 2000 }, + { label: 'Amélie', year: 2001 }, + { label: 'A Clockwork Orange', year: 1971 }, + { label: 'Like Stars on Earth', year: 2007 }, + { label: 'Taxi Driver', year: 1976 }, + { label: 'Lawrence of Arabia', year: 1962 }, + { label: 'Double Indemnity', year: 1944 }, + { + label: 'Eternal Sunshine of the Spotless Mind', + year: 2004, + }, + { label: 'Amadeus', year: 1984 }, + { label: 'To Kill a Mockingbird', year: 1962 }, + { label: 'Toy Story 3', year: 2010 }, + { label: 'Logan', year: 2017 }, + { label: 'Full Metal Jacket', year: 1987 }, + { label: 'Dangal', year: 2016 }, + { label: 'The Sting', year: 1973 }, + { label: '2001: A Space Odyssey', year: 1968 }, + { label: "Singin' in the Rain", year: 1952 }, + { label: 'Toy Story', year: 1995 }, + { label: 'Bicycle Thieves', year: 1948 }, + { label: 'The Kid', year: 1921 }, + { label: 'Inglourious Basterds', year: 2009 }, + { label: 'Snatch', year: 2000 }, + { label: '3 Idiots', year: 2009 }, + { label: 'Monty Python and the Holy Grail', year: 1975 }, +]; + +export default top100Films; diff --git a/docs/src/modules/components/Demo.js b/docs/src/modules/components/Demo.js index 4bebe7324c9390..674fb346d39b9b 100644 --- a/docs/src/modules/components/Demo.js +++ b/docs/src/modules/components/Demo.js @@ -4,6 +4,8 @@ import { useRouter } from 'next/router'; import { debounce } from '@mui/material/utils'; import { alpha, styled } from '@mui/material/styles'; import { styled as joyStyled } from '@mui/joy/styles'; +import { Tabs } from '@mui/base/Tabs'; +import { TabPanel } from '@mui/base/TabPanel'; import { unstable_useId as useId } from '@mui/utils'; import IconButton from '@mui/material/IconButton'; import Box from '@mui/material/Box'; @@ -21,8 +23,9 @@ import { useCodeStyling } from 'docs/src/modules/utils/codeStylingSolution'; import { CODE_VARIANTS, CODE_STYLING } from 'docs/src/modules/constants'; import { useUserLanguage, useTranslate } from '@mui/docs/i18n'; import stylingSolutionMapping from 'docs/src/modules/utils/stylingSolutionMapping'; -import { BrandingProvider, blue, blueDark, grey } from '@mui/docs/branding'; import DemoToolbarRoot from 'docs/src/modules/components/DemoToolbarRoot'; +import { BrandingProvider, blue, blueDark, grey } from '@mui/docs/branding'; +import { CodeTab, CodeTabList } from 'docs/src/modules/components/HighlightedCodeWithTabs'; /** * Removes leading spaces (indentation) present in the `.tsx` previews @@ -68,24 +71,31 @@ function useDemoData(codeVariant, demo, githubLocation, codeStyling) { } let codeOptions = {}; - if (codeStyling === CODE_STYLING.SYSTEM) { if (codeVariant === CODE_VARIANTS.TS && demo.rawTS) { codeOptions = { codeVariant: CODE_VARIANTS.TS, githubLocation: githubLocation.replace(/\.js$/, '.tsx'), raw: demo.rawTS, - Component: demo.tsx, + module: demo.moduleTS, + Component: demo.tsx ?? null, sourceLanguage: 'tsx', }; + if (demo.relativeModules) { + codeOptions.relativeModules = demo.relativeModules[CODE_VARIANTS.TS]; + } } else { codeOptions = { codeVariant: CODE_VARIANTS.JS, githubLocation, raw: demo.raw, + module: demo.module, Component: demo.js, sourceLanguage: 'jsx', }; + if (demo.relativeModules) { + codeOptions.relativeModules = demo.relativeModules[CODE_VARIANTS.JS]; + } } } else if (codeStyling === CODE_STYLING.TAILWIND) { if (codeVariant === CODE_VARIANTS.TS && demo.rawTailwindTS) { @@ -93,6 +103,7 @@ function useDemoData(codeVariant, demo, githubLocation, codeStyling) { codeVariant: CODE_VARIANTS.TS, githubLocation: githubLocation.replace(/\/system\/index\.js$/, '/tailwind/index.tsx'), raw: demo.rawTailwindTS, + module: demo.moduleTS, Component: demo.tsxTailwind, sourceLanguage: 'tsx', }; @@ -101,6 +112,7 @@ function useDemoData(codeVariant, demo, githubLocation, codeStyling) { codeVariant: CODE_VARIANTS.JS, githubLocation: githubLocation.replace(/\/system\/index\.js$/, '/tailwind/index.js'), raw: demo.rawTailwind ?? demo.raw, + module: demo.module, Component: demo.jsTailwind ?? demo.js, sourceLanguage: 'jsx', }; @@ -111,6 +123,7 @@ function useDemoData(codeVariant, demo, githubLocation, codeStyling) { codeVariant: CODE_VARIANTS.TS, githubLocation: githubLocation.replace(/\/system\/index\.js$/, '/css/index.tsx'), raw: demo.rawCSSTS, + module: demo.moduleTS, Component: demo.tsxCSS, sourceLanguage: 'tsx', }; @@ -119,6 +132,7 @@ function useDemoData(codeVariant, demo, githubLocation, codeStyling) { codeVariant: CODE_VARIANTS.JS, githubLocation: githubLocation.replace(/\/system\/index\.js$/, '/css/index.js'), raw: demo.rawCSS ?? demo.raw, + module: demo.module, Component: demo.jsCSS ?? demo.js, sourceLanguage: 'jsx', }; @@ -220,6 +234,7 @@ const DemoRootMaterial = styled('div', { borderRightWidth: 0, ...theme.applyDarkStyles({ backgroundColor: alpha(theme.palette.primaryDark[700], 0.1), + borderBottom: 0, }), }), /* Similar to the outlined one but without padding. Ideal for playground demos. */ @@ -327,9 +342,12 @@ const DemoRootJoy = joyStyled('div', { const DemoCodeViewer = styled(HighlightedCode)(() => ({ '& pre': { margin: 0, + marginTop: -1, maxHeight: 'min(68vh, 1000px)', maxWidth: 'initial', borderRadius: 0, + borderBottomLeftRadius: 12, + borderBottomRightRadius: 12, }, })); @@ -347,6 +365,25 @@ const InitialFocus = styled(IconButton)(({ theme }) => ({ pointerEvents: 'none', })); +const bordersOverride = { + borderTopLeftRadius: 0, + borderTopRightRadius: 0, +}; + +const selectionOverride = (theme) => ({ + cursor: 'pointer', + '&.base--selected': { + color: (theme.vars || theme).palette.primary[700], + backgroundColor: (theme.vars || theme).palette.primary[50], + borderColor: (theme.vars || theme).palette.primary[200], + ...theme.applyDarkStyles({ + color: (theme.vars || theme).palette.primary[200], + backgroundColor: alpha((theme.vars || theme).palette.primary[900], 0.4), + borderColor: (theme.vars || theme).palette.primary[800], + }), + }, +}); + export default function Demo(props) { const { demo, demoOptions, disableAd, githubLocation, mode } = props; @@ -495,6 +532,32 @@ export default function Demo(props) { liveDemoActive, }); + const [activeTab, setActiveTab] = React.useState(0); + const handleTabChange = (event, newValue) => { + setActiveTab(newValue); + }; + const ownerState = { mounted: true, contained: true }; + + const tabs = React.useMemo(() => { + if (!demoData.relativeModules) { + return [{ module: demoData.module, raw: demoData.raw }]; + } + let demoModule = demoData.module; + if (codeVariant === CODE_VARIANTS.TS && demo.moduleTS) { + demoModule = + demo.moduleTS === demo.module ? demoData.module.replace(/\.js$/, '.tsx') : demo.moduleTS; + } + + return [{ module: demoModule, raw: demoData.raw }, ...demoData.relativeModules]; + }, [ + codeVariant, + demo.moduleTS, + demo.module, + demoData.module, + demoData.raw, + demoData.relativeModules, + ]); + return ( @@ -553,46 +616,81 @@ export default function Demo(props) { - - {/* A limitation from https://github.com/nihgwu/react-runner, + + {demoData.relativeModules && openDemoSource && !editorCode.isPreview ? ( + + {tabs.map((tab, index) => ( + + {tab.module} + + ))} + + ) : null} + + {/* A limitation from https://github.com/nihgwu/react-runner, we can't inject the `window` of the iframe so we need a disableLiveEdit option. */} - {demoOptions.disableLiveEdit ? ( - - ) : ( - { - setEditorCode({ - ...editorCode, - value, - }); - }} - onFocus={() => { - setLiveDemoActive(true); - }} - id={demoSourceId} - language={demoData.sourceLanguage} - copyButtonProps={{ - 'data-ga-event-category': codeOpen ? 'demo-expand' : 'demo', - 'data-ga-event-label': demo.gaLabel, - 'data-ga-event-action': 'copy-click', - }} - > - {debouncedError} - - )} - + {demoOptions.disableLiveEdit + ? tabs.map((tab, index) => ( + + )) + : tabs.map((tab, index) => ( + + {index === 0 ? ( + { + setEditorCode({ + ...editorCode, + value, + }); + }} + onFocus={() => { + setLiveDemoActive(true); + }} + id={demoSourceId} + language={demoData.sourceLanguage} + copyButtonProps={{ + 'data-ga-event-category': codeOpen ? 'demo-expand' : 'demo', + 'data-ga-event-label': demo.gaLabel, + 'data-ga-event-action': 'copy-click', + }} + > + {debouncedError} + + ) : ( + + )} + + ))} + + {adVisibility ? : null} )} diff --git a/docs/src/modules/components/DemoEditor.tsx b/docs/src/modules/components/DemoEditor.tsx index e32390019b3f63..3c04c63dbd73e2 100644 --- a/docs/src/modules/components/DemoEditor.tsx +++ b/docs/src/modules/components/DemoEditor.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import SimpleCodeEditor from 'react-simple-code-editor'; import Box from '@mui/material/Box'; import { NoSsr } from '@mui/base/NoSsr'; -import { styled, useTheme } from '@mui/material/styles'; +import { styled, useTheme, alpha } from '@mui/material/styles'; import prism from '@mui/internal-markdown/prism'; import MarkdownElement from 'docs/src/modules/components/MarkdownElement'; import CodeCopyButton from 'docs/src/modules/components/CodeCopyButton'; @@ -17,17 +17,21 @@ const StyledMarkdownElement = styled(MarkdownElement)(({ theme }) => [ overflow: 'auto', marginTop: -1, backgroundColor: '#0F1924', // a special, one-off, color tailored for the code blocks using MUI's branding theme blue palette as the starting point. It has a less saturaded color but still maintaining a bit of the blue tint. + borderTop: 0, border: `1px solid ${(theme.vars || theme).palette.divider}`, colorScheme: 'dark', '&:hover': { - boxShadow: `0 0 0 3px ${(theme.vars || theme).palette.primary.light}`, + boxShadow: `0 0 0 3px ${alpha((theme.vars || theme).palette.primary[500], 0.5)}`, }, '&:focus-within': { - boxShadow: `0 0 0 2px ${(theme.vars || theme).palette.primary.main}`, + boxShadow: `0 0 0 3px ${alpha((theme.vars || theme).palette.primary[500], 0.8)}`, }, [theme.breakpoints.up('sm')]: { borderRadius: '0 0 12px 12px', }, + ...theme.applyDarkStyles({ + borderTop: 1, + }), }, '& pre': { // The scroll container needs to be the parent of the editor, overriding: @@ -36,17 +40,6 @@ const StyledMarkdownElement = styled(MarkdownElement)(({ theme }) => [ maxHeight: 'initial', }, }, - theme.applyDarkStyles({ - '& .scrollContainer': { - borderColor: (theme.vars || theme).palette.divider, - '&:hover': { - boxShadow: `0 0 0 3px ${(theme.vars || theme).palette.primaryDark[300]}`, - }, - '&:focus-within': { - boxShadow: `0 0 0 2px ${(theme.vars || theme).palette.primaryDark[400]}`, - }, - }, - }), ]) as any; const StyledSimpleCodeEditor = styled(SimpleCodeEditor)(({ theme }) => ({ diff --git a/docs/src/modules/components/DemoToolbar.js b/docs/src/modules/components/DemoToolbar.js index bb057eb447e4a4..fb2d64bdc7891d 100644 --- a/docs/src/modules/components/DemoToolbar.js +++ b/docs/src/modules/components/DemoToolbar.js @@ -84,8 +84,8 @@ const ToggleButtonGroup = styled(MDToggleButtonGroup)(({ theme }) => [ ]); const Button = styled(MDButton)(({ theme }) => ({ - height: 24, - padding: '5px 8px 6px 8px', // the one-off 5px is for visually centering the text on the button's container + height: 26, + padding: '6px 8px', flexShrink: 0, borderRadius: 999, border: '1px solid', @@ -130,6 +130,7 @@ const MenuItem = styled(MDMenuItem)(({ theme }) => ({ const ToggleButton = styled(MDToggleButton)(({ theme }) => [ theme.unstable_sx({ + height: 26, padding: theme.spacing(0, 1, 0.1, 1), fontSize: theme.typography.pxToRem(13), borderColor: 'grey.200', @@ -281,6 +282,18 @@ function useToolbar(controlRefs, options = {}) { }; } +function copyWithRelativeModules(raw, relativeModules) { + if (relativeModules) { + relativeModules.forEach(({ module, raw: content }) => { + // remove exports from relative module + content = content.replace(/export( )*(default)*( )*\w+;|export default|export/gm, ''); + // replace import statement with relative module content + raw = raw.replace(new RegExp(`import (.*) from '${module}';`, 'g'), content); + }); + } + return copy(raw); +} + export default function DemoToolbar(props) { const { codeOpen, @@ -332,9 +345,10 @@ export default function DemoToolbar(props) { const handleSnackbarClose = () => { setSnackbarOpen(false); }; + const handleCopyClick = async () => { try { - await copy(demoData.raw); + await copyWithRelativeModules(demoData.raw); setSnackbarMessage(t('copiedSource')); setSnackbarOpen(true); } finally { diff --git a/docs/src/modules/components/HighlightedCodeWithTabs.tsx b/docs/src/modules/components/HighlightedCodeWithTabs.tsx index 7372011ff47f06..9ea6bd0abf59d5 100644 --- a/docs/src/modules/components/HighlightedCodeWithTabs.tsx +++ b/docs/src/modules/components/HighlightedCodeWithTabs.tsx @@ -7,22 +7,35 @@ import { Tab as TabBase } from '@mui/base/Tab'; import useLocalStorageState from '@mui/utils/useLocalStorageState'; import HighlightedCode from './HighlightedCode'; -const TabList = styled(TabsListBase)(({ theme }) => ({ - padding: 6, +export const CodeTabList = styled(TabsListBase)<{ + ownerState: { mounted: boolean; contained?: boolean }; +}>(({ theme, ownerState }) => ({ + padding: ownerState?.contained ? theme.spacing(1.5, 1) : theme.spacing(1), display: 'flex', - border: '1px solid', - borderColor: (theme.vars || theme).palette.primaryDark[700], - backgroundColor: (theme.vars || theme).palette.primaryDark[900], - borderTopLeftRadius: (theme.vars || theme).shape.borderRadius, - borderTopRightRadius: (theme.vars || theme).shape.borderRadius, + gap: theme.spacing(0.5), + borderLeft: '1px solid', + borderRight: '1px solid', + borderTop: ownerState?.contained ? 'none' : '1px solid', + borderBottom: ownerState?.contained ? 'none' : '1px solid', + borderTopLeftRadius: ownerState?.contained ? 0 : (theme.vars || theme).shape.borderRadius, + borderTopRightRadius: ownerState?.contained ? 0 : (theme.vars || theme).shape.borderRadius, + borderColor: ownerState?.contained + ? (theme.vars || theme).palette.divider + : (theme.vars || theme).palette.primaryDark[700], + backgroundColor: ownerState?.contained + ? alpha(theme.palette.grey[50], 0.2) + : (theme.vars || theme).palette.primaryDark[900], ...theme.applyDarkStyles({ - backgroundColor: alpha(theme.palette.primaryDark[800], 0.5), + backgroundColor: alpha(theme.palette.primaryDark[800], 0.2), }), })); -const TabPanel = styled(TabPanelBase)<{ ownerState: { mounted: boolean } }>(({ ownerState }) => ({ +export const CodeTabPanel = styled(TabPanelBase)<{ + ownerState: { mounted: boolean; contained?: boolean }; +}>(({ ownerState }) => ({ + marginTop: ownerState?.contained ? -1 : 0, '& pre': { - marginTop: -1, + marginTop: ownerState?.contained ? 0 : -1, borderTopLeftRadius: 0, borderTopRightRadius: 0, '& code': { @@ -31,46 +44,59 @@ const TabPanel = styled(TabPanelBase)<{ ownerState: { mounted: boolean } }>(({ o }, })); -const Tab = styled(TabBase)<{ ownerState: { mounted: boolean } }>(({ theme, ownerState }) => - theme.unstable_sx({ - p: 0.8, - border: 'none', - bgcolor: 'transparent', - color: (theme.vars || theme).palette.grey[500], - fontSize: theme.typography.pxToRem(12), - fontWeight: theme.typography.fontWeightSemiBold, - fontFamily: theme.typography.fontFamilyCode, - outline: 'none', - minWidth: 52, - cursor: 'pointer', - borderRadius: '8px', - position: 'relative', - '&:not(:first-of-type)': { - marginLeft: 0.5, - }, - ...(ownerState.mounted && { - '&.base--selected': { - color: '#FFF', - '&::after': { - content: "''", - position: 'absolute', - left: 0, - bottom: '-6px', - height: 2, - width: '100%', - bgcolor: (theme.vars || theme).palette.primary.light, - }, +export const CodeTab = styled(TabBase)<{ ownerState: { mounted: boolean; contained?: boolean } }>( + ({ theme, ownerState }) => + theme.unstable_sx({ + height: 26, + p: '0 8px', + border: ownerState?.contained ? '1px solid transparent' : 'none', + bgcolor: 'transparent', + color: ownerState?.contained + ? (theme.vars || theme).palette.text.tertiary + : (theme.vars || theme).palette.grey[500], + fontSize: theme.typography.pxToRem(ownerState?.contained ? 13 : 12), + fontFamily: ownerState?.contained + ? theme.typography.fontFamily + : theme.typography.fontFamilyCode, + fontWeight: ownerState?.contained + ? theme.typography.fontWeightMedium + : theme.typography.fontWeightBold, + lineHeight: 1.2, + outline: 'none', + minWidth: 52, + cursor: 'pointer', + borderRadius: 99, + position: 'relative', + transition: ownerState?.contained ? 'background, color, 100ms ease' : 'unset', + '&:hover': { + backgroundColor: (theme.vars || theme).palette.divider, }, + '&:focus-visible': { + outline: '3px solid', + outlineOffset: '1px', + outlineColor: (theme.vars || theme).palette.primary.light, + }, + ...(!ownerState?.contained && { + '&:hover': { + backgroundColor: alpha(theme.palette.primaryDark[500], 0.5), + color: (theme.vars || theme).palette.grey[400], + }, + ...(ownerState.mounted && { + '&.base--selected': { + color: '#FFF', + '&::after': { + content: "''", + position: 'absolute', + left: 0, + bottom: '-8px', + height: 2, + width: '100%', + bgcolor: (theme.vars || theme).palette.primary.light, + }, + }, + }), + }), }), - '&:hover': { - backgroundColor: alpha(theme.palette.primaryDark[500], 0.5), - }, - '&:focus-visible': { - outline: '2px solid', - outlineOffset: '-2px', - outlineColor: (theme.vars || theme).palette.primary.light, - }, - }), ); type TabsConfig = { @@ -102,21 +128,21 @@ export default function HighlightedCodeWithTabs( const ownerState = { mounted }; return ( - + {tabs.map(({ tab }) => ( - + {tab} - + ))} - + {tabs.map(({ tab, language, code }) => ( - + - + ))} ); diff --git a/docs/src/modules/components/MarkdownElement.js b/docs/src/modules/components/MarkdownElement.js index 1b2b6a0816f49c..3e3684b6686cd6 100644 --- a/docs/src/modules/components/MarkdownElement.js +++ b/docs/src/modules/components/MarkdownElement.js @@ -426,7 +426,7 @@ const Root = styled('div')( }, }, '& a code': { - color: darken(lightTheme.palette.primary.main, 0.2), + color: darken(lightTheme.palette.primary.main, 0.04), }, '& img, & video': { // Use !important so that inline style on or