diff --git a/CHANGELOG.md b/CHANGELOG.md index 75519e46dc..a85218ae75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +### Documentation +- Add the concept of the color palette @layershifter ([#451](https://github.com/stardust-ui/react/pull/451)) + ### Fixes - Add `react-dom` as available import in the editor @mnajdova ([#553](https://github.com/stardust-ui/react/pull/553)) - Fix incorrect and missing filled or outline versions of Teams SVG icons @codepretty ([#552](https://github.com/stardust-ui/react/pull/552)) @@ -26,6 +29,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Features - Add `render` callback as an option for shorthand value @kuzhelov ([#519](https://github.com/stardust-ui/react/pull/519)) +- Add `color` prop to `Divider` component @layershifter ([#451](https://github.com/stardust-ui/react/pull/451)) ## [v0.13.1](https://github.com/stardust-ui/react/tree/v0.13.1) (2018-12-03) diff --git a/docs/src/components/ColorBox.tsx b/docs/src/components/ColorBox.tsx new file mode 100644 index 0000000000..361114d2b1 --- /dev/null +++ b/docs/src/components/ColorBox.tsx @@ -0,0 +1,96 @@ +import { ComponentSlotStylesInput, createComponent, Icon, ICSSInJSStyle } from '@stardust-ui/react' +import * as Color from 'color' +import * as _ from 'lodash' +import * as React from 'react' + +import CopyToClipboard from './CopyToClipboard' + +type ColorBoxProps = { + children?: React.ReactNode + name?: string + rounded?: boolean + size?: 'small' | 'normal' | 'big' + value: string +} + +type ColorBoxVariables = { + colorBlack: string + colorWhite: string + fontSize: { + big: string + normal: string + small: string + } + padding: { + big: string + normal: string + small: string + } +} + +export const colorBoxVariables = (siteVariables): ColorBoxVariables => ({ + colorBlack: siteVariables.colors.black, + colorWhite: siteVariables.colors.white, + fontSize: { + big: '1.25em', + small: '.85em', + normal: '1.25em', + }, + padding: { + big: '4rem .75rem .75rem .75rem', + small: '.75rem', + normal: '2.5rem .75rem .75rem .75rem', + }, +}) + +export const colorBoxStyles: ComponentSlotStylesInput = { + root: ({ props: p, variables: v }): ICSSInJSStyle => ({ + backgroundColor: p.value, + border: '1px solid transparent', + borderRadius: p.rounded && '.25rem', + color: Color(p.value).isDark() ? v.colorWhite : v.colorBlack, + display: 'grid', + gridTemplateColumns: 'repeat(2, 1fr)', + fontSize: v.padding[p.size], + padding: v.padding[p.size], + }), + name: { + fontWeight: 'bold', + }, + value: { + fontFamily: 'Monospace', + textAlign: 'right', + userSelect: 'all', + + '> span': { + cursor: 'pointer', + }, + }, +} + +const ColorBox = createComponent({ + displayName: 'ColorBox', + render: ({ children, name, value, stardust: { classes } }) => ( +
+
{children || _.startCase(name)}
+ + ( +
+ + + {value} + +
+ )} + value={value} + /> +
+ ), +}) + +ColorBox.defaultProps = { + size: 'normal', +} + +export default ColorBox diff --git a/docs/src/components/ColorVariants.tsx b/docs/src/components/ColorVariants.tsx new file mode 100644 index 0000000000..f898456a91 --- /dev/null +++ b/docs/src/components/ColorVariants.tsx @@ -0,0 +1,37 @@ +import * as _ from 'lodash' +import * as React from 'react' +import { createComponent, ComponentSlotStylesInput } from '@stardust-ui/react' + +import ProviderConsumer from 'src/components/Provider/ProviderConsumer' +import ColorBox from './ColorBox' + +type ColorVariantsProps = { + name: string +} + +export const colorVariantsStyles: ComponentSlotStylesInput = { + root: { + border: '1px solid transparent', + borderRadius: '.25rem', + overflow: 'hidden', + }, +} + +const ColorVariants = createComponent({ + displayName: 'ColorVariants', + render: ({ name, stardust: { classes } }) => ( + ( +
+ + + {_.map(colors[name], (value, variable) => ( + + ))} +
+ )} + /> + ), +}) + +export default ColorVariants diff --git a/docs/src/components/CopyToClipboard.tsx b/docs/src/components/CopyToClipboard.tsx new file mode 100644 index 0000000000..1f35f83a4a --- /dev/null +++ b/docs/src/components/CopyToClipboard.tsx @@ -0,0 +1,50 @@ +import * as React from 'react' +import * as copyToClipboard from 'copy-to-clipboard' + +export type CopyToClipboardProps = { + render: (active, onClick) => React.ReactNode + timeout?: number + value: string +} + +type CopyToClipboardState = { + active: boolean +} + +class CopyToClipboard extends React.Component { + state = { + active: false, + } + + private timeoutId + + static defaultProps = { + timeout: 3000, + } + + componentWillUnmount() { + clearTimeout(this.timeoutId) + } + + handleClick = () => { + const { timeout, value } = this.props + + clearTimeout(this.timeoutId) + + this.setState({ active: true }) + this.timeoutId = setTimeout(() => { + this.setState({ active: false }) + }, timeout) + + copyToClipboard(value) + } + + render() { + const { render } = this.props + const { active } = this.state + + return render(active, this.handleClick) + } +} + +export default CopyToClipboard diff --git a/docs/src/components/Sidebar/Sidebar.tsx b/docs/src/components/Sidebar/Sidebar.tsx index 873b805b0d..be019d4886 100644 --- a/docs/src/components/Sidebar/Sidebar.tsx +++ b/docs/src/components/Sidebar/Sidebar.tsx @@ -225,6 +225,9 @@ class Sidebar extends React.Component { Introduction + + Color Palette + Shorthand Props diff --git a/docs/src/examples/components/Divider/Variations/DividerExampleColor.shorthand.tsx b/docs/src/examples/components/Divider/Variations/DividerExampleColor.shorthand.tsx new file mode 100644 index 0000000000..5be8010eb9 --- /dev/null +++ b/docs/src/examples/components/Divider/Variations/DividerExampleColor.shorthand.tsx @@ -0,0 +1,15 @@ +import _ from 'lodash' +import React from 'react' +import { Divider, ProviderConsumer } from '@stardust-ui/react' + +const DividerExampleColor = () => ( + + _.map({ ...emphasisColors, ...naturalColors }, (variants, name) => ( + + )) + } + /> +) + +export default DividerExampleColor diff --git a/docs/src/examples/components/Divider/Variations/index.tsx b/docs/src/examples/components/Divider/Variations/index.tsx index b5eb43aba6..43151f0cdc 100644 --- a/docs/src/examples/components/Divider/Variations/index.tsx +++ b/docs/src/examples/components/Divider/Variations/index.tsx @@ -4,6 +4,11 @@ import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection' const Variations = () => ( + ( path="/integrate-custom-components" component={IntegrateCustomComponents} /> + diff --git a/docs/src/views/ColorPalette.tsx b/docs/src/views/ColorPalette.tsx new file mode 100644 index 0000000000..133773e772 --- /dev/null +++ b/docs/src/views/ColorPalette.tsx @@ -0,0 +1,123 @@ +import { Provider, ProviderConsumer } from '@stardust-ui/react' +import * as faker from 'faker' +import * as _ from 'lodash' +import * as React from 'react' +import { Grid, Header } from 'semantic-ui-react' + +import ColorBox, { colorBoxStyles, colorBoxVariables } from 'docs/src/components/ColorBox' +import ColorVariants, { colorVariantsStyles } from 'docs/src/components/ColorVariants' +import DocPage from 'docs/src/components/DocPage/DocPage' + +const ColorPalette = () => ( + + ( + +
Introduction
+

