diff --git a/docs/src/pages/customization/palette/palette.md b/docs/src/pages/customization/palette/palette.md index 68ba4d3baa240a..a2dbf3586606e5 100644 --- a/docs/src/pages/customization/palette/palette.md +++ b/docs/src/pages/customization/palette/palette.md @@ -102,6 +102,15 @@ As in the example above, if the intention object contains custom colors using an according to the "contrastThreshold" value. Both the "tonalOffset" and "contrastThreshold" values may be customized as needed. +The "tonalOffset" value can either be a number between 0 and 1, which will apply to both light and dark variants, or an object with light and dark variants specified by the following TypeScript type: + +```ts +type PaletteTonalOffset = number | { + light: number; + dark: number; +}; +``` + A higher value for "tonalOffset" will make calculated values for "light" lighter, and "dark" darker. A higher value for "contrastThreshold" increases the point at which a background color is considered light, and given a dark "contrastText". diff --git a/packages/material-ui/src/styles/createPalette.d.ts b/packages/material-ui/src/styles/createPalette.d.ts index 05fbb0d6495abd..fa4a5c1e141357 100644 --- a/packages/material-ui/src/styles/createPalette.d.ts +++ b/packages/material-ui/src/styles/createPalette.d.ts @@ -61,6 +61,13 @@ export interface TypeObject { background: TypeBackground; } +export type PaletteTonalOffset = + | number + | { + light: number; + dark: number; + }; + export const light: TypeObject; export const dark: TypeObject; @@ -68,7 +75,7 @@ export interface Palette { common: CommonColors; type: PaletteType; contrastThreshold: number; - tonalOffset: number; + tonalOffset: PaletteTonalOffset; primary: PaletteColor; secondary: PaletteColor; error: PaletteColor; @@ -102,7 +109,7 @@ export interface PaletteOptions { info?: PaletteColorOptions; success?: PaletteColorOptions; type?: PaletteType; - tonalOffset?: number; + tonalOffset?: PaletteTonalOffset; contrastThreshold?: number; common?: Partial; grey?: ColorPartial; diff --git a/packages/material-ui/src/styles/createPalette.js b/packages/material-ui/src/styles/createPalette.js index ef668ad6ac3a81..f76cf68f32a395 100644 --- a/packages/material-ui/src/styles/createPalette.js +++ b/packages/material-ui/src/styles/createPalette.js @@ -79,13 +79,16 @@ export const dark = { }; function addLightOrDark(intent, direction, shade, tonalOffset) { + const tonalOffsetLight = tonalOffset.light || tonalOffset; + const tonalOffsetDark = tonalOffset.dark || tonalOffset * 1.5; + if (!intent[direction]) { if (intent.hasOwnProperty(shade)) { intent[direction] = intent[shade]; } else if (direction === 'light') { - intent.light = lighten(intent.main, tonalOffset); + intent.light = lighten(intent.main, tonalOffsetLight); } else if (direction === 'dark') { - intent.dark = darken(intent.main, tonalOffset * 1.5); + intent.dark = darken(intent.main, tonalOffsetDark); } } } diff --git a/packages/material-ui/src/styles/createPalette.test.js b/packages/material-ui/src/styles/createPalette.test.js index 4116e046e19dd1..5847f2955b6fa7 100644 --- a/packages/material-ui/src/styles/createPalette.test.js +++ b/packages/material-ui/src/styles/createPalette.test.js @@ -43,7 +43,7 @@ describe('createPalette()', () => { }); }); - it('should calculate light and dark colors using the provided tonalOffset', () => { + it('should calculate light and dark colors using a simple tonalOffset number value', () => { const palette = createPalette({ primary: { main: deepOrange[500] }, tonalOffset: 0.1, @@ -56,6 +56,22 @@ describe('createPalette()', () => { }); }); + it('should calculate light and dark colors using a custom tonalOffset object value', () => { + const palette = createPalette({ + primary: { main: deepOrange[500] }, + tonalOffset: { + light: 0.8, + dark: 0.5, + }, + }); + + expect(palette.primary).to.deep.include({ + main: deepOrange[500], + light: lighten(deepOrange[500], 0.8), + dark: darken(deepOrange[500], 0.5), + }); + }); + it('should calculate contrastText using the provided contrastThreshold', () => { const palette = createPalette({ contrastThreshold: 7 }); expect(