UNPKG

@material-ui/core

Version:

React components that implement Google's Material Design.

175 lines (160 loc) 6.36 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose"; import warning from 'warning'; import deepmerge from 'deepmerge'; // < 1kb payload overhead when lodash/merge is > 3kb. import indigo from '../colors/indigo'; import pink from '../colors/pink'; import grey from '../colors/grey'; import red from '../colors/red'; import common from '../colors/common'; import { getContrastRatio, darken, lighten } from './colorManipulator'; export const light = { // The colors used to style the text. text: { // The most important text. primary: 'rgba(0, 0, 0, 0.87)', // Secondary text. secondary: 'rgba(0, 0, 0, 0.54)', // Disabled text have even lower visual prominence. disabled: 'rgba(0, 0, 0, 0.38)', // Text hints. hint: 'rgba(0, 0, 0, 0.38)' }, // The color used to divide different elements. divider: 'rgba(0, 0, 0, 0.12)', // The background colors used to style the surfaces. // Consistency between these values is important. background: { paper: common.white, default: grey[50] }, // The colors used to style the action elements. action: { // The color of an active action like an icon button. active: 'rgba(0, 0, 0, 0.54)', // The color of an hovered action. hover: 'rgba(0, 0, 0, 0.08)', hoverOpacity: 0.08, // The color of a selected action. selected: 'rgba(0, 0, 0, 0.14)', // The color of a disabled action. disabled: 'rgba(0, 0, 0, 0.26)', // The background color of a disabled action. disabledBackground: 'rgba(0, 0, 0, 0.12)' } }; export const dark = { text: { primary: common.white, secondary: 'rgba(255, 255, 255, 0.7)', disabled: 'rgba(255, 255, 255, 0.5)', hint: 'rgba(255, 255, 255, 0.5)', icon: 'rgba(255, 255, 255, 0.5)' }, divider: 'rgba(255, 255, 255, 0.12)', background: { paper: grey[800], default: '#303030' }, action: { active: common.white, hover: 'rgba(255, 255, 255, 0.1)', hoverOpacity: 0.1, selected: 'rgba(255, 255, 255, 0.2)', disabled: 'rgba(255, 255, 255, 0.3)', disabledBackground: 'rgba(255, 255, 255, 0.12)' } }; function addLightOrDark(intent, direction, shade, tonalOffset) { if (!intent[direction]) { if (intent.hasOwnProperty(shade)) { intent[direction] = intent[shade]; } else if (direction === 'light') { intent.light = lighten(intent.main, tonalOffset); } else if (direction === 'dark') { intent.dark = darken(intent.main, tonalOffset * 1.5); } } } export default function createPalette(palette) { const { primary = { light: indigo[300], main: indigo[500], dark: indigo[700] }, secondary = { light: pink.A200, main: pink.A400, dark: pink.A700 }, error = { light: red[300], main: red[500], dark: red[700] }, type = 'light', contrastThreshold = 3, tonalOffset = 0.2 } = palette, other = _objectWithoutPropertiesLoose(palette, ["primary", "secondary", "error", "type", "contrastThreshold", "tonalOffset"]); // Use the same logic as // Bootstrap: https://github.com/twbs/bootstrap/blob/1d6e3710dd447de1a200f29e8fa521f8a0908f70/scss/_functions.scss#L59 // and material-components-web https://github.com/material-components/material-components-web/blob/ac46b8863c4dab9fc22c4c662dc6bd1b65dd652f/packages/mdc-theme/_functions.scss#L54 function getContrastText(background) { process.env.NODE_ENV !== "production" ? warning(background, `Material-UI: missing background argument in getContrastText(${background}).`) : void 0; const contrastText = getContrastRatio(background, dark.text.primary) >= contrastThreshold ? dark.text.primary : light.text.primary; if (process.env.NODE_ENV !== 'production') { const contrast = getContrastRatio(background, contrastText); process.env.NODE_ENV !== "production" ? warning(contrast >= 3, [`Material-UI: the contrast ratio of ${contrast}:1 for ${contrastText} on ${background}`, 'falls below the WACG recommended absolute minimum contrast ratio of 3:1.', 'https://www.w3.org/TR/2008/REC-WCAG20-20081211/#visual-audio-contrast-contrast'].join('\n')) : void 0; } return contrastText; } function augmentColor(color, mainShade = 500, lightShade = 300, darkShade = 700) { color = _extends({}, color); if (!color.main && color[mainShade]) { color.main = color[mainShade]; } if (process.env.NODE_ENV !== 'production' && !color.main) { throw new Error(['Material-UI: the color provided to augmentColor(color) is invalid.', `The color object needs to have a \`main\` property or a \`${mainShade}\` property.`].join('\n')); } addLightOrDark(color, 'light', lightShade, tonalOffset); addLightOrDark(color, 'dark', darkShade, tonalOffset); if (!color.contrastText) { color.contrastText = getContrastText(color.main); } return color; } const types = { dark, light }; process.env.NODE_ENV !== "production" ? warning(types[type], `Material-UI: the palette type \`${type}\` is not supported.`) : void 0; const paletteOutput = deepmerge(_extends({ // A collection of common colors. common, // The palette type, can be light or dark. type, // The colors used to represent primary interface elements for a user. primary: augmentColor(primary), // The colors used to represent secondary interface elements for a user. secondary: augmentColor(secondary, 'A400', 'A200', 'A700'), // The colors used to represent interface elements that the user should be made aware of. error: augmentColor(error), // The grey colors. grey, // Used by `getContrastText()` to maximize the contrast between the background and // the text. contrastThreshold, // Take a background color and return the color of the text to maximize the contrast. getContrastText, // Generate a rich color object. augmentColor, // Used by the functions below to shift a color's luminance by approximately // two indexes within its tonal palette. // E.g., shift from Red 500 to Red 300 or Red 700. tonalOffset }, types[type]), other, { clone: false // No need to clone deep }); return paletteOutput; }