Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document new functional color system #225

Merged
merged 16 commits into from
Sep 3, 2021
Merged
Show file tree
Hide file tree
Changes from 9 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: 3 additions & 1 deletion data/colors_v2/deprecations.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
"icon.warning": "attention.fg",
"border.primary": "border.default",
"border.secondary": "border.muted",
"border.tertiary": "neutral.muted",
"border.overlay": "border.default",
"border.inverse": "fg.onEmphasis",
"border.info": "accent.emphasis",
"border.danger": "success.emphasis",
"border.success": "success.emphasis",
"border.danger": "danger.emphasis",
"border.warning": "attention.emphasis",
"bg.canvas": "canvas.default",
"bg.canvasMobile": null,
Expand Down
121 changes: 121 additions & 0 deletions docs/content/colors.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
title: Colors
---

import colors from '../../dist/js/colors_v2'
import deprecatedColors from '../../dist/deprecations/colors_v2.json'
import filterObj from 'filter-obj'
import flatten from 'flat'
import {Box} from '@primer/components'
import {SwatchGrid} from '../src/components/swatch-grid'
import {ColorThemePicker} from '../src/components/color-theme-picker'
import {ColorScales} from '../src/components/color-scales'

## Themes

Preview color variables in any of the available themes:

<ColorThemePicker />

## Functional variables

### Foreground

<SwatchGrid names={Object.keys(flatten(colors.light)).filter(key => key.split('.')[0] === 'fg')} />

### Canvas

<SwatchGrid names={Object.keys(flatten(colors.light)).filter(key => key.split('.')[0] === 'canvas')} />

### Border

<SwatchGrid
names={Object.keys(flatten(colors.light)).filter(
key => key.split('.')[0] === 'border' && !Object.keys(deprecatedColors).includes(key)
)}
/>

### Shadow

<SwatchGrid
names={Object.keys(flatten(colors.light)).filter(
key => key.split('.')[0] === 'shadow' && !Object.keys(deprecatedColors).includes(key)
)}
/>

### Neutral

Use to highlight content without any added meaning.

<SwatchGrid names={Object.keys(flatten(colors.light)).filter(key => key.split('.')[0] === 'neutral')} />

### Accent

Use to draw attention to interactive elements.

<SwatchGrid names={Object.keys(flatten(colors.light)).filter(key => key.split('.')[0] === 'accent')} />

### Success

Use to expresses the completion or positive outcome of a task.

<SwatchGrid names={Object.keys(flatten(colors.light)).filter(key => key.split('.')[0] === 'success')} />

### Attention

Use to warn of pending tasks or highlight active content.

<SwatchGrid names={Object.keys(flatten(colors.light)).filter(key => key.split('.')[0] === 'attention')} />

### Severe

Use when there are more than 3 levels of states, for example in heatmaps.

<SwatchGrid names={Object.keys(flatten(colors.light)).filter(key => key.split('.')[0] === 'severe')} />

### Danger

Use to inform of error or another negative message.

<SwatchGrid names={Object.keys(flatten(colors.light)).filter(key => key.split('.')[0] === 'danger')} />

### Done

Completion color for productivity and code review workflows.

<SwatchGrid names={Object.keys(flatten(colors.light)).filter(key => key.split('.')[0] === 'done')} />

### Sponsors

Use for Sponsors-related interfaces.

<SwatchGrid names={Object.keys(flatten(colors.light)).filter(key => key.split('.')[0] === 'sponsors')} />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sponsors is it's own section?


## Scale variable

<Note variant="warning">
Avoid referencing scale variables directly when building UI that needs to adapt to different color themes. Instead,
use the functional variables listed above. In rare cases, you may need to use scale variables to define custom
functional variables in your application.
</Note>

<ColorScales />

## Deprecated variables

<table>
<thead>
<tr>
<th>Deprecated variable</th>
<th>Replacement variable(s)</th>
</tr>
</thead>
<tbody>
{Object.entries(deprecatedColors).map(([key, value]) => (
<tr>
<td>{key}</td>
<td>{value}</td>
</tr>
))}
</tbody>
</table>
21 changes: 21 additions & 0 deletions docs/content/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: Primer Primitives
---

import {HeroLayout} from '@primer/gatsby-theme-doctocat'

export default HeroLayout

## Install

```shell
npm install @primer/primitives
```

## Usage

