Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.

feat(Theming): add color palette #451

Merged
merged 1 commit into from
Dec 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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 ]------------------------------- -->
## [v0.13.1](https://github.com/stardust-ui/react/tree/v0.13.1) (2018-12-03)
Expand Down
96 changes: 96 additions & 0 deletions docs/src/components/ColorBox.tsx
Original file line number Diff line number Diff line change
@@ -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<ColorBoxProps, ColorBoxVariables> = {
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<ColorBoxProps>({
displayName: 'ColorBox',
render: ({ children, name, value, stardust: { classes } }) => (
<div className={classes.root}>
<div className={classes.name}>{children || _.startCase(name)}</div>

<CopyToClipboard
render={(active, onClick) => (
<div className={classes.value}>
<span onClick={onClick}>
<Icon name={active ? 'checkmark' : 'copy outline'} size="small" />
{value}
</span>
</div>
)}
value={value}
/>
</div>
),
})

ColorBox.defaultProps = {
size: 'normal',
}

export default ColorBox
37 changes: 37 additions & 0 deletions docs/src/components/ColorVariants.tsx
Original file line number Diff line number Diff line change
@@ -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<ColorVariantsProps> = {
root: {
border: '1px solid transparent',
borderRadius: '.25rem',
overflow: 'hidden',
},
}

const ColorVariants = createComponent<ColorVariantsProps>({
displayName: 'ColorVariants',
render: ({ name, stardust: { classes } }) => (
<ProviderConsumer
render={({ siteVariables: { colors } }) => (
<div className={classes.root}>
<ColorBox name={name} size="big" value={colors[name][500]} />

{_.map(colors[name], (value, variable) => (
<ColorBox key={variable} name={variable} size="small" value={value} />
))}
</div>
)}
/>
),
})

export default ColorVariants
50 changes: 50 additions & 0 deletions docs/src/components/CopyToClipboard.tsx
Original file line number Diff line number Diff line change
@@ -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<CopyToClipboardProps, CopyToClipboardState> {
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
3 changes: 3 additions & 0 deletions docs/src/components/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ class Sidebar extends React.Component<any, any> {
<Menu.Item as={NavLink} exact to="/" activeClassName="active">
Introduction
</Menu.Item>
<Menu.Item as={NavLink} exact to="/color-palette" activeClassName="active">
Color Palette
</Menu.Item>
<Menu.Item as={NavLink} exact to="/shorthand-props" activeClassName="active">
Shorthand Props
</Menu.Item>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import _ from 'lodash'
import React from 'react'
import { Divider, ProviderConsumer } from '@stardust-ui/react'

const DividerExampleColor = () => (
<ProviderConsumer
render={({ siteVariables: { emphasisColors, naturalColors } }) =>
_.map({ ...emphasisColors, ...naturalColors }, (variants, name) => (
<Divider key={name} color={name} content={_.startCase(name)} />
))
}
/>
)

export default DividerExampleColor
5 changes: 5 additions & 0 deletions docs/src/examples/components/Divider/Variations/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'

const Variations = () => (
<ExampleSection title="Variations">
<ComponentExample
title="Color"
description="A divider can have different colors."
examplePath="components/Divider/Variations/DividerExampleColor"
/>
<ComponentExample
title="Size"
description="A divider can have different sizes."
Expand Down
2 changes: 2 additions & 0 deletions docs/src/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import DocsLayout from './components/DocsLayout'
import DocsRoot from './components/DocsRoot'

import Accessibility from './views/Accessibility'
import ColorPalette from './views/ColorPalette'
import ShorthandProps from './views/ShorthandProps'
import Introduction from './views/Introduction'
import PageNotFound from './views/PageNotFound'
Expand Down Expand Up @@ -74,6 +75,7 @@ const Router = () => (
path="/integrate-custom-components"
component={IntegrateCustomComponents}
/>
<DocsLayout exact path="/color-palette" component={ColorPalette} />
<DocsLayout exact path="/*" component={PageNotFound} />
</Switch>
</Switch>
Expand Down
123 changes: 123 additions & 0 deletions docs/src/views/ColorPalette.tsx
Original file line number Diff line number Diff line change
@@ -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 = () => (
<Provider
theme={{
componentStyles: {
ColorBox: colorBoxStyles,
ColorVariants: colorVariantsStyles,
},
componentVariables: {
ColorBox: colorBoxVariables,
},
}}
>
<ProviderConsumer
render={({ siteVariables: { colors, contextualColors, emphasisColors, naturalColors } }) => (
<DocPage title="Color Palette">
<Header as="h2">Introduction</Header>
<p>
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.
</p>
<p>
Each theme should match our color palette types fully. This will allow you to use our
theming features completely and keep your palette structured.
</p>

<Header as="h2">Primitive colors</Header>
<p>
This part of the palette includes only <i>black</i> and <i>white</i> colors, we decided
to separate by semantical ideas. There is nothing blacker than black and nothing whiter
than white.
</p>

<Grid columns={2}>
{_.map(['black', 'white'], color => (
<Grid.Column key={color}>
<ColorBox name={color} rounded size="big" value={colors[color]} />
</Grid.Column>
))}
</Grid>

<Header as="h2">Natural colors</Header>
<p>
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.).
</p>

<Grid columns={2}>
{_.map(naturalColors, (variants, color) => (
<Grid.Column key={color}>
<ColorBox name={color} rounded value={colors[color][500]} />
</Grid.Column>
))}
</Grid>

<Header as="h2">Emphasis colors</Header>
<p>This part of the palette includes primary and secondary colors.</p>

<Grid columns={2}>
{_.map(emphasisColors, (variants, color) => (
<Grid.Column key={color}>
<ColorBox name={color} rounded size="big" value={colors[color][500]} />
</Grid.Column>
))}
</Grid>

<Header as="h2">Contextual colors</Header>
<p>
Contextual colors can be used to provide "meaning through colors", however they can be
just aliases for natural colors.
</p>

<Grid columns={2}>
{_.map(contextualColors, (variants, color) => (
<Grid.Column key={color}>
<ColorBox name={color} rounded size="big" value={colors[color][500]} />
</Grid.Column>
))}
</Grid>

<Header as="h2">Text colors</Header>
<p>
Text variants are also provided as a separate color because in the most cases it's not
correct to use grey color for text.
</p>

{_.map(colors.text, (color, variant) => (
<ColorBox key={color} size="small" value={color}>
{`${variant} | ${faker.lorem.sentence(4)}`}
</ColorBox>
))}

<Header as="h2">Color variables</Header>
<Grid columns={2}>
{_.map(
{ ...emphasisColors, ...contextualColors, ...naturalColors },
(variants, color) => (
<Grid.Column key={color}>
<ColorVariants name={color} />
</Grid.Column>
),
)}
</Grid>
</DocPage>
)}
/>
</Provider>
)

export default ColorPalette
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
Loading