From e76c8f2eed0f96631b8f0ca28b0f952043a067bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Zl=C3=A1mal?= Date: Thu, 8 Apr 2021 15:38:29 -0500 Subject: [PATCH] SX Design: update CSS variables I took a great inspiration from https://vercel.com/design/color. The main change (other than adding new variables for colors) is that I got rid of "text color" and replaced it with "foreground color". This allows use to better describe the actual use-case when there is no text involved. I have other PRs in the queue using these colors so stay tuned. --- .../continuous-integration-javascript.yml | 2 +- package.json | 2 +- src/sx-design/README.md | 121 ++++++++++++++---- .../src/ErrorBoundary/ErrorBoundary.js | 6 +- src/sx-design/src/Heading/Heading.js | 2 +- .../src/Heading/__tests__/Heading.test.js | 4 +- .../__snapshots__/Heading.test.js.snap | 38 +++--- src/sx-design/src/Kbd/Kbd.js | 2 +- src/sx-design/src/Money/Money.js | 2 +- src/sx-design/src/ProductCard/ProductCard.js | 12 +- src/sx-design/src/Section/Section.js | 2 +- src/sx-design/src/SkipLink/SkipLink.js | 5 +- .../src/SxDesignProviderCSSVariables.js | 51 ++++++-- src/sx-design/src/stories/ColorShowcase.js | 23 ++++ src/sx-design/src/stories/Colors.stories.mdx | 64 +++++++++ .../src/stories/Introduction.stories.mdx | 2 +- 16 files changed, 264 insertions(+), 74 deletions(-) create mode 100644 src/sx-design/src/stories/ColorShowcase.js create mode 100644 src/sx-design/src/stories/Colors.stories.mdx diff --git a/.github/workflows/continuous-integration-javascript.yml b/.github/workflows/continuous-integration-javascript.yml index 85fb0217ba..dc93d9bae2 100644 --- a/.github/workflows/continuous-integration-javascript.yml +++ b/.github/workflows/continuous-integration-javascript.yml @@ -29,7 +29,7 @@ jobs: - name: yarn install, build, and test run: | yarn install --frozen-lockfile - yarn run flow + yarn run flow --max-warnings=0 yarn run lint yarn run test-only yarn workspace @adeira/example-relay test-bc diff --git a/package.json b/package.json index 43c98b5daf..f96c95925a 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ ], "lint": "yarn run eslint-config-prettier src/js/src/invariant.js && yarn run prettier --check \"src/**/*.md\" && yarn run jest --config=.jest-eslint.config.js --changedSince=origin/master^", "scanner": "yarn run jest --config src/monorepo-scanner/.jest.config.js", - "test": "yarn run flow && yarn run lint && yarn run test-only --ci --colors && yarn run scanner", + "test": "yarn run flow --max-warnings=0 && yarn run lint && yarn run test-only --ci --colors && yarn run scanner", "test-only": "src/monorepo-utils/bin/monorepo-run-tests.js" }, "jest-runner-eslint": { diff --git a/src/sx-design/README.md b/src/sx-design/README.md index 69f8d068d1..79fb647a29 100644 --- a/src/sx-design/README.md +++ b/src/sx-design/README.md @@ -36,32 +36,59 @@ export default function MyRootApp() { The error boundary is optional but highly recommended. -## Styles customization +# Styles customization -SX Design leverages full power of [CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) as a main way of style customization. You can optionally adjust the values if you want from your application. Here are some component specific default values (not dependent on dark mode): +SX Design leverages full power of [CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) as a main way of style customization. You can optionally adjust the values if you want from your application. Here are some component specific default values and colors (not dependent on dark mode): ```text --sx-kbd-border: 1px solid #b4b4b4 ---sx-money-text-color: var(--sx-text-color) ¹ ---sx-skipLink-background-color: 28, 30, 33 ² ---sx-skipLink-text-color: 255, 255, 255 +--sx-money-text-color: var(--sx-foreground) ¹ + +--sx-error-lighter: 247, 212, 214 ² +--sx-error-light: 255, 26, 26 +--sx-error: 238, 0, 0 +--sx-error-dark: 197, 0, 0 + +--sx-success-lighter: 211, 229, 255 +--sx-success-light: 50, 145, 255 +--sx-success: 0, 112, 243 +--sx-success-dark: 7, 97, 209 + +--sx-warning-lighter: 255, 239, 207 +--sx-warning-light: 247, 185, 85 +--sx-warning: 245, 166, 35 +--sx-warning-dark: 171, 87, 10 ``` Generic default values for light mode: ```text ---sx-background-color: 255, 255, 255 ² ---sx-text-color: 28, 30, 33 +--sx-background: 255, 255, 255 ² +--sx-accent-1: 227, 227, 227 +--sx-accent-2: 198, 199, 200 +--sx-accent-3: 170, 171, 172 +--sx-accent-4: 142, 143, 144 +--sx-accent-5: 113, 114, 116 +--sx-accent-6: 85, 86, 89 +--sx-accent-7: 56, 58, 61 +--sx-foreground: 28, 30, 33 --sx-text-link-color: 3, 102, 214 ``` And finally generic default values for dark mode: ```text ---sx-background-color: 51, 51, 51 ² ---sx-text-color: 255, 255, 255 +--sx-background: 51, 51, 51 ² +--sx-accent-1: 77, 77, 77 +--sx-accent-2: 102, 102, 102 +--sx-accent-3: 128, 128, 128 +--sx-accent-4: 153, 153, 153 +--sx-accent-5: 179, 179, 179 +--sx-accent-6: 204, 204, 204 +--sx-accent-7: 230, 230, 230 +--sx-foreground: 255, 255, 255 --sx-text-link-color: 88, 166, 255 ``` @@ -78,7 +105,7 @@ export default function MyComponent() { } ``` -## Available components +# Available components **🚧 WORK in PROGRESS 🚧** @@ -89,28 +116,72 @@ Legend: 🧐 not evaluated/ready yet ``` -| Component | Localized? | Dark mode? | Has stories? | Tested? | -| ------------------- | :--------: | :--------: | :----------: | :-----: | -| `` | ✅ | ✅ | ✅ | 🧐 | -| `` | ✅ | ✅ | 🧐 | ✅ | -| `` | ✅ | ✅ | ✅ | ✅ | -| `` | ✅ | ✅ | ✅ | ✅ | -| `` | ✅ | ✅ | ✅ | 🧐 | -| `` | ✅ | ✅ | ✅ | 🧐 | -| `` | ✅ | ✅ | 🧐 | ✅ | -| `` | ✅ | ✅ | ✅ | 🧐 | -| `
` | ✅ | ✅ | ✅ | 🧐 | -| `` | ✅ | ✅ | ✅ | 🧐 | -| `` | ✅ | 🧐 | 🧐 | 🧐 | +| Component | Localized?¹ | Dark mode?² | Has stories?³ | Tested?⁴ | +| ------------------- | :---------: | :---------: | :-----------: | :------: | +| `` | ✅ | ✅ | ✅ | 🧐 | +| `` | ✅ | ✅ | 🧐 | ✅ | +| `` | ✅ | ✅ | ✅ | ✅ | +| `` | ✅ | ✅ | ✅ | ✅ | +| `` | ✅ | ✅ | ✅ | 🧐 | +| `` | ✅ | ✅ | ✅ | 🧐 | +| `` | ✅ | ✅ | 🧐 | ✅ | +| `` | ✅ | ✅ | ✅ | 🧐 | +| `
` | ✅ | ✅ | ✅ | 🧐 | +| `` | ✅ | ✅ | ✅ | 🧐 | +| `` | ✅ | 🧐 | 🧐 | 🧐 | _Did you find a mistake in this table? Please, [report is as an issue](https://github.com/adeira/universe/issues/new)._ -## Development +¹ Localized means that it's either translated by us or the component inputs are (Flow) typed in a way that encourages passing translated strings instead of plain strings. -To start storybook run: +² Component should look fine in both light and dark mode. + +³ There are stories in the [Storybook](https://sx-design.vercel.app/) and these stories are somehow useful and explanatory. + +⁴ There are tests available to make sure that the component works as expected and we won't break it by accident. + +# Development + +## Storybook + +The easiest way how to develop these components is to run a Storybook: ```bash yarn workspace @adeira/sx-design storybook ``` Please, make sure that any changes still follow the core values of this project and the matrix of available components was updated accordingly. + +## Working with SX Design colors + +It's recommended to use [`pastel`](https://github.com/sharkdp/pastel) when working with the SX Design colors: + +```bash +brew install pastel +``` + +SX Design commonly uses colors written as triplets of values from 0 to 255. Here is how you can convert these triplets back and forth: + +```bash +pastel color "28, 30, 33" +pastel format hex "28, 30, 33" +``` + +To generate colors gradient run: + +```bash +pastel gradient -n 9 '255, 255, 255' '28, 30, 33' +pastel gradient -s rgb -n 9 '255, 255, 255' '28, 30, 33' | pastel format rgb +``` + +Another interesting command for checking colors with simulated colorblindness: + +```bash +pastel colorblind deuter "247,212,214" "255,26,26" "238,0,0" "197,0,0" +``` + +For more info run: + +```bash +pastel --help +``` diff --git a/src/sx-design/src/ErrorBoundary/ErrorBoundary.js b/src/sx-design/src/ErrorBoundary/ErrorBoundary.js index d6d0082d1f..e5228a10f8 100644 --- a/src/sx-design/src/ErrorBoundary/ErrorBoundary.js +++ b/src/sx-design/src/ErrorBoundary/ErrorBoundary.js @@ -80,8 +80,8 @@ export default class ErrorBoundary extends React.Component { const styles = sx.create({ error: { - color: 'rgb(var(--sx-text-color))', - background: 'rgb(var(--sx-background-color))', + color: 'rgb(var(--sx-foreground))', + background: 'rgb(var(--sx-background))', fontFamily: '-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif', height: '100vh', @@ -100,7 +100,7 @@ const styles = sx.create({ }, h1: { display: 'inline-block', - borderRight: '1px solid rgba(var(--sx-text-color), 0.3)', + borderRight: '1px solid rgba(var(--sx-foreground), 0.3)', margin: 0, marginRight: 20, padding: '10px 23px 10px 0', diff --git a/src/sx-design/src/Heading/Heading.js b/src/sx-design/src/Heading/Heading.js index a769aff8a1..d59287fe33 100644 --- a/src/sx-design/src/Heading/Heading.js +++ b/src/sx-design/src/Heading/Heading.js @@ -32,6 +32,6 @@ export default function Heading(props: Props): React.Node { const styles = sx.create({ heading: { - color: 'rgba(var(--sx-text-color))', + color: 'rgba(var(--sx-foreground))', }, }); diff --git a/src/sx-design/src/Heading/__tests__/Heading.test.js b/src/sx-design/src/Heading/__tests__/Heading.test.js index db7d5a8f82..c898536a26 100644 --- a/src/sx-design/src/Heading/__tests__/Heading.test.js +++ b/src/sx-design/src/Heading/__tests__/Heading.test.js @@ -9,7 +9,7 @@ import Section from '../../Section/Section'; it('renders top level by default', () => { const { container } = render(level one); - expect(container.innerHTML).toMatchInlineSnapshot(`"

