From 3ca97c11a305ff09da0ac524fc8e60ab34c7321a Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 14 Aug 2024 10:51:20 +0700 Subject: [PATCH 01/11] fix color value --- .../src/Breadcrumbs/Breadcrumbs.js | 2 +- .../mui-material/src/CardHeader/CardHeader.js | 2 +- .../DialogContentText/DialogContentText.js | 2 +- .../DialogContentText.spec.tsx | 2 +- .../src/InputAdornment/InputAdornment.js | 2 +- .../src/ListItemText/ListItemText.js | 2 +- .../src/Typography/Typography.d.ts | 22 ++++++++++++++++++- .../mui-material/src/Typography/Typography.js | 8 +++++++ .../src/Typography/typography.spec.tsx | 2 +- 9 files changed, 36 insertions(+), 8 deletions(-) diff --git a/packages/mui-material/src/Breadcrumbs/Breadcrumbs.js b/packages/mui-material/src/Breadcrumbs/Breadcrumbs.js index a398e73d9fd778..650644850712ac 100644 --- a/packages/mui-material/src/Breadcrumbs/Breadcrumbs.js +++ b/packages/mui-material/src/Breadcrumbs/Breadcrumbs.js @@ -183,7 +183,7 @@ const Breadcrumbs = React.forwardRef(function Breadcrumbs(inProps, ref) { { - + {/* TODO: system props did not catch this error. Add @ts-expect-error after it is fixed. */} diff --git a/packages/mui-material/src/InputAdornment/InputAdornment.js b/packages/mui-material/src/InputAdornment/InputAdornment.js index 58f8c75fbc7764..dcb85e41a1b8bc 100644 --- a/packages/mui-material/src/InputAdornment/InputAdornment.js +++ b/packages/mui-material/src/InputAdornment/InputAdornment.js @@ -139,7 +139,7 @@ const InputAdornment = React.forwardRef(function InputAdornment(inProps, ref) { {...other} > {typeof children === 'string' && !disableTypography ? ( - {children} + {children} ) : ( {/* To have the correct vertical alignment baseline */} diff --git a/packages/mui-material/src/ListItemText/ListItemText.js b/packages/mui-material/src/ListItemText/ListItemText.js index aa7256d91194ea..51379b3d523836 100644 --- a/packages/mui-material/src/ListItemText/ListItemText.js +++ b/packages/mui-material/src/ListItemText/ListItemText.js @@ -106,7 +106,7 @@ const ListItemText = React.forwardRef(function ListItemText(inProps, ref) { diff --git a/packages/mui-material/src/Typography/Typography.d.ts b/packages/mui-material/src/Typography/Typography.d.ts index e4ff039a9cac8c..7c3d2ef966962a 100644 --- a/packages/mui-material/src/Typography/Typography.d.ts +++ b/packages/mui-material/src/Typography/Typography.d.ts @@ -8,7 +8,9 @@ import { TypographyClasses } from './typographyClasses'; export interface TypographyPropsVariantOverrides {} -export interface TypographyOwnProps extends SystemProps { +export interface TypographyPropsColorOverrides {} + +export interface TypographyOwnProps extends Omit, 'color'> { /** * Set the text-align on the component. * @default 'inherit' @@ -22,6 +24,24 @@ export interface TypographyOwnProps extends SystemProps { * Override or extend the styles applied to the component. */ classes?: Partial; + /** + * The color of the component. + * It supports both default and custom theme colors, which can be added as shown in the + * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors). + */ + color?: + | OverridableStringUnion< + | 'primary' + | 'secondary' + | 'success' + | 'error' + | 'info' + | 'warning' + | 'textPrimary' + | 'textSecondary', + TypographyPropsColorOverrides + > + | (string & {}); // to work with v5 color prop type which allows any string /** * If `true`, the text will have a bottom margin. * @default false diff --git a/packages/mui-material/src/Typography/Typography.js b/packages/mui-material/src/Typography/Typography.js index c5b7391526137c..cd14ac61cd3139 100644 --- a/packages/mui-material/src/Typography/Typography.js +++ b/packages/mui-material/src/Typography/Typography.js @@ -70,6 +70,14 @@ export const TypographyRoot = styled('span', { color: (theme.vars || theme).palette[color].main, }, })), + { + props: { color: 'textPrimary' }, + style: { color: (theme.vars || theme).palette.text?.primary }, + }, + { + props: { color: 'textSecondary' }, + style: { color: (theme.vars || theme).palette.text?.secondary }, + }, { props: ({ ownerState }) => ownerState.align !== 'inherit', style: { diff --git a/packages/mui-material/src/Typography/typography.spec.tsx b/packages/mui-material/src/Typography/typography.spec.tsx index e5a04e944952d7..20bf35cfc469ef 100644 --- a/packages/mui-material/src/Typography/typography.spec.tsx +++ b/packages/mui-material/src/Typography/typography.spec.tsx @@ -32,7 +32,7 @@ const typographyTest = () => { - + {/* TODO: system props did not catch this error. Add @ts-expect-error after it is fixed. */} From 96ec723f8d5297afcfc74ffe1be801b311c3de2d Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 14 Aug 2024 21:26:08 +0700 Subject: [PATCH 02/11] support all values in palette.text --- .../mui-material/src/Typography/Typography.d.ts | 5 ++--- .../mui-material/src/Typography/Typography.js | 16 ++++++++-------- .../src/Typography/typography.spec.tsx | 1 + 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/mui-material/src/Typography/Typography.d.ts b/packages/mui-material/src/Typography/Typography.d.ts index 7c3d2ef966962a..f07841314f040f 100644 --- a/packages/mui-material/src/Typography/Typography.d.ts +++ b/packages/mui-material/src/Typography/Typography.d.ts @@ -1,7 +1,7 @@ import * as React from 'react'; import { OverridableStringUnion } from '@mui/types'; import { SxProps, SystemProps } from '@mui/system'; -import { Theme } from '../styles'; +import { Theme, TypeText } from '../styles'; import { OverrideProps, OverridableComponent } from '../OverridableComponent'; import { Variant } from '../styles/createTypography'; import { TypographyClasses } from './typographyClasses'; @@ -37,8 +37,7 @@ export interface TypographyOwnProps extends Omit, 'color'> { | 'error' | 'info' | 'warning' - | 'textPrimary' - | 'textSecondary', + | `text${Capitalize}`, TypographyPropsColorOverrides > | (string & {}); // to work with v5 color prop type which allows any string diff --git a/packages/mui-material/src/Typography/Typography.js b/packages/mui-material/src/Typography/Typography.js index cd14ac61cd3139..c325911db12e76 100644 --- a/packages/mui-material/src/Typography/Typography.js +++ b/packages/mui-material/src/Typography/Typography.js @@ -70,14 +70,14 @@ export const TypographyRoot = styled('span', { color: (theme.vars || theme).palette[color].main, }, })), - { - props: { color: 'textPrimary' }, - style: { color: (theme.vars || theme).palette.text?.primary }, - }, - { - props: { color: 'textSecondary' }, - style: { color: (theme.vars || theme).palette.text?.secondary }, - }, + ...Object.entries(theme.palette?.text || {}) + .filter(([, value]) => typeof value === 'string') + .map(([color]) => ({ + props: { color: `text${capitalize(color)}` }, + style: { + color: (theme.vars || theme).palette.text[color], + }, + })), { props: ({ ownerState }) => ownerState.align !== 'inherit', style: { diff --git a/packages/mui-material/src/Typography/typography.spec.tsx b/packages/mui-material/src/Typography/typography.spec.tsx index 20bf35cfc469ef..c2a8be36a0960e 100644 --- a/packages/mui-material/src/Typography/typography.spec.tsx +++ b/packages/mui-material/src/Typography/typography.spec.tsx @@ -33,6 +33,7 @@ const typographyTest = () => { + {/* TODO: system props did not catch this error. Add @ts-expect-error after it is fixed. */} From 92e480110f84656523aa563aee0bf245f11fd3ae Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Wed, 14 Aug 2024 23:29:28 +0700 Subject: [PATCH 03/11] run proptypes and docs:api --- docs/pages/material-ui/api/typography.json | 6 ++++++ .../api-docs/typography/typography.json | 3 +++ .../mui-material/src/Typography/Typography.js | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/docs/pages/material-ui/api/typography.json b/docs/pages/material-ui/api/typography.json index a86efbb836ab3e..5bc2114152dd81 100644 --- a/docs/pages/material-ui/api/typography.json +++ b/docs/pages/material-ui/api/typography.json @@ -9,6 +9,12 @@ }, "children": { "type": { "name": "node" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, + "color": { + "type": { + "name": "union", + "description": "'primary'
| 'secondary'
| 'success'
| 'error'
| 'info'
| 'warning'
| 'textPrimary'
| 'textSecondary'
| 'textDisabled'
| string" + } + }, "component": { "type": { "name": "elementType" } }, "gutterBottom": { "type": { "name": "bool" }, "default": "false" }, "noWrap": { "type": { "name": "bool" }, "default": "false" }, diff --git a/docs/translations/api-docs/typography/typography.json b/docs/translations/api-docs/typography/typography.json index 369e9d2b613a5f..39506c3f3df3d2 100644 --- a/docs/translations/api-docs/typography/typography.json +++ b/docs/translations/api-docs/typography/typography.json @@ -4,6 +4,9 @@ "align": { "description": "Set the text-align on the component." }, "children": { "description": "The content of the component." }, "classes": { "description": "Override or extend the styles applied to the component." }, + "color": { + "description": "The color of the component. It supports both default and custom theme colors, which can be added as shown in the palette customization guide." + }, "component": { "description": "The component used for the root node. Either a string to use a HTML element or a component." }, diff --git a/packages/mui-material/src/Typography/Typography.js b/packages/mui-material/src/Typography/Typography.js index c325911db12e76..dbff393dea3b0f 100644 --- a/packages/mui-material/src/Typography/Typography.js +++ b/packages/mui-material/src/Typography/Typography.js @@ -213,6 +213,25 @@ Typography.propTypes /* remove-proptypes */ = { * @ignore */ className: PropTypes.string, + /** + * The color of the component. + * It supports both default and custom theme colors, which can be added as shown in the + * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors). + */ + color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ + PropTypes.oneOf([ + 'primary', + 'secondary', + 'success', + 'error', + 'info', + 'warning', + 'textPrimary', + 'textSecondary', + 'textDisabled', + ]), + PropTypes.string, + ]), /** * The component used for the root node. * Either a string to use a HTML element or a component. From d3c91aae7f0d33055dd4b10d879fef97487ac423 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 15 Aug 2024 10:23:13 +0700 Subject: [PATCH 04/11] add deprecation --- .../migrating-from-deprecated-apis.md | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/docs/data/material/migration/migrating-from-deprecated-apis/migrating-from-deprecated-apis.md b/docs/data/material/migration/migrating-from-deprecated-apis/migrating-from-deprecated-apis.md index f28287296f0666..fd4db2280497d5 100644 --- a/docs/data/material/migration/migrating-from-deprecated-apis/migrating-from-deprecated-apis.md +++ b/docs/data/material/migration/migrating-from-deprecated-apis/migrating-from-deprecated-apis.md @@ -1061,6 +1061,38 @@ The InputBase's prop `componentsProps` was deprecated in favor of `slotProps`: /> ``` +## Link + +The dot notation value for the `color` prop was deprecated: + +```diff + +``` + +For the `inherit` value, use the `sx` prop instead: + +```diff + +``` + ## ListItem Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#list-item-props) below to migrate the code as described in the following sections: @@ -1557,6 +1589,36 @@ The Tooltip's prop `componentsProps` was deprecated in favor of `slotProps`: ## Typography +The dot notation value for the `color` prop was deprecated: + +```diff + +``` + +For the `inherit` value, use the `sx` prop instead: + +```diff + +``` + Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#typography-props) below to migrate the code as described in the following sections: ```bash From 08c6911c2e3ee62404afea48bc0cf8bb309fc69f Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 15 Aug 2024 10:42:58 +0700 Subject: [PATCH 05/11] update Link to have text* colors --- packages/mui-material/src/Link/Link.js | 66 +++++++-- .../src/Link/getTextDecoration.test.js | 125 ------------------ .../src/Link/getTextDecoration.ts | 41 ------ .../mui-material/src/Typography/Typography.js | 24 +--- 4 files changed, 56 insertions(+), 200 deletions(-) delete mode 100644 packages/mui-material/src/Link/getTextDecoration.test.js delete mode 100644 packages/mui-material/src/Link/getTextDecoration.ts diff --git a/packages/mui-material/src/Link/Link.js b/packages/mui-material/src/Link/Link.js index 895fb42716d157..ec05879650c7db 100644 --- a/packages/mui-material/src/Link/Link.js +++ b/packages/mui-material/src/Link/Link.js @@ -7,11 +7,22 @@ import elementTypeAcceptingRef from '@mui/utils/elementTypeAcceptingRef'; import composeClasses from '@mui/utils/composeClasses'; import isFocusVisible from '@mui/utils/isFocusVisible'; import capitalize from '../utils/capitalize'; -import { styled, useTheme } from '../zero-styled'; +import { styled } from '../zero-styled'; import { useDefaultProps } from '../DefaultPropsProvider'; import Typography from '../Typography'; import linkClasses, { getLinkUtilityClass } from './linkClasses'; -import getTextDecoration, { colorTransformations } from './getTextDecoration'; + +const v6Colors = { + primary: true, + secondary: true, + error: true, + info: true, + success: true, + warning: true, + textPrimary: true, + textSecondary: true, + textDisabled: true, +}; const useUtilityClasses = (ownerState) => { const { classes, component, focusVisible, underline } = ownerState; @@ -90,6 +101,28 @@ const LinkRoot = styled(Typography, { : alpha(theme.palette[color].main, 0.4), }, })), + { + props: { underline: 'always', color: 'textPrimary' }, + style: { + '--Link-underlineColor': theme.vars + ? `rgba(${theme.vars.palette.text.primaryChannel} / 0.4)` + : alpha(theme.palette.text.primary, 0.4), + }, + }, + { + props: { underline: 'always', color: 'textSecondary' }, + style: { + '--Link-underlineColor': theme.vars + ? `rgba(${theme.vars.palette.text.secondaryChannel} / 0.4)` + : alpha(theme.palette.text.secondary, 0.4), + }, + }, + { + props: { underline: 'always', color: 'textDisabled' }, + style: { + '--Link-underlineColor': (theme.vars || theme).palette.text.disabled, + }, + }, { props: { component: 'button', @@ -126,7 +159,6 @@ const Link = React.forwardRef(function Link(inProps, ref) { props: inProps, name: 'MuiLink', }); - const theme = useTheme(); const { className, @@ -183,16 +215,9 @@ const Link = React.forwardRef(function Link(inProps, ref) { variant={variant} {...other} sx={[ - ...(colorTransformations[color] === undefined ? [{ color }] : []), + ...(v6Colors[color] === undefined ? [{ color }] : []), ...(Array.isArray(sx) ? sx : [sx]), ]} - style={{ - ...other.style, - ...(underline === 'always' && - color !== 'inherit' && { - '--Link-underlineColor': getTextDecoration({ theme, ownerState }), - }), - }} /> ); }); @@ -215,10 +240,25 @@ Link.propTypes /* remove-proptypes */ = { */ className: PropTypes.string, /** - * The color of the link. + * The color of the component. + * It supports both default and custom theme colors, which can be added as shown in the + * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors). * @default 'primary' */ - color: PropTypes /* @typescript-to-proptypes-ignore */.any, + color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ + PropTypes.oneOf([ + 'primary', + 'secondary', + 'success', + 'error', + 'info', + 'warning', + 'textPrimary', + 'textSecondary', + 'textDisabled', + ]), + PropTypes.string, + ]), /** * The component used for the root node. * Either a string to use a HTML element or a component. diff --git a/packages/mui-material/src/Link/getTextDecoration.test.js b/packages/mui-material/src/Link/getTextDecoration.test.js deleted file mode 100644 index cf15c993b1d48c..00000000000000 --- a/packages/mui-material/src/Link/getTextDecoration.test.js +++ /dev/null @@ -1,125 +0,0 @@ -import { expect } from 'chai'; -import { createTheme, extendTheme } from '../styles'; -import getTextDecoration from './getTextDecoration'; - -describe('getTextDecoration', () => { - describe('without theme.vars', () => { - const theme = createTheme(); - - it('deprecated color', () => { - expect(getTextDecoration({ theme, ownerState: { color: 'textPrimary' } })).to.equal( - 'rgba(0, 0, 0, 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'textSecondary' } })).to.equal( - 'rgba(0, 0, 0, 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'primary' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'secondary' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'error' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'info' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'success' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'warning' } })).to.equal(null); - }); - - it('system color', () => { - expect(getTextDecoration({ theme, ownerState: { color: 'primary.main' } })).to.equal( - 'rgba(25, 118, 210, 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'text.primary' } })).to.equal( - 'rgba(0, 0, 0, 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'secondary.main' } })).to.equal( - 'rgba(156, 39, 176, 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'text.secondary' } })).to.equal( - 'rgba(0, 0, 0, 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'error.main' } })).to.equal( - 'rgba(211, 47, 47, 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'grey.500' } })).to.equal( - 'rgba(158, 158, 158, 0.4)', - ); - }); - - it('valid CSS color', () => { - expect(getTextDecoration({ theme, ownerState: { color: '#000' } })).to.equal( - 'rgba(0, 0, 0, 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'rgb(1, 1, 1)' } })).to.equal( - 'rgba(1, 1, 1, 0.4)', - ); - expect(() => getTextDecoration({ theme, ownerState: { color: 'yellow' } })).to.throw(); - }); - }); - - describe('CSS variables', () => { - const theme = extendTheme(); - theme.palette = theme.colorSchemes.light.palette; - theme.vars = { - palette: { - primary: { - mainChannel: 'var(--palette-primary-mainChannel)', - }, - secondary: { - mainChannel: 'var(--palette-secondary-mainChannel)', - }, - text: { - primaryChannel: 'var(--palette-text-primaryChannel)', - secondaryChannel: 'var(--palette-text-secondaryChannel)', - }, - error: { - mainChannel: 'var(--palette-error-mainChannel)', - }, - }, - }; - // in the application, the value will be CSS variable: `rgba(var(--the-color-channel) / 0.4)` - it('deprecated color', () => { - expect(getTextDecoration({ theme, ownerState: { color: 'textPrimary' } })).to.equal( - 'rgba(var(--palette-text-primaryChannel) / 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'textSecondary' } })).to.equal( - 'rgba(var(--palette-text-secondaryChannel) / 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'primary' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'secondary' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'error' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'info' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'success' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'warning' } })).to.equal(null); - }); - - it('system color', () => { - expect(getTextDecoration({ theme, ownerState: { color: 'primary.main' } })).to.equal( - 'rgba(var(--palette-primary-mainChannel) / 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'text.primary' } })).to.equal( - 'rgba(var(--palette-text-primaryChannel) / 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'secondary.main' } })).to.equal( - 'rgba(var(--palette-secondary-mainChannel) / 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'text.secondary' } })).to.equal( - 'rgba(var(--palette-text-secondaryChannel) / 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'error.main' } })).to.equal( - 'rgba(var(--palette-error-mainChannel) / 0.4)', - ); - - // it fallback to use `theme.palette.grey.500` with alpha() if it could not find channel color - expect(getTextDecoration({ theme, ownerState: { color: 'grey.500' } })).to.equal( - 'rgba(158, 158, 158, 0.4)', - ); - }); - - it('valid CSS color', () => { - expect(getTextDecoration({ theme, ownerState: { color: '#000' } })).to.equal( - 'rgba(0, 0, 0, 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'rgb(1, 1, 1)' } })).to.equal( - 'rgba(1, 1, 1, 0.4)', - ); - expect(() => getTextDecoration({ theme, ownerState: { color: 'yellow' } })).to.throw(); - }); - }); -}); diff --git a/packages/mui-material/src/Link/getTextDecoration.ts b/packages/mui-material/src/Link/getTextDecoration.ts deleted file mode 100644 index 517d8e77eaab23..00000000000000 --- a/packages/mui-material/src/Link/getTextDecoration.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { getPath } from '@mui/system/style'; -import { alpha } from '@mui/system/colorManipulator'; -import type { Theme } from '../styles'; - -// TODO v7: remove this transformation -export const colorTransformations: Record = { - textPrimary: 'text.primary', - textSecondary: 'text.secondary', - // For main palette, the color will be applied by the styles above. - primary: null, - secondary: null, - error: null, - info: null, - success: null, - warning: null, -}; - -const getTextDecoration = ({ - theme, - ownerState, -}: { - theme: T; - ownerState: { color: string }; -}) => { - let transformedColor = colorTransformations[ownerState.color]; - if (transformedColor === null) { - return null; - } - if (transformedColor === undefined) { - transformedColor = ownerState.color; - } - const color = (getPath(theme, `palette.${transformedColor}`, false) || - ownerState.color) as string; - const channelColor = getPath(theme, `palette.${transformedColor}Channel`) as string | null; - if ('vars' in theme && channelColor) { - return `rgba(${channelColor} / 0.4)`; - } - return alpha(color, 0.4); -}; - -export default getTextDecoration; diff --git a/packages/mui-material/src/Typography/Typography.js b/packages/mui-material/src/Typography/Typography.js index dbff393dea3b0f..6ffe876db91022 100644 --- a/packages/mui-material/src/Typography/Typography.js +++ b/packages/mui-material/src/Typography/Typography.js @@ -121,31 +121,13 @@ const defaultVariantMapping = { inherit: 'p', }; -// TODO v7: remove this transformation and `extendSxProp` -const colorTransformations = { - textPrimary: 'text.primary', - textSecondary: 'text.secondary', - // For the main palette, the color will be applied by the `...Object.entries(theme.palette)` clause in the TypographyRoot's styles - primary: null, - secondary: null, - error: null, - info: null, - success: null, - warning: null, -}; - const Typography = React.forwardRef(function Typography(inProps, ref) { - const { color, ...themeProps } = useDefaultProps({ props: inProps, name: 'MuiTypography' }); - const textColor = colorTransformations[color]; - const props = extendSxProp({ - ...themeProps, - ...(textColor !== null && { - color: textColor || color, - }), - }); + const themeProps = useDefaultProps({ props: inProps, name: 'MuiTypography' }); + const props = extendSxProp(themeProps); const { align = 'inherit', + color, className, component, gutterBottom = false, From 47084eb040d82ea79804e3c7406afc60cebd0c75 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 15 Aug 2024 10:43:57 +0700 Subject: [PATCH 06/11] run proptypes and api --- docs/pages/material-ui/api/link.json | 8 +++++++- packages/mui-material/src/Link/Link.js | 8 +------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/pages/material-ui/api/link.json b/docs/pages/material-ui/api/link.json index 64a6aef9859d7f..a277ca0f21a218 100644 --- a/docs/pages/material-ui/api/link.json +++ b/docs/pages/material-ui/api/link.json @@ -2,7 +2,13 @@ "props": { "children": { "type": { "name": "node" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, - "color": { "type": { "name": "any" }, "default": "'primary'" }, + "color": { + "type": { + "name": "union", + "description": "'primary'
| 'secondary'
| 'success'
| 'error'
| 'info'
| 'warning'
| 'textPrimary'
| 'textSecondary'
| 'textDisabled'
| string" + }, + "default": "'primary'" + }, "component": { "type": { "name": "custom", "description": "element type" } }, "sx": { "type": { diff --git a/packages/mui-material/src/Link/Link.js b/packages/mui-material/src/Link/Link.js index ec05879650c7db..3832f47dfb4361 100644 --- a/packages/mui-material/src/Link/Link.js +++ b/packages/mui-material/src/Link/Link.js @@ -240,9 +240,7 @@ Link.propTypes /* remove-proptypes */ = { */ className: PropTypes.string, /** - * The color of the component. - * It supports both default and custom theme colors, which can be added as shown in the - * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors). + * The color of the link. * @default 'primary' */ color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ @@ -272,10 +270,6 @@ Link.propTypes /* remove-proptypes */ = { * @ignore */ onFocus: PropTypes.func, - /** - * @ignore - */ - style: PropTypes.object, /** * The system prop that allows defining system overrides as well as additional CSS styles. */ From 784e77858021dffb398ed57c23d660a504c6792b Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 15 Aug 2024 11:07:57 +0700 Subject: [PATCH 07/11] fix Typography sx color --- .../mui-material/src/Typography/Typography.js | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/mui-material/src/Typography/Typography.js b/packages/mui-material/src/Typography/Typography.js index 6ffe876db91022..9ba5bdffcec985 100644 --- a/packages/mui-material/src/Typography/Typography.js +++ b/packages/mui-material/src/Typography/Typography.js @@ -8,6 +8,18 @@ import { useDefaultProps } from '../DefaultPropsProvider'; import capitalize from '../utils/capitalize'; import { getTypographyUtilityClass } from './typographyClasses'; +const v6Colors = { + primary: true, + secondary: true, + error: true, + info: true, + success: true, + warning: true, + textPrimary: true, + textSecondary: true, + textDisabled: true, +}; + const extendSxProp = internal_createExtendSxProp(); const useUtilityClasses = (ownerState) => { @@ -122,12 +134,16 @@ const defaultVariantMapping = { }; const Typography = React.forwardRef(function Typography(inProps, ref) { - const themeProps = useDefaultProps({ props: inProps, name: 'MuiTypography' }); - const props = extendSxProp(themeProps); + const { color, ...themeProps } = useDefaultProps({ props: inProps, name: 'MuiTypography' }); + const isSxColor = !v6Colors[color]; + // TODO: Remove `extendSxProp` in v7 + const props = extendSxProp({ + ...themeProps, + ...(isSxColor && { color }), + }); const { align = 'inherit', - color, className, component, gutterBottom = false, From ec1b578d4aee7b33b817d389135467ab30d4a20d Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 15 Aug 2024 11:15:53 +0700 Subject: [PATCH 08/11] remove duplicated content --- .../migrating-from-deprecated-apis.md | 62 ------------------- 1 file changed, 62 deletions(-) diff --git a/docs/data/material/migration/migrating-from-deprecated-apis/migrating-from-deprecated-apis.md b/docs/data/material/migration/migrating-from-deprecated-apis/migrating-from-deprecated-apis.md index fd4db2280497d5..f28287296f0666 100644 --- a/docs/data/material/migration/migrating-from-deprecated-apis/migrating-from-deprecated-apis.md +++ b/docs/data/material/migration/migrating-from-deprecated-apis/migrating-from-deprecated-apis.md @@ -1061,38 +1061,6 @@ The InputBase's prop `componentsProps` was deprecated in favor of `slotProps`: /> ``` -## Link - -The dot notation value for the `color` prop was deprecated: - -```diff - -``` - -For the `inherit` value, use the `sx` prop instead: - -```diff - -``` - ## ListItem Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#list-item-props) below to migrate the code as described in the following sections: @@ -1589,36 +1557,6 @@ The Tooltip's prop `componentsProps` was deprecated in favor of `slotProps`: ## Typography -The dot notation value for the `color` prop was deprecated: - -```diff - -``` - -For the `inherit` value, use the `sx` prop instead: - -```diff - -``` - Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#typography-props) below to migrate the code as described in the following sections: ```bash From dfddc03473d7028e35455c5751e8821ab2d0912f Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 15 Aug 2024 11:36:18 +0700 Subject: [PATCH 09/11] revert Link color sx value --- packages/mui-material/src/Link/Link.js | 12 +- .../src/Link/getTextDecoration.test.js | 125 ++++++++++++++++++ .../src/Link/getTextDecoration.ts | 22 +++ 3 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 packages/mui-material/src/Link/getTextDecoration.test.js create mode 100644 packages/mui-material/src/Link/getTextDecoration.ts diff --git a/packages/mui-material/src/Link/Link.js b/packages/mui-material/src/Link/Link.js index 3832f47dfb4361..05abc11d12354a 100644 --- a/packages/mui-material/src/Link/Link.js +++ b/packages/mui-material/src/Link/Link.js @@ -7,10 +7,11 @@ import elementTypeAcceptingRef from '@mui/utils/elementTypeAcceptingRef'; import composeClasses from '@mui/utils/composeClasses'; import isFocusVisible from '@mui/utils/isFocusVisible'; import capitalize from '../utils/capitalize'; -import { styled } from '../zero-styled'; +import { styled, useTheme } from '../zero-styled'; import { useDefaultProps } from '../DefaultPropsProvider'; import Typography from '../Typography'; import linkClasses, { getLinkUtilityClass } from './linkClasses'; +import getTextDecoration from './getTextDecoration'; const v6Colors = { primary: true, @@ -159,6 +160,7 @@ const Link = React.forwardRef(function Link(inProps, ref) { props: inProps, name: 'MuiLink', }); + const theme = useTheme(); const { className, @@ -218,6 +220,14 @@ const Link = React.forwardRef(function Link(inProps, ref) { ...(v6Colors[color] === undefined ? [{ color }] : []), ...(Array.isArray(sx) ? sx : [sx]), ]} + style={{ + ...other.style, + ...(underline === 'always' && + color !== 'inherit' && + !v6Colors[color] && { + '--Link-underlineColor': getTextDecoration({ theme, ownerState }), + }), + }} /> ); }); diff --git a/packages/mui-material/src/Link/getTextDecoration.test.js b/packages/mui-material/src/Link/getTextDecoration.test.js new file mode 100644 index 00000000000000..cf15c993b1d48c --- /dev/null +++ b/packages/mui-material/src/Link/getTextDecoration.test.js @@ -0,0 +1,125 @@ +import { expect } from 'chai'; +import { createTheme, extendTheme } from '../styles'; +import getTextDecoration from './getTextDecoration'; + +describe('getTextDecoration', () => { + describe('without theme.vars', () => { + const theme = createTheme(); + + it('deprecated color', () => { + expect(getTextDecoration({ theme, ownerState: { color: 'textPrimary' } })).to.equal( + 'rgba(0, 0, 0, 0.4)', + ); + expect(getTextDecoration({ theme, ownerState: { color: 'textSecondary' } })).to.equal( + 'rgba(0, 0, 0, 0.4)', + ); + expect(getTextDecoration({ theme, ownerState: { color: 'primary' } })).to.equal(null); + expect(getTextDecoration({ theme, ownerState: { color: 'secondary' } })).to.equal(null); + expect(getTextDecoration({ theme, ownerState: { color: 'error' } })).to.equal(null); + expect(getTextDecoration({ theme, ownerState: { color: 'info' } })).to.equal(null); + expect(getTextDecoration({ theme, ownerState: { color: 'success' } })).to.equal(null); + expect(getTextDecoration({ theme, ownerState: { color: 'warning' } })).to.equal(null); + }); + + it('system color', () => { + expect(getTextDecoration({ theme, ownerState: { color: 'primary.main' } })).to.equal( + 'rgba(25, 118, 210, 0.4)', + ); + expect(getTextDecoration({ theme, ownerState: { color: 'text.primary' } })).to.equal( + 'rgba(0, 0, 0, 0.4)', + ); + expect(getTextDecoration({ theme, ownerState: { color: 'secondary.main' } })).to.equal( + 'rgba(156, 39, 176, 0.4)', + ); + expect(getTextDecoration({ theme, ownerState: { color: 'text.secondary' } })).to.equal( + 'rgba(0, 0, 0, 0.4)', + ); + expect(getTextDecoration({ theme, ownerState: { color: 'error.main' } })).to.equal( + 'rgba(211, 47, 47, 0.4)', + ); + expect(getTextDecoration({ theme, ownerState: { color: 'grey.500' } })).to.equal( + 'rgba(158, 158, 158, 0.4)', + ); + }); + + it('valid CSS color', () => { + expect(getTextDecoration({ theme, ownerState: { color: '#000' } })).to.equal( + 'rgba(0, 0, 0, 0.4)', + ); + expect(getTextDecoration({ theme, ownerState: { color: 'rgb(1, 1, 1)' } })).to.equal( + 'rgba(1, 1, 1, 0.4)', + ); + expect(() => getTextDecoration({ theme, ownerState: { color: 'yellow' } })).to.throw(); + }); + }); + + describe('CSS variables', () => { + const theme = extendTheme(); + theme.palette = theme.colorSchemes.light.palette; + theme.vars = { + palette: { + primary: { + mainChannel: 'var(--palette-primary-mainChannel)', + }, + secondary: { + mainChannel: 'var(--palette-secondary-mainChannel)', + }, + text: { + primaryChannel: 'var(--palette-text-primaryChannel)', + secondaryChannel: 'var(--palette-text-secondaryChannel)', + }, + error: { + mainChannel: 'var(--palette-error-mainChannel)', + }, + }, + }; + // in the application, the value will be CSS variable: `rgba(var(--the-color-channel) / 0.4)` + it('deprecated color', () => { + expect(getTextDecoration({ theme, ownerState: { color: 'textPrimary' } })).to.equal( + 'rgba(var(--palette-text-primaryChannel) / 0.4)', + ); + expect(getTextDecoration({ theme, ownerState: { color: 'textSecondary' } })).to.equal( + 'rgba(var(--palette-text-secondaryChannel) / 0.4)', + ); + expect(getTextDecoration({ theme, ownerState: { color: 'primary' } })).to.equal(null); + expect(getTextDecoration({ theme, ownerState: { color: 'secondary' } })).to.equal(null); + expect(getTextDecoration({ theme, ownerState: { color: 'error' } })).to.equal(null); + expect(getTextDecoration({ theme, ownerState: { color: 'info' } })).to.equal(null); + expect(getTextDecoration({ theme, ownerState: { color: 'success' } })).to.equal(null); + expect(getTextDecoration({ theme, ownerState: { color: 'warning' } })).to.equal(null); + }); + + it('system color', () => { + expect(getTextDecoration({ theme, ownerState: { color: 'primary.main' } })).to.equal( + 'rgba(var(--palette-primary-mainChannel) / 0.4)', + ); + expect(getTextDecoration({ theme, ownerState: { color: 'text.primary' } })).to.equal( + 'rgba(var(--palette-text-primaryChannel) / 0.4)', + ); + expect(getTextDecoration({ theme, ownerState: { color: 'secondary.main' } })).to.equal( + 'rgba(var(--palette-secondary-mainChannel) / 0.4)', + ); + expect(getTextDecoration({ theme, ownerState: { color: 'text.secondary' } })).to.equal( + 'rgba(var(--palette-text-secondaryChannel) / 0.4)', + ); + expect(getTextDecoration({ theme, ownerState: { color: 'error.main' } })).to.equal( + 'rgba(var(--palette-error-mainChannel) / 0.4)', + ); + + // it fallback to use `theme.palette.grey.500` with alpha() if it could not find channel color + expect(getTextDecoration({ theme, ownerState: { color: 'grey.500' } })).to.equal( + 'rgba(158, 158, 158, 0.4)', + ); + }); + + it('valid CSS color', () => { + expect(getTextDecoration({ theme, ownerState: { color: '#000' } })).to.equal( + 'rgba(0, 0, 0, 0.4)', + ); + expect(getTextDecoration({ theme, ownerState: { color: 'rgb(1, 1, 1)' } })).to.equal( + 'rgba(1, 1, 1, 0.4)', + ); + expect(() => getTextDecoration({ theme, ownerState: { color: 'yellow' } })).to.throw(); + }); + }); +}); diff --git a/packages/mui-material/src/Link/getTextDecoration.ts b/packages/mui-material/src/Link/getTextDecoration.ts new file mode 100644 index 00000000000000..8afec8d8a45927 --- /dev/null +++ b/packages/mui-material/src/Link/getTextDecoration.ts @@ -0,0 +1,22 @@ +import { getPath } from '@mui/system/style'; +import { alpha } from '@mui/system/colorManipulator'; +import type { Theme } from '../styles'; + +const getTextDecoration = ({ + theme, + ownerState, +}: { + theme: T; + ownerState: { color: string }; +}) => { + const transformedColor = ownerState.color; + const color = (getPath(theme, `palette.${transformedColor}`, false) || + ownerState.color) as string; + const channelColor = getPath(theme, `palette.${transformedColor}Channel`) as string | null; + if ('vars' in theme && channelColor) { + return `rgba(${channelColor} / 0.4)`; + } + return alpha(color, 0.4); +}; + +export default getTextDecoration; From b1ab060666301501dac308ca808138d2c2f5c1dd Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 15 Aug 2024 12:01:29 +0700 Subject: [PATCH 10/11] remove unnecessary tests --- .../src/Link/getTextDecoration.test.js | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/packages/mui-material/src/Link/getTextDecoration.test.js b/packages/mui-material/src/Link/getTextDecoration.test.js index cf15c993b1d48c..142b16a9499ad0 100644 --- a/packages/mui-material/src/Link/getTextDecoration.test.js +++ b/packages/mui-material/src/Link/getTextDecoration.test.js @@ -6,21 +6,6 @@ describe('getTextDecoration', () => { describe('without theme.vars', () => { const theme = createTheme(); - it('deprecated color', () => { - expect(getTextDecoration({ theme, ownerState: { color: 'textPrimary' } })).to.equal( - 'rgba(0, 0, 0, 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'textSecondary' } })).to.equal( - 'rgba(0, 0, 0, 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'primary' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'secondary' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'error' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'info' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'success' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'warning' } })).to.equal(null); - }); - it('system color', () => { expect(getTextDecoration({ theme, ownerState: { color: 'primary.main' } })).to.equal( 'rgba(25, 118, 210, 0.4)', @@ -73,21 +58,6 @@ describe('getTextDecoration', () => { }, }, }; - // in the application, the value will be CSS variable: `rgba(var(--the-color-channel) / 0.4)` - it('deprecated color', () => { - expect(getTextDecoration({ theme, ownerState: { color: 'textPrimary' } })).to.equal( - 'rgba(var(--palette-text-primaryChannel) / 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'textSecondary' } })).to.equal( - 'rgba(var(--palette-text-secondaryChannel) / 0.4)', - ); - expect(getTextDecoration({ theme, ownerState: { color: 'primary' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'secondary' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'error' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'info' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'success' } })).to.equal(null); - expect(getTextDecoration({ theme, ownerState: { color: 'warning' } })).to.equal(null); - }); it('system color', () => { expect(getTextDecoration({ theme, ownerState: { color: 'primary.main' } })).to.equal( From f126e59d5c541e9a0ebbdb16721dfb2a02d30889 Mon Sep 17 00:00:00 2001 From: siriwatknp Date: Thu, 15 Aug 2024 12:03:04 +0700 Subject: [PATCH 11/11] run proptypes --- packages/mui-material/src/Link/Link.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/mui-material/src/Link/Link.js b/packages/mui-material/src/Link/Link.js index 05abc11d12354a..a452e41828657e 100644 --- a/packages/mui-material/src/Link/Link.js +++ b/packages/mui-material/src/Link/Link.js @@ -280,6 +280,10 @@ Link.propTypes /* remove-proptypes */ = { * @ignore */ onFocus: PropTypes.func, + /** + * @ignore + */ + style: PropTypes.object, /** * The system prop that allows defining system overrides as well as additional CSS styles. */