+ The color palette for a theme has many requirements and constraints. There is a need to + be intentional and functional with color use. We analyzed existing frameworks and picked + the best ideas from them. +

+

+ Each theme should match our color palette types fully. This will allow you to use our + theming features completely and keep your palette structured. +

+ +
Primitive colors
+

+ This part of the palette includes only black and white colors, we decided + to separate by semantical ideas. There is nothing blacker than black and nothing whiter + than white. +

+ + + {_.map(['black', 'white'], color => ( + + + + ))} + + +
Natural colors
+

+ This part of palette includes nine colors (note, this number might be different for + non-default theme) that are the most frequently used among popular frameworks. Each + color includes ten gradients, this allows us to satisfy most common needs. This decision + is experienced from Material UI and allows to define more variants than semantical + naming (lightest, lighter, etc.). +

+ + + {_.map(naturalColors, (variants, color) => ( + + + + ))} + + +
Emphasis colors
+

This part of the palette includes primary and secondary colors.

+ + + {_.map(emphasisColors, (variants, color) => ( + + + + ))} + + +
Contextual colors
+

+ Contextual colors can be used to provide "meaning through colors", however they can be + just aliases for natural colors. +

+ + + {_.map(contextualColors, (variants, color) => ( + + + + ))} + + +
Text colors
+

