diff --git a/docs/data/material/components/chips/AvatarChips.js b/docs/data/material/components/chips/AvatarChips.js deleted file mode 100644 index 2a8e585ba484e5..00000000000000 --- a/docs/data/material/components/chips/AvatarChips.js +++ /dev/null @@ -1,16 +0,0 @@ -import Avatar from '@mui/material/Avatar'; -import Chip from '@mui/material/Chip'; -import Stack from '@mui/material/Stack'; - -export default function AvatarChips() { - return ( - - M} label="Avatar" /> - } - label="Avatar" - variant="outlined" - /> - - ); -} diff --git a/docs/data/material/components/chips/AvatarChips.tsx b/docs/data/material/components/chips/AvatarChips.tsx deleted file mode 100644 index 2a8e585ba484e5..00000000000000 --- a/docs/data/material/components/chips/AvatarChips.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import Avatar from '@mui/material/Avatar'; -import Chip from '@mui/material/Chip'; -import Stack from '@mui/material/Stack'; - -export default function AvatarChips() { - return ( - - M} label="Avatar" /> - } - label="Avatar" - variant="outlined" - /> - - ); -} diff --git a/docs/data/material/components/chips/AvatarChips.tsx.preview b/docs/data/material/components/chips/AvatarChips.tsx.preview deleted file mode 100644 index 23fb3c626e7538..00000000000000 --- a/docs/data/material/components/chips/AvatarChips.tsx.preview +++ /dev/null @@ -1,6 +0,0 @@ -M} label="Avatar" /> -} - label="Avatar" - variant="outlined" -/> \ No newline at end of file diff --git a/docs/data/material/components/chips/BasicChips.js b/docs/data/material/components/chips/BasicChips.js index d6721ac1787f96..b4568ab3464a92 100644 --- a/docs/data/material/components/chips/BasicChips.js +++ b/docs/data/material/components/chips/BasicChips.js @@ -4,8 +4,8 @@ import Stack from '@mui/material/Stack'; export default function BasicChips() { return ( - - + + ); } diff --git a/docs/data/material/components/chips/BasicChips.tsx b/docs/data/material/components/chips/BasicChips.tsx index d6721ac1787f96..b4568ab3464a92 100644 --- a/docs/data/material/components/chips/BasicChips.tsx +++ b/docs/data/material/components/chips/BasicChips.tsx @@ -4,8 +4,8 @@ import Stack from '@mui/material/Stack'; export default function BasicChips() { return ( - - + + ); } diff --git a/docs/data/material/components/chips/BasicChips.tsx.preview b/docs/data/material/components/chips/BasicChips.tsx.preview index 6aa80b6b44274c..7f1b24bd6a6291 100644 --- a/docs/data/material/components/chips/BasicChips.tsx.preview +++ b/docs/data/material/components/chips/BasicChips.tsx.preview @@ -1,2 +1,2 @@ - - \ No newline at end of file + + \ No newline at end of file diff --git a/docs/data/material/components/chips/ChipAdornments.js b/docs/data/material/components/chips/ChipAdornments.js new file mode 100644 index 00000000000000..7bd2831541be49 --- /dev/null +++ b/docs/data/material/components/chips/ChipAdornments.js @@ -0,0 +1,24 @@ +import Avatar from '@mui/material/Avatar'; +import Chip from '@mui/material/Chip'; +import Stack from '@mui/material/Stack'; +import ScheduleIcon from '@mui/icons-material/Schedule'; +import DoneIcon from '@mui/icons-material/Done'; + +export default function ChipAdornments() { + return ( + + M} + /> + } + /> + } /> + + ); +} diff --git a/docs/data/material/components/chips/ChipAdornments.tsx b/docs/data/material/components/chips/ChipAdornments.tsx new file mode 100644 index 00000000000000..7bd2831541be49 --- /dev/null +++ b/docs/data/material/components/chips/ChipAdornments.tsx @@ -0,0 +1,24 @@ +import Avatar from '@mui/material/Avatar'; +import Chip from '@mui/material/Chip'; +import Stack from '@mui/material/Stack'; +import ScheduleIcon from '@mui/icons-material/Schedule'; +import DoneIcon from '@mui/icons-material/Done'; + +export default function ChipAdornments() { + return ( + + M} + /> + } + /> + } /> + + ); +} diff --git a/docs/data/material/components/chips/ChipAdornments.tsx.preview b/docs/data/material/components/chips/ChipAdornments.tsx.preview new file mode 100644 index 00000000000000..c4668f1cff568c --- /dev/null +++ b/docs/data/material/components/chips/ChipAdornments.tsx.preview @@ -0,0 +1,12 @@ +M} +/> +} +/> +} /> \ No newline at end of file diff --git a/docs/data/material/components/chips/ChipButtons.js b/docs/data/material/components/chips/ChipButtons.js new file mode 100644 index 00000000000000..5439be93f15720 --- /dev/null +++ b/docs/data/material/components/chips/ChipButtons.js @@ -0,0 +1,24 @@ +import Chip from '@mui/material/Chip'; +import ChipButton from '@mui/material/ChipButton'; +import Stack from '@mui/material/Stack'; +import PersonAddIcon from '@mui/icons-material/PersonAdd'; +import LoopIcon from '@mui/icons-material/Loop'; + +export default function ChipButtons() { + return ( + + } + action={ {}} />} + /> + } + action={ {}} />} + /> + + ); +} diff --git a/docs/data/material/components/chips/ChipButtons.tsx b/docs/data/material/components/chips/ChipButtons.tsx new file mode 100644 index 00000000000000..5439be93f15720 --- /dev/null +++ b/docs/data/material/components/chips/ChipButtons.tsx @@ -0,0 +1,24 @@ +import Chip from '@mui/material/Chip'; +import ChipButton from '@mui/material/ChipButton'; +import Stack from '@mui/material/Stack'; +import PersonAddIcon from '@mui/icons-material/PersonAdd'; +import LoopIcon from '@mui/icons-material/Loop'; + +export default function ChipButtons() { + return ( + + } + action={ {}} />} + /> + } + action={ {}} />} + /> + + ); +} diff --git a/docs/data/material/components/chips/ChipButtons.tsx.preview b/docs/data/material/components/chips/ChipButtons.tsx.preview new file mode 100644 index 00000000000000..e763e548ae615b --- /dev/null +++ b/docs/data/material/components/chips/ChipButtons.tsx.preview @@ -0,0 +1,12 @@ +} + action={ {}} />} +/> +} + action={ {}} />} +/> \ No newline at end of file diff --git a/docs/data/material/components/chips/ColorChips.js b/docs/data/material/components/chips/ChipColors.js similarity index 50% rename from docs/data/material/components/chips/ColorChips.js rename to docs/data/material/components/chips/ChipColors.js index 43b81a63988835..d681d5073b164d 100644 --- a/docs/data/material/components/chips/ColorChips.js +++ b/docs/data/material/components/chips/ChipColors.js @@ -1,16 +1,16 @@ import Chip from '@mui/material/Chip'; import Stack from '@mui/material/Stack'; -export default function ColorChips() { +export default function ChipColors() { return ( - - + + - - + + ); diff --git a/docs/data/material/components/chips/ColorChips.tsx b/docs/data/material/components/chips/ChipColors.tsx similarity index 50% rename from docs/data/material/components/chips/ColorChips.tsx rename to docs/data/material/components/chips/ChipColors.tsx index 43b81a63988835..d681d5073b164d 100644 --- a/docs/data/material/components/chips/ColorChips.tsx +++ b/docs/data/material/components/chips/ChipColors.tsx @@ -1,16 +1,16 @@ import Chip from '@mui/material/Chip'; import Stack from '@mui/material/Stack'; -export default function ColorChips() { +export default function ChipColors() { return ( - - + + - - + + ); diff --git a/docs/data/material/components/chips/ChipColors.tsx.preview b/docs/data/material/components/chips/ChipColors.tsx.preview new file mode 100644 index 00000000000000..290d37eae0dcae --- /dev/null +++ b/docs/data/material/components/chips/ChipColors.tsx.preview @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/docs/data/material/components/chips/ChipLinks.js b/docs/data/material/components/chips/ChipLinks.js new file mode 100644 index 00000000000000..f5f2ef47f7e780 --- /dev/null +++ b/docs/data/material/components/chips/ChipLinks.js @@ -0,0 +1,22 @@ +import Avatar from '@mui/material/Avatar'; +import Chip from '@mui/material/Chip'; +import ChipLink from '@mui/material/ChipLink'; +import Stack from '@mui/material/Stack'; +import OpenInNewIcon from '@mui/icons-material/OpenInNew'; + +export default function ChipLinks() { + return ( + + A} + action={} + /> + } + action={} + /> + + ); +} diff --git a/docs/data/material/components/chips/ChipLinks.tsx b/docs/data/material/components/chips/ChipLinks.tsx new file mode 100644 index 00000000000000..f5f2ef47f7e780 --- /dev/null +++ b/docs/data/material/components/chips/ChipLinks.tsx @@ -0,0 +1,22 @@ +import Avatar from '@mui/material/Avatar'; +import Chip from '@mui/material/Chip'; +import ChipLink from '@mui/material/ChipLink'; +import Stack from '@mui/material/Stack'; +import OpenInNewIcon from '@mui/icons-material/OpenInNew'; + +export default function ChipLinks() { + return ( + + A} + action={} + /> + } + action={} + /> + + ); +} diff --git a/docs/data/material/components/chips/ChipLinks.tsx.preview b/docs/data/material/components/chips/ChipLinks.tsx.preview new file mode 100644 index 00000000000000..95d1e790f2597f --- /dev/null +++ b/docs/data/material/components/chips/ChipLinks.tsx.preview @@ -0,0 +1,10 @@ +A} + action={} +/> +} + action={} +/> \ No newline at end of file diff --git a/docs/data/material/components/chips/SizesChips.js b/docs/data/material/components/chips/ChipSizes.js similarity index 86% rename from docs/data/material/components/chips/SizesChips.js rename to docs/data/material/components/chips/ChipSizes.js index a98030b591886e..e907ef4d7bbeae 100644 --- a/docs/data/material/components/chips/SizesChips.js +++ b/docs/data/material/components/chips/ChipSizes.js @@ -1,7 +1,7 @@ import Chip from '@mui/material/Chip'; import Stack from '@mui/material/Stack'; -export default function SizesChips() { +export default function ChipSizes() { return ( diff --git a/docs/data/material/components/chips/SizesChips.tsx b/docs/data/material/components/chips/ChipSizes.tsx similarity index 86% rename from docs/data/material/components/chips/SizesChips.tsx rename to docs/data/material/components/chips/ChipSizes.tsx index a98030b591886e..e907ef4d7bbeae 100644 --- a/docs/data/material/components/chips/SizesChips.tsx +++ b/docs/data/material/components/chips/ChipSizes.tsx @@ -1,7 +1,7 @@ import Chip from '@mui/material/Chip'; import Stack from '@mui/material/Stack'; -export default function SizesChips() { +export default function ChipSizes() { return ( diff --git a/docs/data/material/components/chips/SizesChips.tsx.preview b/docs/data/material/components/chips/ChipSizes.tsx.preview similarity index 100% rename from docs/data/material/components/chips/SizesChips.tsx.preview rename to docs/data/material/components/chips/ChipSizes.tsx.preview diff --git a/docs/data/material/components/chips/ChipsArray.js b/docs/data/material/components/chips/ChipsArray.js deleted file mode 100644 index 8accf7d5a8429f..00000000000000 --- a/docs/data/material/components/chips/ChipsArray.js +++ /dev/null @@ -1,55 +0,0 @@ -import * as React from 'react'; -import { styled } from '@mui/material/styles'; -import Chip from '@mui/material/Chip'; -import Paper from '@mui/material/Paper'; -import TagFacesIcon from '@mui/icons-material/TagFaces'; - -const ListItem = styled('li')(({ theme }) => ({ - margin: theme.spacing(0.5), -})); - -export default function ChipsArray() { - const [chipData, setChipData] = React.useState([ - { key: 0, label: 'Angular' }, - { key: 1, label: 'jQuery' }, - { key: 2, label: 'Polymer' }, - { key: 3, label: 'React' }, - { key: 4, label: 'Vue.js' }, - ]); - - const handleDelete = (chipToDelete) => () => { - setChipData((chips) => chips.filter((chip) => chip.key !== chipToDelete.key)); - }; - - return ( - - {chipData.map((data) => { - let icon; - - if (data.label === 'React') { - icon = ; - } - - return ( - - - - ); - })} - - ); -} diff --git a/docs/data/material/components/chips/ChipsArray.tsx b/docs/data/material/components/chips/ChipsArray.tsx deleted file mode 100644 index 4c58adeaaf0821..00000000000000 --- a/docs/data/material/components/chips/ChipsArray.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import * as React from 'react'; -import { styled } from '@mui/material/styles'; -import Chip from '@mui/material/Chip'; -import Paper from '@mui/material/Paper'; -import TagFacesIcon from '@mui/icons-material/TagFaces'; - -interface ChipData { - key: number; - label: string; -} - -const ListItem = styled('li')(({ theme }) => ({ - margin: theme.spacing(0.5), -})); - -export default function ChipsArray() { - const [chipData, setChipData] = React.useState([ - { key: 0, label: 'Angular' }, - { key: 1, label: 'jQuery' }, - { key: 2, label: 'Polymer' }, - { key: 3, label: 'React' }, - { key: 4, label: 'Vue.js' }, - ]); - - const handleDelete = (chipToDelete: ChipData) => () => { - setChipData((chips) => chips.filter((chip) => chip.key !== chipToDelete.key)); - }; - - return ( - - {chipData.map((data) => { - let icon; - - if (data.label === 'React') { - icon = ; - } - - return ( - - - - ); - })} - - ); -} diff --git a/docs/data/material/components/chips/ChipsPlayground.js b/docs/data/material/components/chips/ChipsPlayground.js deleted file mode 100644 index 74f0ac2b7921c0..00000000000000 --- a/docs/data/material/components/chips/ChipsPlayground.js +++ /dev/null @@ -1,291 +0,0 @@ -import * as React from 'react'; -import Grid from '@mui/material/Grid'; -import FormControl from '@mui/material/FormControl'; -import FormLabel from '@mui/material/FormLabel'; -import FormControlLabel from '@mui/material/FormControlLabel'; -import RadioGroup from '@mui/material/RadioGroup'; -import Radio from '@mui/material/Radio'; -import Avatar from '@mui/material/Avatar'; -import Chip from '@mui/material/Chip'; -import FaceIcon from '@mui/icons-material/Face'; -import DoneIcon from '@mui/icons-material/Done'; -import { HighlightedCode } from '@mui/docs/HighlightedCode'; - -function ChipsPlayground() { - const [state, setState] = React.useState({ - color: 'default', - onDelete: 'none', - avatar: 'none', - icon: 'none', - variant: 'filled', - size: 'medium', - }); - const { color, onDelete, avatar, icon, variant, size } = state; - - const handleChange = (event) => { - setState({ - ...state, - [event.target.name]: event.target.value, - }); - }; - - const handleDeleteExample = () => { - console.info('You clicked the delete icon.'); - }; - - const colorToCode = color !== 'default' ? `color="${color}" ` : ''; - const sizeToCode = size === 'small' ? `size="small" ` : ''; - const variantToCode = variant !== 'filled' ? `variant="${variant}" ` : ''; - - let onDeleteToCode; - switch (onDelete) { - case 'none': - onDeleteToCode = ''; - break; - case 'custom': - onDeleteToCode = 'deleteIcon={} onDelete={handleDelete} '; - break; - default: - onDeleteToCode = 'onDelete={handleDelete} '; - break; - } - - let iconToCode; - let iconToPlayground; - switch (icon) { - case 'none': - iconToCode = ''; - break; - default: - iconToCode = 'icon={} '; - iconToPlayground = ; - break; - } - - let avatarToCode; - let avatarToPlayground; - switch (avatar) { - case 'none': - avatarToCode = ''; - break; - case 'img': - avatarToCode = 'avatar={} '; - avatarToPlayground = ; - break; - case 'letter': - avatarToCode = 'avatar={F} '; - avatarToPlayground = F; - break; - default: - break; - } - - if (avatar !== 'none') { - iconToCode = ''; - iconToPlayground = null; - } - - const jsx = ` - -`; - - return ( - - - - ({ height: theme.spacing(10) })}> - : undefined} - onDelete={onDelete !== 'none' ? handleDeleteExample : undefined} - avatar={avatarToPlayground} - icon={iconToPlayground} - variant={variant} - size={size} - /> - - - - - - - - variant - - } - label="filled" - /> - } - label="outlined" - /> - - - - - - color - - } - label="default" - /> - } - label="primary" - /> - } - label="secondary" - /> - } label="error" /> - } label="info" /> - } - label="success" - /> - } - label="warning" - /> - - - - - - size - - } - label="medium" - /> - } label="small" /> - - - - - - icon - - } label="none" /> - } label="icon" /> - - - - - - avatar - - } label="none" /> - } - label="letter" - /> - } label="img" /> - - - - - - onDelete - - } label="none" /> - } - label="default" - /> - } - label="custom" - /> - - - - - - - - - - ); -} -export default ChipsPlayground; diff --git a/docs/data/material/components/chips/ClickableAndDeletableChips.js b/docs/data/material/components/chips/ClickableAndDeletableChips.js deleted file mode 100644 index 41985d055fb793..00000000000000 --- a/docs/data/material/components/chips/ClickableAndDeletableChips.js +++ /dev/null @@ -1,28 +0,0 @@ -import Chip from '@mui/material/Chip'; -import Stack from '@mui/material/Stack'; - -export default function ClickableAndDeletableChips() { - const handleClick = () => { - console.info('You clicked the Chip.'); - }; - - const handleDelete = () => { - console.info('You clicked the delete icon.'); - }; - - return ( - - - - - ); -} diff --git a/docs/data/material/components/chips/ClickableAndDeletableChips.tsx b/docs/data/material/components/chips/ClickableAndDeletableChips.tsx deleted file mode 100644 index 41985d055fb793..00000000000000 --- a/docs/data/material/components/chips/ClickableAndDeletableChips.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import Chip from '@mui/material/Chip'; -import Stack from '@mui/material/Stack'; - -export default function ClickableAndDeletableChips() { - const handleClick = () => { - console.info('You clicked the Chip.'); - }; - - const handleDelete = () => { - console.info('You clicked the delete icon.'); - }; - - return ( - - - - - ); -} diff --git a/docs/data/material/components/chips/ClickableAndDeletableChips.tsx.preview b/docs/data/material/components/chips/ClickableAndDeletableChips.tsx.preview deleted file mode 100644 index 8cdc03cd9125e2..00000000000000 --- a/docs/data/material/components/chips/ClickableAndDeletableChips.tsx.preview +++ /dev/null @@ -1,11 +0,0 @@ - - \ No newline at end of file diff --git a/docs/data/material/components/chips/ClickableChips.js b/docs/data/material/components/chips/ClickableChips.js deleted file mode 100644 index b1c7fc991928d5..00000000000000 --- a/docs/data/material/components/chips/ClickableChips.js +++ /dev/null @@ -1,15 +0,0 @@ -import Chip from '@mui/material/Chip'; -import Stack from '@mui/material/Stack'; - -export default function ClickableChips() { - const handleClick = () => { - console.info('You clicked the Chip.'); - }; - - return ( - - - - - ); -} diff --git a/docs/data/material/components/chips/ClickableChips.tsx b/docs/data/material/components/chips/ClickableChips.tsx deleted file mode 100644 index b1c7fc991928d5..00000000000000 --- a/docs/data/material/components/chips/ClickableChips.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import Chip from '@mui/material/Chip'; -import Stack from '@mui/material/Stack'; - -export default function ClickableChips() { - const handleClick = () => { - console.info('You clicked the Chip.'); - }; - - return ( - - - - - ); -} diff --git a/docs/data/material/components/chips/ClickableChips.tsx.preview b/docs/data/material/components/chips/ClickableChips.tsx.preview deleted file mode 100644 index e1e68e8edae4d7..00000000000000 --- a/docs/data/material/components/chips/ClickableChips.tsx.preview +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/docs/data/material/components/chips/ClickableLinkChips.js b/docs/data/material/components/chips/ClickableLinkChips.js deleted file mode 100644 index 2e28cd0745f611..00000000000000 --- a/docs/data/material/components/chips/ClickableLinkChips.js +++ /dev/null @@ -1,17 +0,0 @@ -import Chip from '@mui/material/Chip'; -import Stack from '@mui/material/Stack'; - -export default function ClickableLinkChips() { - return ( - - - - - ); -} diff --git a/docs/data/material/components/chips/ClickableLinkChips.tsx b/docs/data/material/components/chips/ClickableLinkChips.tsx deleted file mode 100644 index 2e28cd0745f611..00000000000000 --- a/docs/data/material/components/chips/ClickableLinkChips.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import Chip from '@mui/material/Chip'; -import Stack from '@mui/material/Stack'; - -export default function ClickableLinkChips() { - return ( - - - - - ); -} diff --git a/docs/data/material/components/chips/ClickableLinkChips.tsx.preview b/docs/data/material/components/chips/ClickableLinkChips.tsx.preview deleted file mode 100644 index 929b6f99b224e3..00000000000000 --- a/docs/data/material/components/chips/ClickableLinkChips.tsx.preview +++ /dev/null @@ -1,8 +0,0 @@ - - \ No newline at end of file diff --git a/docs/data/material/components/chips/ColorChips.tsx.preview b/docs/data/material/components/chips/ColorChips.tsx.preview deleted file mode 100644 index 46ba56daf805f8..00000000000000 --- a/docs/data/material/components/chips/ColorChips.tsx.preview +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/docs/data/material/components/chips/CustomDeleteIconChips.js b/docs/data/material/components/chips/CustomDeleteIconChips.js deleted file mode 100644 index c148735d0b5b30..00000000000000 --- a/docs/data/material/components/chips/CustomDeleteIconChips.js +++ /dev/null @@ -1,32 +0,0 @@ -import Chip from '@mui/material/Chip'; -import Stack from '@mui/material/Stack'; -import DoneIcon from '@mui/icons-material/Done'; -import DeleteIcon from '@mui/icons-material/Delete'; - -export default function CustomDeleteIconChips() { - const handleClick = () => { - console.info('You clicked the Chip.'); - }; - - const handleDelete = () => { - console.info('You clicked the delete icon.'); - }; - - return ( - - } - /> - } - variant="outlined" - /> - - ); -} diff --git a/docs/data/material/components/chips/CustomDeleteIconChips.tsx b/docs/data/material/components/chips/CustomDeleteIconChips.tsx deleted file mode 100644 index c148735d0b5b30..00000000000000 --- a/docs/data/material/components/chips/CustomDeleteIconChips.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import Chip from '@mui/material/Chip'; -import Stack from '@mui/material/Stack'; -import DoneIcon from '@mui/icons-material/Done'; -import DeleteIcon from '@mui/icons-material/Delete'; - -export default function CustomDeleteIconChips() { - const handleClick = () => { - console.info('You clicked the Chip.'); - }; - - const handleDelete = () => { - console.info('You clicked the delete icon.'); - }; - - return ( - - } - /> - } - variant="outlined" - /> - - ); -} diff --git a/docs/data/material/components/chips/CustomDeleteIconChips.tsx.preview b/docs/data/material/components/chips/CustomDeleteIconChips.tsx.preview deleted file mode 100644 index 0aa814842a6f82..00000000000000 --- a/docs/data/material/components/chips/CustomDeleteIconChips.tsx.preview +++ /dev/null @@ -1,13 +0,0 @@ -} -/> -} - variant="outlined" -/> \ No newline at end of file diff --git a/docs/data/material/components/chips/DeletableActionChips.js b/docs/data/material/components/chips/DeletableActionChips.js new file mode 100644 index 00000000000000..254c6a0fbd7b53 --- /dev/null +++ b/docs/data/material/components/chips/DeletableActionChips.js @@ -0,0 +1,22 @@ +import Chip from '@mui/material/Chip'; +import ChipButton from '@mui/material/ChipButton'; +import ChipDelete from '@mui/material/ChipDelete'; +import ChipLink from '@mui/material/ChipLink'; +import Stack from '@mui/material/Stack'; + +export default function DeletableActionChips() { + return ( + + } + action={ {}} />} + /> + } + action={} + /> + + ); +} diff --git a/docs/data/material/components/chips/DeletableActionChips.tsx b/docs/data/material/components/chips/DeletableActionChips.tsx new file mode 100644 index 00000000000000..254c6a0fbd7b53 --- /dev/null +++ b/docs/data/material/components/chips/DeletableActionChips.tsx @@ -0,0 +1,22 @@ +import Chip from '@mui/material/Chip'; +import ChipButton from '@mui/material/ChipButton'; +import ChipDelete from '@mui/material/ChipDelete'; +import ChipLink from '@mui/material/ChipLink'; +import Stack from '@mui/material/Stack'; + +export default function DeletableActionChips() { + return ( + + } + action={ {}} />} + /> + } + action={} + /> + + ); +} diff --git a/docs/data/material/components/chips/DeletableActionChips.tsx.preview b/docs/data/material/components/chips/DeletableActionChips.tsx.preview new file mode 100644 index 00000000000000..e63c9117bcacd2 --- /dev/null +++ b/docs/data/material/components/chips/DeletableActionChips.tsx.preview @@ -0,0 +1,10 @@ +} + action={ {}} />} +/> +} + action={} +/> \ No newline at end of file diff --git a/docs/data/material/components/chips/DeletableChips.js b/docs/data/material/components/chips/DeletableChips.js index 5b88d350c3a967..5afbdd23429c01 100644 --- a/docs/data/material/components/chips/DeletableChips.js +++ b/docs/data/material/components/chips/DeletableChips.js @@ -1,15 +1,21 @@ import Chip from '@mui/material/Chip'; +import ChipDelete from '@mui/material/ChipDelete'; import Stack from '@mui/material/Stack'; export default function DeletableChips() { - const handleDelete = () => { - console.info('You clicked the delete icon.'); - }; - return ( - - + alert('"Photography" deleted')} />} + /> + alert('"Nature" deleted')} />} + /> ); } diff --git a/docs/data/material/components/chips/DeletableChips.tsx b/docs/data/material/components/chips/DeletableChips.tsx index 5b88d350c3a967..5afbdd23429c01 100644 --- a/docs/data/material/components/chips/DeletableChips.tsx +++ b/docs/data/material/components/chips/DeletableChips.tsx @@ -1,15 +1,21 @@ import Chip from '@mui/material/Chip'; +import ChipDelete from '@mui/material/ChipDelete'; import Stack from '@mui/material/Stack'; export default function DeletableChips() { - const handleDelete = () => { - console.info('You clicked the delete icon.'); - }; - return ( - - + alert('"Photography" deleted')} />} + /> + alert('"Nature" deleted')} />} + /> ); } diff --git a/docs/data/material/components/chips/DeletableChips.tsx.preview b/docs/data/material/components/chips/DeletableChips.tsx.preview index 5cdedd6b39ecff..580ef52d0fb048 100644 --- a/docs/data/material/components/chips/DeletableChips.tsx.preview +++ b/docs/data/material/components/chips/DeletableChips.tsx.preview @@ -1,2 +1,11 @@ - - \ No newline at end of file + alert('"Photography" deleted')} />} +/> + alert('"Nature" deleted')} />} +/> \ No newline at end of file diff --git a/docs/data/material/components/chips/DisabledChips.js b/docs/data/material/components/chips/DisabledChips.js new file mode 100644 index 00000000000000..9bac442c3c5ea7 --- /dev/null +++ b/docs/data/material/components/chips/DisabledChips.js @@ -0,0 +1,23 @@ +import Chip from '@mui/material/Chip'; +import ChipButton from '@mui/material/ChipButton'; +import ChipDelete from '@mui/material/ChipDelete'; +import Stack from '@mui/material/Stack'; + +export default function DisabledChips() { + return ( + + } + action={ {}} />} + /> + } + action={ {}} focusableWhenDisabled={false} />} + /> + + ); +} diff --git a/docs/data/material/components/chips/DisabledChips.tsx b/docs/data/material/components/chips/DisabledChips.tsx new file mode 100644 index 00000000000000..9bac442c3c5ea7 --- /dev/null +++ b/docs/data/material/components/chips/DisabledChips.tsx @@ -0,0 +1,23 @@ +import Chip from '@mui/material/Chip'; +import ChipButton from '@mui/material/ChipButton'; +import ChipDelete from '@mui/material/ChipDelete'; +import Stack from '@mui/material/Stack'; + +export default function DisabledChips() { + return ( + + } + action={ {}} />} + /> + } + action={ {}} focusableWhenDisabled={false} />} + /> + + ); +} diff --git a/docs/data/material/components/chips/DisabledChips.tsx.preview b/docs/data/material/components/chips/DisabledChips.tsx.preview new file mode 100644 index 00000000000000..1c2c7b69cf0a23 --- /dev/null +++ b/docs/data/material/components/chips/DisabledChips.tsx.preview @@ -0,0 +1,12 @@ +} + action={ {}} />} +/> +} + action={ {}} focusableWhenDisabled={false} />} +/> \ No newline at end of file diff --git a/docs/data/material/components/chips/IconChips.js b/docs/data/material/components/chips/IconChips.js deleted file mode 100644 index 9fe5e6a1ac9b25..00000000000000 --- a/docs/data/material/components/chips/IconChips.js +++ /dev/null @@ -1,12 +0,0 @@ -import Chip from '@mui/material/Chip'; -import Stack from '@mui/material/Stack'; -import FaceIcon from '@mui/icons-material/Face'; - -export default function IconChips() { - return ( - - } label="With Icon" /> - } label="With Icon" variant="outlined" /> - - ); -} diff --git a/docs/data/material/components/chips/IconChips.tsx b/docs/data/material/components/chips/IconChips.tsx deleted file mode 100644 index 9fe5e6a1ac9b25..00000000000000 --- a/docs/data/material/components/chips/IconChips.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import Chip from '@mui/material/Chip'; -import Stack from '@mui/material/Stack'; -import FaceIcon from '@mui/icons-material/Face'; - -export default function IconChips() { - return ( - - } label="With Icon" /> - } label="With Icon" variant="outlined" /> - - ); -} diff --git a/docs/data/material/components/chips/IconChips.tsx.preview b/docs/data/material/components/chips/IconChips.tsx.preview deleted file mode 100644 index a0f528c3e8e765..00000000000000 --- a/docs/data/material/components/chips/IconChips.tsx.preview +++ /dev/null @@ -1,2 +0,0 @@ -} label="With Icon" /> -} label="With Icon" variant="outlined" /> \ No newline at end of file diff --git a/docs/data/material/components/chips/MultilineChips.js b/docs/data/material/components/chips/MultilineChips.js deleted file mode 100644 index c7425acc1a1e16..00000000000000 --- a/docs/data/material/components/chips/MultilineChips.js +++ /dev/null @@ -1,19 +0,0 @@ -import Chip from '@mui/material/Chip'; -import Box from '@mui/material/Box'; - -export default function MultilineChips() { - return ( - - - - ); -} diff --git a/docs/data/material/components/chips/MultilineChips.tsx b/docs/data/material/components/chips/MultilineChips.tsx deleted file mode 100644 index c7425acc1a1e16..00000000000000 --- a/docs/data/material/components/chips/MultilineChips.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import Chip from '@mui/material/Chip'; -import Box from '@mui/material/Box'; - -export default function MultilineChips() { - return ( - - - - ); -} diff --git a/docs/data/material/components/chips/MultilineChips.tsx.preview b/docs/data/material/components/chips/MultilineChips.tsx.preview deleted file mode 100644 index 45f16da37ca0df..00000000000000 --- a/docs/data/material/components/chips/MultilineChips.tsx.preview +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/docs/data/material/components/chips/chips.md b/docs/data/material/components/chips/chips.md index 1be197edc180d1..25fd6cc2b6b144 100644 --- a/docs/data/material/components/chips/chips.md +++ b/docs/data/material/components/chips/chips.md @@ -1,7 +1,7 @@ --- productId: material-ui title: React Chip component -components: Chip +components: Chip, ChipButton, ChipLink, ChipDelete githubLabel: 'scope: chip' materialDesign: https://m2.material.io/components/chips githubSource: packages/mui-material/src/Chip @@ -19,85 +19,60 @@ not shown in context. {{"component": "@mui/docs/ComponentLinkHeader"}} -## Basic chip +## Basic chips -The `Chip` component supports outlined and filled styling. +The `Chip` component supports `'outlined'` and `'filled'` variants. {{"demo": "BasicChips.js"}} -## Chip actions +### Colors -You can use the following actions. +Use the `color` prop to assign a color from the theme palette. -- Chips with the `onClick` prop defined change appearance on focus, hover, and click. -- Chips with the `onDelete` prop defined will display a delete icon which changes appearance on hover. +{{"demo": "ChipColors.js"}} -### Clickable +### Sizes -{{"demo": "ClickableChips.js"}} +Use the `size` prop to control the size. -### Deletable +{{"demo": "ChipSizes.js"}} -{{"demo": "DeletableChips.js"}} - -### Clickable and deletable - -{{"demo": "ClickableAndDeletableChips.js"}} - -### Clickable link - -{{"demo": "ClickableLinkChips.js"}} - -### Custom delete icon +## Adornments -{{"demo": "CustomDeleteIconChips.js"}} +You can add ornaments like icons or `` to the beginning or end of the component using the `startAdornment` and `endAdornment` props: -## Chip adornments +{{"demo": "ChipAdornments.js"}} -You can add ornaments to the beginning of the component. +### Delete button -Use the `avatar` prop to add an avatar or use the `icon` prop to add an icon. +Use `` as an adornment to add an accessible delete button. A `onDelete` callback is provided that runs when `` is clicked, and additionally when the `Backspace` or `Delete` keys are pressed while focused. -### Avatar chip - -{{"demo": "AvatarChips.js"}} - -### Icon chip - -{{"demo": "IconChips.js"}} - -## Color chip - -You can use the `color` prop to define a color from theme palette. +{{"demo": "DeletableChips.js"}} -{{"demo": "ColorChips.js"}} +## Actions -## Sizes chip +Pass `` or `` to the `action` prop to create interactive chips. -You can use the `size` prop to define a small Chip. +### ChipButton -{{"demo": "SizesChips.js"}} +Use `` for triggering actions: -## Multiline chip +{{"demo": "ChipButtons.js"}} -By default, Chips displays labels only in a single line. -To have them support multiline content, use the `sx` prop to add `height:auto` to the Chip component, and `whiteSpace: normal` to the `label` styles. +### ChipLink -{{"demo": "MultilineChips.js"}} +Use `` to navigate to a URL: -## Chip array +{{"demo": "ChipLinks.js"}} -An example of rendering multiple chips from an array of values. -Deleting a chip removes it from the array. Note that since no -`onClick` prop is defined, the `Chip` can be focused, but does not -gain depth while clicked or touched. +### ChipDelete -{{"demo": "ChipsArray.js"}} +`` cam be used to make interactive chips deletable. Both the `action` component and the delete button are discrete tab stops. -## Chip playground +{{"demo": "DeletableActionChips.js"}} -{{"demo": "ChipsPlayground.js", "hideToolbar": true}} +### Disabled state -## Accessibility +Both `` and `` can receive focus normally when disabled to remain discoverable to assistive technology, which typically ignores disabled elements. Only `focus` and `blur` events will run. This can be individually disabled by with `focusableWhenDisabled={false}`. -If the Chip is deletable or clickable then it is a button in tab order. When the Chip is focused (for example when tabbing) releasing (`keyup` event) `Backspace` or `Delete` will call the `onDelete` handler while releasing `Escape` will blur the Chip. +{{"demo": "DisabledChips.js"}} diff --git a/docs/data/material/pagesApi.js b/docs/data/material/pagesApi.js index ee76034af9e54a..e4b56d2f208c71 100644 --- a/docs/data/material/pagesApi.js +++ b/docs/data/material/pagesApi.js @@ -26,6 +26,9 @@ export default [ { pathname: '/material-ui/api/card-media' }, { pathname: '/material-ui/api/checkbox' }, { pathname: '/material-ui/api/chip' }, + { pathname: '/material-ui/api/chip-button' }, + { pathname: '/material-ui/api/chip-delete' }, + { pathname: '/material-ui/api/chip-link' }, { pathname: '/material-ui/api/circular-progress' }, { pathname: '/material-ui/api/click-away-listener' }, { pathname: '/material-ui/api/collapse' }, diff --git a/docs/pages/experiments/material-ui-interactive-chips.tsx b/docs/pages/experiments/material-ui-interactive-chips.tsx new file mode 100644 index 00000000000000..cc10ab4752f0e8 --- /dev/null +++ b/docs/pages/experiments/material-ui-interactive-chips.tsx @@ -0,0 +1,402 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import ClickAwayListener from '@mui/material/ClickAwayListener'; +import Paper from '@mui/material/Paper'; +import Popper from '@mui/material/Popper'; +import Typography from '@mui/material/Typography'; +import Avatar from '@mui/material/Avatar'; +import CssBaseline from '@mui/material/CssBaseline'; +import useMediaQuery from '@mui/material/useMediaQuery'; +import { ThemeProvider, createTheme } from '@mui/material/styles'; +import FaceIcon from '@mui/icons-material/Face'; +import Chip from '@mui/material/Chip'; +import ChipButton from '@mui/material/ChipButton'; +import ChipDelete from '@mui/material/ChipDelete'; +import ChipLink from '@mui/material/ChipLink'; + +export default function MaterialUiInteractiveChips() { + const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)'); + const theme = React.useMemo( + () => + createTheme({ + palette: { + mode: prefersDarkMode ? 'dark' : 'light', + }, + }), + [prefersDarkMode], + ); + const [chips, setChips] = React.useState(['Deletable 1', 'Deletable 2', 'Deletable 3']); + const handleDelete = (chipToDelete: string) => () => { + setChips((prev) => prev.filter((chip) => chip !== chipToDelete)); + }; + + return ( + + + + + Interactive Chips (material-ui) + + + {/* -- Action chip (button) -- */} +
+ {}} />} /> + {}} />} /> + {}} />} /> + {}} />} /> + {}} />} /> + {}} />} /> + {}} />} /> +
+ +
+ {}} />} /> + {}} />} + /> + {}} />} + /> + {}} />} + /> +
+ +
+ {}} />} /> + {}} />} /> +
+ + {/* -- With adornments -- */} +
+ {}} />} + startAdornment={} + /> + {}} />} + startAdornment={} + /> +
+ +
+ {}} />} + startAdornment={M} + /> + {}} />} + startAdornment={} + /> +
+ +
+ {}} />} + endAdornment={} + /> + {}} />} + endAdornment={} + /> + {}} />} + endAdornment={} + /> +
+ +
+ {}} />} + endAdornment={M} + /> + {}} />} + endAdornment={J} + /> + {}} />} + endAdornment={} + /> +
+ + {/* -- With delete -- */} +
+ {}} />} + endAdornment={ {}} />} + /> + {}} />} + endAdornment={ {}} />} + /> + {}} />} + endAdornment={ {}} />} + /> + {}} disableRipple />} + endAdornment={ {}} />} + /> +
+ +
+ {}} />} + startAdornment={ {}} />} + /> + {}} />} + startAdornment={ {}} />} + /> + {}} />} + startAdornment={ {}} />} + /> +
+ +
+ {}} />} /> + {}} />} /> + } + endAdornment={ {}} />} + /> +
+ +
+ {}} />} + startAdornment={M} + endAdornment={} + /> + {}} />} + startAdornment={ {}} />} + endAdornment={} + /> + } + startAdornment={R} + endAdornment={ {}} />} + /> +
+ + {/* -- Disabled states -- */} +
+ {}} />} /> + {}} />} + endAdornment={ {}} />} + /> + {}} />} + /> +
+ +
+ {}} focusableWhenDisabled={false} />} + /> + {}} focusableWhenDisabled={false} />} + endAdornment={ {}} />} + /> +
+ + {/* -- Link chip -- */} +
+ } /> + } /> + } /> + } /> +
+ +
+ } + startAdornment={} + /> + } + endAdornment={} + /> + } + startAdornment={ {}} />} + /> + } + endAdornment={ {}} />} + /> + } + endAdornment={ {}} />} + /> +
+ + {/* -- ClickAway bug repro -- */} + + + {/* -- Static chip (no action) -- */} +
+ + } /> + +
+ + {/* -- Live delete demo with aria-live -- */} +
+ + {chips.map((chip) => ( + {}} />} + endAdornment={} + /> + ))} + {chips.length === 0 && ( + + All chips deleted. + + )} + +
+
+
+ ); +} + +function ClickAwayPopperSection() { + const [anchorEl, setAnchorEl] = React.useState(); + const isOpen = Boolean(anchorEl); + + return ( + + + + ClickAway + Popper bug repro + + + + Open the popper, then click the delete icon on the chip. With the old API the popper does + NOT close (bug). With the new API it should close. + + + + New API: + + {}} />} + endAdornment={ {}} />} + /> + + + + Old API: + + {}} /> + + + + setAnchorEl(undefined)}> + + + Clicking anywhere on the page closes this popper. + + + Bug: clicking the delete icon on the OLD API chip does NOT close the popper (because + of stopPropagation on ButtonBase). + + + + + + ); +} + +function Section({ title, children }: { title: string; children: React.ReactNode }) { + return ( + + + {title} + + {children} + + ); +} diff --git a/docs/pages/material-ui/api/chip-button.js b/docs/pages/material-ui/api/chip-button.js new file mode 100644 index 00000000000000..cd59e39a6a0329 --- /dev/null +++ b/docs/pages/material-ui/api/chip-button.js @@ -0,0 +1,20 @@ +import * as React from 'react'; +import ApiPage from 'docs/src/modules/components/ApiPage'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './chip-button.json'; + +export default function Page(props) { + const { descriptions } = props; + return ; +} + +export async function getStaticProps() { + const req = require.context( + 'docs/translations/api-docs/chip-button', + false, + /\.\/chip-button.*\.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { props: { descriptions } }; +} diff --git a/docs/pages/material-ui/api/chip-button.json b/docs/pages/material-ui/api/chip-button.json new file mode 100644 index 00000000000000..28e665b1176a1d --- /dev/null +++ b/docs/pages/material-ui/api/chip-button.json @@ -0,0 +1,42 @@ +{ + "props": { + "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, + "component": { "type": { "name": "custom", "description": "element type" } }, + "disabled": { "type": { "name": "bool" }, "default": "false" }, + "focusableWhenDisabled": { "type": { "name": "bool" }, "default": "true" }, + "nativeButton": { "type": { "name": "bool" } }, + "sx": { + "type": { + "name": "union", + "description": "Array<func
| object
| bool>
| func
| object" + }, + "additionalInfo": { "sx": true } + } + }, + "name": "ChipButton", + "imports": [ + "import ChipButton from '@mui/material/ChipButton';", + "import { ChipButton } from '@mui/material';" + ], + "classes": [ + { + "key": "disabled", + "className": "Mui-disabled", + "description": "State class applied to the root element if `disabled={true}`.", + "isGlobal": true + }, + { + "key": "root", + "className": "MuiChipButton-root", + "description": "Styles applied to the root element.", + "isGlobal": false + } + ], + "spread": true, + "themeDefaultProps": null, + "muiName": "MuiChipButton", + "filename": "/packages/mui-material/src/ChipButton/ChipButton.tsx", + "inheritance": null, + "demos": "", + "cssComponent": false +} diff --git a/docs/pages/material-ui/api/chip-delete.js b/docs/pages/material-ui/api/chip-delete.js new file mode 100644 index 00000000000000..df9067902e2ac8 --- /dev/null +++ b/docs/pages/material-ui/api/chip-delete.js @@ -0,0 +1,20 @@ +import * as React from 'react'; +import ApiPage from 'docs/src/modules/components/ApiPage'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './chip-delete.json'; + +export default function Page(props) { + const { descriptions } = props; + return ; +} + +export async function getStaticProps() { + const req = require.context( + 'docs/translations/api-docs/chip-delete', + false, + /\.\/chip-delete.*\.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { props: { descriptions } }; +} diff --git a/docs/pages/material-ui/api/chip-delete.json b/docs/pages/material-ui/api/chip-delete.json new file mode 100644 index 00000000000000..5b55bb180ac111 --- /dev/null +++ b/docs/pages/material-ui/api/chip-delete.json @@ -0,0 +1,111 @@ +{ + "props": { + "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, + "component": { "type": { "name": "custom", "description": "element type" } }, + "disabled": { "type": { "name": "bool" }, "default": "false" }, + "focusableWhenDisabled": { "type": { "name": "bool" }, "default": "true" }, + "icon": { "type": { "name": "element" } }, + "label": { "type": { "name": "string" }, "default": "'Remove'" }, + "nativeButton": { "type": { "name": "bool" } }, + "onDelete": { "type": { "name": "func" } }, + "sx": { + "type": { + "name": "union", + "description": "Array<func
| object
| bool>
| func
| object" + }, + "additionalInfo": { "sx": true } + } + }, + "name": "ChipDelete", + "imports": [ + "import ChipDelete from '@mui/material/ChipDelete';", + "import { ChipDelete } from '@mui/material';" + ], + "classes": [ + { + "key": "colorDefault", + "className": "MuiChipDelete-colorDefault", + "description": "Styles applied to the root element if `color=\"default\"`.", + "isGlobal": false + }, + { + "key": "colorError", + "className": "MuiChipDelete-colorError", + "description": "Styles applied to the root element if `color=\"error\"`.", + "isGlobal": false + }, + { + "key": "colorInfo", + "className": "MuiChipDelete-colorInfo", + "description": "Styles applied to the root element if `color=\"info\"`.", + "isGlobal": false + }, + { + "key": "colorPrimary", + "className": "MuiChipDelete-colorPrimary", + "description": "Styles applied to the root element if `color=\"primary\"`.", + "isGlobal": false + }, + { + "key": "colorSecondary", + "className": "MuiChipDelete-colorSecondary", + "description": "Styles applied to the root element if `color=\"secondary\"`.", + "isGlobal": false + }, + { + "key": "colorSuccess", + "className": "MuiChipDelete-colorSuccess", + "description": "Styles applied to the root element if `color=\"success\"`.", + "isGlobal": false + }, + { + "key": "colorWarning", + "className": "MuiChipDelete-colorWarning", + "description": "Styles applied to the root element if `color=\"warning\"`.", + "isGlobal": false + }, + { + "key": "disabled", + "className": "Mui-disabled", + "description": "State class applied to the root element if `disabled={true}`.", + "isGlobal": true + }, + { + "key": "filled", + "className": "MuiChipDelete-filled", + "description": "Styles applied to the root element if `variant=\"filled\"`.", + "isGlobal": false + }, + { + "key": "outlined", + "className": "MuiChipDelete-outlined", + "description": "Styles applied to the root element if `variant=\"outlined\"`.", + "isGlobal": false + }, + { + "key": "root", + "className": "MuiChipDelete-root", + "description": "Styles applied to the root element.", + "isGlobal": false + }, + { + "key": "sizeMedium", + "className": "MuiChipDelete-sizeMedium", + "description": "Styles applied to the root element if `size=\"medium\"`.", + "isGlobal": false + }, + { + "key": "sizeSmall", + "className": "MuiChipDelete-sizeSmall", + "description": "Styles applied to the root element if `size=\"small\"`.", + "isGlobal": false + } + ], + "spread": true, + "themeDefaultProps": null, + "muiName": "MuiChipDelete", + "filename": "/packages/mui-material/src/ChipDelete/ChipDelete.tsx", + "inheritance": null, + "demos": "", + "cssComponent": false +} diff --git a/docs/pages/material-ui/api/chip-link.js b/docs/pages/material-ui/api/chip-link.js new file mode 100644 index 00000000000000..65d9f29aa3ff2f --- /dev/null +++ b/docs/pages/material-ui/api/chip-link.js @@ -0,0 +1,20 @@ +import * as React from 'react'; +import ApiPage from 'docs/src/modules/components/ApiPage'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './chip-link.json'; + +export default function Page(props) { + const { descriptions } = props; + return ; +} + +export async function getStaticProps() { + const req = require.context( + 'docs/translations/api-docs/chip-link', + false, + /\.\/chip-link.*\.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { props: { descriptions } }; +} diff --git a/docs/pages/material-ui/api/chip-link.json b/docs/pages/material-ui/api/chip-link.json new file mode 100644 index 00000000000000..c737584a00e1f0 --- /dev/null +++ b/docs/pages/material-ui/api/chip-link.json @@ -0,0 +1,33 @@ +{ + "props": { + "href": { "type": { "name": "string" }, "required": true }, + "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, + "sx": { + "type": { + "name": "union", + "description": "Array<func
| object
| bool>
| func
| object" + }, + "additionalInfo": { "sx": true } + } + }, + "name": "ChipLink", + "imports": [ + "import ChipLink from '@mui/material/ChipLink';", + "import { ChipLink } from '@mui/material';" + ], + "classes": [ + { + "key": "root", + "className": "MuiChipLink-root", + "description": "Styles applied to the root element.", + "isGlobal": false + } + ], + "spread": true, + "themeDefaultProps": null, + "muiName": "MuiChipLink", + "filename": "/packages/mui-material/src/ChipLink/ChipLink.tsx", + "inheritance": null, + "demos": "", + "cssComponent": false +} diff --git a/docs/pages/material-ui/api/chip.json b/docs/pages/material-ui/api/chip.json index 9f00c3d59befc0..eca1f2c662a4f6 100644 --- a/docs/pages/material-ui/api/chip.json +++ b/docs/pages/material-ui/api/chip.json @@ -1,9 +1,18 @@ { "props": { - "avatar": { "type": { "name": "element" } }, + "action": { "type": { "name": "element" } }, + "avatar": { + "type": { "name": "element" }, + "deprecated": true, + "deprecationInfo": "Use startAdornment instead. Ignored when startAdornment or action are used." + }, "children": { "type": { "name": "custom", "description": "unsupportedProp" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, - "clickable": { "type": { "name": "bool" } }, + "clickable": { + "type": { "name": "bool" }, + "deprecated": true, + "deprecationInfo": "Use action={<ChipButton onClick={...} />} instead. Ignored when action is present." + }, "color": { "type": { "name": "union", @@ -12,12 +21,25 @@ "default": "'default'" }, "component": { "type": { "name": "elementType" } }, - "deleteIcon": { "type": { "name": "element" } }, + "deleteIcon": { + "type": { "name": "element" }, + "deprecated": true, + "deprecationInfo": "Use endAdornment={<ChipDelete />} instead. Ignored when endAdornment or action are used." + }, "disabled": { "type": { "name": "bool" }, "default": "false" }, - "icon": { "type": { "name": "element" } }, + "endAdornment": { "type": { "name": "node" } }, + "icon": { + "type": { "name": "element" }, + "deprecated": true, + "deprecationInfo": "Use startAdornment instead. Ignored when startAdornment or action are used." + }, "label": { "type": { "name": "node" } }, "nativeButton": { "type": { "name": "bool" } }, - "onDelete": { "type": { "name": "func" } }, + "onDelete": { + "type": { "name": "func" }, + "deprecated": true, + "deprecationInfo": "Use endAdornment={<ChipDelete onClick={...} />} instead. Ignored when endAdornment or action are used." + }, "size": { "type": { "name": "union", @@ -25,18 +47,27 @@ }, "default": "'medium'" }, - "skipFocusWhenDisabled": { "type": { "name": "bool" }, "default": "false" }, + "skipFocusWhenDisabled": { + "type": { "name": "bool" }, + "default": "false", + "deprecated": true, + "deprecationInfo": "Use focusableWhenDisabled on the action element instead." + }, "slotProps": { "type": { "name": "shape", - "description": "{ label?: func
| object, root?: func
| object }" + "description": "{ endAdornment?: func
| object, label?: func
| object, root?: func
| object, startAdornment?: func
| object }" }, "default": "{}" }, "slots": { - "type": { "name": "shape", "description": "{ label?: elementType, root?: elementType }" }, + "type": { + "name": "shape", + "description": "{ endAdornment?: elementType, label?: elementType, root?: elementType, startAdornment?: elementType }" + }, "default": "{}" }, + "startAdornment": { "type": { "name": "node" } }, "sx": { "type": { "name": "union", @@ -66,9 +97,27 @@ "description": "The component that renders the label.", "default": "span", "class": "MuiChip-label" + }, + { + "name": "startAdornment", + "description": "The component that renders the start adornment wrapper.", + "default": "span", + "class": "MuiChip-startAdornment" + }, + { + "name": "endAdornment", + "description": "The component that renders the end adornment wrapper.", + "default": "span", + "class": "MuiChip-endAdornment" } ], "classes": [ + { + "key": "actionable", + "className": "MuiChip-actionable", + "description": "Styles applied to the root element when `action` is provided.", + "isGlobal": false + }, { "key": "avatar", "className": "MuiChip-avatar", diff --git a/docs/translations/api-docs/chip-button/chip-button.json b/docs/translations/api-docs/chip-button/chip-button.json new file mode 100644 index 00000000000000..7e86da008e857f --- /dev/null +++ b/docs/translations/api-docs/chip-button/chip-button.json @@ -0,0 +1,30 @@ +{ + "componentDescription": "An action overlay for the `Chip` component with button semantics.\n\nMust be used as the `action` prop of a `Chip`:\n```jsx\n} />\n```", + "propDescriptions": { + "classes": { "description": "Override or extend the styles applied to the component." }, + "component": { + "description": "The component used for the root node. Either a string to use a HTML element or a component.", + "requiresRef": true + }, + "disabled": { + "description": "If true, the component is disabled. When nested inside a Chip, inherits from the parent's disabled prop." + }, + "focusableWhenDisabled": { + "description": "If true, the disabled button can receive focus." + }, + "nativeButton": { + "description": "If true, the component is expected to resolve to a native <button> element. When omitted, native button semantics are inferred when component is 'button' or absent. Set explicitly when using a custom component that resolves to a native <button>." + }, + "sx": { + "description": "The system prop that allows defining system overrides as well as additional CSS styles." + } + }, + "classDescriptions": { + "disabled": { + "description": "State class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "disabled={true}" + }, + "root": { "description": "Styles applied to the root element." } + } +} diff --git a/docs/translations/api-docs/chip-delete/chip-delete.json b/docs/translations/api-docs/chip-delete/chip-delete.json new file mode 100644 index 00000000000000..bf597bd3142361 --- /dev/null +++ b/docs/translations/api-docs/chip-delete/chip-delete.json @@ -0,0 +1,90 @@ +{ + "componentDescription": "A chip-aware delete button, designed to be used as an adornment of `Chip`.\n\nWhen rendered inside a `Chip`, it inherits `disabled`, `color`, `size`, and `variant`\nfrom the chip context.", + "propDescriptions": { + "classes": { "description": "Override or extend the styles applied to the component." }, + "component": { + "description": "The component used for the root node. Either a string to use a HTML element or a component.", + "requiresRef": true + }, + "disabled": { + "description": "If true, the component is disabled. When inside a Chip, inherits the chip's disabled state." + }, + "focusableWhenDisabled": { + "description": "If true, the disabled delete button can receive focus." + }, + "icon": { "description": "Override the default delete icon element." }, + "label": { "description": "The accessible label for the delete button." }, + "nativeButton": { + "description": "If true, the component is expected to resolve to a native <button> element. When omitted, native button semantics are inferred when component is 'button' or absent. Set explicitly when using a custom component that resolves to a native <button>." + }, + "onDelete": { + "description": "Callback fired when the delete action is triggered. This fires on click, keyboard activation (Enter/Space), and when Backspace or Delete is pressed while the component has focus." + }, + "sx": { + "description": "The system prop that allows defining system overrides as well as additional CSS styles." + } + }, + "classDescriptions": { + "colorDefault": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "color=\"default\"" + }, + "colorError": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "color=\"error\"" + }, + "colorInfo": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "color=\"info\"" + }, + "colorPrimary": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "color=\"primary\"" + }, + "colorSecondary": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "color=\"secondary\"" + }, + "colorSuccess": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "color=\"success\"" + }, + "colorWarning": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "color=\"warning\"" + }, + "disabled": { + "description": "State class applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "disabled={true}" + }, + "filled": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "variant=\"filled\"" + }, + "outlined": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "variant=\"outlined\"" + }, + "root": { "description": "Styles applied to the root element." }, + "sizeMedium": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "size=\"medium\"" + }, + "sizeSmall": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "size=\"small\"" + } + } +} diff --git a/docs/translations/api-docs/chip-link/chip-link.json b/docs/translations/api-docs/chip-link/chip-link.json new file mode 100644 index 00000000000000..5c516bfc4b6ad5 --- /dev/null +++ b/docs/translations/api-docs/chip-link/chip-link.json @@ -0,0 +1,11 @@ +{ + "componentDescription": "An action overlay for the `Chip` component with link semantics.\n\nMust be used as the `action` prop of a `Chip`:\n\n```jsx\n} />\n```\n\nIntentionally ignores the parent Chip's `disabled` state because links should\nalways remain navigable. When used with a disabled Chip, the link stays enabled\nand the Chip root suppresses disabled styling.", + "propDescriptions": { + "classes": { "description": "Override or extend the styles applied to the component." }, + "href": { "description": "The URL to link to." }, + "sx": { + "description": "The system prop that allows defining system overrides as well as additional CSS styles." + } + }, + "classDescriptions": { "root": { "description": "Styles applied to the root element." } } +} diff --git a/docs/translations/api-docs/chip/chip.json b/docs/translations/api-docs/chip/chip.json index 2b5f2b375a3860..2f4cbbfface0fb 100644 --- a/docs/translations/api-docs/chip/chip.json +++ b/docs/translations/api-docs/chip/chip.json @@ -1,6 +1,9 @@ { "componentDescription": "Chips represent complex entities in small blocks, such as a contact.", "propDescriptions": { + "action": { + "description": "The action element to render inside the chip. Should be a <ChipButton> or <ChipLink> element. When provided, the chip root becomes a non-interactive shell and the action element handles all interactivity." + }, "avatar": { "description": "The Avatar element to display." }, "children": { "description": "This prop isn't supported. Use the component prop if you need to change the children structure." @@ -19,6 +22,9 @@ "description": "Override the default delete icon element. Shown only if onDelete is set." }, "disabled": { "description": "If true, the component is disabled." }, + "endAdornment": { + "description": "Content to render after the label. Typically a <ChipDelete> element. When provided, onDelete and deleteIcon are ignored." + }, "icon": { "description": "Icon element." }, "label": { "description": "The content of the component." }, "nativeButton": { @@ -33,12 +39,20 @@ }, "slotProps": { "description": "The props used for each slot inside." }, "slots": { "description": "The components used for each slot inside." }, + "startAdornment": { + "description": "Content to render before the label. Typically an icon or avatar element. When provided, avatar and icon are ignored." + }, "sx": { "description": "The system prop that allows defining system overrides as well as additional CSS styles." }, "variant": { "description": "The variant to use." } }, "classDescriptions": { + "actionable": { + "description": "Styles applied to {{nodeName}} when {{conditions}}.", + "nodeName": "the root element", + "conditions": "action is provided" + }, "avatar": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the avatar element" @@ -125,7 +139,9 @@ } }, "slotDescriptions": { + "endAdornment": "The component that renders the end adornment wrapper.", "label": "The component that renders the label.", - "root": "The component that renders the root." + "root": "The component that renders the root.", + "startAdornment": "The component that renders the start adornment wrapper." } } diff --git a/packages/mui-material/package.json b/packages/mui-material/package.json index 380ad752409229..f3cfd8d2ddc723 100644 --- a/packages/mui-material/package.json +++ b/packages/mui-material/package.json @@ -96,6 +96,9 @@ "./ButtonBase/TouchRipple": "./src/ButtonBase/TouchRipple.js", "./zero-styled": "./src/zero-styled/index.tsx", "./className": "./src/className/index.ts", + "./ChipButton": "./src/ChipButton/index.ts", + "./ChipDelete": "./src/ChipDelete/index.ts", + "./ChipLink": "./src/ChipLink/index.ts", "./ClickAwayListener": "./src/ClickAwayListener/index.ts", "./darkScrollbar": "./src/darkScrollbar/index.ts", "./DefaultPropsProvider": "./src/DefaultPropsProvider/index.ts", diff --git a/packages/mui-material/src/Chip/Chip.d.ts b/packages/mui-material/src/Chip/Chip.d.ts index 5659d853050fd8..3234a4f10a0c6b 100644 --- a/packages/mui-material/src/Chip/Chip.d.ts +++ b/packages/mui-material/src/Chip/Chip.d.ts @@ -17,6 +17,16 @@ export interface ChipSlots { * @default span */ label: React.ElementType; + /** + * The component that renders the start adornment wrapper. + * @default span + */ + startAdornment: React.ElementType; + /** + * The component that renders the end adornment wrapper. + * @default span + */ + endAdornment: React.ElementType; } export type ChipSlotsAndSlotProps = CreateSlotsAndSlotProps< @@ -32,6 +42,16 @@ export type ChipSlotsAndSlotProps = CreateSlotsAndSlotProps< * By default, the available props are based on the span element. */ label: SlotProps<'span', {}, ChipOwnerState>; + /** + * Props forwarded to the start adornment slot. + * By default, the available props are based on the span element. + */ + startAdornment: SlotProps<'span', {}, ChipOwnerState>; + /** + * Props forwarded to the end adornment slot. + * By default, the available props are based on the span element. + */ + endAdornment: SlotProps<'span', {}, ChipOwnerState>; } >; @@ -44,8 +64,16 @@ export interface ChipPropsSizeOverrides {} export interface ChipPropsColorOverrides {} export interface ChipOwnProps { + /** + * The action element to render inside the chip. + * Should be a `` or `` element. + * When provided, the chip root becomes a non-interactive shell and the action + * element handles all interactivity. + */ + action?: React.ReactElement | undefined; /** * The Avatar element to display. + * @deprecated Use `startAdornment` instead. Ignored when `startAdornment` or `action` are used. */ avatar?: React.ReactElement | undefined; /** @@ -64,6 +92,7 @@ export interface ChipOwnProps { * This can be used, for example, * along with the component prop to indicate an anchor Chip is clickable. * Note: this controls the UI and does not affect the onClick event. + * @deprecated Use `action={}` instead. Ignored when `action` is present. */ clickable?: boolean | undefined; /** @@ -80,6 +109,7 @@ export interface ChipOwnProps { | undefined; /** * Override the default delete icon element. Shown only if `onDelete` is set. + * @deprecated Use `endAdornment={}` instead. Ignored when `endAdornment` or `action` are used. */ deleteIcon?: React.ReactElement | undefined; /** @@ -87,8 +117,15 @@ export interface ChipOwnProps { * @default false */ disabled?: boolean | undefined; + /** + * Content to render after the label. + * Typically a `` element. + * When provided, `onDelete` and `deleteIcon` are ignored. + */ + endAdornment?: React.ReactNode | undefined; /** * Icon element. + * @deprecated Use `startAdornment` instead. Ignored when `startAdornment` or `action` are used. */ icon?: React.ReactElement | undefined; /** @@ -98,13 +135,9 @@ export interface ChipOwnProps { /** * Callback fired when the delete icon is clicked. * If set, the delete icon will be shown. + * @deprecated Use `endAdornment={}` instead. Ignored when `endAdornment` or `action` are used. */ onDelete?: React.EventHandler | undefined; - /** - * The size of the component. - * @default 'medium' - */ - size?: OverridableStringUnion<'small' | 'medium', ChipPropsSizeOverrides> | undefined; /** * If `true`, the component is expected to resolve to a native `} />); + }).toErrorDev([ + 'MUI: The `action` prop expects a `` or `` component.', + !strictModeDoubleLoggingSuppressed && + 'MUI: The `action` prop expects a `` or `` component.', + ]); + }); + + const onDeleteAdornmentWarning = [ + 'MUI: The `onDelete` prop is incompatible with the `startAdornment` and `endAdornment` props. ' + + 'Use `` as an adornment instead.', + !strictModeDoubleLoggingSuppressed && + 'MUI: The `onDelete` prop is incompatible with the `startAdornment` and `endAdornment` props. ' + + 'Use `` as an adornment instead.', + ]; + + it('warns when startAdornment is mixed with onDelete', () => { + expect(() => { + render( {}} startAdornment={} />); + }).toErrorDev(onDeleteAdornmentWarning); + }); + + it('warns when endAdornment is mixed with onDelete', () => { + expect(() => { + render( {}} endAdornment={} />); + }).toErrorDev(onDeleteAdornmentWarning); + }); + + it('does not warn when both adornments use ChipDelete', () => { + expect(() => { + render(} endAdornment={} />); + }).not.toErrorDev(); + }); + + it('warns when adornments are used with onClick but no action', () => { + expect(() => { + render(} onClick={() => {}} />); + }).toErrorDev([ + 'MUI: The `onClick` and `clickable` props have no effect when `startAdornment` or ' + + '`endAdornment` is provided without `action`. ' + + 'Use `action={}` to make the chip interactive.', + !strictModeDoubleLoggingSuppressed && + 'MUI: The `onClick` and `clickable` props have no effect when `startAdornment` or ' + + '`endAdornment` is provided without `action`. ' + + 'Use `action={}` to make the chip interactive.', + ]); + }); + + it('warns when adornments are used with clickable but no action', () => { + expect(() => { + render(} clickable />); + }).toErrorDev([ + 'MUI: The `onClick` and `clickable` props have no effect when `startAdornment` or ' + + '`endAdornment` is provided without `action`. ' + + 'Use `action={}` to make the chip interactive.', + !strictModeDoubleLoggingSuppressed && + 'MUI: The `onClick` and `clickable` props have no effect when `startAdornment` or ' + + '`endAdornment` is provided without `action`. ' + + 'Use `action={}` to make the chip interactive.', + ]); + }); + }); +}); diff --git a/packages/mui-material/src/Chip/ChipContext.ts b/packages/mui-material/src/Chip/ChipContext.ts new file mode 100644 index 00000000000000..612720af4ff1d1 --- /dev/null +++ b/packages/mui-material/src/Chip/ChipContext.ts @@ -0,0 +1,20 @@ +'use client'; +import * as React from 'react'; + +export interface ChipContextType { + color?: string | undefined; + disabled?: boolean | undefined; + size?: string | undefined; + variant?: string | undefined; +} + +/** + * @ignore - internal component. + */ +const ChipContext = React.createContext({}); + +if (process.env.NODE_ENV !== 'production') { + ChipContext.displayName = 'ChipContext'; +} + +export default ChipContext; diff --git a/packages/mui-material/src/Chip/chipClasses.ts b/packages/mui-material/src/Chip/chipClasses.ts index 84fcb3f3499a70..e5dc2dfdc41497 100644 --- a/packages/mui-material/src/Chip/chipClasses.ts +++ b/packages/mui-material/src/Chip/chipClasses.ts @@ -42,6 +42,12 @@ export interface ChipClasses { deleteIcon: string; /** State class applied to the root element if keyboard focused. */ focusVisible: string; + /** Styles applied to the startAdornment wrapper element. */ + startAdornment: string; + /** Styles applied to the endAdornment wrapper element. */ + endAdornment: string; + /** Styles applied to the root element when `action` is provided. */ + actionable: string; } export type ChipClassKey = keyof ChipClasses; @@ -71,6 +77,9 @@ const chipClasses: ChipClasses = generateUtilityClasses('MuiChip', [ 'label', 'deleteIcon', 'focusVisible', + 'startAdornment', + 'endAdornment', + 'actionable', ]); export default chipClasses; diff --git a/packages/mui-material/src/Chip/chipSharedStyles.ts b/packages/mui-material/src/Chip/chipSharedStyles.ts new file mode 100644 index 00000000000000..d9a5d7e91a1ec0 --- /dev/null +++ b/packages/mui-material/src/Chip/chipSharedStyles.ts @@ -0,0 +1,388 @@ +import type { Theme } from '../styles'; +import createSimplePaletteValueFilter from '../utils/createSimplePaletteValueFilter'; + +// Palette accessed with a dynamic color key from Object.entries(theme.palette). +// The `createSimplePaletteValueFilter` guarantees the entry is a valid palette color, +// but TypeScript can't narrow `string` to specific palette keys. +const p = (theme: Theme, color: string) => + ((theme.vars || theme).palette as Record)[color] as { + main: string; + dark: string; + contrastText: string; + }; + +type ChipAdornmentEdge = 'start' | 'end'; + +function getChipAdornmentMarginStyles( + edge: ChipAdornmentEdge, + startMargin: number, + endMargin: number, +) { + return edge === 'start' + ? { marginLeft: startMargin, marginRight: endMargin } + : { marginLeft: endMargin, marginRight: startMargin }; +} + +/** + * Class references needed by root styles for state-dependent selectors. + * Each consumer (ChipButton, ChipLink) passes its own class constants. + */ +interface ChipRootClassRefs { + focusVisible: string; + disabled?: string | undefined; +} + +/** + * Base CSS properties shared by all chip root elements (legacy ChipRoot and new ChipNewApiRoot). + * Extracted to prevent style drift between the two render paths. + */ +export function getChipBaseStyles(theme: Theme) { + return { + maxWidth: '100%', + fontFamily: theme.typography.fontFamily, + fontSize: theme.typography.pxToRem(13), + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + height: 32, + lineHeight: 1.5, + color: (theme.vars || theme).palette.text.primary, + backgroundColor: (theme.vars || theme).palette.action.selected, + borderRadius: 32 / 2, + whiteSpace: 'nowrap' as const, + transition: theme.transitions.create(['background-color', 'box-shadow']), + cursor: 'unset', + outline: 0, + textDecoration: 'none', + border: 0, + padding: 0, + verticalAlign: 'middle', + boxSizing: 'border-box' as const, + }; +} + +/** + * Root element styles shared by ChipButton and ChipLink. + * + * The root acts as either the interactive element itself (non-overlay mode) + * or a container div (overlay mode). The `interactive` ownerState flag + * controls which styles are applied, driven by the `variants` array. + */ +export function getChipRootStyles(theme: Theme, classes: ChipRootClassRefs) { + const hover = classes.disabled ? `&:not(.${classes.disabled}):hover` : '&:hover'; + return { + ...getChipBaseStyles(theme), + position: 'relative' as const, + // Contain internal z-index layering (label, adornments, action ::after) + // so it doesn't bleed into external stacking contexts (e.g. Popper). + isolation: 'isolate' as const, + ...(classes.disabled && { + [`&.${classes.disabled}`]: { + opacity: (theme.vars || theme).palette.action.disabledOpacity, + pointerEvents: 'none', + }, + }), + variants: [ + // ---- Size ---- + { + props: { size: 'small' }, + style: { + height: 24, + }, + }, + // ---- Colors (filled) ---- + ...Object.entries(theme.palette) + .filter(createSimplePaletteValueFilter(['contrastText'])) + .map(([color]) => ({ + props: { color }, + style: { + backgroundColor: p(theme, color).main, + color: p(theme, color).contrastText, + }, + })), + // ---- Interactive (non-overlay) ---- + { + props: { interactive: true }, + style: { + userSelect: 'none' as const, + WebkitTapHighlightColor: 'transparent', + cursor: 'pointer', + [`&.${classes.focusVisible}`]: { + backgroundColor: theme.alpha( + (theme.vars || theme).palette.action.selected, + `${(theme.vars || theme).palette.action.selectedOpacity} + ${(theme.vars || theme).palette.action.focusOpacity}`, + ), + }, + [hover]: { + backgroundColor: theme.alpha( + (theme.vars || theme).palette.action.selected, + `${(theme.vars || theme).palette.action.selectedOpacity} + ${(theme.vars || theme).palette.action.hoverOpacity}`, + ), + }, + '&:active': { + boxShadow: (theme.vars || theme).shadows[1], + }, + }, + }, + // ---- Interactive + color ---- + ...Object.entries(theme.palette) + .filter(createSimplePaletteValueFilter(['dark'])) + .map(([color]) => ({ + props: { color, interactive: true }, + style: { + [`${hover}, &.${classes.focusVisible}`]: { + backgroundColor: p(theme, color).dark, + }, + }, + })), + // ---- Overlay mode (hasDelete): root is
, hover triggered by nested action ---- + { + props: { interactive: false }, + style: { + [`&.${classes.focusVisible}`]: { + backgroundColor: theme.alpha( + (theme.vars || theme).palette.action.selected, + `${(theme.vars || theme).palette.action.selectedOpacity} + ${(theme.vars || theme).palette.action.focusOpacity}`, + ), + }, + [hover]: { + backgroundColor: theme.alpha( + (theme.vars || theme).palette.action.selected, + `${(theme.vars || theme).palette.action.selectedOpacity} + ${(theme.vars || theme).palette.action.hoverOpacity}`, + ), + }, + }, + }, + ...Object.entries(theme.palette) + .filter(createSimplePaletteValueFilter(['dark'])) + .map(([color]) => ({ + props: { color, interactive: false }, + style: { + [`${hover}, &.${classes.focusVisible}`]: { + backgroundColor: p(theme, color).dark, + }, + }, + })), + // ---- Outlined variant ---- + { + props: { variant: 'outlined' }, + style: { + backgroundColor: 'transparent', + border: theme.vars + ? `1px solid ${theme.vars.palette.Chip.defaultBorder}` + : `1px solid ${ + theme.palette.mode === 'light' ? theme.palette.grey[400] : theme.palette.grey[700] + }`, + [`&.${classes.focusVisible}`]: { + backgroundColor: (theme.vars || theme).palette.action.focus, + }, + [hover]: { + backgroundColor: (theme.vars || theme).palette.action.hover, + }, + }, + }, + // ---- Outlined + color ---- + ...Object.entries(theme.palette) + .filter(createSimplePaletteValueFilter()) + .map(([color]) => ({ + props: { variant: 'outlined', color }, + style: { + color: p(theme, color).main, + border: `1px solid ${theme.alpha(p(theme, color).main, 0.7)}`, + [hover]: { + backgroundColor: theme.alpha( + p(theme, color).main, + (theme.vars || theme).palette.action.hoverOpacity, + ), + }, + [`&.${classes.focusVisible}`]: { + backgroundColor: theme.alpha( + p(theme, color).main, + (theme.vars || theme).palette.action.focusOpacity, + ), + }, + }, + })), + ], + }; +} + +/** + * Action styles using the stretched-link pattern. + * + * The action element (`