level one

"`); + expect(container.innerHTML).toMatchInlineSnapshot(`"

level one

"`); }); it('renders H1 tags in parallel', () => { @@ -20,7 +20,7 @@ it('renders H1 tags in parallel', () => { , ); expect(container.innerHTML).toMatchInlineSnapshot( - `"

level one

level one

"`, + `"

level one

level one

"`, ); }); diff --git a/src/sx-design/src/Heading/__tests__/__snapshots__/Heading.test.js.snap b/src/sx-design/src/Heading/__tests__/__snapshots__/Heading.test.js.snap index 3469c16ba8..153a9c2c8b 100644 --- a/src/sx-design/src/Heading/__tests__/__snapshots__/Heading.test.js.snap +++ b/src/sx-design/src/Heading/__tests__/__snapshots__/Heading.test.js.snap @@ -1,30 +1,30 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`renders maximum 6 levels 1`] = ` -"

level one

-
-

level two

-
-

level three

-
-

level four

-
-
level five
-
-
level six
-
-
level six again
-
level six again
+"

level one

+
+

level two

+
+

level three

+
+

level four

+
+
level five
+
+
level six
+
+
level six again
+
level six again
-
level six
+
level six
-
level five
+
level five
-

level four

+

level four

-

level three

+

level three

-

