├── .gitignore ├── .prettierrc ├── .travis.yml ├── LICENSE ├── Readme.md ├── babel.config.js ├── package.json ├── src ├── components │ ├── ColorSwatch.jsx │ ├── ColorSwatch.md │ ├── Colors.jsx │ ├── Colors.md │ ├── PaletteSwatch.jsx │ ├── PaletteSwatch.md │ ├── Spacing.jsx │ ├── Spacing.md │ ├── SpacingSwatch.jsx │ ├── SpacingSwatch.md │ ├── Swatch.jsx │ ├── SwatchToken.jsx │ ├── SwatchToken.md │ ├── SwatchValue.jsx │ ├── SwatchValue.md │ ├── Swatches.jsx │ ├── Swatches.md │ ├── TextStyleSwatch.jsx │ ├── TextStyleSwatch.md │ ├── Typography.jsx │ └── Typography.md ├── examples │ ├── Readme.md │ ├── Text.js │ ├── cdds.js │ └── primer.js ├── index.js ├── propTypes.js └── theme.js ├── styleguide.config.js ├── styleguide └── Provider.jsx ├── tsconfig.json ├── webpack.config.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | Changelog.md 63 | 64 | # styleguide 65 | 66 | docs/ 67 | 68 | # Dist 69 | 70 | dist/ 71 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": true, 3 | "overrides": [ 4 | { 5 | "files": "*.md", 6 | "options": { 7 | "printWidth": 70, 8 | "useTabs": false, 9 | "trailingComma": "none", 10 | "proseWrap": "never" 11 | } 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | cache: yarn 3 | node_js: 4 | - '10' 5 | after_success: 6 | - npm install --no-save semantic-release 7 | - npx travis-deploy-once "semantic-release" 8 | branches: 9 | except: 10 | - /^v\d+\.\d+\.\d+$/ 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 component-driven 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | 🚨 Moved to https://github.com/component-driven/ui 2 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | "@babel/env", 5 | { 6 | modules: "commonjs" 7 | } 8 | ], 9 | "@babel/react", 10 | "@emotion/babel-preset-css-prop" 11 | ] 12 | }; 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@component-driven/react-design-tokens", 3 | "version": "0.0.0-development", 4 | "description": "React components to document design tokens in a styleguide", 5 | "main": "dist/index.js", 6 | "files": [ 7 | "dist" 8 | ], 9 | "scripts": { 10 | "start": "npm run styleguide", 11 | "test": "echo \"No test specified\" && exit 0", 12 | "styleguide": "styleguidist server", 13 | "styleguide:build": "styleguidist build", 14 | "build": "babel --delete-dir-on-start --ignore '**/*.spec.js' --env-name cjs -d dist/ src/", 15 | "prepublishOnly": "npm run build" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "git+https://github.com/component-driven/react-design-tokens.git" 20 | }, 21 | "publishConfig": { 22 | "access": "public" 23 | }, 24 | "keywords": [], 25 | "author": "Andrey Okonetchnikov ", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/component-driven/react-design-tokens/issues" 29 | }, 30 | "homepage": "https://github.com/component-driven/react-design-tokens#readme", 31 | "peerDependencies": { 32 | "react": "^16.8.0", 33 | "react-dom": "^16.8.0" 34 | }, 35 | "dependencies": { 36 | "clipboard-copy": "^3.0.0", 37 | "lodash": "^4.17.11", 38 | "polished": "^3.4.0", 39 | "prop-types": "^15.7.2", 40 | "react": "^16.8.6", 41 | "react-dom": "^16.8.6", 42 | "theme-ui": "^0.3.1" 43 | }, 44 | "devDependencies": { 45 | "@babel/cli": "^7.4.4", 46 | "@babel/core": "^7.4.5", 47 | "@babel/preset-env": "^7.4.5", 48 | "@babel/preset-react": "^7.0.0", 49 | "@babel/preset-typescript": "^7.3.3", 50 | "@emotion/babel-preset-css-prop": "^10.0.9", 51 | "@emotion/styled": "^10.0.11", 52 | "babel-loader": "^8.0.6", 53 | "husky": "^2.4.0", 54 | "lint-staged": "^8.2.0", 55 | "prettier": "^1.18.0", 56 | "primer-colors": "^1.0.1", 57 | "primer-spacing": "^1.0.2", 58 | "primer-typography": "^1.0.1", 59 | "react-styleguidist": "^9.1.4", 60 | "webpack": "^4.33.0" 61 | }, 62 | "husky": { 63 | "hooks": { 64 | "pre-commit": "lint-staged" 65 | } 66 | }, 67 | "lint-staged": { 68 | "*.{js,jsx,ts,tsx,md}": [ 69 | "prettier --write", 70 | "git add" 71 | ] 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/components/ColorSwatch.jsx: -------------------------------------------------------------------------------- 1 | /* @jsx jsx */ 2 | import { jsx } from "theme-ui"; 3 | import React from "react"; 4 | import { readableColor } from "polished"; 5 | import { Swatch, SwatchToken, SwatchValue } from "../"; 6 | import { tokenPropType, valuePropType } from "../propTypes"; 7 | 8 | export const ColorSwatch = ({ value, token }) => { 9 | const color = readableColor(value, "black", "white"); 10 | return ( 11 | 12 |
20 | {token} 21 | {value} 22 |
23 |
24 | ); 25 | }; 26 | 27 | ColorSwatch.propTypes = { 28 | ...tokenPropType, 29 | ...valuePropType 30 | }; 31 | 32 | /** @component */ 33 | export default ColorSwatch; 34 | -------------------------------------------------------------------------------- /src/components/ColorSwatch.md: -------------------------------------------------------------------------------- 1 | Renders a color swatch with a readable text. 2 | 3 | ```jsx harmony 4 | 5 | ``` 6 | 7 | When clicked, the value of the token is copied to clipboard. 8 | -------------------------------------------------------------------------------- /src/components/Colors.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Grid, ThemeProvider } from "theme-ui"; 3 | import { omitBy, pickBy, isString } from "lodash"; 4 | import { Swatches, ColorSwatch, PaletteSwatch } from "../index"; 5 | 6 | export default function Colors({ theme }) { 7 | const gap = 2; 8 | const colors = pickBy(theme.colors, isString); 9 | const palettes = omitBy(theme.colors, isString); 10 | return ( 11 | 12 | 13 | 14 | {(token, value) => ( 15 | 22 | 23 | 24 | )} 25 | 26 | 32 | 33 | {(token, value) => ( 34 | 35 | )} 36 | 37 | 38 | 39 | 40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /src/components/Colors.md: -------------------------------------------------------------------------------- 1 | ```jsx harmony 2 | import theme from "../theme"; 3 | 4 | ; 5 | ``` 6 | -------------------------------------------------------------------------------- /src/components/PaletteSwatch.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { Swatches, ColorSwatch } from "../index"; 4 | import { tokenPropType, valuePropType } from "../propTypes"; 5 | 6 | export const PaletteSwatch = ({ token, value }) => ( 7 | 8 | {(key, value) => ( 9 | 14 | )} 15 | 16 | ); 17 | 18 | PaletteSwatch.propTypes = { 19 | ...tokenPropType, 20 | ...valuePropType 21 | }; 22 | 23 | /** @component */ 24 | export default PaletteSwatch; 25 | -------------------------------------------------------------------------------- /src/components/PaletteSwatch.md: -------------------------------------------------------------------------------- 1 | Palette swatch renders all color tokens from a palette as defined in [System UI theme specification](https://system-ui.com/theme/) 2 | 3 | It supports arrays 4 | 5 | ```jsx harmony 6 | const palette = [ 7 | "#FFCDD2", 8 | "#EF9A9A", 9 | "#E57373", 10 | "#EF5350", 11 | "#F44336", 12 | "#E53935", 13 | "#D32F2F", 14 | "#C62828", 15 | "#B71C1C" 16 | ]; 17 | ; 18 | ``` 19 | 20 | as well as object notation: 21 | 22 | ```jsx harmony 23 | import theme from "../theme"; 24 | 25 | ; 26 | ``` 27 | -------------------------------------------------------------------------------- /src/components/Spacing.jsx: -------------------------------------------------------------------------------- 1 | /* @jsx jsx */ 2 | import React from "react"; 3 | import { Grid, jsx, ThemeProvider } from "theme-ui"; 4 | import { SpacingSwatch, Swatch, Swatches, SwatchToken } from "../index"; 5 | 6 | export default function Spacing({ theme }) { 7 | return ( 8 | 9 | 10 | 11 | {(token, value) => ( 12 | 13 | 17 | {token} 18 | 19 | 20 | 21 | )} 22 | 23 | 24 | 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /src/components/Spacing.md: -------------------------------------------------------------------------------- 1 | Spacing renders all `space` tokens from the theme in a convenient way. 2 | 3 | ```jsx harmony 4 | import theme from "../theme"; 5 | 6 | ; 7 | ``` 8 | -------------------------------------------------------------------------------- /src/components/SpacingSwatch.jsx: -------------------------------------------------------------------------------- 1 | /* @jsx jsx */ 2 | import React from "react"; 3 | import { jsx } from "theme-ui"; 4 | import { SwatchValue } from "../"; 5 | import { valuePropType } from "../propTypes"; 6 | 7 | const SpacingSwatch = ({ value, css: componentCSS, ...rest }) => { 8 | return ( 9 |
19 | 20 | {value} 21 | 22 |
23 | ); 24 | }; 25 | 26 | SpacingSwatch.propTypes = { 27 | ...valuePropType 28 | }; 29 | 30 | /** @component */ 31 | export default SpacingSwatch; 32 | -------------------------------------------------------------------------------- /src/components/SpacingSwatch.md: -------------------------------------------------------------------------------- 1 | Spacing swatch renders a bar with a width of the provided `value` and its content as a text 2 | 3 | ```jsx harmony 4 | 5 | ``` 6 | 7 | You can override default styles using `css` prop: 8 | 9 | ```jsx harmony 10 | 17 | ``` 18 | -------------------------------------------------------------------------------- /src/components/Swatch.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import copy from "clipboard-copy"; 4 | import { tokenPropType, valuePropType } from "../propTypes"; 5 | 6 | function Swatch(props) { 7 | return ( 8 |
copy(props.token)} 11 | css={{ 12 | cursor: "pointer" 13 | }} 14 | {...props} 15 | /> 16 | ); 17 | } 18 | 19 | Swatch.propTypes = { 20 | ...tokenPropType, 21 | ...valuePropType 22 | }; 23 | 24 | export default Swatch; 25 | -------------------------------------------------------------------------------- /src/components/SwatchToken.jsx: -------------------------------------------------------------------------------- 1 | /* @jsx jsx */ 2 | import { jsx } from "theme-ui"; 3 | import React from "react"; 4 | 5 | function SwatchToken({ color = "text", css: componentCSS, ...rest }) { 6 | return ( 7 |

18 | ); 19 | } 20 | 21 | export default SwatchToken; 22 | -------------------------------------------------------------------------------- /src/components/SwatchToken.md: -------------------------------------------------------------------------------- 1 | A primitive to render the token name. 2 | 3 | ```jsx harmony 4 | Token name 5 | ``` 6 | 7 | Color can be customized using `color` prop: 8 | 9 | ```jsx harmony 10 | Primary token 11 | ``` 12 | 13 | For more customization use `css` and `style` props 14 | 15 | ```jsx harmony 16 | 24 | Custom style 25 | 26 | ``` 27 | -------------------------------------------------------------------------------- /src/components/SwatchValue.jsx: -------------------------------------------------------------------------------- 1 | /* @jsx jsx */ 2 | import { jsx } from "theme-ui"; 3 | import React from "react"; 4 | 5 | function SwatchValue({ color = "secondary", css: componentCSS, ...rest }) { 6 | return ( 7 |

18 | ); 19 | } 20 | 21 | export default SwatchValue; 22 | -------------------------------------------------------------------------------- /src/components/SwatchValue.md: -------------------------------------------------------------------------------- 1 | A primitive to render token's value 2 | 3 | ```jsx harmony 4 | 13px 5 | ``` 6 | 7 | Use `color` prop to customize color: 8 | 9 | ```jsx harmony 10 | 24px 11 | ``` 12 | 13 | or `css` and `style` to customize everything else: 14 | 15 | ```jsx harmony 16 | 24 | Custom value 25 | 26 | ``` 27 | -------------------------------------------------------------------------------- /src/components/Swatches.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | 4 | const Swatches = ({ items = [], children }) => ( 5 | <> 6 | {Array.isArray(items) 7 | ? items.map((value, index) => children(index, value)) 8 | : Object.keys(items).map(key => children(key, items[key]))} 9 | 10 | ); 11 | 12 | Swatches.propTypes = { 13 | items: PropTypes.oneOfType([PropTypes.array, PropTypes.object]).isRequired, 14 | children: PropTypes.func.isRequired 15 | }; 16 | 17 | /** @component */ 18 | export default Swatches; 19 | -------------------------------------------------------------------------------- /src/components/Swatches.md: -------------------------------------------------------------------------------- 1 | ```jsx harmony 2 | import { Grid } from "theme-ui"; 3 | import theme from "../theme"; 4 | import { Swatch, Swatches, SwatchToken, SpacingSwatch } from "../"; 5 | 6 | 7 | 8 | {(token, value) => ( 9 | 10 | {token} 11 | 12 | 13 | )} 14 | 15 | ; 16 | ``` 17 | -------------------------------------------------------------------------------- /src/components/TextStyleSwatch.jsx: -------------------------------------------------------------------------------- 1 | /* @jsx jsx */ 2 | import { jsx } from "theme-ui"; 3 | import React from "react"; 4 | import { valuePropType } from "../propTypes"; 5 | 6 | /** 7 | * A swatch to render a `textStyle` variant. Provide the sample text as `children`. 8 | * @param value 9 | * @param componentCSS 10 | * @param rest 11 | * @return React.Element 12 | * @constructor 13 | */ 14 | const TextStyleSwatch = ({ value, css: componentCSS, ...rest }) => ( 15 |