+ Text variants are also provided as a separate color because in the most cases it's not + correct to use grey color for text. +

+ + {_.map(colors.text, (color, variant) => ( + + {`${variant} | ${faker.lorem.sentence(4)}`} + + ))} + +
Color variables
+ + {_.map( + { ...emphasisColors, ...contextualColors, ...naturalColors }, + (variants, color) => ( + + + + ), + )} + +
+ )} + /> +
+) + +export default ColorPalette diff --git a/package.json b/package.json index 9a330c8cb8..c0cde93e43 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "homepage": "https://github.com/stardust-ui/react#readme", "dependencies": { "classnames": "^2.2.5", + "color": "^3.1.0", "fela": "^6.1.7", "fela-plugin-fallback-value": "^5.0.17", "fela-plugin-placeholder-prefixer": "^5.0.18", @@ -74,6 +75,7 @@ "devDependencies": { "@babel/standalone": "^7.1.0", "@types/classnames": "^2.2.4", + "@types/color": "^3.0.0", "@types/enzyme": "^3.1.14", "@types/faker": "^4.1.3", "@types/gulp-load-plugins": "^0.0.31", diff --git a/src/components/Divider/Divider.tsx b/src/components/Divider/Divider.tsx index 8911bcbdbd..a08eb5c961 100644 --- a/src/components/Divider/Divider.tsx +++ b/src/components/Divider/Divider.tsx @@ -7,6 +7,7 @@ import { UIComponent, UIComponentProps, ChildrenComponentProps, + ColorComponentProps, ContentComponentProps, commonPropTypes, } from '../../lib' @@ -15,6 +16,7 @@ import { Extendable } from '../../../types/utils' export interface DividerProps extends UIComponentProps, ChildrenComponentProps, + ColorComponentProps, ContentComponentProps { /** A divider can be fitted, without any space above or below it. */ fitted?: boolean @@ -40,7 +42,7 @@ class Divider extends UIComponent, any> { static className = 'ui-divider' static propTypes = { - ...commonPropTypes.createCommon(), + ...commonPropTypes.createCommon({ color: true }), fitted: PropTypes.bool, size: PropTypes.number, type: PropTypes.oneOf(['primary', 'secondary']), diff --git a/src/lib/colorUtils.ts b/src/lib/colorUtils.ts new file mode 100644 index 0000000000..f6de1a60f2 --- /dev/null +++ b/src/lib/colorUtils.ts @@ -0,0 +1,21 @@ +import * as Color from 'color' +import { ColorVariants } from '../themes/types' + +export const setColorLightness = (base: string, value: number) => + Color(base) + .hsl() + .lightness(100 - value) + .hex() + +export const createColorVariants = (base: string): ColorVariants => ({ + 50: setColorLightness(base, 5), + 100: setColorLightness(base, 10), + 200: setColorLightness(base, 20), + 300: setColorLightness(base, 30), + 400: setColorLightness(base, 40), + 500: base, + 600: setColorLightness(base, 60), + 700: setColorLightness(base, 70), + 800: setColorLightness(base, 80), + 900: setColorLightness(base, 90), +}) diff --git a/src/lib/commonPropInterfaces.ts b/src/lib/commonPropInterfaces.ts index e83617fc85..df04272e05 100644 --- a/src/lib/commonPropInterfaces.ts +++ b/src/lib/commonPropInterfaces.ts @@ -25,6 +25,23 @@ export interface UIComponentProps

className?: string } +export interface ColorComponentProps { + /** A component can have a color. */ + color?: + | 'primary' + | 'secondary' + | 'blue' + | 'green' + | 'grey' + | 'orange' + | 'pink' + | 'purple' + | 'teal' + | 'red' + | 'yellow' + | string +} + export interface ContentComponentProps { /** Shorthand for primary content. */ content?: TContent diff --git a/src/lib/commonPropTypes.ts b/src/lib/commonPropTypes.ts index 0d2894e876..caed444a75 100644 --- a/src/lib/commonPropTypes.ts +++ b/src/lib/commonPropTypes.ts @@ -6,6 +6,7 @@ export interface CreateCommonConfig { children?: boolean | 'node' | 'element' as?: boolean className?: boolean + color?: boolean content?: boolean | 'node' | 'shorthand' styled?: boolean } @@ -16,6 +17,7 @@ export const createCommon = (config: CreateCommonConfig = {}) => { as = true, children = 'node', className = true, + color = false, content = 'node', styled = true, } = config @@ -32,6 +34,24 @@ export const createCommon = (config: CreateCommonConfig = {}) => { ...(className && { className: PropTypes.string, }), + ...(color && { + color: PropTypes.oneOfType([ + PropTypes.oneOf([ + 'primary', + 'secondary', + 'blue', + 'green', + 'grey', + 'orange', + 'pink', + 'purple', + 'teal', + 'red', + 'yellow', + ]), + PropTypes.string, + ]), + }), ...(content && { content: content === 'shorthand' ? customPropTypes.itemShorthand : customPropTypes.nodeContent, diff --git a/src/lib/index.ts b/src/lib/index.ts index 64ff0cc256..a78717e539 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -3,6 +3,7 @@ import * as commonPropTypes from './commonPropTypes' export { default as AutoControlledComponent } from './AutoControlledComponent' export { default as childrenExist } from './childrenExist' +export * from './colorUtils' export { default as UIComponent } from './UIComponent' export { EventStack } from './eventStack' export { felaRenderer, felaRtlRenderer } from './felaRenderer' diff --git a/src/lib/renderComponent.tsx b/src/lib/renderComponent.tsx index ead1e1bfc2..812eb1cfd9 100644 --- a/src/lib/renderComponent.tsx +++ b/src/lib/renderComponent.tsx @@ -140,7 +140,13 @@ const renderComponent =

(config: RenderConfig

): React.ReactElem } const { - siteVariables = { fontSizes: {} }, + siteVariables = { + colors: {}, + contextualColors: {}, + emphasisColors: {}, + naturalColors: {}, + fontSizes: {}, + }, componentVariables = {}, componentStyles = {}, rtl = false, diff --git a/src/themes/default/.gitkeep b/src/themes/default/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/themes/default/colors.ts b/src/themes/default/colors.ts new file mode 100644 index 0000000000..2b7851dcc6 --- /dev/null +++ b/src/themes/default/colors.ts @@ -0,0 +1,36 @@ +import { createColorVariants } from '../../lib' +import { ColorPalette, ContextualColors, EmphasisColors, NaturalColors } from '../types' + +export const naturalColors: NaturalColors = { + blue: createColorVariants('#0a84ff'), + green: createColorVariants('#30e60b'), + grey: createColorVariants('#737373'), + orange: createColorVariants('#ff9400'), + pink: createColorVariants('#ff1ad9'), + purple: createColorVariants('#9400ff'), + teal: createColorVariants('#00feff'), + red: createColorVariants('#ff0039'), + yellow: createColorVariants('#ffe900'), +} + +export const emphasisColors: EmphasisColors = { + primary: createColorVariants('#0a84ff'), + secondary: naturalColors.grey, +} + +export const contextualColors: ContextualColors = { + text: naturalColors.grey, + info: naturalColors.blue, + danger: naturalColors.red, + success: naturalColors.green, + warning: naturalColors.yellow, +} + +export const colors: ColorPalette = { + ...contextualColors, + ...emphasisColors, + ...naturalColors, + + black: '#000', + white: '#fff', +} diff --git a/src/themes/default/index.ts b/src/themes/default/index.ts new file mode 100644 index 0000000000..24c7c37db0 --- /dev/null +++ b/src/themes/default/index.ts @@ -0,0 +1,6 @@ +import { ThemeInput } from '../types' +import * as siteVariables from './siteVariables' + +export default { + siteVariables, +} as ThemeInput diff --git a/src/themes/default/siteVariables.ts b/src/themes/default/siteVariables.ts new file mode 100644 index 0000000000..d5419e65b5 --- /dev/null +++ b/src/themes/default/siteVariables.ts @@ -0,0 +1 @@ +export { colors, contextualColors, emphasisColors, naturalColors } from './colors' diff --git a/src/themes/index.ts b/src/themes/index.ts index 4dfa3d06e2..00abe53c86 100644 --- a/src/themes/index.ts +++ b/src/themes/index.ts @@ -1,4 +1,5 @@ // Themes +export { default } from './default' export { default as teams } from './teams' export { default as teamsDark } from './teams-dark' export { default as teamsHighContrast } from './teams-high-contrast' diff --git a/src/themes/teams/colors.ts b/src/themes/teams/colors.ts new file mode 100644 index 0000000000..ab7bec2375 --- /dev/null +++ b/src/themes/teams/colors.ts @@ -0,0 +1,154 @@ +import { ColorPalette, ContextualColors, EmphasisColors, NaturalColors } from '../types' + +export const emphasisColors: EmphasisColors = { + primary: { + 50: '#F4F4FC', + 100: '#E2E2F6', + 200: '#BDBDE6', + 300: '#8F90C1', + 400: '#6E70AE', + 500: '#6264A7', + 600: '#55578D', + 700: '#4A4C78', + 800: '#414265', + 900: '#33344A', + }, +} + +export const naturalColors: NaturalColors = { + green: { + 50: '#D3E4DB', + 100: '#C4DCCF', + 200: '#B3D1C1', + 300: '#9DC4AF', + 400: '#8CBAA1', + 500: '#7BB093', + 600: '#68A584', + 700: '#579A75', + 800: '#458F67', + 900: '#237B4B', + }, + grey: { + 50: '#FFFFFF', + 100: '#E6E6E6', + 200: '#CDCCCC', + 300: '#B8B8B8', + 400: '#A2A2A2', + 500: '#8C8C8C', + 600: '#747373', + 700: '#5F5E5E', + 800: '#404040', + 900: '#252424', + }, + orange: { + 50: '#FEF9F7', + 100: '#FDF0EB', + 200: '#FAE3DA', + 300: '#F8D3C5', + 400: '#F5C6B3', + 500: '#F4B8A1', + 600: '#F2AD92', + 700: '#F0A081', + 800: '#ED8E6A', + 900: '#E97548', + }, + pink: { + 50: '#E8BDD5', + 100: '#E1ABC8', + 200: '#DA9EBF', + 300: '#D693B8', + 400: '#D28BB2', + 500: '#CA7BA6', + 600: '#C775A3', + 700: '#C06597', + 800: '#BA598F', + 900: '#B34A84', + }, + red: { + 50: '#F2D1D7', + 100: '#ECBDC5', + 200: '#E8AFB9', + 300: '#E39EAA', + 400: '#DE8D9B', + 500: '#D97B8C', + 600: '#D56B7E', + 700: '#D05B70', + 800: '#CC4B61', + 900: '#C4314B', + }, + yellow: { + 50: '#FEF5D0', + 100: '#FDF1BE', + 200: '#FDEEAE', + 300: '#FBEA9D', + 400: '#FCE78E', + 500: '#FAE37C', + 600: '#FAE06C', + 700: '#F9DC58', + 800: '#F9D844', + 900: '#F8D22A', + }, + + darkOrange: { + 50: '#F9ECEA', + 100: '#ECBCB3', + 200: '#E29C8F', + 300: '#D97B69', + 400: '#CC4A31', + 500: '#C5472F', + 600: '#B7432D', + 700: '#A73D29', + 800: '#983927', + 900: '#833122', + }, + lightGreen: { + 50: '#E7F2D9', + 100: '#DFEECD', + 200: '#D8EAC1', + 300: '#CDE3B0', + 400: '#C6DFA4', + 500: '#BDDB96', + 600: '#B4D689', + 700: '#ACD17B', + 800: '#A1CC6B', + 900: '#92C353', + }, + magenta: { + 50: '#E8D4E0', + 100: '#DEC0D2', + 200: '#D4ADC5', + 300: '#CDA0BC', + 400: '#C491B0', + 500: '#BB7FA4', + 600: '#B26E98', + 700: '#AA5F8D', + 800: '#A14F82', + 900: '#953872', + }, + postOrange: { + 50: '#FDF6F7', + 100: '#FBF2F3', + 200: '#FAEEEF', + 300: '#F9ECED', + 400: '#F8E9EA', + 500: '#F7E5E6', + 600: '#F7E2E4', + 700: '#F5DEE0', + 800: '#F5DBDD', + 900: '#F3D6D8', + }, +} + +export const contextualColors: ContextualColors = { + text: naturalColors.grey, +} + +export const colors: ColorPalette = { + ...contextualColors, + ...emphasisColors, + ...naturalColors, + + // Primitive colors + black: naturalColors.grey[900], + white: naturalColors.grey[50], +} diff --git a/src/themes/teams/components/Divider/dividerStyles.ts b/src/themes/teams/components/Divider/dividerStyles.ts index 5dae860af6..53e266927e 100644 --- a/src/themes/teams/components/Divider/dividerStyles.ts +++ b/src/themes/teams/components/Divider/dividerStyles.ts @@ -1,3 +1,5 @@ +import * as _ from 'lodash' + import { childrenExist, pxToRem } from '../../../../lib' import { ComponentSlotStylesInput, ICSSInJSStyle, ICSSPseudoElementStyle } from '../../../types' import { DividerPropsWithDefaults } from '../../../../components/Divider/Divider' @@ -7,10 +9,13 @@ const dividerBorderStyle = (size, color): ICSSInJSStyle => ({ background: color, }) -const beforeAndAfter = (size, type, variables): ICSSPseudoElementStyle => ({ +const beforeAndAfter = (color, size, type, variables): ICSSPseudoElementStyle => ({ content: '""', flex: 1, ...dividerBorderStyle(size, variables.dividerColor), + ...(color && { + ...dividerBorderStyle(size, _.get(variables.colors, [color, 500])), + }), ...(type === 'primary' && { ...dividerBorderStyle(size, variables.primaryColor), }), @@ -18,7 +23,7 @@ const beforeAndAfter = (size, type, variables): ICSSPseudoElementStyle => ({ const dividerStyles: ComponentSlotStylesInput = { root: ({ props, variables }): ICSSInJSStyle => { - const { children, fitted, size, type, important, content } = props + const { children, color, fitted, size, type, important, content } = props return { color: variables.textColor, display: 'flex', @@ -27,6 +32,9 @@ const dividerStyles: ComponentSlotStylesInput = { paddingTop: variables.dividerPadding, paddingBottom: variables.dividerPadding, }), + ...(color && { + color: _.get(variables.colors, [color, 500]), + }), ...(type === 'primary' && { color: variables.primaryColor, }), @@ -39,17 +47,17 @@ const dividerStyles: ComponentSlotStylesInput = { fontSize: pxToRem(12 + size), lineHeight: variables.textLineHeight, '::before': { - ...beforeAndAfter(size, type, variables), + ...beforeAndAfter(color, size, type, variables), marginRight: pxToRem(20), }, '::after': { - ...beforeAndAfter(size, type, variables), + ...beforeAndAfter(color, size, type, variables), marginLeft: pxToRem(20), }, } : { '::before': { - ...beforeAndAfter(size, type, variables), + ...beforeAndAfter(color, size, type, variables), }, }), } diff --git a/src/themes/teams/components/Divider/dividerVariables.ts b/src/themes/teams/components/Divider/dividerVariables.ts index b363fbd31f..e6831123d0 100644 --- a/src/themes/teams/components/Divider/dividerVariables.ts +++ b/src/themes/teams/components/Divider/dividerVariables.ts @@ -1,6 +1,8 @@ +import { EmphasisColors, NaturalColors } from '../../../types' import { pxToRem } from '../../../../lib' export interface DividerVariables { + colors: EmphasisColors & NaturalColors dividerColor: string textColor: string textFontSize: string @@ -12,6 +14,7 @@ export interface DividerVariables { export default (siteVars: any): DividerVariables => { return { + colors: { ...siteVars.emphasisColors, ...siteVars.naturalColors }, dividerColor: siteVars.gray09, textColor: siteVars.gray03, textFontSize: siteVars.fontSizeSmall, diff --git a/src/themes/teams/siteVariables.ts b/src/themes/teams/siteVariables.ts index 78703a3bab..caa1aa4226 100644 --- a/src/themes/teams/siteVariables.ts +++ b/src/themes/teams/siteVariables.ts @@ -1,4 +1,5 @@ import { pxToRem } from '../../lib' +import { colors } from './colors' // // VARIABLES @@ -8,7 +9,9 @@ export const htmlFontSize = '10px' // what 1rem represents // // COLORS // -export const black = '#252423' +export { colors, contextualColors, emphasisColors, naturalColors } from './colors' + +export const black = colors.black export const gray02 = '#484644' export const gray03 = '#605E5C' export const gray04 = '#979593' @@ -18,16 +21,16 @@ export const gray09 = '#EDEBE9' export const gray10 = '#F3F2F1' export const gray14 = '#FAF9F8' -export const white = '#FFF' +export const white = colors.white -export const brand = '#6264A7' -export const brand02 = '#33344A' +export const brand = colors.primary[500] +export const brand02 = colors.primary[900] export const brand04 = '#464775' -export const brand06 = '#6264A7' +export const brand06 = colors.primary[500] export const brand08 = '#8B8CC7' -export const brand12 = '#BDBDE6' -export const brand14 = '#E2E2F6' -export const brand16 = '#F4F4FC' +export const brand12 = colors.primary[200] +export const brand14 = colors.primary[100] +export const brand16 = colors.primary[50] export const orange04 = '#CC4A31' export const magenta = '#B24782' diff --git a/src/themes/types.ts b/src/themes/types.ts index e2cb1f04e7..3c467662f8 100644 --- a/src/themes/types.ts +++ b/src/themes/types.ts @@ -10,6 +10,82 @@ import { Extendable, ObjectOf, ObjectOrFunc } from '../../types/utils' // // We use these terms in typings to indicate which phase the typings apply to. +// ======================================================== +// Colors +// ======================================================== + +/** + * A type for a palette for a single color. + */ +export type ColorVariants = { + 50: string + 100: string + 200: string + 300: string + 400: string + 500: string + 600: string + 700: string + 800: string + 900: string +} + +/** + * A type for a predefined natural colors. + */ +type NaturalColorsStrict = Partial<{ + blue: ColorVariants + green: ColorVariants + grey: ColorVariants + orange: ColorVariants + pink: ColorVariants + purple: ColorVariants + teal: ColorVariants + red: ColorVariants + yellow: ColorVariants +}> + +export type NaturalColors = Extendable + +/** + * A type for a predefined state colors. + */ +export type ContextualColorsStrict = Partial<{ + text: ColorVariants + + danger: ColorVariants + info: ColorVariants + success: ColorVariants + warning: ColorVariants +}> + +export type ContextualColors = Extendable + +/** + * A type for a predefined emphasis colors. + */ +type EmphasisColorsStrict = Partial<{ + primary: ColorVariants + secondary: ColorVariants +}> + +export type EmphasisColors = Extendable + +/** + * A type for a base colors. + */ +export type PrimitiveColors = Partial<{ + black: string + white: string +}> + +type ExtendablePalette = T & + { [K in keyof T]?: K extends keyof PrimitiveColors ? string : ColorVariants } + +export type ColorPalette = ExtendablePalette< + EmphasisColorsStrict & ContextualColorsStrict & NaturalColorsStrict & PrimitiveColors +> + // ======================================================== // Props // ======================================================== @@ -30,11 +106,19 @@ export type State = ObjectOf // ======================================================== export interface SiteVariablesInput extends ObjectOf { + colors?: ColorPalette + contextualColors?: ContextualColors + emphasisColors?: EmphasisColors + naturalColors?: NaturalColorsStrict brand?: string htmlFontSize?: string } export interface SiteVariablesPrepared extends ObjectOf { + colors?: ColorPalette + contextualColors?: ContextualColors + emphasisColors?: EmphasisColors + naturalColors?: NaturalColorsStrict brand?: string htmlFontSize?: string fontSizes: ObjectOf diff --git a/types/utils.d.ts b/types/utils.d.ts index a2ab20c94e..8d7078163c 100644 --- a/types/utils.d.ts +++ b/types/utils.d.ts @@ -4,8 +4,8 @@ import * as React from 'react' -export type Extendable = T & { - [key: string]: any +export type Extendable = T & { + [key: string]: V } export type Partial = { [Key in keyof T]?: T[Key] } diff --git a/yarn.lock b/yarn.lock index f4f40f7489..d56addd0d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -105,6 +105,25 @@ resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.4.tgz#d3ee9ebf714aa34006707b8f4a58fd46b642305a" integrity sha512-UWUmNYhaIGDx8Kv0NSqFRwP6HWnBMXam4nBacOrjIiPBKKCdWMCe77+Nbn6rI9+Us9c+BhE26u84xeYQv2bKeA== +"@types/color-convert@*": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@types/color-convert/-/color-convert-1.9.0.tgz#bfa8203e41e7c65471e9841d7e306a7cd8b5172d" + integrity sha512-OKGEfULrvSL2VRbkl/gnjjgbbF7ycIlpSsX7Nkab4MOWi5XxmgBYvuiQ7lcCFY5cPDz7MUNaKgxte2VRmtr4Fg== + dependencies: + "@types/color-name" "*" + +"@types/color-name@*": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.0.tgz#926f76f7e66f49cc59ad880bb15b030abbf0b66d" + integrity sha512-gZ/Rb+MFXF0pXSEQxdRoPMm5jeO3TycjOdvbpbcpHX/B+n9AqaHFe5q6Ga9CsZ7ir/UgIWPfrBzUzn3F19VH/w== + +"@types/color@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/color/-/color-3.0.0.tgz#40f8a6bf2fd86e969876b339a837d8ff1b0a6e30" + integrity sha512-5qqtNia+m2I0/85+pd2YzAXaTyKO8j+svirO5aN+XaQJ5+eZ8nx0jPtEWZLxCi50xwYsX10xUHetFzfb1WEs4Q== + dependencies: + "@types/color-convert" "*" + "@types/enzyme@^3.1.14": version "3.1.14" resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.1.14.tgz#379c26205f6e0e272f3a51d6bbdd50071a9d03a6" @@ -1811,16 +1830,49 @@ color-convert@^1.9.0: dependencies: color-name "1.1.1" +color-convert@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + color-name@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" integrity sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok= +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + color-support@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== +color@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.0.tgz#d8e9fb096732875774c84bf922815df0308d0ffc" + integrity sha512-CwyopLkuRYO5ei2EpzpIh6LqJMt6Mt+jZhO5VI5f/wJLZriXQE32/SSqzmrh+QB+AZT81Cj8yv+7zwToW8ahZg== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + colors@0.5.x: version "0.5.1" resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774" @@ -4815,6 +4867,11 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -9112,6 +9169,13 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + simulant@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simulant/-/simulant-0.2.2.tgz#f1bce52712b6a7a0da38ddfdda7e83b20b1da01e"