level two

+

level two

" `; diff --git a/src/sx-design/src/Kbd/Kbd.js b/src/sx-design/src/Kbd/Kbd.js index 6eecdcbbfe..5292e90732 100644 --- a/src/sx-design/src/Kbd/Kbd.js +++ b/src/sx-design/src/Kbd/Kbd.js @@ -29,7 +29,7 @@ const styles = sx.create({ kbd: { borderRadius: '3px', border: 'var(--sx-kbd-border, 1px solid #b4b4b4)', - color: 'rgba(var(--sx-text-color))', + color: 'rgba(var(--sx-foreground))', display: 'inline-block', fontSize: '0.85em', fontWeight: '700', diff --git a/src/sx-design/src/Money/Money.js b/src/sx-design/src/Money/Money.js index de8a4f6f2a..2b26f76ace 100644 --- a/src/sx-design/src/Money/Money.js +++ b/src/sx-design/src/Money/Money.js @@ -25,7 +25,7 @@ export default function Money(props: MoneyProps): React.Node { const styles = sx.create({ text: { - color: 'rgba(var(--sx-money-text-color, var(--sx-text-color)))', + color: 'rgba(var(--sx-money-text-color, var(--sx-foreground)))', transition: 'inherit', }, }); diff --git a/src/sx-design/src/ProductCard/ProductCard.js b/src/sx-design/src/ProductCard/ProductCard.js index f63a500a14..931ea56d27 100644 --- a/src/sx-design/src/ProductCard/ProductCard.js +++ b/src/sx-design/src/ProductCard/ProductCard.js @@ -133,14 +133,14 @@ const styles = sx.create({ padding: '1rem', }, highlight: { - 'color': 'rgba(var(--sx-text-color))', - 'backgroundColor': 'rgba(var(--sx-background-color))', - '--sx-money-text-color': 'var(--sx-text-color)', + 'color': 'rgba(var(--sx-foreground))', + 'backgroundColor': 'rgba(var(--sx-background))', + '--sx-money-text-color': 'var(--sx-foreground)', }, highlightHover: { - 'color': 'rgba(var(--sx-background-color))', - 'backgroundColor': 'rgba(var(--sx-text-color))', - '--sx-money-text-color': 'var(--sx-background-color)', + 'color': 'rgba(var(--sx-background))', + 'backgroundColor': 'rgba(var(--sx-foreground))', + '--sx-money-text-color': 'var(--sx-background)', }, heading: { margin: 0, diff --git a/src/sx-design/src/Section/Section.js b/src/sx-design/src/Section/Section.js index aa941487d9..183b6d199e 100644 --- a/src/sx-design/src/Section/Section.js +++ b/src/sx-design/src/Section/Section.js @@ -28,6 +28,6 @@ export default function Section(props: Props): React.Node { const styles = sx.create({ section: { - color: 'rgba(var(--sx-text-color))', + color: 'rgba(var(--sx-foreground))', }, }); diff --git a/src/sx-design/src/SkipLink/SkipLink.js b/src/sx-design/src/SkipLink/SkipLink.js index ac0d4efffa..c745e427a7 100644 --- a/src/sx-design/src/SkipLink/SkipLink.js +++ b/src/sx-design/src/SkipLink/SkipLink.js @@ -21,8 +21,9 @@ const styles = sx.create({ 'position': 'absolute', 'top': -40, 'left': 0, - 'background': 'rgba(var(--sx-skipLink-background-color))', - 'color': 'rgba(var(--sx-skipLink-text-color))', + // the colors are flipped on purpose so it's visible in light/dark mode + 'background': 'rgba(var(--sx-foreground))', + 'color': 'rgba(var(--sx-background))', 'padding': 8, 'zIndex': 100, ':focus': { diff --git a/src/sx-design/src/SxDesignProviderCSSVariables.js b/src/sx-design/src/SxDesignProviderCSSVariables.js index 379809fedd..66d9ce6239 100644 --- a/src/sx-design/src/SxDesignProviderCSSVariables.js +++ b/src/sx-design/src/SxDesignProviderCSSVariables.js @@ -3,13 +3,13 @@ * apply alpha channel when needed (https://stackoverflow.com/a/41265350). Usage: * * ```js - * { color: 'rgba(var(--sx-text-color))' } + * { color: 'rgba(var(--sx-foreground))' } * ``` * * With optional alpha channel: * * ```js - * { color: 'rgba(var(--sx-text-color), 0.5)' } + * { color: 'rgba(var(--sx-foreground), 0.5)' } * ``` * * @flow @@ -17,18 +17,49 @@ export default { // Check and update README.md as well! + // https://coolors.co/generate common: { - '--sx-skipLink-background-color': '28, 30, 33', - '--sx-skipLink-text-color': '255, 255, 255', + '--sx-error-lighter': '247, 212, 214', + '--sx-error-light': '255, 26, 26', + '--sx-error': '238, 0, 0', + '--sx-error-dark': '197, 0, 0', + + '--sx-success-lighter': '211, 229, 255', + '--sx-success-light': '50, 145, 255', + '--sx-success': '0, 112, 243', + '--sx-success-dark': '7, 97, 209', + + '--sx-warning-lighter': '255, 239, 207', + '--sx-warning-light': '247, 185, 85', + '--sx-warning': '245, 166, 35', + '--sx-warning-dark': '171, 87, 10', }, lightTheme: { - '--sx-background-color': '255, 255, 255', - '--sx-text-color': '28, 30, 33', - '--sx-text-link-color': '3, 102, 214', + '--sx-background': '255, 255, 255', // lighter + '--sx-accent-1': '227, 227, 227', + '--sx-accent-2': '198, 199, 200', + '--sx-accent-3': '170, 171, 172', + '--sx-accent-4': '142, 143, 144', + '--sx-accent-5': '113, 114, 116', + '--sx-accent-6': '85, 86, 89', + '--sx-accent-7': '56, 58, 61', + '--sx-foreground': '28, 30, 33', // darker + + // + '--sx-text-link-color': '3, 102, 214', // TODO: naming (?) }, darkTheme: { - '--sx-background-color': '51, 51, 51', - '--sx-text-color': '255, 255, 255', - '--sx-text-link-color': '88, 166, 255', + '--sx-background': '51, 51, 51', + '--sx-accent-1': '77, 77, 77', + '--sx-accent-2': '102, 102, 102', + '--sx-accent-3': '128, 128, 128', + '--sx-accent-4': '153, 153, 153', + '--sx-accent-5': '179, 179, 179', + '--sx-accent-6': '204, 204, 204', + '--sx-accent-7': '230, 230, 230', + '--sx-foreground': '255, 255, 255', + + // + '--sx-text-link-color': '88, 166, 255', // TODO: naming (?) }, }; diff --git a/src/sx-design/src/stories/ColorShowcase.js b/src/sx-design/src/stories/ColorShowcase.js new file mode 100644 index 0000000000..0c1085e1cb --- /dev/null +++ b/src/sx-design/src/stories/ColorShowcase.js @@ -0,0 +1,23 @@ +// @flow strict + +import * as React from 'react'; + +type Props = { + +color: string, +}; + +export default function ColorShowcase(props: Props): React.Node { + return ( +
+ {props.color} +
+ ); +} diff --git a/src/sx-design/src/stories/Colors.stories.mdx b/src/sx-design/src/stories/Colors.stories.mdx new file mode 100644 index 0000000000..1d2bb71320 --- /dev/null +++ b/src/sx-design/src/stories/Colors.stories.mdx @@ -0,0 +1,64 @@ +import { Meta, Story, Canvas } from '@storybook/addon-docs/blocks'; +import SxDesignProvider from '../SxDesignProvider'; +import ColorShowcase from './ColorShowcase'; + + + +# Colors showcase + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + colors for light theme + + + + + + + + + + + + + + + colors for dark theme (it's not a simple reverse of light mode) + + + + + + + + + + + diff --git a/src/sx-design/src/stories/Introduction.stories.mdx b/src/sx-design/src/stories/Introduction.stories.mdx index 8b069c4e58..2484e58518 100644 --- a/src/sx-design/src/stories/Introduction.stories.mdx +++ b/src/sx-design/src/stories/Introduction.stories.mdx @@ -8,7 +8,7 @@ import Plugin from './assets/plugin.svg'; import Repo from './assets/repo.svg'; import StackAlt from './assets/stackalt.svg'; - +