From 01dfb8e5be9d761c08f2ced26f3677ee57a12c9f Mon Sep 17 00:00:00 2001 From: josefie Date: Tue, 24 May 2022 15:34:47 +0200 Subject: [PATCH] [#181944040] generate variables from tokens (#4) * playing around with theme switcher * pivotal-181957167 switch theme css * pivotal-181957167 pass tokens via context * pivotal-181944040 generate css variables (WIP) * pivotal-181944040 add parser for reference syntax, merge all tokens into one file, handle shadows and typography (WIP) * pivotal-181944040 make references work in style-dictionary by removing global key * pivotal-181944040 refactor * pivotal-181944040 add token config for js * pivotal-181944040 change output to json and use generated tokens in color palette * pivotal-181944040 expand typography tokens * add a bit more info to readme --- .eslintignore | 1 + .prettierignore | 1 + README.md | 38 +- build/css/globals.css | 187 ++++++ build/css/themes/at.css | 9 + build/css/themes/me.css | 9 + build/css/themes/org.css | 9 + build/json/globals.json | 182 ++++++ build/json/themes/at.json | 4 + build/json/themes/me.json | 4 + build/json/themes/org.json | 4 + config/sd.config.js | 50 ++ config/sd/parsers.js | 26 + config/sd/transformGroups.js | 23 + config/sd/transforms.js | 72 +++ config/themes.json | 1 + config/tokens.json | 866 ++++++++++++++++++++++++++ package.json | 2 + src/helpers/ThemeProvider.tsx | 15 +- src/lib/theme/theme-at.css | 4 - src/lib/theme/theme-me.css | 4 - src/lib/theme/theme-org.css | 4 - src/stories/tokens/Colors.stories.tsx | 3 +- tokens/globals.json | 7 - tokens/index.ts | 11 - tokens/theme-at.json | 5 - tokens/theme-me.json | 5 - tokens/theme-org.json | 5 - yarn.lock | 116 +++- 29 files changed, 1596 insertions(+), 71 deletions(-) create mode 100644 build/css/globals.css create mode 100644 build/css/themes/at.css create mode 100644 build/css/themes/me.css create mode 100644 build/css/themes/org.css create mode 100644 build/json/globals.json create mode 100644 build/json/themes/at.json create mode 100644 build/json/themes/me.json create mode 100644 build/json/themes/org.json create mode 100644 config/sd.config.js create mode 100644 config/sd/parsers.js create mode 100644 config/sd/transformGroups.js create mode 100644 config/sd/transforms.js create mode 100644 config/themes.json create mode 100644 config/tokens.json delete mode 100644 src/lib/theme/theme-at.css delete mode 100644 src/lib/theme/theme-me.css delete mode 100644 src/lib/theme/theme-org.css delete mode 100644 tokens/globals.json delete mode 100644 tokens/index.ts delete mode 100644 tokens/theme-at.json delete mode 100644 tokens/theme-me.json delete mode 100644 tokens/theme-org.json diff --git a/.eslintignore b/.eslintignore index 3b7c2766..5d21585f 100644 --- a/.eslintignore +++ b/.eslintignore @@ -11,5 +11,6 @@ app/javascript/shared/i18n.ts config/**/*.js vite.config.ts node_modules +sd.config.js storybook-static dist diff --git a/.prettierignore b/.prettierignore index 1e94a183..7e4c2d46 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,3 +4,4 @@ coverage .history app/javascript/gql/generated.ts app/javascript/shared/i18n.ts +build \ No newline at end of file diff --git a/README.md b/README.md index 85b2b832..d3dc0214 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,37 @@ -# Projectname +# Betterplace Design System -What it does nobody knows. +This is the repository for [betterplace](https://www.betterplace.org/)'s design system. -## Overview +The system uses [Storybook](https://storybook.js.org/) as a tool for developing a component library, guidelines and documentation, that work across all betterplace platforms. -Only needed if lengthy -- [🔧 Setup](#-1-Setup) -- [💻 Development](#-Development) - - [📦 Data model](#-Data-model) +## 🔧 Setup +1. `git clone git@github.com:betterplace/betterplace-design-system.git` +2. `cd betterplace-design-system` +3. `yarn install` +4. `yarn storybook` -## 🔧 1 Setup +## Dependencies -How to set it up. +See [.tool-versions](.tool-versions) -### ... +## 💻 Development -## Dependencies +### Scripts -## 💻 Development +| Command | Description | +| ---------------------- | ---------------------------------------- | +| `yarn storybook` | Start and open storybook in the browser. | +| `yarn build-storybook` | Build static storybook output. | +| `yarn build-tokens` | Generate all CSS variables from tokens. | + +### Design Tokens + +We use Design Tokens exported by [Figma Tokens](https://docs.tokens.studio/) and generate CSS variables from these tokens using [Style Dictionary](https://amzn.github.io/style-dictionary/#/). + +The tokens input file is located in [config/tokens.json](config/tokens.json) (the exported file from Figma). The generated output is located in the [build](build) folder. Each theme is generated into its own file with variables, that would override each other. This is by design, because we only include one of these at a time. For example, theme org would include [build/css/themes/org.css](build/css/themes/org.css). Additionally, a [globals.css](build/css/globals.css) is generated, which includes only unique global tokens. -You might want to link to an [Architectural overview](doc/architecture.md) -here, if you have one: +To re-generate tokens with style-dictionary, run the following command: `yarn build-tokens` ### 📦 Data model diff --git a/build/css/globals.css b/build/css/globals.css new file mode 100644 index 00000000..083c00f2 --- /dev/null +++ b/build/css/globals.css @@ -0,0 +1,187 @@ +/** + * Do not edit directly + * Generated on Thu, 12 May 2022 16:07:15 GMT + */ + +:root { + --betterplace-text-decoration-underline: underline; + --betterplace-text-decoration-none: none; + --betterplace-text-case-none: none; + --betterplace-paragraph-spacing-1: 0.5rem; + --betterplace-paragraph-spacing-0: 0rem; + --betterplace-letter-spacing-0: 0%; + --betterplace-font-size-5: 3.5rem; + --betterplace-font-size-4: 2rem; + --betterplace-font-size-3: 1.5rem; + --betterplace-font-size-2: 1.125rem; + --betterplace-font-size-1: 1rem; + --betterplace-font-size-0: 0.875rem; + --betterplace-font-weights-fira-sans-1: Bold; + --betterplace-font-weights-fira-sans-0: Regular; + --betterplace-line-heights-3: 140%; + --betterplace-line-heights-2: 130%; + --betterplace-line-heights-1: 110%; + --betterplace-line-heights-0: 120%; + --betterplace-font-families-fira-sans: 'Fira Sans'; + --betterplace-dropshadow-large: 0px 0px 24px 0px #00000029; + --betterplace-dropshadow-small: 0px 0px 16px 0px #00000014; + --betterplace-danger-red-800: #b11b3e; + --betterplace-danger-red-700: #d32b43; + --betterplace-danger-red-200: #ffc4c4; + --betterplace-warning-yellow-400: #f6ce46; + --betterplace-warning-yellow-100: #fff4d2; + --betterplace-tertiary-teal-800: #1e6761; + --betterplace-tertiary-teal-700: #2b8475; + --betterplace-tertiary-teal-500: #60b2a4; + --betterplace-secondary-me-blue-700: #005d90; + --betterplace-secondary-me-blue-500: #00a0c8; + --betterplace-secondary-me-blue-100: #e0f4f9; + --betterplace-secondary-purple-600: #6d2c64; + --betterplace-gray-900: #292929; + --betterplace-gray-700: #636363; + --betterplace-gray-300: #cccccc; + --betterplace-gray-200: #eeeeee; + --betterplace-gray-100: #f8f8f8; + --betterplace-shades-black: #000000; + --betterplace-shades-white: #ffffff; + --betterplace-newbrand-01-0-2-opacity: #30604933; + --betterplace-newbrand-activecolor: #43a4ba; + --betterplace-newbrand-pastell-6: #a4ffd3; + --betterplace-newbrand-pastell-5: #7bffbf; + --betterplace-newbrand-pastell-4: #7debb6; + --betterplace-newbrand-pastell-3: #67e1a6; + --betterplace-newbrand-pastell-2: #54d898; + --betterplace-newbrand-pastell-1: #47ba82; + --betterplace-newbrand-ruby-6: #17ff8f; + --betterplace-newbrand-ruby-5: #23e487; + --betterplace-newbrand-ruby-4: #00e476; + --betterplace-newbrand-ruby-3: #1dc976; + --betterplace-newbrand-ruby-2: #21bf73; + --betterplace-newbrand-ruby-1: #05bb63; + --betterplace-newbrand-dark-6: #3e8261; + --betterplace-newbrand-dark-5: #218756; + --betterplace-newbrand-dark-4: #017d41; + --betterplace-newbrand-dark-3: #006534; + --betterplace-newbrand-dark-2: #16603c; + --betterplace-newbrand-dark-1: #306049; + --betterplace-primary-me-orange-800: #6f1f06; + --betterplace-primary-me-orange-600: #db6038; + --betterplace-primary-me-orange-500: #ff854d; + --betterplace-primary-me-orange-100: #ffe3c2; + --betterplace-primary-green-800: #357c00; + --betterplace-primary-green-600: #85ac1c; + --betterplace-primary-green-500: #9ecb0a; + --betterplace-primary-green-100: #f5fccc; + --betterplace-link-underlined-text-decoration: var(--betterplace-text-decoration-underline); + --betterplace-link-underlined-text-case: var(--betterplace-text-case-none); + --betterplace-link-underlined-paragraph-spacing: var(--betterplace-paragraph-spacing-1); + --betterplace-link-underlined-letter-spacing: var(--betterplace-letter-spacing-0); + --betterplace-link-underlined-font-size: var(--betterplace-font-size-1); + --betterplace-link-underlined-line-height: var(--betterplace-line-heights-3); + --betterplace-link-underlined-font-weight: var(--betterplace-font-weights-fira-sans-1); + --betterplace-link-underlined-font-family: var(--betterplace-font-families-fira-sans); + --betterplace-small-text-bold-text-decoration: var(--betterplace-text-decoration-none); + --betterplace-small-text-bold-text-case: var(--betterplace-text-case-none); + --betterplace-small-text-bold-paragraph-spacing: var(--betterplace-paragraph-spacing-0); + --betterplace-small-text-bold-letter-spacing: var(--betterplace-letter-spacing-0); + --betterplace-small-text-bold-font-size: var(--betterplace-font-size-0); + --betterplace-small-text-bold-line-height: var(--betterplace-line-heights-2); + --betterplace-small-text-bold-font-weight: var(--betterplace-font-weights-fira-sans-1); + --betterplace-small-text-bold-font-family: var(--betterplace-font-families-fira-sans); + --betterplace-small-text-text-decoration: var(--betterplace-text-decoration-none); + --betterplace-small-text-text-case: var(--betterplace-text-case-none); + --betterplace-small-text-paragraph-spacing: var(--betterplace-paragraph-spacing-0); + --betterplace-small-text-letter-spacing: var(--betterplace-letter-spacing-0); + --betterplace-small-text-font-size: var(--betterplace-font-size-0); + --betterplace-small-text-line-height: var(--betterplace-line-heights-2); + --betterplace-small-text-font-weight: var(--betterplace-font-weights-fira-sans-0); + --betterplace-small-text-font-family: var(--betterplace-font-families-fira-sans); + --betterplace-link-text-decoration: var(--betterplace-text-decoration-none); + --betterplace-link-text-case: var(--betterplace-text-case-none); + --betterplace-link-paragraph-spacing: var(--betterplace-paragraph-spacing-0); + --betterplace-link-letter-spacing: var(--betterplace-letter-spacing-0); + --betterplace-link-font-size: var(--betterplace-font-size-1); + --betterplace-link-line-height: var(--betterplace-line-heights-3); + --betterplace-link-font-weight: var(--betterplace-font-weights-fira-sans-1); + --betterplace-link-font-family: var(--betterplace-font-families-fira-sans); + --betterplace-body-bold-text-decoration: var(--betterplace-text-decoration-none); + --betterplace-body-bold-text-case: var(--betterplace-text-case-none); + --betterplace-body-bold-paragraph-spacing: var(--betterplace-paragraph-spacing-1); + --betterplace-body-bold-letter-spacing: var(--betterplace-letter-spacing-0); + --betterplace-body-bold-font-size: var(--betterplace-font-size-1); + --betterplace-body-bold-line-height: var(--betterplace-line-heights-3); + --betterplace-body-bold-font-weight: var(--betterplace-font-weights-fira-sans-1); + --betterplace-body-bold-font-family: var(--betterplace-font-families-fira-sans); + --betterplace-body-text-decoration: var(--betterplace-text-decoration-none); + --betterplace-body-text-case: var(--betterplace-text-case-none); + --betterplace-body-paragraph-spacing: var(--betterplace-paragraph-spacing-1); + --betterplace-body-letter-spacing: var(--betterplace-letter-spacing-0); + --betterplace-body-font-size: var(--betterplace-font-size-1); + --betterplace-body-line-height: var(--betterplace-line-heights-3); + --betterplace-body-font-weight: var(--betterplace-font-weights-fira-sans-0); + --betterplace-body-font-family: var(--betterplace-font-families-fira-sans); + --betterplace-large-text-bold-text-decoration: var(--betterplace-text-decoration-none); + --betterplace-large-text-bold-text-case: var(--betterplace-text-case-none); + --betterplace-large-text-bold-paragraph-spacing: var(--betterplace-paragraph-spacing-0); + --betterplace-large-text-bold-letter-spacing: var(--betterplace-letter-spacing-0); + --betterplace-large-text-bold-font-size: var(--betterplace-font-size-2); + --betterplace-large-text-bold-line-height: var(--betterplace-line-heights-3); + --betterplace-large-text-bold-font-weight: var(--betterplace-font-weights-fira-sans-1); + --betterplace-large-text-bold-font-family: var(--betterplace-font-families-fira-sans); + --betterplace-large-text-text-decoration: var(--betterplace-text-decoration-none); + --betterplace-large-text-text-case: var(--betterplace-text-case-none); + --betterplace-large-text-paragraph-spacing: var(--betterplace-paragraph-spacing-0); + --betterplace-large-text-letter-spacing: var(--betterplace-letter-spacing-0); + --betterplace-large-text-font-size: var(--betterplace-font-size-2); + --betterplace-large-text-line-height: var(--betterplace-line-heights-3); + --betterplace-large-text-font-weight: var(--betterplace-font-weights-fira-sans-0); + --betterplace-large-text-font-family: var(--betterplace-font-families-fira-sans); + --betterplace-x-large-bold-text-decoration: var(--betterplace-text-decoration-none); + --betterplace-x-large-bold-text-case: var(--betterplace-text-case-none); + --betterplace-x-large-bold-paragraph-spacing: var(--betterplace-paragraph-spacing-0); + --betterplace-x-large-bold-letter-spacing: var(--betterplace-letter-spacing-0); + --betterplace-x-large-bold-font-size: var(--betterplace-font-size-3); + --betterplace-x-large-bold-line-height: var(--betterplace-line-heights-2); + --betterplace-x-large-bold-font-weight: var(--betterplace-font-weights-fira-sans-1); + --betterplace-x-large-bold-font-family: var(--betterplace-font-families-fira-sans); + --betterplace-x-large-text-decoration: var(--betterplace-text-decoration-none); + --betterplace-x-large-text-case: var(--betterplace-text-case-none); + --betterplace-x-large-paragraph-spacing: var(--betterplace-paragraph-spacing-0); + --betterplace-x-large-letter-spacing: var(--betterplace-letter-spacing-0); + --betterplace-x-large-font-size: var(--betterplace-font-size-3); + --betterplace-x-large-line-height: var(--betterplace-line-heights-2); + --betterplace-x-large-font-weight: var(--betterplace-font-weights-fira-sans-0); + --betterplace-x-large-font-family: var(--betterplace-font-families-fira-sans); + --betterplace-xx-large-bold-text-decoration: var(--betterplace-text-decoration-none); + --betterplace-xx-large-bold-text-case: var(--betterplace-text-case-none); + --betterplace-xx-large-bold-paragraph-spacing: var(--betterplace-paragraph-spacing-0); + --betterplace-xx-large-bold-letter-spacing: var(--betterplace-letter-spacing-0); + --betterplace-xx-large-bold-font-size: var(--betterplace-font-size-4); + --betterplace-xx-large-bold-line-height: var(--betterplace-line-heights-0); + --betterplace-xx-large-bold-font-weight: var(--betterplace-font-weights-fira-sans-1); + --betterplace-xx-large-bold-font-family: var(--betterplace-font-families-fira-sans); + --betterplace-xx-large-text-decoration: var(--betterplace-text-decoration-none); + --betterplace-xx-large-text-case: var(--betterplace-text-case-none); + --betterplace-xx-large-paragraph-spacing: var(--betterplace-paragraph-spacing-0); + --betterplace-xx-large-letter-spacing: var(--betterplace-letter-spacing-0); + --betterplace-xx-large-font-size: var(--betterplace-font-size-4); + --betterplace-xx-large-line-height: var(--betterplace-line-heights-0); + --betterplace-xx-large-font-weight: var(--betterplace-font-weights-fira-sans-0); + --betterplace-xx-large-font-family: var(--betterplace-font-families-fira-sans); + --betterplace-xxx-large-bold-text-decoration: var(--betterplace-text-decoration-none); + --betterplace-xxx-large-bold-text-case: var(--betterplace-text-case-none); + --betterplace-xxx-large-bold-paragraph-spacing: var(--betterplace-paragraph-spacing-0); + --betterplace-xxx-large-bold-letter-spacing: var(--betterplace-letter-spacing-0); + --betterplace-xxx-large-bold-font-size: var(--betterplace-font-size-5); + --betterplace-xxx-large-bold-line-height: var(--betterplace-line-heights-1); + --betterplace-xxx-large-bold-font-weight: var(--betterplace-font-weights-fira-sans-1); + --betterplace-xxx-large-bold-font-family: var(--betterplace-font-families-fira-sans); + --betterplace-xxx-large-text-decoration: var(--betterplace-text-decoration-none); + --betterplace-xxx-large-text-case: var(--betterplace-text-case-none); + --betterplace-xxx-large-paragraph-spacing: var(--betterplace-paragraph-spacing-0); + --betterplace-xxx-large-letter-spacing: var(--betterplace-letter-spacing-0); + --betterplace-xxx-large-font-size: var(--betterplace-font-size-5); + --betterplace-xxx-large-line-height: var(--betterplace-line-heights-0); + --betterplace-xxx-large-font-weight: var(--betterplace-font-weights-fira-sans-0); + --betterplace-xxx-large-font-family: var(--betterplace-font-families-fira-sans); +} diff --git a/build/css/themes/at.css b/build/css/themes/at.css new file mode 100644 index 00000000..b8979aa5 --- /dev/null +++ b/build/css/themes/at.css @@ -0,0 +1,9 @@ +/** + * Do not edit directly + * Generated on Thu, 12 May 2022 16:07:15 GMT + */ + +:root { + --betterplace-color-secondary: var(--betterplace-secondary-purple-600); + --betterplace-color-primary: var(--betterplace-primary-green-800); +} diff --git a/build/css/themes/me.css b/build/css/themes/me.css new file mode 100644 index 00000000..494b2c8b --- /dev/null +++ b/build/css/themes/me.css @@ -0,0 +1,9 @@ +/** + * Do not edit directly + * Generated on Thu, 12 May 2022 16:07:15 GMT + */ + +:root { + --betterplace-color-secondary: var(--betterplace-secondary-me-blue-500); + --betterplace-color-primary: var(--betterplace-primary-me-orange-500); +} diff --git a/build/css/themes/org.css b/build/css/themes/org.css new file mode 100644 index 00000000..45f5517e --- /dev/null +++ b/build/css/themes/org.css @@ -0,0 +1,9 @@ +/** + * Do not edit directly + * Generated on Thu, 12 May 2022 16:07:15 GMT + */ + +:root { + --betterplace-color-secondary: var(--betterplace-tertiary-teal-500); + --betterplace-color-primary: var(--betterplace-primary-green-500); +} diff --git a/build/json/globals.json b/build/json/globals.json new file mode 100644 index 00000000..c5f85070 --- /dev/null +++ b/build/json/globals.json @@ -0,0 +1,182 @@ +{ + "betterplace-primary-green-100": "#f5fccc", + "betterplace-primary-green-500": "#9ecb0a", + "betterplace-primary-green-600": "#85ac1c", + "betterplace-primary-green-800": "#357c00", + "betterplace-primary-me-orange-100": "#ffe3c2", + "betterplace-primary-me-orange-500": "#ff854d", + "betterplace-primary-me-orange-600": "#db6038", + "betterplace-primary-me-orange-800": "#6f1f06", + "betterplace-newbrand-dark-1": "#306049", + "betterplace-newbrand-dark-2": "#16603c", + "betterplace-newbrand-dark-3": "#006534", + "betterplace-newbrand-dark-4": "#017d41", + "betterplace-newbrand-dark-5": "#218756", + "betterplace-newbrand-dark-6": "#3e8261", + "betterplace-newbrand-ruby-1": "#05bb63", + "betterplace-newbrand-ruby-2": "#21bf73", + "betterplace-newbrand-ruby-3": "#1dc976", + "betterplace-newbrand-ruby-4": "#00e476", + "betterplace-newbrand-ruby-5": "#23e487", + "betterplace-newbrand-ruby-6": "#17ff8f", + "betterplace-newbrand-pastell-1": "#47ba82", + "betterplace-newbrand-pastell-2": "#54d898", + "betterplace-newbrand-pastell-3": "#67e1a6", + "betterplace-newbrand-pastell-4": "#7debb6", + "betterplace-newbrand-pastell-5": "#7bffbf", + "betterplace-newbrand-pastell-6": "#a4ffd3", + "betterplace-newbrand-activecolor": "#43a4ba", + "betterplace-newbrand-01-0-2-opacity": "#30604933", + "betterplace-shades-white": "#ffffff", + "betterplace-shades-black": "#000000", + "betterplace-gray-100": "#f8f8f8", + "betterplace-gray-200": "#eeeeee", + "betterplace-gray-300": "#cccccc", + "betterplace-gray-700": "#636363", + "betterplace-gray-900": "#292929", + "betterplace-secondary-purple-600": "#6d2c64", + "betterplace-secondary-me-blue-100": "#e0f4f9", + "betterplace-secondary-me-blue-500": "#00a0c8", + "betterplace-secondary-me-blue-700": "#005d90", + "betterplace-tertiary-teal-500": "#60b2a4", + "betterplace-tertiary-teal-700": "#2b8475", + "betterplace-tertiary-teal-800": "#1e6761", + "betterplace-warning-yellow-100": "#fff4d2", + "betterplace-warning-yellow-400": "#f6ce46", + "betterplace-danger-red-200": "#ffc4c4", + "betterplace-danger-red-700": "#d32b43", + "betterplace-danger-red-800": "#b11b3e", + "betterplace-dropshadow-small": "0px 0px 16px 0px #00000014", + "betterplace-dropshadow-large": "0px 0px 24px 0px #00000029", + "betterplace-font-families-fira-sans": "Fira Sans", + "betterplace-line-heights-0": "120%", + "betterplace-line-heights-1": "110%", + "betterplace-line-heights-2": "130%", + "betterplace-line-heights-3": "140%", + "betterplace-font-weights-fira-sans-0": "Regular", + "betterplace-font-weights-fira-sans-1": "Bold", + "betterplace-font-size-0": "0.875rem", + "betterplace-font-size-1": "1rem", + "betterplace-font-size-2": "1.125rem", + "betterplace-font-size-3": "1.5rem", + "betterplace-font-size-4": "2rem", + "betterplace-font-size-5": "3.5rem", + "betterplace-letter-spacing-0": "0%", + "betterplace-paragraph-spacing-0": "0rem", + "betterplace-paragraph-spacing-1": "0.5rem", + "betterplace-xxx-large-font-family": "Fira Sans", + "betterplace-xxx-large-font-weight": "Regular", + "betterplace-xxx-large-line-height": "120%", + "betterplace-xxx-large-font-size": "3.5rem", + "betterplace-xxx-large-letter-spacing": "0%", + "betterplace-xxx-large-paragraph-spacing": "0rem", + "betterplace-xxx-large-text-case": "none", + "betterplace-xxx-large-text-decoration": "none", + "betterplace-xxx-large-bold-font-family": "Fira Sans", + "betterplace-xxx-large-bold-font-weight": "Bold", + "betterplace-xxx-large-bold-line-height": "110%", + "betterplace-xxx-large-bold-font-size": "3.5rem", + "betterplace-xxx-large-bold-letter-spacing": "0%", + "betterplace-xxx-large-bold-paragraph-spacing": "0rem", + "betterplace-xxx-large-bold-text-case": "none", + "betterplace-xxx-large-bold-text-decoration": "none", + "betterplace-xx-large-font-family": "Fira Sans", + "betterplace-xx-large-font-weight": "Regular", + "betterplace-xx-large-line-height": "120%", + "betterplace-xx-large-font-size": "2rem", + "betterplace-xx-large-letter-spacing": "0%", + "betterplace-xx-large-paragraph-spacing": "0rem", + "betterplace-xx-large-text-case": "none", + "betterplace-xx-large-text-decoration": "none", + "betterplace-xx-large-bold-font-family": "Fira Sans", + "betterplace-xx-large-bold-font-weight": "Bold", + "betterplace-xx-large-bold-line-height": "120%", + "betterplace-xx-large-bold-font-size": "2rem", + "betterplace-xx-large-bold-letter-spacing": "0%", + "betterplace-xx-large-bold-paragraph-spacing": "0rem", + "betterplace-xx-large-bold-text-case": "none", + "betterplace-xx-large-bold-text-decoration": "none", + "betterplace-x-large-font-family": "Fira Sans", + "betterplace-x-large-font-weight": "Regular", + "betterplace-x-large-line-height": "130%", + "betterplace-x-large-font-size": "1.5rem", + "betterplace-x-large-letter-spacing": "0%", + "betterplace-x-large-paragraph-spacing": "0rem", + "betterplace-x-large-text-case": "none", + "betterplace-x-large-text-decoration": "none", + "betterplace-x-large-bold-font-family": "Fira Sans", + "betterplace-x-large-bold-font-weight": "Bold", + "betterplace-x-large-bold-line-height": "130%", + "betterplace-x-large-bold-font-size": "1.5rem", + "betterplace-x-large-bold-letter-spacing": "0%", + "betterplace-x-large-bold-paragraph-spacing": "0rem", + "betterplace-x-large-bold-text-case": "none", + "betterplace-x-large-bold-text-decoration": "none", + "betterplace-large-text-font-family": "Fira Sans", + "betterplace-large-text-font-weight": "Regular", + "betterplace-large-text-line-height": "140%", + "betterplace-large-text-font-size": "1.125rem", + "betterplace-large-text-letter-spacing": "0%", + "betterplace-large-text-paragraph-spacing": "0rem", + "betterplace-large-text-text-case": "none", + "betterplace-large-text-text-decoration": "none", + "betterplace-large-text-bold-font-family": "Fira Sans", + "betterplace-large-text-bold-font-weight": "Bold", + "betterplace-large-text-bold-line-height": "140%", + "betterplace-large-text-bold-font-size": "1.125rem", + "betterplace-large-text-bold-letter-spacing": "0%", + "betterplace-large-text-bold-paragraph-spacing": "0rem", + "betterplace-large-text-bold-text-case": "none", + "betterplace-large-text-bold-text-decoration": "none", + "betterplace-body-font-family": "Fira Sans", + "betterplace-body-font-weight": "Regular", + "betterplace-body-line-height": "140%", + "betterplace-body-font-size": "1rem", + "betterplace-body-letter-spacing": "0%", + "betterplace-body-paragraph-spacing": "0.5rem", + "betterplace-body-text-case": "none", + "betterplace-body-text-decoration": "none", + "betterplace-body-bold-font-family": "Fira Sans", + "betterplace-body-bold-font-weight": "Bold", + "betterplace-body-bold-line-height": "140%", + "betterplace-body-bold-font-size": "1rem", + "betterplace-body-bold-letter-spacing": "0%", + "betterplace-body-bold-paragraph-spacing": "0.5rem", + "betterplace-body-bold-text-case": "none", + "betterplace-body-bold-text-decoration": "none", + "betterplace-link-font-family": "Fira Sans", + "betterplace-link-font-weight": "Bold", + "betterplace-link-line-height": "140%", + "betterplace-link-font-size": "1rem", + "betterplace-link-letter-spacing": "0%", + "betterplace-link-paragraph-spacing": "0rem", + "betterplace-link-text-case": "none", + "betterplace-link-text-decoration": "none", + "betterplace-small-text-font-family": "Fira Sans", + "betterplace-small-text-font-weight": "Regular", + "betterplace-small-text-line-height": "130%", + "betterplace-small-text-font-size": "0.875rem", + "betterplace-small-text-letter-spacing": "0%", + "betterplace-small-text-paragraph-spacing": "0rem", + "betterplace-small-text-text-case": "none", + "betterplace-small-text-text-decoration": "none", + "betterplace-small-text-bold-font-family": "Fira Sans", + "betterplace-small-text-bold-font-weight": "Bold", + "betterplace-small-text-bold-line-height": "130%", + "betterplace-small-text-bold-font-size": "0.875rem", + "betterplace-small-text-bold-letter-spacing": "0%", + "betterplace-small-text-bold-paragraph-spacing": "0rem", + "betterplace-small-text-bold-text-case": "none", + "betterplace-small-text-bold-text-decoration": "none", + "betterplace-link-underlined-font-family": "Fira Sans", + "betterplace-link-underlined-font-weight": "Bold", + "betterplace-link-underlined-line-height": "140%", + "betterplace-link-underlined-font-size": "1rem", + "betterplace-link-underlined-letter-spacing": "0%", + "betterplace-link-underlined-paragraph-spacing": "0.5rem", + "betterplace-link-underlined-text-case": "none", + "betterplace-link-underlined-text-decoration": "underline", + "betterplace-text-case-none": "none", + "betterplace-text-decoration-none": "none", + "betterplace-text-decoration-underline": "underline" +} \ No newline at end of file diff --git a/build/json/themes/at.json b/build/json/themes/at.json new file mode 100644 index 00000000..15281f36 --- /dev/null +++ b/build/json/themes/at.json @@ -0,0 +1,4 @@ +{ + "betterplace-color-primary": "#357c00", + "betterplace-color-secondary": "#6d2c64" +} \ No newline at end of file diff --git a/build/json/themes/me.json b/build/json/themes/me.json new file mode 100644 index 00000000..ac3f863e --- /dev/null +++ b/build/json/themes/me.json @@ -0,0 +1,4 @@ +{ + "betterplace-color-primary": "#ff854d", + "betterplace-color-secondary": "#00a0c8" +} \ No newline at end of file diff --git a/build/json/themes/org.json b/build/json/themes/org.json new file mode 100644 index 00000000..679fb61b --- /dev/null +++ b/build/json/themes/org.json @@ -0,0 +1,4 @@ +{ + "betterplace-color-primary": "#9ecb0a", + "betterplace-color-secondary": "#60b2a4" +} \ No newline at end of file diff --git a/config/sd.config.js b/config/sd.config.js new file mode 100644 index 00000000..1a0b25fb --- /dev/null +++ b/config/sd.config.js @@ -0,0 +1,50 @@ +const themes = require('./themes.json') +require('./sd/transforms.js') +require('./sd/transformGroups.js') +require('./sd/parsers.js') + +const getFileConfig = (platform, format) => { + const themeFiles = themes.map((theme) => ({ + destination: `themes/${theme}.${platform}`, + format: format, + filter: (token) => { + return token.attributes.category === theme + }, + })) + + const globalFile = { + destination: `globals.${platform}`, + format: format, + filter: (token) => { + // all non-theme tokens are considered globals + return !themes.includes(token.attributes.category) + }, + } + + return [...themeFiles, globalFile] +} + +module.exports = { + source: ['config/tokens.json'], + platforms: { + css: { + transformGroup: 'custom/css', + prefix: 'betterplace', + buildPath: 'build/css/', + files: getFileConfig('css', 'css/variables'), + options: { + // if we want to only include the theme specific variables we would need to set this to false + outputReferences: true, + }, + }, + json: { + transformGroup: 'custom/json', + prefix: 'betterplace', + buildPath: 'build/json/', + files: getFileConfig('json', 'json/flat'), + options: { + outputReferences: true, + }, + }, + }, +} diff --git a/config/sd/parsers.js b/config/sd/parsers.js new file mode 100644 index 00000000..c62878e5 --- /dev/null +++ b/config/sd/parsers.js @@ -0,0 +1,26 @@ +const StyleDictionary = require('style-dictionary') +const themes = require('../themes.json') + +StyleDictionary.registerParser({ + pattern: /\.json$/, + parse: ({ contents }) => { + // replace the old reference syntax with the one style-dictionary understands + // e.g. "$fontFamilies.fira-sans" -> "{fontFamilies.fira-sans}" + // see https://docs.tokens.studio/tokens/aliases + const tokens = JSON.parse(contents.replace(/\$([^"]+)/g, `{$1}`)) + + // strip away the global key for global token set but keep the themes nested + // this is necessary, because the references from Figma Tokens do not include the token set key + // e.g. {Primary.Green 800} would not work + let transformedTokens = tokens['global'] + + Object.keys(tokens).forEach((set) => { + // only add the token set if it is defined as a valid theme + if (themes.includes(set)) { + transformedTokens[set] = tokens[set] + } + }) + + return transformedTokens + }, +}) diff --git a/config/sd/transformGroups.js b/config/sd/transformGroups.js new file mode 100644 index 00000000..c53b5dcf --- /dev/null +++ b/config/sd/transformGroups.js @@ -0,0 +1,23 @@ +const StyleDictionary = require('style-dictionary') + +StyleDictionary.registerTransformGroup({ + name: 'custom/css', + transforms: [ + ...StyleDictionary.transformGroup['web'], + 'name/theme', + 'size/pxToRem', + 'value/quote', + 'value/boxShadow', + ], +}) + +StyleDictionary.registerTransformGroup({ + name: 'custom/json', + transforms: [ + ...StyleDictionary.transformGroup['js'], + 'name/cti/kebab', + 'name/theme', + 'size/pxToRem', + 'value/boxShadow', + ], +}) diff --git a/config/sd/transforms.js b/config/sd/transforms.js new file mode 100644 index 00000000..39cae038 --- /dev/null +++ b/config/sd/transforms.js @@ -0,0 +1,72 @@ +const StyleDictionary = require('style-dictionary') +const themes = require('../themes.json') + +// remove the theme key from the alias name +StyleDictionary.registerTransform({ + name: 'name/theme', + type: 'name', + matcher: function (token) { + return themes.includes(token.attributes.category) + }, + transformer: function (token) { + const regex = new RegExp(token.attributes.category, 'ig') + return token.name.replace(regex, '').replace('--', '-') + }, +}) + +// convert px values to rem values +StyleDictionary.registerTransform({ + name: 'size/pxToRem', + type: 'value', + matcher: function (token) { + return ['fontSizes', 'paragraphSpacing'].includes(token.type) + }, + transformer: function (token) { + return (parseInt(token.original.value) / 16).toString() + 'rem' + }, +}) + +// quote values +StyleDictionary.registerTransform({ + name: 'value/quote', + type: 'value', + matcher: function (token) { + return ['fontFamilies'].includes(token.type) + }, + transformer: function (token) { + return `'${token.original.value}'` + }, +}) + +// shadows +StyleDictionary.registerTransform({ + name: 'value/boxShadow', + type: 'value', + matcher: function (token) { + return token.type === 'boxShadow' + }, + transformer: function (token) { + return `${token.original.value.x}px ${token.original.value.y}px ${token.original.value.blur}px ${token.original.value.spread}px ${token.original.value.color}` + }, +}) + +// TODO: output typography styles as mixin +StyleDictionary.registerTransform({ + name: 'value/typography', + type: 'value', + matcher: function (token) { + return token.type === 'typography' + }, + transformer: function (token) { + console.log(token) + return `{ + font-family: ${token.value.fontFamily}; + font-size: ${token.value.fontSize}; + font-weight: ${token.value.fontWeight}; + line-height: ${token.value.lineHeight}; + letter-spacing: ${token.value.letterSpacing}; + text-transform: ${token.value.textCase}; + text-decoration: ${token.value.textDecoration}; + }` + }, +}) diff --git a/config/themes.json b/config/themes.json new file mode 100644 index 00000000..b306adf4 --- /dev/null +++ b/config/themes.json @@ -0,0 +1 @@ +["at", "me", "org"] diff --git a/config/tokens.json b/config/tokens.json new file mode 100644 index 00000000..3567f62e --- /dev/null +++ b/config/tokens.json @@ -0,0 +1,866 @@ +{ + "global": { + "Primary": { + "Green 100": { + "value": "#f5fccc", + "type": "color", + "description": "Background Success-Messages, Secondary-button hover" + }, + "Green 500": { + "value": "#9ecb0a", + "type": "color", + "description": "Buttons, Brand Color, bg color section" + }, + "Green 600": { + "value": "#85ac1c", + "type": "color", + "description": "Hover" + }, + "Green 800": { + "value": "#357c00", + "type": "color", + "description": "Links, Secondary-button outline " + }, + "me": { + "Orange 100": { + "value": "#ffe3c2", + "type": "color", + "description": "Background color" + }, + "Orange 500": { + "value": "#ff854d", + "type": "color", + "description": "Primary Color " + }, + "Orange 600": { + "value": "#db6038", + "type": "color", + "description": "Primary butto hover" + }, + "Orange 800": { + "value": "#6f1f06", + "type": "color", + "description": "Button label hover" + } + } + }, + "newbrand": { + "Dark 1": { + "value": "#306049", + "type": "color" + }, + "Dark 2": { + "value": "#16603c", + "type": "color" + }, + "Dark 3": { + "value": "#006534", + "type": "color" + }, + "Dark 4": { + "value": "#017d41", + "type": "color" + }, + "Dark 5": { + "value": "#218756", + "type": "color" + }, + "Dark 6": { + "value": "#3e8261", + "type": "color" + }, + "Ruby 1": { + "value": "#05bb63", + "type": "color" + }, + "Ruby 2": { + "value": "#21bf73", + "type": "color" + }, + "Ruby 3": { + "value": "#1dc976", + "type": "color" + }, + "Ruby 4": { + "value": "#00e476", + "type": "color" + }, + "Ruby 5": { + "value": "#23e487", + "type": "color" + }, + "Ruby 6": { + "value": "#17ff8f", + "type": "color" + }, + "Pastell 1": { + "value": "#47ba82", + "type": "color" + }, + "Pastell 2": { + "value": "#54d898", + "type": "color" + }, + "Pastell 3": { + "value": "#67e1a6", + "type": "color" + }, + "Pastell 4": { + "value": "#7debb6", + "type": "color" + }, + "Pastell 5": { + "value": "#7bffbf", + "type": "color" + }, + "Pastell 6": { + "value": "#a4ffd3", + "type": "color" + }, + "activecolor": { + "value": "#43a4ba", + "type": "color" + }, + "01": { + "0": { + "2 opacity": { + "value": "#30604933", + "type": "color" + } + } + } + }, + "Shades": { + "White": { + "value": "#ffffff", + "type": "color" + }, + "Black": { + "value": "#000000", + "type": "color" + } + }, + "Gray": { + "100": { + "value": "#f8f8f8", + "type": "color", + "description": "Admin box" + }, + "200": { + "value": "#eeeeee", + "type": "color", + "description": "Background" + }, + "300": { + "value": "#cccccc", + "type": "color", + "description": "Outline" + }, + "700": { + "value": "#636363", + "type": "color" + }, + "900": { + "value": "#292929", + "type": "color", + "description": "Textcolor" + } + }, + "Secondary": { + "Purple 600": { + "value": "#6d2c64", + "type": "color" + }, + "me": { + "Blue 100": { + "value": "#e0f4f9", + "type": "color", + "description": "Background" + }, + "Blue 500": { + "value": "#00a0c8", + "type": "color", + "description": "Highlights" + }, + "Blue 700": { + "value": "#005d90", + "type": "color", + "description": "Footer" + } + } + }, + "Tertiary": { + "Teal 500": { + "value": "#60b2a4", + "type": "color", + "description": "Background for Form which are not in Manage-area" + }, + "Teal 700": { + "value": "#2b8475", + "type": "color", + "description": "Admin main color" + }, + "Teal 800": { + "value": "#1e6761", + "type": "color", + "description": "Hover admin area" + } + }, + "Warning": { + "Yellow 100": { + "value": "#fff4d2", + "type": "color", + "description": "Background Warning Messages" + }, + "Yellow 400": { + "value": "#f6ce46", + "type": "color" + } + }, + "Danger": { + "Red 200": { + "value": "#ffc4c4", + "type": "color", + "description": "Background Error Messages" + }, + "Red 700": { + "value": "#d32b43", + "type": "color", + "description": "Error font color " + }, + "Red 800": { + "value": "#b11b3e", + "type": "color", + "description": "Error hover color" + } + }, + "Dropshadow": { + "small": { + "value": { + "color": "#00000014", + "type": "dropShadow", + "x": 0, + "y": 0, + "blur": 16, + "spread": 0 + }, + "type": "boxShadow" + }, + "large": { + "value": { + "color": "#00000029", + "type": "dropShadow", + "x": 0, + "y": 0, + "blur": 24, + "spread": 0 + }, + "type": "boxShadow" + } + }, + "fontFamilies": { + "fira-sans": { + "value": "Fira Sans", + "type": "fontFamilies" + } + }, + "lineHeights": { + "0": { + "value": "120%", + "type": "lineHeights" + }, + "1": { + "value": "110%", + "type": "lineHeights" + }, + "2": { + "value": "130%", + "type": "lineHeights" + }, + "3": { + "value": "140%", + "type": "lineHeights" + } + }, + "fontWeights": { + "fira-sans-0": { + "value": "Regular", + "type": "fontWeights" + }, + "fira-sans-1": { + "value": "Bold", + "type": "fontWeights" + } + }, + "fontSize": { + "0": { + "value": "14", + "type": "fontSizes" + }, + "1": { + "value": "16", + "type": "fontSizes" + }, + "2": { + "value": "18", + "type": "fontSizes" + }, + "3": { + "value": "24", + "type": "fontSizes" + }, + "4": { + "value": "32", + "type": "fontSizes" + }, + "5": { + "value": "56", + "type": "fontSizes" + } + }, + "letterSpacing": { + "0": { + "value": "0%", + "type": "letterSpacing" + } + }, + "paragraphSpacing": { + "0": { + "value": "0", + "type": "paragraphSpacing" + }, + "1": { + "value": "8", + "type": "paragraphSpacing" + } + }, + "XXX-Large": { + "fontFamily": { + "value": "$fontFamilies.fira-sans", + "type": "fontFamily" + }, + "fontWeight": { + "value": "$fontWeights.fira-sans-0", + "type": "fontWeight" + }, + "lineHeight": { + "value": "$lineHeights.0", + "type": "lineHeight" + }, + "fontSize": { + "value": "$fontSize.5", + "type": "fontSize" + }, + "letterSpacing": { + "value": "$letterSpacing.0", + "type": "letterSpacing" + }, + "paragraphSpacing": { + "value": "$paragraphSpacing.0", + "type": "paragraphSpacing" + }, + "textCase": { + "value": "$textCase.none", + "type": "textCase" + }, + "textDecoration": { + "value": "$textDecoration.none", + "type": "textDecoration" + } + }, + "XXX-Large Bold": { + "fontFamily": { + "value": "$fontFamilies.fira-sans", + "type": "fontFamily" + }, + "fontWeight": { + "value": "$fontWeights.fira-sans-1", + "type": "fontWeight" + }, + "lineHeight": { + "value": "$lineHeights.1", + "type": "lineHeight" + }, + "fontSize": { + "value": "$fontSize.5", + "type": "fontSize" + }, + "letterSpacing": { + "value": "$letterSpacing.0", + "type": "letterSpacing" + }, + "paragraphSpacing": { + "value": "$paragraphSpacing.0", + "type": "paragraphSpacing" + }, + "textCase": { + "value": "$textCase.none", + "type": "textCase" + }, + "textDecoration": { + "value": "$textDecoration.none", + "type": "textDecoration" + } + }, + "XX-Large": { + "fontFamily": { + "value": "$fontFamilies.fira-sans", + "type": "fontFamily" + }, + "fontWeight": { + "value": "$fontWeights.fira-sans-0", + "type": "fontWeight" + }, + "lineHeight": { + "value": "$lineHeights.0", + "type": "lineHeight" + }, + "fontSize": { + "value": "$fontSize.4", + "type": "fontSize" + }, + "letterSpacing": { + "value": "$letterSpacing.0", + "type": "letterSpacing" + }, + "paragraphSpacing": { + "value": "$paragraphSpacing.0", + "type": "paragraphSpacing" + }, + "textCase": { + "value": "$textCase.none", + "type": "textCase" + }, + "textDecoration": { + "value": "$textDecoration.none", + "type": "textDecoration" + } + }, + "XX-Large Bold": { + "fontFamily": { + "value": "$fontFamilies.fira-sans", + "type": "fontFamily" + }, + "fontWeight": { + "value": "$fontWeights.fira-sans-1", + "type": "fontWeight" + }, + "lineHeight": { + "value": "$lineHeights.0", + "type": "lineHeight" + }, + "fontSize": { + "value": "$fontSize.4", + "type": "fontSize" + }, + "letterSpacing": { + "value": "$letterSpacing.0", + "type": "letterSpacing" + }, + "paragraphSpacing": { + "value": "$paragraphSpacing.0", + "type": "paragraphSpacing" + }, + "textCase": { + "value": "$textCase.none", + "type": "textCase" + }, + "textDecoration": { + "value": "$textDecoration.none", + "type": "textDecoration" + } + }, + "X-Large": { + "fontFamily": { + "value": "$fontFamilies.fira-sans", + "type": "fontFamily" + }, + "fontWeight": { + "value": "$fontWeights.fira-sans-0", + "type": "fontWeight" + }, + "lineHeight": { + "value": "$lineHeights.2", + "type": "lineHeight" + }, + "fontSize": { + "value": "$fontSize.3", + "type": "fontSize" + }, + "letterSpacing": { + "value": "$letterSpacing.0", + "type": "letterSpacing" + }, + "paragraphSpacing": { + "value": "$paragraphSpacing.0", + "type": "paragraphSpacing" + }, + "textCase": { + "value": "$textCase.none", + "type": "textCase" + }, + "textDecoration": { + "value": "$textDecoration.none", + "type": "textDecoration" + } + }, + "X-Large Bold": { + "fontFamily": { + "value": "$fontFamilies.fira-sans", + "type": "fontFamily" + }, + "fontWeight": { + "value": "$fontWeights.fira-sans-1", + "type": "fontWeight" + }, + "lineHeight": { + "value": "$lineHeights.2", + "type": "lineHeight" + }, + "fontSize": { + "value": "$fontSize.3", + "type": "fontSize" + }, + "letterSpacing": { + "value": "$letterSpacing.0", + "type": "letterSpacing" + }, + "paragraphSpacing": { + "value": "$paragraphSpacing.0", + "type": "paragraphSpacing" + }, + "textCase": { + "value": "$textCase.none", + "type": "textCase" + }, + "textDecoration": { + "value": "$textDecoration.none", + "type": "textDecoration" + } + }, + "Large text": { + "fontFamily": { + "value": "$fontFamilies.fira-sans", + "type": "fontFamily" + }, + "fontWeight": { + "value": "$fontWeights.fira-sans-0", + "type": "fontWeight" + }, + "lineHeight": { + "value": "$lineHeights.3", + "type": "lineHeight" + }, + "fontSize": { + "value": "$fontSize.2", + "type": "fontSize" + }, + "letterSpacing": { + "value": "$letterSpacing.0", + "type": "letterSpacing" + }, + "paragraphSpacing": { + "value": "$paragraphSpacing.0", + "type": "paragraphSpacing" + }, + "textCase": { + "value": "$textCase.none", + "type": "textCase" + }, + "textDecoration": { + "value": "$textDecoration.none", + "type": "textDecoration" + } + }, + "Large Text Bold": { + "fontFamily": { + "value": "$fontFamilies.fira-sans", + "type": "fontFamily" + }, + "fontWeight": { + "value": "$fontWeights.fira-sans-1", + "type": "fontWeight" + }, + "lineHeight": { + "value": "$lineHeights.3", + "type": "lineHeight" + }, + "fontSize": { + "value": "$fontSize.2", + "type": "fontSize" + }, + "letterSpacing": { + "value": "$letterSpacing.0", + "type": "letterSpacing" + }, + "paragraphSpacing": { + "value": "$paragraphSpacing.0", + "type": "paragraphSpacing" + }, + "textCase": { + "value": "$textCase.none", + "type": "textCase" + }, + "textDecoration": { + "value": "$textDecoration.none", + "type": "textDecoration" + } + }, + "Body": { + "fontFamily": { + "value": "$fontFamilies.fira-sans", + "type": "fontFamily" + }, + "fontWeight": { + "value": "$fontWeights.fira-sans-0", + "type": "fontWeight" + }, + "lineHeight": { + "value": "$lineHeights.3", + "type": "lineHeight" + }, + "fontSize": { + "value": "$fontSize.1", + "type": "fontSize" + }, + "letterSpacing": { + "value": "$letterSpacing.0", + "type": "letterSpacing" + }, + "paragraphSpacing": { + "value": "$paragraphSpacing.1", + "type": "paragraphSpacing" + }, + "textCase": { + "value": "$textCase.none", + "type": "textCase" + }, + "textDecoration": { + "value": "$textDecoration.none", + "type": "textDecoration" + } + }, + "Body Bold": { + "fontFamily": { + "value": "$fontFamilies.fira-sans", + "type": "fontFamily" + }, + "fontWeight": { + "value": "$fontWeights.fira-sans-1", + "type": "fontWeight" + }, + "lineHeight": { + "value": "$lineHeights.3", + "type": "lineHeight" + }, + "fontSize": { + "value": "$fontSize.1", + "type": "fontSize" + }, + "letterSpacing": { + "value": "$letterSpacing.0", + "type": "letterSpacing" + }, + "paragraphSpacing": { + "value": "$paragraphSpacing.1", + "type": "paragraphSpacing" + }, + "textCase": { + "value": "$textCase.none", + "type": "textCase" + }, + "textDecoration": { + "value": "$textDecoration.none", + "type": "textDecoration" + } + }, + "Link": { + "fontFamily": { + "value": "$fontFamilies.fira-sans", + "type": "fontFamily" + }, + "fontWeight": { + "value": "$fontWeights.fira-sans-1", + "type": "fontWeight" + }, + "lineHeight": { + "value": "$lineHeights.3", + "type": "lineHeight" + }, + "fontSize": { + "value": "$fontSize.1", + "type": "fontSize" + }, + "letterSpacing": { + "value": "$letterSpacing.0", + "type": "letterSpacing" + }, + "paragraphSpacing": { + "value": "$paragraphSpacing.0", + "type": "paragraphSpacing" + }, + "textCase": { + "value": "$textCase.none", + "type": "textCase" + }, + "textDecoration": { + "value": "$textDecoration.none", + "type": "textDecoration" + } + }, + "Small Text": { + "fontFamily": { + "value": "$fontFamilies.fira-sans", + "type": "fontFamily" + }, + "fontWeight": { + "value": "$fontWeights.fira-sans-0", + "type": "fontWeight" + }, + "lineHeight": { + "value": "$lineHeights.2", + "type": "lineHeight" + }, + "fontSize": { + "value": "$fontSize.0", + "type": "fontSize" + }, + "letterSpacing": { + "value": "$letterSpacing.0", + "type": "letterSpacing" + }, + "paragraphSpacing": { + "value": "$paragraphSpacing.0", + "type": "paragraphSpacing" + }, + "textCase": { + "value": "$textCase.none", + "type": "textCase" + }, + "textDecoration": { + "value": "$textDecoration.none", + "type": "textDecoration" + } + }, + "Small Text Bold": { + "fontFamily": { + "value": "$fontFamilies.fira-sans", + "type": "fontFamily" + }, + "fontWeight": { + "value": "$fontWeights.fira-sans-1", + "type": "fontWeight" + }, + "lineHeight": { + "value": "$lineHeights.2", + "type": "lineHeight" + }, + "fontSize": { + "value": "$fontSize.0", + "type": "fontSize" + }, + "letterSpacing": { + "value": "$letterSpacing.0", + "type": "letterSpacing" + }, + "paragraphSpacing": { + "value": "$paragraphSpacing.0", + "type": "paragraphSpacing" + }, + "textCase": { + "value": "$textCase.none", + "type": "textCase" + }, + "textDecoration": { + "value": "$textDecoration.none", + "type": "textDecoration" + } + }, + "Link underlined": { + "fontFamily": { + "value": "$fontFamilies.fira-sans", + "type": "fontFamily" + }, + "fontWeight": { + "value": "$fontWeights.fira-sans-1", + "type": "fontWeight" + }, + "lineHeight": { + "value": "$lineHeights.3", + "type": "lineHeight" + }, + "fontSize": { + "value": "$fontSize.1", + "type": "fontSize" + }, + "letterSpacing": { + "value": "$letterSpacing.0", + "type": "letterSpacing" + }, + "paragraphSpacing": { + "value": "$paragraphSpacing.1", + "type": "paragraphSpacing" + }, + "textCase": { + "value": "$textCase.none", + "type": "textCase" + }, + "textDecoration": { + "value": "$textDecoration.underline", + "type": "textDecoration" + } + }, + "textCase": { + "none": { + "value": "none", + "type": "textCase" + } + }, + "textDecoration": { + "none": { + "value": "none", + "type": "textDecoration" + }, + "underline": { + "value": "underline", + "type": "textDecoration" + } + } + }, + "at": { + "color": { + "primary": { + "value": "$Primary.Green 800", + "type": "color" + }, + "secondary": { + "value": "$Secondary.Purple 600", + "type": "color" + } + } + }, + "me": { + "color": { + "primary": { + "value": "$Primary.me.Orange 500", + "type": "color" + }, + "secondary": { + "value": "$Secondary.me.Blue 500", + "type": "color" + } + } + }, + "org": { + "color": { + "primary": { + "value": "$Primary.Green 500", + "type": "color" + }, + "secondary": { + "value": "$Tertiary.Teal 500", + "type": "color" + } + } + } +} diff --git a/package.json b/package.json index e15d6f2a..dead7e36 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "preview": "vite preview", "storybook": "start-storybook -p 6006", "build-storybook": "export BASE_URL='/betterplace-design-system/'; build-storybook", + "build-tokens": "style-dictionary build --config config/sd.config.js", "test": "echo 'TEST PLACEHOLDER'", "lint": "tsc && eslint . && stylelint src/**/*.css", "prepare": "husky install" @@ -67,6 +68,7 @@ "husky": ">=6", "lint-staged": ">=10", "storybook-addon-designs": "^6.2.1", + "style-dictionary": "^3.7.0", "stylelint": "^14.8.1", "stylelint-config-prettier": "^9.0.3", "stylelint-config-standard": "^25.0.0", diff --git a/src/helpers/ThemeProvider.tsx b/src/helpers/ThemeProvider.tsx index 5ac882b3..9c75fcba 100644 --- a/src/helpers/ThemeProvider.tsx +++ b/src/helpers/ThemeProvider.tsx @@ -1,5 +1,6 @@ import React, { ReactNode, useState } from 'react' -import { tokens } from '../../tokens' +import tokens from '../../config/tokens.json' +import '../../build/css/globals.css' export const AVAILABLE_THEMES = [ { @@ -28,7 +29,7 @@ type Tokens = typeof tokens export type ThemeProviderContext = { theme?: Theme tokens?: { - global: Tokens['globals'] + global: Tokens['global'] theme: Tokens[Exclude] } } @@ -36,23 +37,23 @@ export type ThemeProviderContext = { export const ThemeContext = React.createContext({}) export const ThemeProvider = (props: ThemeProviderProps) => { - const [themeStyles, setThemeStyles] = useState('') + const [themeVars, setThemeVars] = useState('') const theme: ThemeProviderContext = { theme: props.theme, tokens: { - global: tokens.globals, + global: tokens.global, theme: tokens[props.theme], }, } - import(`../../src/lib/theme/theme-${props.theme}.css`).then((styles) => { - setThemeStyles(styles.default) + import(`../../build/css/themes/${props.theme}.css`).then((styles) => { + setThemeVars(styles.default) }) return ( - + {props.children} ) diff --git a/src/lib/theme/theme-at.css b/src/lib/theme/theme-at.css deleted file mode 100644 index ca284e8b..00000000 --- a/src/lib/theme/theme-at.css +++ /dev/null @@ -1,4 +0,0 @@ -:root { - --primary: #357c00; - --secondary: #6d2c64; -} diff --git a/src/lib/theme/theme-me.css b/src/lib/theme/theme-me.css deleted file mode 100644 index 3dd60337..00000000 --- a/src/lib/theme/theme-me.css +++ /dev/null @@ -1,4 +0,0 @@ -:root { - --primary: #ff854d; - --secondary: #00a0c8; -} diff --git a/src/lib/theme/theme-org.css b/src/lib/theme/theme-org.css deleted file mode 100644 index fde315cb..00000000 --- a/src/lib/theme/theme-org.css +++ /dev/null @@ -1,4 +0,0 @@ -:root { - --primary: #9ecb0a; - --secondary: #a75c96; -} diff --git a/src/stories/tokens/Colors.stories.tsx b/src/stories/tokens/Colors.stories.tsx index 869af5e0..569684ee 100644 --- a/src/stories/tokens/Colors.stories.tsx +++ b/src/stories/tokens/Colors.stories.tsx @@ -1,4 +1,5 @@ import { ComponentStory, ComponentMeta } from '@storybook/react' +import themeTokens from '../../../build/json/themes/org.json' export default { title: 'Tokens/Design Tokens/Colors', @@ -22,5 +23,5 @@ const Template: ComponentStory = (args) => token.startsWith('betterplace-color')), } diff --git a/tokens/globals.json b/tokens/globals.json deleted file mode 100644 index 0504a39d..00000000 --- a/tokens/globals.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "colors": { - "colorRed100": "#ff0000", - "colorGreen100": "#00ff00", - "colorGreen300": "#00aa00" - } -} diff --git a/tokens/index.ts b/tokens/index.ts deleted file mode 100644 index 70ad0c5d..00000000 --- a/tokens/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -import globals from './globals.json' -import org from './theme-org.json' -import at from './theme-at.json' -import me from './theme-me.json' - -export const tokens = { - globals, - org, - at, - me, -} diff --git a/tokens/theme-at.json b/tokens/theme-at.json deleted file mode 100644 index ca1e7f29..00000000 --- a/tokens/theme-at.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "colors": { - "colorPrimary": "colorGreen300" - } -} diff --git a/tokens/theme-me.json b/tokens/theme-me.json deleted file mode 100644 index 383b0355..00000000 --- a/tokens/theme-me.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "colors": { - "colorPrimary": "colorRed100" - } -} diff --git a/tokens/theme-org.json b/tokens/theme-org.json deleted file mode 100644 index f5a851d3..00000000 --- a/tokens/theme-org.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "colors": { - "colorPrimary": "colorGreen100" - } -} diff --git a/yarn.lock b/yarn.lock index f8e7adf4..15f829cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3971,7 +3971,7 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camel-case@^4.1.1: +camel-case@^4.1.1, camel-case@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== @@ -4008,6 +4008,15 @@ caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001332: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001334.tgz#892e9965b35285033fc2b8a8eff499fe02f13d8b" integrity sha512-kbaCEBRRVSoeNs74sCuq92MJyGrMtjWVfhltoHUCW4t4pXFvGjUBrfo47weBRViHkiV3eBYyIsfl956NtHGazw== +capital-case@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/capital-case/-/capital-case-1.0.4.tgz#9d130292353c9249f6b00fa5852bee38a717e669" + integrity sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + upper-case-first "^2.0.2" + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -4042,6 +4051,24 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" +change-case@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/change-case/-/change-case-4.1.2.tgz#fedfc5f136045e2398c0410ee441f95704641e12" + integrity sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A== + dependencies: + camel-case "^4.1.2" + capital-case "^1.0.4" + constant-case "^3.0.4" + dot-case "^3.0.4" + header-case "^2.0.4" + no-case "^3.0.4" + param-case "^3.0.4" + pascal-case "^3.1.2" + path-case "^3.0.4" + sentence-case "^3.0.4" + snake-case "^3.0.4" + tslib "^2.0.3" + character-entities-html4@^1.0.0: version "1.1.4" resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.1.4.tgz#0e64b0a3753ddbf1fdc044c5fd01d0199a02e125" @@ -4379,6 +4406,15 @@ console-control-strings@^1.0.0, console-control-strings@^1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= +constant-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-3.0.4.tgz#3b84a9aeaf4cf31ec45e6bf5de91bdfb0589faf1" + integrity sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + upper-case "^2.0.2" + constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -6049,7 +6085,7 @@ fs-extra@^0.30.0: path-is-absolute "^1.0.0" rimraf "^2.2.8" -fs-extra@^10.0.1: +fs-extra@^10.0.0, fs-extra@^10.0.1: version "10.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== @@ -6549,6 +6585,14 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +header-case@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/header-case/-/header-case-2.0.4.tgz#5a42e63b55177349cf405beb8d775acabb92c063" + integrity sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q== + dependencies: + capital-case "^1.0.4" + tslib "^2.0.3" + highlight.js@^10.1.1, highlight.js@~10.7.0: version "10.7.3" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" @@ -7384,11 +7428,16 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.1.2, json5@^2.1.3, json5@^2.2.1: +json5@^2.1.2, json5@^2.1.3, json5@^2.2.0, json5@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== +jsonc-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" + integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== + jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" @@ -8655,7 +8704,7 @@ parallel-transform@^1.1.0: inherits "^2.0.3" readable-stream "^2.1.5" -param-case@^3.0.3: +param-case@^3.0.3, param-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== @@ -8736,6 +8785,14 @@ path-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== +path-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/path-case/-/path-case-3.0.4.tgz#9168645334eb942658375c56f80b4c0cb5f82c6f" + integrity sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" @@ -9932,6 +9989,15 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" +sentence-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-3.0.4.tgz#3645a7b8c117c787fde8702056225bb62a45131f" + integrity sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + upper-case-first "^2.0.2" + serialize-javascript@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" @@ -10091,6 +10157,14 @@ slice-ansi@^5.0.0: ansi-styles "^6.0.0" is-fullwidth-code-point "^4.0.0" +snake-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" + integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -10458,6 +10532,21 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1, strip-json-comments@~3.1 resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +style-dictionary@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/style-dictionary/-/style-dictionary-3.7.0.tgz#02f4b17232cbb1142a3fdc09a17dfb08aafde3b0" + integrity sha512-BL4AQS5kNDBXbFHWJhlCve6+ojnHgHkiwhf2nNByU698elXWdyK5b27OprphT4q0/tJ52zB+lodhqxIxbNOajQ== + dependencies: + chalk "^4.0.0" + change-case "^4.1.2" + commander "^8.3.0" + fs-extra "^10.0.0" + glob "^7.2.0" + json5 "^2.2.0" + jsonc-parser "^3.0.0" + lodash "^4.17.15" + tinycolor2 "^1.4.1" + style-loader@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e" @@ -10744,6 +10833,11 @@ timsort@~0.3.0: resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= +tinycolor2@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803" + integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA== + tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -11137,6 +11231,20 @@ upath@^1.1.1, upath@^1.2.0: resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== +upper-case-first@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-2.0.2.tgz#992c3273f882abd19d1e02894cc147117f844324" + integrity sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg== + dependencies: + tslib "^2.0.3" + +upper-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-2.0.2.tgz#d89810823faab1df1549b7d97a76f8662bae6f7a" + integrity sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg== + dependencies: + tslib "^2.0.3" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"