Primitive data is served in several formats from the [`dist/`](https://unpkg.com/browse/@primer/primitives/dist/) folder:

- `dist/scss` contains [SCSS](https://sass-lang.com/) files that define CSS variables to be imported into other SCSS files
- `dist/json` contains JSON files for each set of primitives
- `dist/js` contains CommonJS-style JavaScript modules for each set of primitives, as well as an index file that loads all of the primitives for all primitive types. The JavaScript modules also include TypeScript typings files for use in TypeScript projects.
13 changes: 9 additions & 4 deletions docs/gatsby-config.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
module.exports = {
siteMetadata: {
title: 'Primer Primitives',
shortName: 'Primitives',
description: 'Color, spacing, and typography primitives for the Primer Design System',
imageUrl: '#'
colebemis marked this conversation as resolved.
Show resolved Hide resolved
},
pathPrefix: '/primitives',
plugins: [
'gatsby-plugin-styled-components',
'gatsby-plugin-react-helmet',
{
resolve: 'gatsby-plugin-manifest',
resolve: '@primer/gatsby-theme-doctocat',
options: {
icon: require.resolve('./src/images/favicon.png')
defaultBranch: 'main',
repoRootPath: '..'
}
}
]
Expand Down
38 changes: 8 additions & 30 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "docs",
"private": true,
"version": "0.1.0",
"repository": "primer/primitives",
"scripts": {
"setup": "cd ..; yarn; yarn build",
"prebuild": "yarn setup",
Expand All @@ -16,39 +17,16 @@
},
"prettier": "@github/prettier-config",
"dependencies": {
"@primer/components": "^20.0.0",
"@primer/octicons-react": "^11.0.0",
"@types/chroma-js": "^2.1.3",
"@types/flat": "^5.0.1",
"@types/lodash.flatmap": "^4.5.6",
"@types/lodash.groupby": "^4.6.6",
"@types/lodash.kebabcase": "^4.1.6",
"@types/lodash.merge": "^4.6.6",
"@types/react-helmet": "^6.1.0",
"@types/react-table": "^7.0.29",
"babel-plugin-styled-components": "^1.11.1",
"chroma-js": "^2.1.1",
"@github/prettier-config": "^0.0.4",
"@primer/gatsby-theme-doctocat": "^1.7.0",
"color2k": "^1.2.4",
"filter-obj": "^2.0.2",
"flat": "^5.0.2",
"fuse.js": "^6.4.1",
"gatsby": "^2.24.66",
"gatsby-plugin-manifest": "^2.4.34",
"gatsby-plugin-react-helmet": "^3.3.13",
"gatsby-plugin-styled-components": "^3.3.12",
"lodash.debounce": "^4.0.8",
"lodash.flatmap": "^4.5.0",
"lodash.groupby": "^4.6.0",
"lodash.kebabcase": "^4.1.1",
"lodash.merge": "^4.6.2",
"lodash.get": "^4.4.2",
"prettier": "2.1.2",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-helmet": "^6.1.0",
"react-table": "^7.6.3",
"sentence-case": "^3.0.3",
"styled-components": "^5.2.0",
"worker-loader": "^3.0.3"
},
"devDependencies": {
"@github/prettier-config": "^0.0.4",
"prettier": "2.1.2"
"sentence-case": "^3.0.4"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {BaseStyles} from '@primer/components'
import SkipLink from '@primer/gatsby-theme-doctocat/src/components/skip-link'
import React from 'react'
import {ColorThemeProvider} from '../../../components/color-theme-context'

// Shadowing this file to wrap the page in our custom ColorThemeProvider.

function wrapPageElement({element}) {
return (
<ColorThemeProvider>
<BaseStyles>
<SkipLink />
{element}
</BaseStyles>
</ColorThemeProvider>
)
}

export default wrapPageElement
2 changes: 2 additions & 0 deletions docs/src/@primer/gatsby-theme-doctocat/nav.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- title: Colors
url: /colors
66 changes: 66 additions & 0 deletions docs/src/components/color-scales.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import colors from '../../../dist/js/colors_v2'
import React from 'react'
import {useColorTheme} from './color-theme-context'
import {Box, Text} from '@primer/components'
import {readableColor} from 'color2k'

export function ColorScales() {
const [colorTheme] = useColorTheme()
return (
<Box
sx={{
display: 'grid',
gridGap: 3,
gridTemplateColumns: 'repeat(auto-fit, minmax(320px, 1fr))',
p: 3,
bg: colors[colorTheme].canvas.default,
boxShadow: 'inset 0 0 0 1px rgba(0,0,0,0.1)',
borderRadius: 2
}}
>
{Object.entries(colors[colorTheme].scale).map(([scaleName, scale]) => {
return (
<Box sx={{overflow: 'hidden', borderRadius: 1}}>
{Array.isArray(scale) ? (
scale.map((color, index) => {
return (
<Box
sx={{
color: readableColor(color),
bg: color,
p: 2,
display: 'flex',
justifyContent: 'space-between',
fontFamily: 'mono',
fontSize: 1
}}
>
<Text>
scale.{scaleName}.{index}
</Text>
<Text>{color}</Text>
</Box>
)
})
) : (
<Box
sx={{
color: readableColor(scale),
bg: scale,
p: 2,
display: 'flex',
justifyContent: 'space-between',
fontFamily: 'mono',
fontSize: 1
}}
>
<Text>scale.{scaleName}</Text>
<Text>{scale}</Text>
</Box>
)}
</Box>
)
})}
</Box>
)
}
15 changes: 15 additions & 0 deletions docs/src/components/color-theme-context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react'
import colors from '../../../dist/js/colors_v2'

const ColorThemeContext = React.createContext<
[keyof typeof colors, React.Dispatch<React.SetStateAction<keyof typeof colors>>]
>(['light', () => {}])

export function ColorThemeProvider({children}) {
const [colorTheme, setColorTheme] = React.useState<keyof typeof colors>('light')
return <ColorThemeContext.Provider value={[colorTheme, setColorTheme]}>{children}</ColorThemeContext.Provider>
}

export function useColorTheme() {
return React.useContext(ColorThemeContext)
}
Loading