24 | ); 25 | 26 | TextStyleSwatch.propTypes = { 27 | ...valuePropType 28 | }; 29 | 30 | /** @component */ 31 | export default TextStyleSwatch; 32 | -------------------------------------------------------------------------------- /src/components/TextStyleSwatch.md: -------------------------------------------------------------------------------- 1 | ```jsx harmony 2 | import theme from "../theme"; 3 | 4 | 5 | Aa 6 | ; 7 | ``` 8 | -------------------------------------------------------------------------------- /src/components/Typography.jsx: -------------------------------------------------------------------------------- 1 | /* @jsx jsx */ 2 | import { Grid, jsx, ThemeProvider } from "theme-ui"; 3 | import React from "react"; 4 | import { Swatch, Swatches, SwatchToken, TextStyleSwatch } from "../"; 5 | 6 | /** 7 | * Typography component showcases all available text styles defined in `theme.textStyles` 8 | * object of [styled-system theme](https://styled-system.com/table#variants). 9 | * @param theme 10 | * @return React.Element 11 | * @constructor 12 | */ 13 | export default function Typography({ theme }) { 14 | return ( 15 | 16 | 17 | 18 | {(token, value) => ( 19 | 20 | 21 | 27 | {token} 28 | 29 | 30 | The quick brown fox jumps over the lazy dog 31 | 32 | 33 | 34 | )} 35 | 36 | 37 | 38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /src/components/Typography.md: -------------------------------------------------------------------------------- 1 | ```jsx harmony 2 | import theme from "../theme"; 3 | 4 | ; 5 | ``` 6 | 7 | Starting from v5 of styled-system, you can co-locate variants inside your components. 8 | 9 | Consider this is your `Text` component that defines text styles: 10 | 11 | ```js { "file": "../../examples/Text.js" } 12 | ``` 13 | 14 | ```jsx harmony 15 | import theme from "../theme"; 16 | import { textStyles } from "../examples/Text"; 17 | 18 | ; 19 | ``` 20 | -------------------------------------------------------------------------------- /src/examples/Readme.md: -------------------------------------------------------------------------------- 1 | ### [Component-driven Design Systems Workshop](https://github.com/component-driven/component-driven-development) Design System 2 | 3 | ```jsx harmony 4 | import { Grid } from "theme-ui"; 5 | import theme from "./cdds"; 6 | import { Colors, Spacing, Typography } from "../"; 7 | 8 | 9 | 10 | 11 | 12 | ; 13 | ``` 14 | 15 | ### GitHub Primer Design System 16 | 17 | ```jsx harmony 18 | import { Grid } from "theme-ui"; 19 | import theme from "./primer"; 20 | import { Colors, Spacing, Typography } from "../"; 21 | 22 | 23 | 24 | 25 | 26 | ; 27 | ``` 28 | -------------------------------------------------------------------------------- /src/examples/Text.js: -------------------------------------------------------------------------------- 1 | import styled from "@emotion/styled"; 2 | import { css } from "@styled-system/css"; 3 | import { typography, variant, compose } from "styled-system"; 4 | 5 | export const textStyles = { 6 | body: { 7 | fontFamily: "body", 8 | fontSize: "md", 9 | fontWeight: "normal", 10 | color: "text" 11 | }, 12 | heading: { 13 | fontFamily: "heading", 14 | fontSize: "xl", 15 | fontWeight: "bold", 16 | color: "secondary" 17 | } 18 | }; 19 | 20 | const Text = styled.p( 21 | css({ 22 | m: 0, 23 | lineHeight: 1.5 24 | }), 25 | compose( 26 | variant({ 27 | prop: "textStyle", 28 | variants: textStyles 29 | }), 30 | typography 31 | ) 32 | ); 33 | 34 | export default Text; 35 | -------------------------------------------------------------------------------- /src/examples/cdds.js: -------------------------------------------------------------------------------- 1 | import { modularScale } from "polished"; 2 | 3 | const scale = value => modularScale(value, "1rem", "goldenSection"); 4 | 5 | const fontSizes = { 6 | xl: scale(3), 7 | lg: scale(1), 8 | md: scale(0), 9 | sm: scale(-0.5), 10 | xs: scale(-0.75) 11 | }; 12 | 13 | const palette = { 14 | grey: [ 15 | "rgb(255, 255, 255)", 16 | "rgb(250, 250, 250)", 17 | "rgb(246, 246, 246)", 18 | "rgb(225, 225, 225)", 19 | "rgb(187, 187, 187)", 20 | "rgb(126, 126, 126)", 21 | "rgb(51, 51, 51)" 22 | ], 23 | purple: [ 24 | "rgb(255, 230, 242)", 25 | "rgb(251, 209, 234)", 26 | "rgb(248, 188, 229)", 27 | "rgb(231, 143, 222)", 28 | "rgb(189, 96, 200)", 29 | "rgb(120, 51, 150)", 30 | "rgb(52, 18, 90)" 31 | ] 32 | }; 33 | 34 | let invertedPalette = {}; 35 | 36 | Object.keys(palette).forEach(key => { 37 | invertedPalette[key] = [...palette[key]].reverse(); 38 | }); 39 | 40 | function getColors(palette) { 41 | return { 42 | ...palette, 43 | bg: palette.grey[0], 44 | base: palette.grey[6], 45 | primary: palette.purple[5], 46 | secondary: palette.grey[5], 47 | muted: palette.grey[2], 48 | hover: palette.purple[2], 49 | focus: palette.purple[1], 50 | error: "#d0453e", 51 | rating: "#f8c124" 52 | }; 53 | } 54 | 55 | const theme = { 56 | fonts: { 57 | body: "Helvetica Neue, Helvetica, Arial, sans-serif", 58 | heading: "Helvetica Neue, Helvetica, Arial, sans-serif", 59 | monospace: "Menlo, monospace" 60 | }, 61 | fontSizes: { 62 | base: fontSizes.md, 63 | ...fontSizes 64 | }, 65 | fontWeights: { 66 | normal: 400, 67 | bold: 700 68 | }, 69 | headingFontWeights: { 70 | xl: 400, 71 | l: 400, 72 | m: 700 73 | }, 74 | lineHeights: { 75 | base: 1.5, 76 | heading: 1.1 77 | }, 78 | palette, 79 | colors: getColors(palette), 80 | borders: { 81 | none: "none", 82 | thin: "1px solid" 83 | }, 84 | radii: { 85 | base: "0.15em" 86 | }, 87 | space: [ 88 | 0, 89 | "0.125rem", // 2px 90 | "0.25rem", // 4px 91 | "0.5rem", // 8px 92 | "1rem", // 16px 93 | "2rem", // 32px 94 | "4rem", // 64px 95 | "8rem", // 128px 96 | "16rem" // 256px 97 | ], 98 | textStyles: { 99 | base: {}, 100 | secondary: { 101 | color: palette.grey[5] 102 | }, 103 | tertiary: { 104 | color: palette.grey[5], 105 | fontSize: fontSizes.s 106 | }, 107 | error: { 108 | color: getColors(palette).error 109 | } 110 | } 111 | }; 112 | 113 | export default theme; 114 | 115 | export const inverted = { 116 | ...theme, 117 | colors: { 118 | ...getColors(invertedPalette), 119 | primary: invertedPalette.grey[4], 120 | hover: invertedPalette.grey[6], 121 | focus: invertedPalette.grey[1] 122 | } 123 | }; 124 | -------------------------------------------------------------------------------- /src/examples/primer.js: -------------------------------------------------------------------------------- 1 | const colors = require("primer-colors"); 2 | const space = require("primer-spacing"); 3 | const { fontSizes, lineHeights } = require("primer-typography"); 4 | 5 | const theme = { 6 | colors, 7 | space, 8 | fontSizes, 9 | lineHeights 10 | }; 11 | 12 | module.exports = theme; 13 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | export { default as Swatches } from "./components/Swatches"; 2 | export { default as Swatch } from "./components/Swatch"; 3 | export { default as SwatchToken } from "./components/SwatchToken"; 4 | export { default as SwatchValue } from "./components/SwatchValue"; 5 | export { default as ColorSwatch } from "./components/ColorSwatch"; 6 | export { default as TextStyleSwatch } from "./components/TextStyleSwatch"; 7 | export { default as PaletteSwatch } from "./components/PaletteSwatch"; 8 | export { default as SpacingSwatch } from "./components/SpacingSwatch"; 9 | export { default as Colors } from "./components/Colors"; 10 | export { default as Typography } from "./components/Typography"; 11 | export { default as Spacing } from "./components/Spacing"; 12 | -------------------------------------------------------------------------------- /src/propTypes.js: -------------------------------------------------------------------------------- 1 | import PropTypes from "prop-types"; 2 | 3 | /** 4 | * Design token name 5 | * See https://theme-ui.com/theme-spec 6 | * */ 7 | export const tokenPropType = { 8 | token: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired 9 | }; 10 | 11 | /** 12 | * The value to render inside the swatch 13 | * */ 14 | export const valuePropType = { 15 | value: PropTypes.oneOfType([ 16 | PropTypes.string, 17 | PropTypes.number, 18 | PropTypes.object, 19 | PropTypes.array 20 | ]).isRequired 21 | }; 22 | -------------------------------------------------------------------------------- /src/theme.js: -------------------------------------------------------------------------------- 1 | import { modularScale } from "polished"; 2 | 3 | const scale = value => modularScale(value, "1rem", "goldenSection"); 4 | 5 | const palette = { 6 | slate: { 7 | darker: "#11161A", 8 | dark: "#1F2932", 9 | base: "#2E3D49", 10 | light: "#6D7780", 11 | lighter: "#B4B9BD", 12 | lightest: "#F7F7F8" 13 | } 14 | }; 15 | export default { 16 | fontSizes: { 17 | xl: scale(3), 18 | lg: scale(1), 19 | md: scale(0), 20 | sm: scale(-0.5), 21 | xs: scale(-0.75) 22 | }, 23 | fonts: { 24 | body: "system-ui, sans-serif", 25 | heading: '"Avenir Next", sans-serif', 26 | monospace: "Menlo, monospace" 27 | }, 28 | textStyles: { 29 | body: { 30 | fontFamily: "body", 31 | fontSize: "md", 32 | color: "text" 33 | }, 34 | heading: { 35 | fontSize: "xl", 36 | fontFamily: "heading", 37 | color: "secondary" 38 | } 39 | }, 40 | space: [ 41 | 0, 42 | "0.125rem", // 2px 43 | "0.25rem", // 4px 44 | "0.5rem", // 8px 45 | "1rem", // 16px 46 | "2rem", // 32px 47 | "4rem", // 64px 48 | "8rem", // 128px 49 | "16rem" // 256px 50 | ], 51 | colors: { 52 | ...palette, 53 | text: palette.slate.base, 54 | background: palette.slate.lightest, 55 | primary: "#E53935", 56 | secondary: palette.slate.light, 57 | muted: palette.slate.lighter 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /styleguide.config.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | const pkg = require("./package.json"); 4 | 5 | module.exports = { 6 | title: pkg.name, 7 | serverPort: 6061, 8 | styleguideDir: path.join(__dirname, "docs"), 9 | getComponentPathLine(componentPath) { 10 | const name = path.basename(componentPath, ".jsx"); 11 | return `import { ${name} } from '${pkg.name}';`; 12 | }, 13 | skipComponentsWithoutExample: true, 14 | styleguideComponents: { 15 | Wrapper: path.join(__dirname, "styleguide", "Provider.jsx") 16 | }, 17 | sections: [ 18 | { 19 | name: "Introduction", 20 | content: path.join(__dirname, "Readme.md") 21 | }, 22 | { 23 | name: "Components", 24 | components: "src/components/*.jsx" 25 | }, 26 | { 27 | name: "Examples", 28 | content: path.join(__dirname, "src/examples/Readme.md") 29 | } 30 | ], 31 | ribbon: { 32 | url: "https://github.com/component-driven/react-design-tokens" 33 | }, 34 | updateExample(props, exampleFilePath) { 35 | // props.settings are passed by any fenced code block, in this case 36 | const { settings, lang } = props; 37 | // "../mySourceCode.js" 38 | if (typeof settings.file === "string") { 39 | // "absolute path to mySourceCode.js" 40 | const filepath = path.resolve(exampleFilePath, settings.file); 41 | // displays the block as static code 42 | settings.static = true; 43 | // no longer needed 44 | delete settings.file; 45 | return { 46 | content: fs.readFileSync(filepath, "utf8"), 47 | settings, 48 | lang 49 | }; 50 | } 51 | return props; 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /styleguide/Provider.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { ThemeProvider } from "theme-ui"; 3 | import theme from "../src/theme"; 4 | 5 | function Provider({ children }) { 6 | return {children}; 7 | } 8 | 9 | export default Provider; 10 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "es2015", 5 | "jsx": "react", 6 | "moduleResolution": "node", 7 | "allowJs": true, 8 | "noEmit": true, 9 | "strict": true, 10 | "isolatedModules": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true 13 | }, 14 | "include": [ 15 | "src", 16 | "styleguide" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | module: { 3 | rules: [ 4 | { 5 | test: /\.(jsx?|tsx?)$/, 6 | exclude: /node_modules/, 7 | loader: "babel-loader" 8 | } 9 | ] 10 | } 11 | }; 12 | --------------------------------------------------------------------------------