From b19c41b7f4a1d0c0620f05f1087ffd1380785892 Mon Sep 17 00:00:00 2001 From: Alexander Schwarzmann Date: Thu, 4 Jul 2024 15:38:00 +0200 Subject: [PATCH 1/3] chore(ui-kit): migrate to radix-ui/colors --- .pnp.cjs | 14 + app/storybook/.storybook/global.css | 4 + app/storybook/.storybook/preview.tsx | 33 +- .../ui-kit/DefaultComponents.mdx | 4 +- packages/ui-kit/package.json | 1 + .../src/components/Button/Button.module.scss | 73 +- .../src/components/Button/Button.stories.tsx | 2 +- .../ui-kit/src/components/Button/Button.tsx | 15 +- .../src/components/Card/Card.module.scss | 8 +- packages/ui-kit/src/components/Card/Card.tsx | 9 +- .../components/Counter/Counter.module.scss | 17 +- .../components/Counter/Counter.stories.tsx | 6 +- .../ui-kit/src/components/Counter/Counter.tsx | 4 +- .../Leaderboard/Leaderboard.module.scss | 2 +- .../src/components/Loader/Loader.module.scss | 18 +- .../ui-kit/src/components/Loader/Loader.tsx | 9 +- .../ThemeProvider/ThemeProvider.tsx | 119 +- .../ThemeProvider/ThemeProvider.types.ts | 16 +- .../TimeSeries/TimeSeries.module.scss | 2 +- .../TimeSeries/TimeSeries.stories.tsx | 51 +- .../src/components/TimeSeries/TimeSeries.tsx | 28 +- .../ui-kit/src/components/TimeSeries/utils.ts | 2 +- .../withContainer/withContainer.tsx | 4 +- .../camelCaseToKebabCase.ts | 2 +- .../src/helpers/themeUtils/themeUtils.ts | 16 +- packages/ui-kit/src/themes/theme.types.ts | 48 +- packages/ui-kit/src/themes/themes.module.scss | 5 +- packages/ui-kit/src/themes/tokens/_base.scss | 4 + .../ui-kit/src/themes/tokens/_colors.scss | 1176 +++++++++++++++++ .../ui-kit/src/themes/tokens/_cursor.scss | 11 + packages/ui-kit/src/themes/tokens/_index.scss | 8 + .../ui-kit/src/themes/tokens/_radius.scss | 38 + .../ui-kit/src/themes/tokens/_scaling.scss | 17 + .../ui-kit/src/themes/tokens/_shadow.scss | 155 +++ packages/ui-kit/src/themes/tokens/_space.scss | 11 + .../ui-kit/src/themes/tokens/_typography.scss | 128 ++ yarn.lock | 8 + 37 files changed, 1869 insertions(+), 199 deletions(-) create mode 100644 packages/ui-kit/src/themes/tokens/_base.scss create mode 100644 packages/ui-kit/src/themes/tokens/_colors.scss create mode 100644 packages/ui-kit/src/themes/tokens/_cursor.scss create mode 100644 packages/ui-kit/src/themes/tokens/_index.scss create mode 100644 packages/ui-kit/src/themes/tokens/_radius.scss create mode 100644 packages/ui-kit/src/themes/tokens/_scaling.scss create mode 100644 packages/ui-kit/src/themes/tokens/_shadow.scss create mode 100644 packages/ui-kit/src/themes/tokens/_space.scss create mode 100644 packages/ui-kit/src/themes/tokens/_typography.scss diff --git a/.pnp.cjs b/.pnp.cjs index b927a1e2..54d5b1bb 100644 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -8793,6 +8793,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@graphql-codegen/typescript-react-query", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:6.0.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40graphql-codegen%2Ftypescript-react-query%2F-%2Ftypescript-react-query-6.0.0.tgz"],\ ["@juggle/resize-observer", "npm:3.4.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40juggle%2Fresize-observer%2F-%2Fresize-observer-3.4.0.tgz"],\ ["@mui/base", "virtual:6dd0ee4544359587d64ff328fe311b923a3c1ee8914df11782918738abbc6520285dc1ca059877f86375600584583e7d6592895c5c96572203f7b48dc4661862#npm:5.0.0-beta.31::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40mui%2Fbase%2F-%2Fbase-5.0.0-beta.31.tgz"],\ + ["@radix-ui/colors", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40radix-ui%2Fcolors%2F-%2Fcolors-3.0.0.tgz"],\ ["@rollup/plugin-commonjs", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:25.0.7::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40rollup%2Fplugin-commonjs%2F-%2Fplugin-commonjs-25.0.7.tgz"],\ ["@rollup/plugin-node-resolve", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:15.2.3::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40rollup%2Fplugin-node-resolve%2F-%2Fplugin-node-resolve-15.2.3.tgz"],\ ["@rollup/plugin-terser", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:0.4.4::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40rollup%2Fplugin-terser%2F-%2Fplugin-terser-0.4.4.tgz"],\ @@ -8861,6 +8862,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@graphql-codegen/typescript-react-query", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:6.0.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40graphql-codegen%2Ftypescript-react-query%2F-%2Ftypescript-react-query-6.0.0.tgz"],\ ["@juggle/resize-observer", "npm:3.4.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40juggle%2Fresize-observer%2F-%2Fresize-observer-3.4.0.tgz"],\ ["@mui/base", "virtual:a84eb495e555084f80c201f07630d1efc544260e49e6a723e5d25c3ed5c3b4ea77b8628678069a7b15d87cb9e6086898e971564f07f3bf23d436e7ee19347a66#npm:5.0.0-beta.31::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40mui%2Fbase%2F-%2Fbase-5.0.0-beta.31.tgz"],\ + ["@radix-ui/colors", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40radix-ui%2Fcolors%2F-%2Fcolors-3.0.0.tgz"],\ ["@rollup/plugin-commonjs", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:25.0.7::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40rollup%2Fplugin-commonjs%2F-%2Fplugin-commonjs-25.0.7.tgz"],\ ["@rollup/plugin-node-resolve", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:15.2.3::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40rollup%2Fplugin-node-resolve%2F-%2Fplugin-node-resolve-15.2.3.tgz"],\ ["@rollup/plugin-terser", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:0.4.4::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40rollup%2Fplugin-terser%2F-%2Fplugin-terser-0.4.4.tgz"],\ @@ -8929,6 +8931,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@graphql-codegen/typescript-react-query", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:6.0.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40graphql-codegen%2Ftypescript-react-query%2F-%2Ftypescript-react-query-6.0.0.tgz"],\ ["@juggle/resize-observer", "npm:3.4.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40juggle%2Fresize-observer%2F-%2Fresize-observer-3.4.0.tgz"],\ ["@mui/base", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:5.0.0-beta.31::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40mui%2Fbase%2F-%2Fbase-5.0.0-beta.31.tgz"],\ + ["@radix-ui/colors", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40radix-ui%2Fcolors%2F-%2Fcolors-3.0.0.tgz"],\ ["@rollup/plugin-commonjs", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:25.0.7::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40rollup%2Fplugin-commonjs%2F-%2Fplugin-commonjs-25.0.7.tgz"],\ ["@rollup/plugin-node-resolve", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:15.2.3::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40rollup%2Fplugin-node-resolve%2F-%2Fplugin-node-resolve-15.2.3.tgz"],\ ["@rollup/plugin-terser", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:0.4.4::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40rollup%2Fplugin-terser%2F-%2Fplugin-terser-0.4.4.tgz"],\ @@ -8995,6 +8998,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@graphql-codegen/typescript-react-query", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:6.0.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40graphql-codegen%2Ftypescript-react-query%2F-%2Ftypescript-react-query-6.0.0.tgz"],\ ["@juggle/resize-observer", "npm:3.4.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40juggle%2Fresize-observer%2F-%2Fresize-observer-3.4.0.tgz"],\ ["@mui/base", "virtual:40f8e5d9470dadd0060c7b0d5ccbc7394cb2631c4c32ded046c14477c91f332b2a7e811fb9423edb388a602730fec4c2d722550b1609515756ea1cf3021c1e93#npm:5.0.0-beta.31::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40mui%2Fbase%2F-%2Fbase-5.0.0-beta.31.tgz"],\ + ["@radix-ui/colors", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40radix-ui%2Fcolors%2F-%2Fcolors-3.0.0.tgz"],\ ["@rollup/plugin-commonjs", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:25.0.7::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40rollup%2Fplugin-commonjs%2F-%2Fplugin-commonjs-25.0.7.tgz"],\ ["@rollup/plugin-node-resolve", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:15.2.3::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40rollup%2Fplugin-node-resolve%2F-%2Fplugin-node-resolve-15.2.3.tgz"],\ ["@rollup/plugin-terser", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:0.4.4::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40rollup%2Fplugin-terser%2F-%2Fplugin-terser-0.4.4.tgz"],\ @@ -9061,6 +9065,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@graphql-codegen/typescript-react-query", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:6.0.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40graphql-codegen%2Ftypescript-react-query%2F-%2Ftypescript-react-query-6.0.0.tgz"],\ ["@juggle/resize-observer", "npm:3.4.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40juggle%2Fresize-observer%2F-%2Fresize-observer-3.4.0.tgz"],\ ["@mui/base", "virtual:a84eb495e555084f80c201f07630d1efc544260e49e6a723e5d25c3ed5c3b4ea77b8628678069a7b15d87cb9e6086898e971564f07f3bf23d436e7ee19347a66#npm:5.0.0-beta.31::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40mui%2Fbase%2F-%2Fbase-5.0.0-beta.31.tgz"],\ + ["@radix-ui/colors", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40radix-ui%2Fcolors%2F-%2Fcolors-3.0.0.tgz"],\ ["@rollup/plugin-commonjs", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:25.0.7::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40rollup%2Fplugin-commonjs%2F-%2Fplugin-commonjs-25.0.7.tgz"],\ ["@rollup/plugin-node-resolve", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:15.2.3::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40rollup%2Fplugin-node-resolve%2F-%2Fplugin-node-resolve-15.2.3.tgz"],\ ["@rollup/plugin-terser", "virtual:6040707e6c7fb3cdae07cc6dc6126c752898b1e11c5b881f764686126da5522333967850c2fd07e811f6e05e1db73260de6d251bcb29bf6a1b6c2ad372b2d3d7#npm:0.4.4::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40rollup%2Fplugin-terser%2F-%2Fplugin-terser-0.4.4.tgz"],\ @@ -9144,6 +9149,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "SOFT"\ }]\ ]],\ + ["@radix-ui/colors", [\ + ["npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40radix-ui%2Fcolors%2F-%2Fcolors-3.0.0.tgz", {\ + "packageLocation": "./.yarn/cache/@radix-ui-colors-npm-3.0.0-9f82aaefb4-5ac1b69df7.zip/node_modules/@radix-ui/colors/",\ + "packageDependencies": [\ + ["@radix-ui/colors", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40radix-ui%2Fcolors%2F-%2Fcolors-3.0.0.tgz"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["@radix-ui/number", [\ ["npm:1.0.1::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40radix-ui%2Fnumber%2F-%2Fnumber-1.0.1.tgz", {\ "packageLocation": "./.yarn/cache/@radix-ui-number-npm-1.0.1-fa6af0b4f7-621ea8b7d4.zip/node_modules/@radix-ui/number/",\ diff --git a/app/storybook/.storybook/global.css b/app/storybook/.storybook/global.css index 52c14d92..9cf6d409 100644 --- a/app/storybook/.storybook/global.css +++ b/app/storybook/.storybook/global.css @@ -28,3 +28,7 @@ a.showCodeLink { font-size: 0.9em; color: #2e90fa; } + +.themeProvider { + --accent-surface: #00ff00; +} diff --git a/app/storybook/.storybook/preview.tsx b/app/storybook/.storybook/preview.tsx index 174c8373..909059f8 100644 --- a/app/storybook/.storybook/preview.tsx +++ b/app/storybook/.storybook/preview.tsx @@ -2,8 +2,9 @@ import { Source } from '@storybook/blocks' import type { Preview, StoryContext } from '@storybook/react' import React from 'react' import withAxiosDecorator from 'storybook-axios' -import { ThemeProvider, useTheme } from '../../../packages/ui-kit/src/components/ThemeProvider' +import { ThemeProvider, ThemeProviderProps, useTheme } from '../../../packages/ui-kit/src/components/ThemeProvider' import { QueryClient, QueryClientProvider } from '../../../packages/ui-kit/src/graphql' +import { accentColors } from '../../../packages/ui-kit/src/themes' import axiosInstance from '../src/axios' import { parseStorySourceCode } from './blocks/SourceCode' import './global.css' @@ -11,7 +12,7 @@ import './global.css' const GlobalStyles = () => { const theme = useTheme() if (document && theme) { - document.body.style.setProperty('--bg-color', theme.backgroundSecondary as string) + document.body.style.setProperty('--bg-color', theme.getVar('--accent-1')) } return null } @@ -25,7 +26,9 @@ const withThemeProvider = (Story: React.FC, context: StoryContext) => { return ( // }} @@ -95,18 +98,28 @@ const preview: Preview = { } }, globalTypes: { - theme: { - name: 'Theme', - description: 'Global theme for components', - defaultValue: 'lightTheme', + appearance: { + name: 'Appearance', + description: 'Global theme appearance', + defaultValue: 'light', toolbar: { - icon: 'circlehollow', + icon: 'mirror', items: [ - { value: 'lightTheme', icon: 'circlehollow', title: 'light' }, - { value: 'darkTheme', icon: 'circle', title: 'dark' } + { value: 'light', title: 'Light appearance' }, + { value: 'dark', title: 'Dark appearance' } ], showName: true } + }, + accentColor: { + name: 'Accent color', + description: 'Global theme accent color', + defaultValue: 'blue', + toolbar: { + icon: 'circle', + items: accentColors.map((color) => ({ value: color, title: color })), + showName: true + } } }, decorators: [ diff --git a/app/storybook/documentation/ui-kit/DefaultComponents.mdx b/app/storybook/documentation/ui-kit/DefaultComponents.mdx index 9464d122..6464b78e 100644 --- a/app/storybook/documentation/ui-kit/DefaultComponents.mdx +++ b/app/storybook/documentation/ui-kit/DefaultComponents.mdx @@ -59,8 +59,8 @@ Or you can customize the fallbacks on a per-component basis. errorFallback={({ theme }) => (
diff --git a/packages/ui-kit/package.json b/packages/ui-kit/package.json index 568806c9..ebacda8e 100644 --- a/packages/ui-kit/package.json +++ b/packages/ui-kit/package.json @@ -41,6 +41,7 @@ "@graphql-codegen/typescript-operations": "^4.0.1", "@graphql-codegen/typescript-react-query": "^6.0.0", "@juggle/resize-observer": "^3.4.0", + "@radix-ui/colors": "^3.0.0", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-terser": "^0.4.4", diff --git a/packages/ui-kit/src/components/Button/Button.module.scss b/packages/ui-kit/src/components/Button/Button.module.scss index 2910e7e8..0ce58aaf 100644 --- a/packages/ui-kit/src/components/Button/Button.module.scss +++ b/packages/ui-kit/src/components/Button/Button.module.scss @@ -1,88 +1,93 @@ -@use '../../themes/generated/tokens'; - .rootButton { - @extend .textMdRegular; + font-family: var(--default-font-family); + font-style: normal; + font-weight: var(--font-weight-medium); + font-size: var(--font-size-2); + line-height: var(--line-height-2); + letter-spacing: var(--letter-spacing-2); - padding: var(--propel-spacing-lg) var(--propel-spacing-4xl); - gap: var(--propel-spacing-lg); - background-color: var(--propel-background-primary); - border-radius: var(--propel-radius-sm); + padding: var(--space-2) var(--space-5); + gap: var(--space-3); + background-color: var(--accent-contrast); + border-radius: var(--radius-1); border-width: 1px; - border-color: var(--propel-border-primary); + border-color: var(--accent-9); border-style: solid; - color: var(--propel-text-quarterary); - cursor: pointer; + color: var(--accent-11); + cursor: var(--cursor-button); white-space: nowrap; display: flex; justify-content: center; align-items: center; box-sizing: border-box; - transition: background-color var(--propel-transition-ease-time) ease, - border-color var(--propel-transition-ease-time) ease, color var(--propel-transition-ease-time) ease; + transition: background-color var(--transition-ease-time) ease, border-color var(--transition-ease-time) ease, + color var(--transition-ease-time) ease; &:hover, &:focus-visible, &.focus { outline: none; - color: var(--propel-text-secondary); - border-color: var(--propel-border-brand-solid); + background-color: var(--accent-a2); + border-color: var(--accent-10); } &.disabled { - color: var(--propel-text-disabled); + color: var(--gray-10); + border-color: var(--gray-3); &:hover { - color: var(--propel-text-disabled); - border-color: var(--propel-border-primary); - cursor: default; + background-color: inherit; + cursor: inherit; } & svg { - color: var(--propel-text-disabled); + color: var(--gray-10); } } &.startAdornment { justify-content: flex-start; - padding-left: var(--propel-spacing-xl); + padding-left: var(--space-2); } &.endAdornment, &.startAdornment.endAdornment { justify-content: space-between; - padding-right: var(--propel-spacing-xl); - padding-left: var(--propel-spacing-xl); + padding-right: var(--space-2); + padding-left: var(--space-2); } &.primary { - background-color: var(--propel-background-brand-solid); - border-color: var(--propel-background-brand-solid); + background-color: var(--accent-9); + border-color: var(--accent-9); color: #ffffff; &:hover, &.focus { - background-color: var(--propel-background-brand-solid-hover); - border-color: var(--propel-background-brand-solid-hover); + background-color: var(--accent-10); + border-color: var(--accent-10); } &.disabled { - color: var(--propel-text-disabled); - background-color: var(--propel-background-disabled-subtle); - border-color: var(--propel-border-primary); + color: var(--gray-a8); + background-color: var(--gray-2); + border-color: var(--gray-a3); } } &.small { - @extend .textSmSemibold; + font-size: var(--font-size-1); + line-height: var(--line-height-1); + letter-spacing: var(--letter-spacing-1); - padding: var(--propel-spacing-md) var(--propel-spacing-4xl); + padding: var(--space-1) var(--space-3); &.startAdornment { - padding-left: var(--propel-spacing-lg); + padding-left: var(--space-1); } &.endAdornment, &.startAdornment.endAdornment { - padding-right: var(--propel-spacing-lg); - padding-left: var(--propel-spacing-lg); + padding-right: var(--space-1); + padding-left: var(--space-1); } } } diff --git a/packages/ui-kit/src/components/Button/Button.stories.tsx b/packages/ui-kit/src/components/Button/Button.stories.tsx index eaef53b1..fff16da4 100644 --- a/packages/ui-kit/src/components/Button/Button.stories.tsx +++ b/packages/ui-kit/src/components/Button/Button.stories.tsx @@ -10,7 +10,7 @@ const meta: Meta = { component: ButtonSource, tags: ['devOnly'], argTypes: { - baseTheme: { + appearance: { table: { disable: true } diff --git a/packages/ui-kit/src/components/Button/Button.tsx b/packages/ui-kit/src/components/Button/Button.tsx index a8e895f1..7bc54e62 100644 --- a/packages/ui-kit/src/components/Button/Button.tsx +++ b/packages/ui-kit/src/components/Button/Button.tsx @@ -2,13 +2,14 @@ import { useButton } from '@mui/base/useButton' import classnames from 'classnames' import * as React from 'react' import { useForwardedRefCallback } from '../../helpers' -import { DefaultThemes, ThemeStateProps, useSetupTheme } from '../ThemeProvider' +import { ThemeAppearances } from '../../themes' +import { ThemeStateProps, useSetupTheme } from '../ThemeProvider' import componentStyles from './Button.module.scss' export interface ButtonProps extends React.ComponentPropsWithoutRef<'button'> { overridable?: boolean - baseTheme?: DefaultThemes - variant?: 'default' | 'primary' + appearance?: ThemeAppearances + variant?: 'outline' | 'primary' size?: 'default' | 'small' startAdornment?: ({ theme }: { theme: ThemeStateProps }) => React.ReactElement endAdornment?: ({ theme }: { theme: ThemeStateProps }) => React.ReactElement @@ -16,12 +17,12 @@ export interface ButtonProps extends React.ComponentPropsWithoutRef<'button'> { export const Button = React.forwardRef((props, forwardedRef) => { const { - baseTheme, + appearance, children, className, disabled, role = 'button', - variant = 'default', + variant = 'outline', size = 'default', startAdornment, endAdornment, @@ -30,7 +31,7 @@ export const Button = React.forwardRef((props, f ...rest } = props const { componentContainer, setRef } = useForwardedRefCallback(forwardedRef) - const { theme, components } = useSetupTheme({ componentContainer, baseTheme }) + const { theme, components } = useSetupTheme({ componentContainer, appearance }) const { active, focusVisible, getRootProps } = useButton({ ...props, rootRef: setRef @@ -53,7 +54,7 @@ export const Button = React.forwardRef((props, f [componentStyles.active]: active, [componentStyles.startAdornment]: startAdornment, [componentStyles.endAdornment]: endAdornment, - [componentStyles[variant]]: variant && variant !== 'default', + [componentStyles[variant]]: variant && variant !== 'outline', [componentStyles[size]]: size && size !== 'default' }, className diff --git a/packages/ui-kit/src/components/Card/Card.module.scss b/packages/ui-kit/src/components/Card/Card.module.scss index e462069e..89beb59a 100644 --- a/packages/ui-kit/src/components/Card/Card.module.scss +++ b/packages/ui-kit/src/components/Card/Card.module.scss @@ -1,6 +1,6 @@ .rootCard { - padding: var(--propel-spacing-3xl); - background-color: var(--propel-background-primary); - border-radius: var(--propel-radius-xs); - box-shadow: var(--propel-shadows-shadow-xs); + padding: var(--space-5); + background-color: var(--color-background); + border-radius: var(--radius-2); + box-shadow: var(--shadow-2); } diff --git a/packages/ui-kit/src/components/Card/Card.tsx b/packages/ui-kit/src/components/Card/Card.tsx index 5979027f..843d27c7 100644 --- a/packages/ui-kit/src/components/Card/Card.tsx +++ b/packages/ui-kit/src/components/Card/Card.tsx @@ -1,17 +1,18 @@ import classnames from 'classnames' import React from 'react' +import { ThemeAppearances } from 'src/themes' import { useForwardedRefCallback } from '../../helpers' -import { DefaultThemes, useSetupTheme } from '../ThemeProvider' +import { useSetupTheme } from '../ThemeProvider' import componentStyles from './Card.module.scss' export interface CardProps extends React.ComponentPropsWithoutRef<'div'> { - baseTheme?: DefaultThemes + appearance?: ThemeAppearances } export const Card = React.forwardRef( - ({ children, className, baseTheme, ...rest }, forwardedRef) => { + ({ children, className, appearance, ...rest }, forwardedRef) => { const { componentContainer, setRef } = useForwardedRefCallback(forwardedRef) - useSetupTheme({ componentContainer, baseTheme }) + useSetupTheme({ componentContainer, appearance }) return (
diff --git a/packages/ui-kit/src/components/Counter/Counter.module.scss b/packages/ui-kit/src/components/Counter/Counter.module.scss index aad5b6c5..cf96db50 100644 --- a/packages/ui-kit/src/components/Counter/Counter.module.scss +++ b/packages/ui-kit/src/components/Counter/Counter.module.scss @@ -1,8 +1,16 @@ -@use '../../themes/common'; +%textSettings { + color: var(--gray-12); + font-family: var(--default-font-family); + font-style: normal; + font-weight: var(--font-weight-bold); + font-size: var(--font-size-8); + line-height: var(--line-height-8); + letter-spacing: var(--letter-spacing-8); +} .rootCounter { - @extend .displayLgBold; - color: var(--propel-text-primary); + @extend %textSettings; + white-space: nowrap; transition: opacity 0.2s ease-in-out; opacity: 1; @@ -13,6 +21,5 @@ } .loader { - @extend .displayLgBold; - color: var(--propel-text-secondary); + @extend %textSettings; } diff --git a/packages/ui-kit/src/components/Counter/Counter.stories.tsx b/packages/ui-kit/src/components/Counter/Counter.stories.tsx index 20d737ac..25bfcc26 100644 --- a/packages/ui-kit/src/components/Counter/Counter.stories.tsx +++ b/packages/ui-kit/src/components/Counter/Counter.stories.tsx @@ -12,7 +12,7 @@ const meta: Meta = { component: CounterComponent, tags: ['tag'], argTypes: { - baseTheme: { + appearance: { table: { disable: true } @@ -197,8 +197,8 @@ export const CustomErrorFallbackStory: Story = { errorFallback: ({ theme }) => (
diff --git a/packages/ui-kit/src/components/Counter/Counter.tsx b/packages/ui-kit/src/components/Counter/Counter.tsx index 8df44ce7..3e3d01ec 100644 --- a/packages/ui-kit/src/components/Counter/Counter.tsx +++ b/packages/ui-kit/src/components/Counter/Counter.tsx @@ -20,7 +20,7 @@ export const CounterComponent = React.forwardRef( loading: isLoadingStatic = false, localize, className, - baseTheme, + appearance, loaderProps: loaderPropsInitial, renderLoader, errorFallbackProps: errorFallbackPropsInitial, @@ -42,7 +42,7 @@ export const CounterComponent = React.forwardRef( renderLoader: renderLoaderComponent, errorFallback: errorFallbackComponent, renderEmpty: renderEmptyComponent - } = useSetupTheme({ componentContainer, baseTheme, renderLoader, errorFallback, renderEmpty }) + } = useSetupTheme({ componentContainer, appearance, renderLoader, errorFallback, renderEmpty }) /** * If the user passes `value` attribute, it diff --git a/packages/ui-kit/src/components/Leaderboard/Leaderboard.module.scss b/packages/ui-kit/src/components/Leaderboard/Leaderboard.module.scss index c97b2256..6c158579 100644 --- a/packages/ui-kit/src/components/Leaderboard/Leaderboard.module.scss +++ b/packages/ui-kit/src/components/Leaderboard/Leaderboard.module.scss @@ -7,7 +7,7 @@ padding: 0; canvas { - height: var(--propel-component-height); + height: var(--component-height); } table { diff --git a/packages/ui-kit/src/components/Loader/Loader.module.scss b/packages/ui-kit/src/components/Loader/Loader.module.scss index fceacf32..1113521e 100644 --- a/packages/ui-kit/src/components/Loader/Loader.module.scss +++ b/packages/ui-kit/src/components/Loader/Loader.module.scss @@ -1,12 +1,12 @@ -@use '../../themes/common'; - .rootLoader { - @extend .textMdRegular; - color: var(--propel-text-secondary); + font-size: var(--font-size-3); + line-height: var(--line-height-3); + letter-spacing: var(--letter-spacing-3); + + color: var(--gray-12); overflow: auto; width: 100%; height: auto; - overflow-y: hidden; } @@ -14,7 +14,7 @@ display: inline-block; position: relative; overflow: hidden; - background-color: var(--propel-background-tertiary); + background-color: var(--gray-2); margin: 0; vertical-align: top; color: transparent; @@ -25,7 +25,7 @@ .loaderAnimation:empty:not(.emptyText) { width: 100%; - height: var(--propel-component-height); + height: var(--component-height); } .emptyText { @@ -42,8 +42,8 @@ background-image: linear-gradient( 90deg, rgba(255, 255, 255, 0) 0, - var(--propel-background-quarterary) 20%, - var(--propel-background-quarterary) 60%, + var(--gray-3) 20%, + var(--gray-3) 60%, rgba(255, 255, 255, 0) ); animation: shimmer 1.5s infinite; diff --git a/packages/ui-kit/src/components/Loader/Loader.tsx b/packages/ui-kit/src/components/Loader/Loader.tsx index 66b509fa..205ba194 100644 --- a/packages/ui-kit/src/components/Loader/Loader.tsx +++ b/packages/ui-kit/src/components/Loader/Loader.tsx @@ -1,18 +1,19 @@ import classnames from 'classnames' import React from 'react' +import { ThemeAppearances } from 'src/themes' import { useForwardedRefCallback } from '../../helpers' -import { DefaultThemes, useSetupTheme } from '../ThemeProvider' +import { useSetupTheme } from '../ThemeProvider' import componentStyles from './Loader.module.scss' export interface LoaderProps extends React.ComponentPropsWithoutRef<'div'> { isText?: boolean - baseTheme?: DefaultThemes + appearance?: ThemeAppearances } export const Loader = React.forwardRef( - ({ children, className, isText, baseTheme, ...rest }, forwardedRef) => { + ({ children, className, isText, appearance, ...rest }, forwardedRef) => { const { componentContainer, setRef } = useForwardedRefCallback(forwardedRef) - useSetupTheme({ componentContainer, baseTheme }) + useSetupTheme({ componentContainer, appearance }) return (
(undefined) @@ -26,10 +28,23 @@ export const useTheme = (): ThemeStateProps | undefined => { return context.theme } +const getAccentColors = (accentColor: AccentColors, appearance: ThemeAppearances) => { + const appearanceSuffix = appearance === 'dark' ? 'Dark' : '' + return { + ...radixColors.whiteA, + ...radixColors.blackA, + ...radixColors[`slate${appearanceSuffix}`], // @TODO: fix this + ...radixColors[`slate${appearanceSuffix}A`], // @TODO: fix this + ...(radixColors[`${accentColor}${appearanceSuffix}`] as Record), + ...(radixColors[`${accentColor}${appearanceSuffix}A`] as Record) + } +} + /** A hook that sets up the theme. */ export const useSetupTheme = ({ componentContainer, - baseTheme = 'lightTheme', + appearance = 'light', + accentColor = 'blue', renderLoader: renderLoaderProp, renderEmpty: renderEmptyProp, errorFallback: errorFallbackProp @@ -37,6 +52,10 @@ export const useSetupTheme = ({ const [theme, setTheme] = useState() const [chartConfig, setChartConfig] = useState>() const context = useContext(ThemeContext) + const colors: Record = React.useMemo( + () => getAccentColors(accentColor, appearance), + [accentColor, appearance] + ) React.useEffect(() => { if (!theme) { @@ -48,9 +67,9 @@ export const useSetupTheme = ({ } config.options = { - color: theme.textSecondary ?? '', - backgroundColor: theme.backgroundBrandSolid ?? '', - borderColor: theme.borderPrimary ?? '', + color: theme.getVar('--gray-11'), + backgroundColor: theme.getVar('--accent-8'), + borderColor: theme.getVar('--gray-7'), elements: { point: { pointStyle: 'circle', @@ -58,13 +77,13 @@ export const useSetupTheme = ({ radius: 0, borderWidth: 2, hoverRadius: 6, - hoverBorderColor: theme.backgroundPrimary ?? '', - backgroundColor: theme.backgroundBrandSolidHover ?? '', - hoverBackgroundColor: theme.backgroundBrandSolidHover ?? '' + hoverBorderColor: theme.getVar('--accent-contrast'), + backgroundColor: theme?.getVar('--accent-10'), + hoverBackgroundColor: theme?.getVar('--accent-10') }, bar: { borderWidth: 0, - hoverBackgroundColor: theme.backgroundBrandSolidHover ?? '' + hoverBackgroundColor: theme.getVar('--accent-10') ?? '' }, line: { borderWidth: 3 @@ -72,18 +91,18 @@ export const useSetupTheme = ({ }, plugins: { tooltip: { - padding: parseInt(theme.spacingMd ?? '') ?? 8, - backgroundColor: theme.backgroundPrimary ?? '', - bodyColor: theme.textSecondary ?? '', - titleColor: theme.textSecondary ?? '', - borderColor: theme.borderPrimary ?? '', + padding: getPixelFontSizeAsNumber(theme.getVar('--space-2')) ?? 8, + backgroundColor: theme.getVar('--accent-1'), + bodyColor: theme.getVar('--gray-9'), + titleColor: theme.getVar('--gray-9'), + borderColor: theme.getVar('--gray-7'), borderWidth: 1, cornerRadius: 4, titleFont: { - size: getPixelFontSizeAsNumber(theme.textXxsRegularFontSize), + size: getPixelFontSizeAsNumber(theme.getVar('--font-size-1')), weight: 'bold', - lineHeight: theme.textXxsRegularLineHeight, - family: theme.textXxsRegularFontFamily + lineHeight: theme.getVar('--line-height-1'), + family: theme.getVar('--default-font-family') } } } @@ -109,18 +128,33 @@ export const useSetupTheme = ({ if (context) { // Merge the theme from the context with the component scope styles - setTheme({ ...context.theme, ...parseComputedStyle(componentContainer) }) + // setThemeOld({ ...context.theme, ...parseComputedStyle(componentContainer) }) + setTheme({ + appearance, + ...context.theme, + ...parseComputedStyle(componentContainer), + tokens: { ...colors }, + componentContainer, + getVar: (key: string) => (componentContainer ? getComputedStyle(componentContainer).getPropertyValue(key) : '') + }) return } // Set the theme from the component scope styles if there is no ThemeProvider context. // Use light theme as a fallback. - if (!componentContainer.classList.contains(themes[baseTheme])) { - componentContainer.classList.add(themes[baseTheme]) + if (!componentContainer.classList.contains(themes[appearance])) { + componentContainer.classList.add(themes[appearance]) } - setTheme(parseComputedStyle(componentContainer)) - }, [context, componentContainer, baseTheme]) + // setThemeOld({ ...parseComputedStyle(componentContainer) }) + setTheme({ + appearance, + ...parseComputedStyle(componentContainer), + tokens: { ...colors }, + componentContainer, + getVar: (key: string) => (componentContainer ? getComputedStyle(componentContainer).getPropertyValue(key) : '') + }) + }, [appearance, context, colors, componentContainer]) const { renderEmpty, errorFallback, renderLoader, components } = context ?? {} @@ -137,15 +171,19 @@ export const useSetupTheme = ({ export const ThemeProvider = ({ children, baseTheme = 'lightTheme', - theme: themeProp, + appearance = 'light', + accentColor = 'blue', + className, globalChartConfigProps, renderEmpty, errorFallback, renderLoader, - components + components, + ...other }: ThemeProviderProps) => { const [theme, setTheme] = useState() const ref = React.useRef(null) + const colors = React.useMemo(() => getAccentColors(accentColor, appearance), [accentColor, appearance]) React.useEffect(() => { if (!ref.current) { @@ -156,21 +194,40 @@ export const ThemeProvider = ({ const baseThemeStyleProps = parseComputedStyle(ref.current) - if (typeof themeProp === 'string') { - setTheme({ ...baseThemeStyleProps, baseTheme }) - return - } + // if (typeof className === 'string') { + // setTheme({ + // appearance, + // ...baseThemeStyleProps, + // tokens: { ...colors }, + // componentContainer: ref?.current, + // getVar: (key: string) => (ref?.current ? getComputedStyle(ref?.current).getPropertyValue(key) : '') + // }) + // return + // } + + const combinedWithBaseProps = { ...baseThemeStyleProps, ...colors } - const combinedWithBaseProps = { ...baseThemeStyleProps, ...themeProp } setContainerStyle(ref.current, combinedWithBaseProps) - setTheme(combinedWithBaseProps) - }, [ref, themeProp, baseTheme]) + setTheme({ + appearance, + ...combinedWithBaseProps, + tokens: { ...colors }, + componentContainer: ref?.current, + getVar: (key: string) => (ref?.current ? getComputedStyle(ref?.current).getPropertyValue(key) : '') + }) + }, [appearance, ref, colors, className, baseTheme]) return (
{ +export interface ThemeProviderProps extends React.ComponentPropsWithoutRef<'div'>, Omit { + accentColor?: AccentColors + appearance?: ThemeAppearances + /** Children components that the theme will be applied to. */ children?: React.ReactNode @@ -31,18 +34,21 @@ export interface ThemeProviderProps extends Omit { /** * This property specifies the theme to be applied to the UI components. The `theme` prop can be used in two ways: * 1. As a CSS class name. - * 2. As a JavaScript object, which should follow the structure of `ThemeTokenProps`. This approach is ideal for detailed, in-line customizations and can be particularly useful when integrating design tokens from CSS-in-JS libraries, such as Material UI. + * 2. As a JavaScript object, which should follow the structure of `ThemeOldTokenProps`. This approach is ideal for detailed, in-line customizations and can be particularly useful when integrating design tokens from CSS-in-JS libraries, such as Material UI. * * The use of this prop is optional. In its absence, UI Kit components will default to a standard pre-set theme. */ - theme?: string | ThemeTokenProps + // className?: string + + // style?: React.CSSProperties } +// export type ThemeOldStateProps = ThemeOldTokenProps | undefined export type ThemeStateProps = ThemeTokenProps | undefined export type ChartVariant = 'bar' | 'line' | 'pie' | 'doughnut' -export interface UseSetupThemeProps extends Pick, FallbackComponents { +export interface UseSetupThemeProps extends Pick, FallbackComponents { /** The component root element to which the theme will be applied. */ componentContainer?: HTMLElement | null } diff --git a/packages/ui-kit/src/components/TimeSeries/TimeSeries.module.scss b/packages/ui-kit/src/components/TimeSeries/TimeSeries.module.scss index 27c0c450..5dfd29d6 100644 --- a/packages/ui-kit/src/components/TimeSeries/TimeSeries.module.scss +++ b/packages/ui-kit/src/components/TimeSeries/TimeSeries.module.scss @@ -1,4 +1,4 @@ .rootTimeSeries { width: 100%; - height: var(--propel-component-height); + height: var(--component-height); } diff --git a/packages/ui-kit/src/components/TimeSeries/TimeSeries.stories.tsx b/packages/ui-kit/src/components/TimeSeries/TimeSeries.stories.tsx index c884a184..cbf7a46f 100644 --- a/packages/ui-kit/src/components/TimeSeries/TimeSeries.stories.tsx +++ b/packages/ui-kit/src/components/TimeSeries/TimeSeries.stories.tsx @@ -1,11 +1,9 @@ import type { Meta, StoryObj } from '@storybook/react' import { Chart } from 'chart.js' -import React, { useState } from 'react' +import React from 'react' import axiosInstance from '../../../../../app/storybook/src/axios' import { RelativeTimeRange, TimeSeriesGranularity } from '../../graphql' import { quotedStringRegex, storybookCodeTemplate, useStorybookAccessToken } from '../../helpers' -import { ThemeTokenProps } from '../../themes' -import { DefaultThemes, ThemeProvider } from '../ThemeProvider' import { TimeSeries as TimeSeriesSource, TimeSeriesComponent } from './TimeSeries' import { TimeSeriesQueryProps } from './TimeSeries.types' @@ -13,7 +11,7 @@ const meta: Meta = { title: 'Components/TimeSeries', component: TimeSeriesComponent, argTypes: { - baseTheme: { + appearance: { table: { disable: true } @@ -322,48 +320,3 @@ export const ErrorStory: Story = { }, render: (args) => } - -export const ThemeStory: Story = { - name: 'Theme', - args: { - variant: 'bar', - card: true, - query: { - ...connectedParams, - timeRange: { - ...connectedParams.timeRange, - n: 90 - } - } - }, - decorators: [ - (Story) => { - const [baseTheme, setBaseTheme] = useState('lightTheme') - - const lightColors: ThemeTokenProps = { - accent: '#3d3d3d', - accentHover: '#3d3d3dc6' - } - - const darkColors: ThemeTokenProps = { - accent: '#adadad', - accentHover: '#ffffffc6' - } - - const theme = baseTheme === 'darkTheme' ? darkColors : lightColors - - return ( - -
- - {baseTheme} -
- -
- ) - } - ], - render: (args) => -} diff --git a/packages/ui-kit/src/components/TimeSeries/TimeSeries.tsx b/packages/ui-kit/src/components/TimeSeries/TimeSeries.tsx index edf9fde5..2c12115d 100644 --- a/packages/ui-kit/src/components/TimeSeries/TimeSeries.tsx +++ b/packages/ui-kit/src/components/TimeSeries/TimeSeries.tsx @@ -63,7 +63,7 @@ export const TimeSeriesComponent = React.forwardRef({ componentContainer, - baseTheme, + appearance, renderLoader, errorFallback, renderEmpty @@ -160,7 +160,7 @@ export const TimeSeriesComponent = React.forwardRef ] @@ -218,7 +220,7 @@ export const TimeSeriesComponent = React.forwardRef( const WithContainer = React.forwardRef((props, ref) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const { errorFallbackProps, card, cardProps, ...componentProps } = props as any - const wrappedComponent = + const wrappedComponent = ( + + ) return ( diff --git a/packages/ui-kit/src/helpers/camelCaseToKebabCase/camelCaseToKebabCase.ts b/packages/ui-kit/src/helpers/camelCaseToKebabCase/camelCaseToKebabCase.ts index be0def2f..87535e9d 100644 --- a/packages/ui-kit/src/helpers/camelCaseToKebabCase/camelCaseToKebabCase.ts +++ b/packages/ui-kit/src/helpers/camelCaseToKebabCase/camelCaseToKebabCase.ts @@ -8,6 +8,6 @@ */ export const camelCaseToKebabCase = (str: string) => str - .replace(/([a-z])([A-Z])/g, '$1-$2') // Insert dash between lower and upper case letters + .replace(/([a-z])([A-Z0-9])/g, '$1-$2') // Insert dash between lower case letters and upper case letters or digits .replace(/^-/, '') // Remove leading dash if present .toLowerCase() // Convert to lower case diff --git a/packages/ui-kit/src/helpers/themeUtils/themeUtils.ts b/packages/ui-kit/src/helpers/themeUtils/themeUtils.ts index 4612d80f..c143c7b2 100644 --- a/packages/ui-kit/src/helpers/themeUtils/themeUtils.ts +++ b/packages/ui-kit/src/helpers/themeUtils/themeUtils.ts @@ -18,6 +18,7 @@ import type { ThemeTokenProps } from '../../themes/theme.types' import { themeDict } from '../../themes/themeDict' +import { camelCaseToKebabCase } from '../camelCaseToKebabCase' /** * Parses the computed style of a given HTML element and extracts theme-related properties. @@ -29,7 +30,10 @@ import { themeDict } from '../../themes/themeDict' */ export const parseComputedStyle = (themeContainer: HTMLElement) => { const computedStyle = getComputedStyle(themeContainer) - const theme: Partial = {} + // const theme: Partial = {} + const theme: { + [key: string]: string + } = {} themeDict.forEach((item) => { const cssVarValue = computedStyle.getPropertyValue(item.cssVarName) @@ -62,11 +66,9 @@ export const clearContainerStyle = (themeContainer: HTMLElement) => { * @param {HTMLElement} themeContainer - The HTML element to which the theme is to be applied. * @param {ThemeTokenProps} theme - An object containing the theme properties and their values to be applied. */ -export const setContainerStyle = (themeContainer: HTMLElement, theme: ThemeTokenProps) => { - themeDict.forEach((item) => { - const themePropValue = theme[item.name as keyof ThemeTokenProps]?.toString() - if (themePropValue) { - themeContainer.style.setProperty(item.cssVarName, themePropValue) - } +// export const setContainerStyle = (themeContainer: HTMLElement, theme: { [key: string]: string | number }) => { +export const setContainerStyle = (themeContainer: HTMLElement, tokens: { [key: string]: string }) => { + Object.keys(tokens).forEach((key) => { + themeContainer.style.setProperty(`--${camelCaseToKebabCase(key)}`, tokens[key]) }) } diff --git a/packages/ui-kit/src/themes/theme.types.ts b/packages/ui-kit/src/themes/theme.types.ts index 73c88aec..0d4ffd34 100644 --- a/packages/ui-kit/src/themes/theme.types.ts +++ b/packages/ui-kit/src/themes/theme.types.ts @@ -2,7 +2,49 @@ import { CSSProperties } from 'react' import type { DefaultThemes } from '../components/ThemeProvider/ThemeProvider.types' import { ThemeTokenGeneratedProps, ThemeCSSTokenGeneratedProps } from './generated/theme.types' -export interface ThemeTokenProps extends ThemeTokenGeneratedProps { +export const accentColors = [ + 'amber', + 'blue', + 'bronze', + 'brown', + 'crimson', + 'cyan', + 'gold', + 'grass', + 'gray', + 'green', + 'indigo', + 'iris', + 'jade', + 'lime', + 'mint', + 'orange', + 'pink', + 'plum', + 'purple', + 'red', + 'ruby', + 'sky', + 'teal', + 'tomato', + 'violet', + 'yellow' +] as const + +export type AccentColors = (typeof accentColors)[number] + +export type ThemeAppearances = 'light' | 'dark' + +export type ThemeTokenProps = { + appearance?: ThemeAppearances + componentContainer?: HTMLElement | null + getVar: (varName: string) => string + tokens: { + [key: string]: string + } +} + +export interface ThemeOldTokenProps extends ThemeTokenGeneratedProps { baseTheme?: DefaultThemes componentHeight?: CSSProperties['height'] transitionEaseTime?: CSSProperties['transitionDuration'] @@ -239,5 +281,7 @@ export type ThemeComponentProps = { className?: string /** Base theme to be used */ - baseTheme?: DefaultThemes + // baseTheme?: DefaultThemes + + appearance?: ThemeAppearances } diff --git a/packages/ui-kit/src/themes/themes.module.scss b/packages/ui-kit/src/themes/themes.module.scss index 8a2f86a3..33f1300d 100644 --- a/packages/ui-kit/src/themes/themes.module.scss +++ b/packages/ui-kit/src/themes/themes.module.scss @@ -1,4 +1,5 @@ /** themes.module.scss */ -@use './lightTheme'; -@use './darkTheme'; +@use './tokens/index'; +// @use './lightTheme'; +// @use './darkTheme'; diff --git a/packages/ui-kit/src/themes/tokens/_base.scss b/packages/ui-kit/src/themes/tokens/_base.scss new file mode 100644 index 00000000..258fa582 --- /dev/null +++ b/packages/ui-kit/src/themes/tokens/_base.scss @@ -0,0 +1,4 @@ +.propel-themes { + --component-height: 300px; + --transition-ease-time: 300ms; +} diff --git a/packages/ui-kit/src/themes/tokens/_colors.scss b/packages/ui-kit/src/themes/tokens/_colors.scss new file mode 100644 index 00000000..25e03272 --- /dev/null +++ b/packages/ui-kit/src/themes/tokens/_colors.scss @@ -0,0 +1,1176 @@ +/* * * * * * * * * * * * * * * * * * * */ +/* */ +/* Semantic colors */ +/* */ +/* * * * * * * * * * * * * * * * * * * */ + +:where(.propel-themes) { + --color-background: white; + --color-overlay: var(--black-a6); + --color-panel-solid: white; + --color-panel-translucent: rgba(255, 255, 255, 0.7); + --color-surface: rgba(255, 255, 255, 0.85); +} + +:is(.dark, .dark-theme), +:is(.dark, .dark-theme) :where(.propel-themes:not(.light, .light-theme)) { + --color-background: var(--gray-1); + --color-overlay: var(--black-a8); + --color-panel-solid: var(--gray-2); + --color-panel-translucent: var(--gray-a2); + --color-surface: rgba(0, 0, 0, 0.25); +} + +/* * * * * * * * * * * * * * * * * * * */ +/* */ +/* Transparency */ +/* */ +/* * * * * * * * * * * * * * * * * * * */ + +/* Because Chrome is buggy with box-shadow transitions from "transparent" keyword and/or RGB color into P3 colors. */ +/* Note: using `:where` here to guarantee that the P3 color will take over regardless of the output rule order. */ +:where(.propel-themes) { + --color-transparent: rgb(0 0 0 / 0); +} +@supports (color: color(display-p3 1 1 1)) { + @media (color-gamut: p3) { + .propel-themes { + --color-transparent: color(display-p3 0 0 0 / 0); + } + } +} + +/* * * * * * * * * * * * * * * * * * * */ +/* */ +/* Color scheme */ +/* */ +/* * * * * * * * * * * * * * * * * * * */ + +/* + * Make sure that forced light/dark appearance also sets corresponding browser colors, + * like input autofill color and body scrollbar + */ +.propel-themes:where(.light, .light-theme) { + color-scheme: light; +} +.propel-themes:where(.dark, .dark-theme) { + color-scheme: dark; +} + +/* * * * * * * * * * * * * * * * * * * */ +/* */ +/* Focus, selection, and autofill */ +/* */ +/* * * * * * * * * * * * * * * * * * * */ + +.propel-themes, +// [data-accent-color]:where(:not([data-accent-color=''], [data-accent-color='gray'])) { +[data-accent-color]:where(:not([data-accent-color=''])) { + --focus-1: var(--accent-1); + --focus-2: var(--accent-2); + --focus-3: var(--accent-3); + --focus-4: var(--accent-4); + --focus-5: var(--accent-5); + --focus-6: var(--accent-6); + --focus-7: var(--accent-7); + --focus-8: var(--accent-8); + --focus-9: var(--accent-9); + --focus-10: var(--accent-10); + --focus-11: var(--accent-11); + --focus-12: var(--accent-12); + + --focus-a1: var(--accent-a1); + --focus-a2: var(--accent-a2); + --focus-a3: var(--accent-a3); + --focus-a4: var(--accent-a4); + --focus-a5: var(--accent-a5); + --focus-a6: var(--accent-a6); + --focus-a7: var(--accent-a7); + --focus-a8: var(--accent-a8); + --focus-a9: var(--accent-a9); + --focus-a10: var(--accent-a10); + --focus-a11: var(--accent-a11); + --focus-a12: var(--accent-a12); +} + +.propel-themes ::selection { + background-color: var(--focus-a5); +} + +/* * * * * * * * * * * * * * * * * * * */ +/* */ +/* Background and text */ +/* */ +/* * * * * * * * * * * * * * * * * * * */ + +.propel-themes { + color: var(--gray-12); + &:where([data-has-background='true']) { + background-color: var(--color-background); + } +} + +/* * * * * * * * * * * * * * * * * * * */ +/* */ +/* Accent color */ +/* */ +/* * * * * * * * * * * * * * * * * * * */ + +[data-accent-color='amber'] { + --accent-1: var(--amber-1); + --accent-2: var(--amber-2); + --accent-3: var(--amber-3); + --accent-4: var(--amber-4); + --accent-5: var(--amber-5); + --accent-6: var(--amber-6); + --accent-7: var(--amber-7); + --accent-8: var(--amber-8); + --accent-9: var(--amber-9); + --accent-10: var(--amber-10); + --accent-11: var(--amber-11); + --accent-12: var(--amber-12); + + --accent-a1: var(--amber-a1); + --accent-a2: var(--amber-a2); + --accent-a3: var(--amber-a3); + --accent-a4: var(--amber-a4); + --accent-a5: var(--amber-a5); + --accent-a6: var(--amber-a6); + --accent-a7: var(--amber-a7); + --accent-a8: var(--amber-a8); + --accent-a9: var(--amber-a9); + --accent-a10: var(--amber-a10); + --accent-a11: var(--amber-a11); + --accent-a12: var(--amber-a12); + + --accent-contrast: var(--amber-contrast); + --accent-surface: var(--amber-surface); + --accent-indicator: var(--amber-indicator); + --accent-track: var(--amber-track); +} + +[data-accent-color='blue'] { + --accent-1: var(--blue-1); + --accent-2: var(--blue-2); + --accent-3: var(--blue-3); + --accent-4: var(--blue-4); + --accent-5: var(--blue-5); + --accent-6: var(--blue-6); + --accent-7: var(--blue-7); + --accent-8: var(--blue-8); + --accent-9: var(--blue-9); + --accent-10: var(--blue-10); + --accent-11: var(--blue-11); + --accent-12: var(--blue-12); + + --accent-a1: var(--blue-a1); + --accent-a2: var(--blue-a2); + --accent-a3: var(--blue-a3); + --accent-a4: var(--blue-a4); + --accent-a5: var(--blue-a5); + --accent-a6: var(--blue-a6); + --accent-a7: var(--blue-a7); + --accent-a8: var(--blue-a8); + --accent-a9: var(--blue-a9); + --accent-a10: var(--blue-a10); + --accent-a11: var(--blue-a11); + --accent-a12: var(--blue-a12); + + --accent-contrast: var(--blue-contrast); + --accent-surface: var(--blue-surface); + --accent-indicator: var(--blue-indicator); + --accent-track: var(--blue-track); + + --blue-contrast: white; + + &.light, + &.light-theme { + --blue-surface: #f1f9ffcc; + --blue-indicator: var(--blue-9); + --blue-track: var(--blue-9); + + @supports (color: color(display-p3 1 1 1)) { + @media (color-gamut: p3) { + --blue-surface: color(display-p3 0.9529 0.9765 0.9961 / 0.8); + } + } + } + + &.dark, + &.dark-theme { + --blue-surface: #11213d80; + --blue-indicator: var(--blue-9); + --blue-track: var(--blue-9); + + @supports (color: color(display-p3 1 1 1)) { + @media (color-gamut: p3) { + --blue-surface: color(display-p3 0.0706 0.1255 0.2196 / 0.5); + } + } + } +} + +[data-accent-color='bronze'] { + --accent-1: var(--bronze-1); + --accent-2: var(--bronze-2); + --accent-3: var(--bronze-3); + --accent-4: var(--bronze-4); + --accent-5: var(--bronze-5); + --accent-6: var(--bronze-6); + --accent-7: var(--bronze-7); + --accent-8: var(--bronze-8); + --accent-9: var(--bronze-9); + --accent-10: var(--bronze-10); + --accent-11: var(--bronze-11); + --accent-12: var(--bronze-12); + + --accent-a1: var(--bronze-a1); + --accent-a2: var(--bronze-a2); + --accent-a3: var(--bronze-a3); + --accent-a4: var(--bronze-a4); + --accent-a5: var(--bronze-a5); + --accent-a6: var(--bronze-a6); + --accent-a7: var(--bronze-a7); + --accent-a8: var(--bronze-a8); + --accent-a9: var(--bronze-a9); + --accent-a10: var(--bronze-a10); + --accent-a11: var(--bronze-a11); + --accent-a12: var(--bronze-a12); + + --accent-contrast: var(--bronze-contrast); + --accent-surface: var(--bronze-surface); + --accent-indicator: var(--bronze-indicator); + --accent-track: var(--bronze-track); +} + +[data-accent-color='brown'] { + --accent-1: var(--brown-1); + --accent-2: var(--brown-2); + --accent-3: var(--brown-3); + --accent-4: var(--brown-4); + --accent-5: var(--brown-5); + --accent-6: var(--brown-6); + --accent-7: var(--brown-7); + --accent-8: var(--brown-8); + --accent-9: var(--brown-9); + --accent-10: var(--brown-10); + --accent-11: var(--brown-11); + --accent-12: var(--brown-12); + + --accent-a1: var(--brown-a1); + --accent-a2: var(--brown-a2); + --accent-a3: var(--brown-a3); + --accent-a4: var(--brown-a4); + --accent-a5: var(--brown-a5); + --accent-a6: var(--brown-a6); + --accent-a7: var(--brown-a7); + --accent-a8: var(--brown-a8); + --accent-a9: var(--brown-a9); + --accent-a10: var(--brown-a10); + --accent-a11: var(--brown-a11); + --accent-a12: var(--brown-a12); + + --accent-contrast: var(--brown-contrast); + --accent-surface: var(--brown-surface); + --accent-indicator: var(--brown-indicator); + --accent-track: var(--brown-track); +} + +[data-accent-color='crimson'] { + --accent-1: var(--crimson-1); + --accent-2: var(--crimson-2); + --accent-3: var(--crimson-3); + --accent-4: var(--crimson-4); + --accent-5: var(--crimson-5); + --accent-6: var(--crimson-6); + --accent-7: var(--crimson-7); + --accent-8: var(--crimson-8); + --accent-9: var(--crimson-9); + --accent-10: var(--crimson-10); + --accent-11: var(--crimson-11); + --accent-12: var(--crimson-12); + + --accent-a1: var(--crimson-a1); + --accent-a2: var(--crimson-a2); + --accent-a3: var(--crimson-a3); + --accent-a4: var(--crimson-a4); + --accent-a5: var(--crimson-a5); + --accent-a6: var(--crimson-a6); + --accent-a7: var(--crimson-a7); + --accent-a8: var(--crimson-a8); + --accent-a9: var(--crimson-a9); + --accent-a10: var(--crimson-a10); + --accent-a11: var(--crimson-a11); + --accent-a12: var(--crimson-a12); + + --accent-contrast: var(--crimson-contrast); + --accent-surface: var(--crimson-surface); + --accent-indicator: var(--crimson-indicator); + --accent-track: var(--crimson-track); +} + +[data-accent-color='cyan'] { + --accent-1: var(--cyan-1); + --accent-2: var(--cyan-2); + --accent-3: var(--cyan-3); + --accent-4: var(--cyan-4); + --accent-5: var(--cyan-5); + --accent-6: var(--cyan-6); + --accent-7: var(--cyan-7); + --accent-8: var(--cyan-8); + --accent-9: var(--cyan-9); + --accent-10: var(--cyan-10); + --accent-11: var(--cyan-11); + --accent-12: var(--cyan-12); + + --accent-a1: var(--cyan-a1); + --accent-a2: var(--cyan-a2); + --accent-a3: var(--cyan-a3); + --accent-a4: var(--cyan-a4); + --accent-a5: var(--cyan-a5); + --accent-a6: var(--cyan-a6); + --accent-a7: var(--cyan-a7); + --accent-a8: var(--cyan-a8); + --accent-a9: var(--cyan-a9); + --accent-a10: var(--cyan-a10); + --accent-a11: var(--cyan-a11); + --accent-a12: var(--cyan-a12); + + --accent-contrast: var(--cyan-contrast); + --accent-surface: var(--cyan-surface); + --accent-indicator: var(--cyan-indicator); + --accent-track: var(--cyan-track); +} + +[data-accent-color='gold'] { + --accent-1: var(--gold-1); + --accent-2: var(--gold-2); + --accent-3: var(--gold-3); + --accent-4: var(--gold-4); + --accent-5: var(--gold-5); + --accent-6: var(--gold-6); + --accent-7: var(--gold-7); + --accent-8: var(--gold-8); + --accent-9: var(--gold-9); + --accent-10: var(--gold-10); + --accent-11: var(--gold-11); + --accent-12: var(--gold-12); + + --accent-a1: var(--gold-a1); + --accent-a2: var(--gold-a2); + --accent-a3: var(--gold-a3); + --accent-a4: var(--gold-a4); + --accent-a5: var(--gold-a5); + --accent-a6: var(--gold-a6); + --accent-a7: var(--gold-a7); + --accent-a8: var(--gold-a8); + --accent-a9: var(--gold-a9); + --accent-a10: var(--gold-a10); + --accent-a11: var(--gold-a11); + --accent-a12: var(--gold-a12); + + --accent-contrast: var(--gold-contrast); + --accent-surface: var(--gold-surface); + --accent-indicator: var(--gold-indicator); + --accent-track: var(--gold-track); +} + +[data-accent-color='grass'] { + --accent-1: var(--grass-1); + --accent-2: var(--grass-2); + --accent-3: var(--grass-3); + --accent-4: var(--grass-4); + --accent-5: var(--grass-5); + --accent-6: var(--grass-6); + --accent-7: var(--grass-7); + --accent-8: var(--grass-8); + --accent-9: var(--grass-9); + --accent-10: var(--grass-10); + --accent-11: var(--grass-11); + --accent-12: var(--grass-12); + + --accent-a1: var(--grass-a1); + --accent-a2: var(--grass-a2); + --accent-a3: var(--grass-a3); + --accent-a4: var(--grass-a4); + --accent-a5: var(--grass-a5); + --accent-a6: var(--grass-a6); + --accent-a7: var(--grass-a7); + --accent-a8: var(--grass-a8); + --accent-a9: var(--grass-a9); + --accent-a10: var(--grass-a10); + --accent-a11: var(--grass-a11); + --accent-a12: var(--grass-a12); + + --accent-contrast: var(--grass-contrast); + --accent-surface: var(--grass-surface); + --accent-indicator: var(--grass-indicator); + --accent-track: var(--grass-track); +} + +[data-accent-color='gray'] { + --accent-1: var(--gray-1); + --accent-2: var(--gray-2); + --accent-3: var(--gray-3); + --accent-4: var(--gray-4); + --accent-5: var(--gray-5); + --accent-6: var(--gray-6); + --accent-7: var(--gray-7); + --accent-8: var(--gray-8); + --accent-9: var(--gray-9); + --accent-10: var(--gray-10); + --accent-11: var(--gray-11); + --accent-12: var(--gray-12); + + --accent-a1: var(--gray-a1); + --accent-a2: var(--gray-a2); + --accent-a3: var(--gray-a3); + --accent-a4: var(--gray-a4); + --accent-a5: var(--gray-a5); + --accent-a6: var(--gray-a6); + --accent-a7: var(--gray-a7); + --accent-a8: var(--gray-a8); + --accent-a9: var(--gray-a9); + --accent-a10: var(--gray-a10); + --accent-a11: var(--gray-a11); + --accent-a12: var(--gray-a12); + + --accent-contrast: var(--gray-contrast); + --accent-surface: var(--gray-surface); + --accent-indicator: var(--gray-indicator); + --accent-track: var(--gray-track); +} + +[data-accent-color='green'] { + --accent-1: var(--green-1); + --accent-2: var(--green-2); + --accent-3: var(--green-3); + --accent-4: var(--green-4); + --accent-5: var(--green-5); + --accent-6: var(--green-6); + --accent-7: var(--green-7); + --accent-8: var(--green-8); + --accent-9: var(--green-9); + --accent-10: var(--green-10); + --accent-11: var(--green-11); + --accent-12: var(--green-12); + + --accent-a1: var(--green-a1); + --accent-a2: var(--green-a2); + --accent-a3: var(--green-a3); + --accent-a4: var(--green-a4); + --accent-a5: var(--green-a5); + --accent-a6: var(--green-a6); + --accent-a7: var(--green-a7); + --accent-a8: var(--green-a8); + --accent-a9: var(--green-a9); + --accent-a10: var(--green-a10); + --accent-a11: var(--green-a11); + --accent-a12: var(--green-a12); + + --accent-contrast: var(--green-contrast); + --accent-surface: var(--green-surface); + --accent-indicator: var(--green-indicator); + --accent-track: var(--green-track); +} + +[data-accent-color='indigo'] { + --accent-1: var(--indigo-1); + --accent-2: var(--indigo-2); + --accent-3: var(--indigo-3); + --accent-4: var(--indigo-4); + --accent-5: var(--indigo-5); + --accent-6: var(--indigo-6); + --accent-7: var(--indigo-7); + --accent-8: var(--indigo-8); + --accent-9: var(--indigo-9); + --accent-10: var(--indigo-10); + --accent-11: var(--indigo-11); + --accent-12: var(--indigo-12); + + --accent-a1: var(--indigo-a1); + --accent-a2: var(--indigo-a2); + --accent-a3: var(--indigo-a3); + --accent-a4: var(--indigo-a4); + --accent-a5: var(--indigo-a5); + --accent-a6: var(--indigo-a6); + --accent-a7: var(--indigo-a7); + --accent-a8: var(--indigo-a8); + --accent-a9: var(--indigo-a9); + --accent-a10: var(--indigo-a10); + --accent-a11: var(--indigo-a11); + --accent-a12: var(--indigo-a12); + + --accent-contrast: var(--indigo-contrast); + --accent-surface: var(--indigo-surface); + --accent-indicator: var(--indigo-indicator); + --accent-track: var(--indigo-track); +} + +[data-accent-color='iris'] { + --accent-1: var(--iris-1); + --accent-2: var(--iris-2); + --accent-3: var(--iris-3); + --accent-4: var(--iris-4); + --accent-5: var(--iris-5); + --accent-6: var(--iris-6); + --accent-7: var(--iris-7); + --accent-8: var(--iris-8); + --accent-9: var(--iris-9); + --accent-10: var(--iris-10); + --accent-11: var(--iris-11); + --accent-12: var(--iris-12); + + --accent-a1: var(--iris-a1); + --accent-a2: var(--iris-a2); + --accent-a3: var(--iris-a3); + --accent-a4: var(--iris-a4); + --accent-a5: var(--iris-a5); + --accent-a6: var(--iris-a6); + --accent-a7: var(--iris-a7); + --accent-a8: var(--iris-a8); + --accent-a9: var(--iris-a9); + --accent-a10: var(--iris-a10); + --accent-a11: var(--iris-a11); + --accent-a12: var(--iris-a12); + + --accent-contrast: var(--iris-contrast); + --accent-surface: var(--iris-surface); + --accent-indicator: var(--iris-indicator); + --accent-track: var(--iris-track); +} + +[data-accent-color='jade'] { + --accent-1: var(--jade-1); + --accent-2: var(--jade-2); + --accent-3: var(--jade-3); + --accent-4: var(--jade-4); + --accent-5: var(--jade-5); + --accent-6: var(--jade-6); + --accent-7: var(--jade-7); + --accent-8: var(--jade-8); + --accent-9: var(--jade-9); + --accent-10: var(--jade-10); + --accent-11: var(--jade-11); + --accent-12: var(--jade-12); + + --accent-a1: var(--jade-a1); + --accent-a2: var(--jade-a2); + --accent-a3: var(--jade-a3); + --accent-a4: var(--jade-a4); + --accent-a5: var(--jade-a5); + --accent-a6: var(--jade-a6); + --accent-a7: var(--jade-a7); + --accent-a8: var(--jade-a8); + --accent-a9: var(--jade-a9); + --accent-a10: var(--jade-a10); + --accent-a11: var(--jade-a11); + --accent-a12: var(--jade-a12); + + --accent-contrast: var(--jade-contrast); + --accent-surface: var(--jade-surface); + --accent-indicator: var(--jade-indicator); + --accent-track: var(--jade-track); +} + +[data-accent-color='lime'] { + --accent-1: var(--lime-1); + --accent-2: var(--lime-2); + --accent-3: var(--lime-3); + --accent-4: var(--lime-4); + --accent-5: var(--lime-5); + --accent-6: var(--lime-6); + --accent-7: var(--lime-7); + --accent-8: var(--lime-8); + --accent-9: var(--lime-9); + --accent-10: var(--lime-10); + --accent-11: var(--lime-11); + --accent-12: var(--lime-12); + + --accent-a1: var(--lime-a1); + --accent-a2: var(--lime-a2); + --accent-a3: var(--lime-a3); + --accent-a4: var(--lime-a4); + --accent-a5: var(--lime-a5); + --accent-a6: var(--lime-a6); + --accent-a7: var(--lime-a7); + --accent-a8: var(--lime-a8); + --accent-a9: var(--lime-a9); + --accent-a10: var(--lime-a10); + --accent-a11: var(--lime-a11); + --accent-a12: var(--lime-a12); + + --accent-contrast: var(--lime-contrast); + --accent-surface: var(--lime-surface); + --accent-indicator: var(--lime-indicator); + --accent-track: var(--lime-track); +} + +[data-accent-color='mint'] { + --accent-1: var(--mint-1); + --accent-2: var(--mint-2); + --accent-3: var(--mint-3); + --accent-4: var(--mint-4); + --accent-5: var(--mint-5); + --accent-6: var(--mint-6); + --accent-7: var(--mint-7); + --accent-8: var(--mint-8); + --accent-9: var(--mint-9); + --accent-10: var(--mint-10); + --accent-11: var(--mint-11); + --accent-12: var(--mint-12); + + --accent-a1: var(--mint-a1); + --accent-a2: var(--mint-a2); + --accent-a3: var(--mint-a3); + --accent-a4: var(--mint-a4); + --accent-a5: var(--mint-a5); + --accent-a6: var(--mint-a6); + --accent-a7: var(--mint-a7); + --accent-a8: var(--mint-a8); + --accent-a9: var(--mint-a9); + --accent-a10: var(--mint-a10); + --accent-a11: var(--mint-a11); + --accent-a12: var(--mint-a12); + + --accent-contrast: var(--mint-contrast); + --accent-surface: var(--mint-surface); + --accent-indicator: var(--mint-indicator); + --accent-track: var(--mint-track); +} + +[data-accent-color='orange'] { + --accent-1: var(--orange-1); + --accent-2: var(--orange-2); + --accent-3: var(--orange-3); + --accent-4: var(--orange-4); + --accent-5: var(--orange-5); + --accent-6: var(--orange-6); + --accent-7: var(--orange-7); + --accent-8: var(--orange-8); + --accent-9: var(--orange-9); + --accent-10: var(--orange-10); + --accent-11: var(--orange-11); + --accent-12: var(--orange-12); + + --accent-a1: var(--orange-a1); + --accent-a2: var(--orange-a2); + --accent-a3: var(--orange-a3); + --accent-a4: var(--orange-a4); + --accent-a5: var(--orange-a5); + --accent-a6: var(--orange-a6); + --accent-a7: var(--orange-a7); + --accent-a8: var(--orange-a8); + --accent-a9: var(--orange-a9); + --accent-a10: var(--orange-a10); + --accent-a11: var(--orange-a11); + --accent-a12: var(--orange-a12); + + --accent-contrast: var(--orange-contrast); + --accent-surface: var(--orange-surface); + --accent-indicator: var(--orange-indicator); + --accent-track: var(--orange-track); +} + +[data-accent-color='pink'] { + --accent-1: var(--pink-1); + --accent-2: var(--pink-2); + --accent-3: var(--pink-3); + --accent-4: var(--pink-4); + --accent-5: var(--pink-5); + --accent-6: var(--pink-6); + --accent-7: var(--pink-7); + --accent-8: var(--pink-8); + --accent-9: var(--pink-9); + --accent-10: var(--pink-10); + --accent-11: var(--pink-11); + --accent-12: var(--pink-12); + + --accent-a1: var(--pink-a1); + --accent-a2: var(--pink-a2); + --accent-a3: var(--pink-a3); + --accent-a4: var(--pink-a4); + --accent-a5: var(--pink-a5); + --accent-a6: var(--pink-a6); + --accent-a7: var(--pink-a7); + --accent-a8: var(--pink-a8); + --accent-a9: var(--pink-a9); + --accent-a10: var(--pink-a10); + --accent-a11: var(--pink-a11); + --accent-a12: var(--pink-a12); + + --accent-contrast: var(--pink-contrast); + --accent-surface: var(--pink-surface); + --accent-indicator: var(--pink-indicator); + --accent-track: var(--pink-track); +} + +[data-accent-color='plum'] { + --accent-1: var(--plum-1); + --accent-2: var(--plum-2); + --accent-3: var(--plum-3); + --accent-4: var(--plum-4); + --accent-5: var(--plum-5); + --accent-6: var(--plum-6); + --accent-7: var(--plum-7); + --accent-8: var(--plum-8); + --accent-9: var(--plum-9); + --accent-10: var(--plum-10); + --accent-11: var(--plum-11); + --accent-12: var(--plum-12); + + --accent-a1: var(--plum-a1); + --accent-a2: var(--plum-a2); + --accent-a3: var(--plum-a3); + --accent-a4: var(--plum-a4); + --accent-a5: var(--plum-a5); + --accent-a6: var(--plum-a6); + --accent-a7: var(--plum-a7); + --accent-a8: var(--plum-a8); + --accent-a9: var(--plum-a9); + --accent-a10: var(--plum-a10); + --accent-a11: var(--plum-a11); + --accent-a12: var(--plum-a12); + + --accent-contrast: var(--plum-contrast); + --accent-surface: var(--plum-surface); + --accent-indicator: var(--plum-indicator); + --accent-track: var(--plum-track); +} + +[data-accent-color='purple'] { + --accent-1: var(--purple-1); + --accent-2: var(--purple-2); + --accent-3: var(--purple-3); + --accent-4: var(--purple-4); + --accent-5: var(--purple-5); + --accent-6: var(--purple-6); + --accent-7: var(--purple-7); + --accent-8: var(--purple-8); + --accent-9: var(--purple-9); + --accent-10: var(--purple-10); + --accent-11: var(--purple-11); + --accent-12: var(--purple-12); + + --accent-a1: var(--purple-a1); + --accent-a2: var(--purple-a2); + --accent-a3: var(--purple-a3); + --accent-a4: var(--purple-a4); + --accent-a5: var(--purple-a5); + --accent-a6: var(--purple-a6); + --accent-a7: var(--purple-a7); + --accent-a8: var(--purple-a8); + --accent-a9: var(--purple-a9); + --accent-a10: var(--purple-a10); + --accent-a11: var(--purple-a11); + --accent-a12: var(--purple-a12); + + --accent-contrast: var(--purple-contrast); + --accent-surface: var(--purple-surface); + --accent-indicator: var(--purple-indicator); + --accent-track: var(--purple-track); +} + +[data-accent-color='red'] { + --accent-1: var(--red-1); + --accent-2: var(--red-2); + --accent-3: var(--red-3); + --accent-4: var(--red-4); + --accent-5: var(--red-5); + --accent-6: var(--red-6); + --accent-7: var(--red-7); + --accent-8: var(--red-8); + --accent-9: var(--red-9); + --accent-10: var(--red-10); + --accent-11: var(--red-11); + --accent-12: var(--red-12); + + --accent-a1: var(--red-a1); + --accent-a2: var(--red-a2); + --accent-a3: var(--red-a3); + --accent-a4: var(--red-a4); + --accent-a5: var(--red-a5); + --accent-a6: var(--red-a6); + --accent-a7: var(--red-a7); + --accent-a8: var(--red-a8); + --accent-a9: var(--red-a9); + --accent-a10: var(--red-a10); + --accent-a11: var(--red-a11); + --accent-a12: var(--red-a12); + + --accent-contrast: var(--red-contrast); + --accent-surface: var(--red-surface); + --accent-indicator: var(--red-indicator); + --accent-track: var(--red-track); +} + +[data-accent-color='ruby'] { + --accent-1: var(--ruby-1); + --accent-2: var(--ruby-2); + --accent-3: var(--ruby-3); + --accent-4: var(--ruby-4); + --accent-5: var(--ruby-5); + --accent-6: var(--ruby-6); + --accent-7: var(--ruby-7); + --accent-8: var(--ruby-8); + --accent-9: var(--ruby-9); + --accent-10: var(--ruby-10); + --accent-11: var(--ruby-11); + --accent-12: var(--ruby-12); + + --accent-a1: var(--ruby-a1); + --accent-a2: var(--ruby-a2); + --accent-a3: var(--ruby-a3); + --accent-a4: var(--ruby-a4); + --accent-a5: var(--ruby-a5); + --accent-a6: var(--ruby-a6); + --accent-a7: var(--ruby-a7); + --accent-a8: var(--ruby-a8); + --accent-a9: var(--ruby-a9); + --accent-a10: var(--ruby-a10); + --accent-a11: var(--ruby-a11); + --accent-a12: var(--ruby-a12); + + --accent-contrast: var(--ruby-contrast); + --accent-surface: var(--ruby-surface); + --accent-indicator: var(--ruby-indicator); + --accent-track: var(--ruby-track); +} + +[data-accent-color='sky'] { + --accent-1: var(--sky-1); + --accent-2: var(--sky-2); + --accent-3: var(--sky-3); + --accent-4: var(--sky-4); + --accent-5: var(--sky-5); + --accent-6: var(--sky-6); + --accent-7: var(--sky-7); + --accent-8: var(--sky-8); + --accent-9: var(--sky-9); + --accent-10: var(--sky-10); + --accent-11: var(--sky-11); + --accent-12: var(--sky-12); + + --accent-a1: var(--sky-a1); + --accent-a2: var(--sky-a2); + --accent-a3: var(--sky-a3); + --accent-a4: var(--sky-a4); + --accent-a5: var(--sky-a5); + --accent-a6: var(--sky-a6); + --accent-a7: var(--sky-a7); + --accent-a8: var(--sky-a8); + --accent-a9: var(--sky-a9); + --accent-a10: var(--sky-a10); + --accent-a11: var(--sky-a11); + --accent-a12: var(--sky-a12); + + --accent-contrast: var(--sky-contrast); + --accent-surface: var(--sky-surface); + --accent-indicator: var(--sky-indicator); + --accent-track: var(--sky-track); +} + +[data-accent-color='teal'] { + --accent-1: var(--teal-1); + --accent-2: var(--teal-2); + --accent-3: var(--teal-3); + --accent-4: var(--teal-4); + --accent-5: var(--teal-5); + --accent-6: var(--teal-6); + --accent-7: var(--teal-7); + --accent-8: var(--teal-8); + --accent-9: var(--teal-9); + --accent-10: var(--teal-10); + --accent-11: var(--teal-11); + --accent-12: var(--teal-12); + + --accent-a1: var(--teal-a1); + --accent-a2: var(--teal-a2); + --accent-a3: var(--teal-a3); + --accent-a4: var(--teal-a4); + --accent-a5: var(--teal-a5); + --accent-a6: var(--teal-a6); + --accent-a7: var(--teal-a7); + --accent-a8: var(--teal-a8); + --accent-a9: var(--teal-a9); + --accent-a10: var(--teal-a10); + --accent-a11: var(--teal-a11); + --accent-a12: var(--teal-a12); + + --accent-contrast: var(--teal-contrast); + --accent-surface: var(--teal-surface); + --accent-indicator: var(--teal-indicator); + --accent-track: var(--teal-track); +} + +[data-accent-color='tomato'] { + --accent-1: var(--tomato-1); + --accent-2: var(--tomato-2); + --accent-3: var(--tomato-3); + --accent-4: var(--tomato-4); + --accent-5: var(--tomato-5); + --accent-6: var(--tomato-6); + --accent-7: var(--tomato-7); + --accent-8: var(--tomato-8); + --accent-9: var(--tomato-9); + --accent-10: var(--tomato-10); + --accent-11: var(--tomato-11); + --accent-12: var(--tomato-12); + + --accent-a1: var(--tomato-a1); + --accent-a2: var(--tomato-a2); + --accent-a3: var(--tomato-a3); + --accent-a4: var(--tomato-a4); + --accent-a5: var(--tomato-a5); + --accent-a6: var(--tomato-a6); + --accent-a7: var(--tomato-a7); + --accent-a8: var(--tomato-a8); + --accent-a9: var(--tomato-a9); + --accent-a10: var(--tomato-a10); + --accent-a11: var(--tomato-a11); + --accent-a12: var(--tomato-a12); + + --accent-contrast: var(--tomato-contrast); + --accent-surface: var(--tomato-surface); + --accent-indicator: var(--tomato-indicator); + --accent-track: var(--tomato-track); +} + +[data-accent-color='violet'] { + --accent-1: var(--violet-1); + --accent-2: var(--violet-2); + --accent-3: var(--violet-3); + --accent-4: var(--violet-4); + --accent-5: var(--violet-5); + --accent-6: var(--violet-6); + --accent-7: var(--violet-7); + --accent-8: var(--violet-8); + --accent-9: var(--violet-9); + --accent-10: var(--violet-10); + --accent-11: var(--violet-11); + --accent-12: var(--violet-12); + + --accent-a1: var(--violet-a1); + --accent-a2: var(--violet-a2); + --accent-a3: var(--violet-a3); + --accent-a4: var(--violet-a4); + --accent-a5: var(--violet-a5); + --accent-a6: var(--violet-a6); + --accent-a7: var(--violet-a7); + --accent-a8: var(--violet-a8); + --accent-a9: var(--violet-a9); + --accent-a10: var(--violet-a10); + --accent-a11: var(--violet-a11); + --accent-a12: var(--violet-a12); + + --accent-contrast: var(--violet-contrast); + --accent-surface: var(--violet-surface); + --accent-indicator: var(--violet-indicator); + --accent-track: var(--violet-track); +} + +[data-accent-color='yellow'] { + --accent-1: var(--yellow-1); + --accent-2: var(--yellow-2); + --accent-3: var(--yellow-3); + --accent-4: var(--yellow-4); + --accent-5: var(--yellow-5); + --accent-6: var(--yellow-6); + --accent-7: var(--yellow-7); + --accent-8: var(--yellow-8); + --accent-9: var(--yellow-9); + --accent-10: var(--yellow-10); + --accent-11: var(--yellow-11); + --accent-12: var(--yellow-12); + + --accent-a1: var(--yellow-a1); + --accent-a2: var(--yellow-a2); + --accent-a3: var(--yellow-a3); + --accent-a4: var(--yellow-a4); + --accent-a5: var(--yellow-a5); + --accent-a6: var(--yellow-a6); + --accent-a7: var(--yellow-a7); + --accent-a8: var(--yellow-a8); + --accent-a9: var(--yellow-a9); + --accent-a10: var(--yellow-a10); + --accent-a11: var(--yellow-a11); + --accent-a12: var(--yellow-a12); + + --accent-contrast: var(--yellow-contrast); + --accent-surface: var(--yellow-surface); + --accent-indicator: var(--yellow-indicator); + --accent-track: var(--yellow-track); +} + +/* * * * * * * * * * * * * * * * * * * */ +/* */ +/* Gray color */ +/* */ +/* * * * * * * * * * * * * * * * * * * */ + +.propel-themes { + &:where([data-gray-color='mauve']) { + --gray-1: var(--mauve-1); + --gray-2: var(--mauve-2); + --gray-3: var(--mauve-3); + --gray-4: var(--mauve-4); + --gray-5: var(--mauve-5); + --gray-6: var(--mauve-6); + --gray-7: var(--mauve-7); + --gray-8: var(--mauve-8); + --gray-9: var(--mauve-9); + --gray-10: var(--mauve-10); + --gray-11: var(--mauve-11); + --gray-12: var(--mauve-12); + + --gray-a1: var(--mauve-a1); + --gray-a2: var(--mauve-a2); + --gray-a3: var(--mauve-a3); + --gray-a4: var(--mauve-a4); + --gray-a5: var(--mauve-a5); + --gray-a6: var(--mauve-a6); + --gray-a7: var(--mauve-a7); + --gray-a8: var(--mauve-a8); + --gray-a9: var(--mauve-a9); + --gray-a10: var(--mauve-a10); + --gray-a11: var(--mauve-a11); + --gray-a12: var(--mauve-a12); + + --gray-contrast: var(--mauve-contrast); + --gray-surface: var(--mauve-surface); + --gray-indicator: var(--mauve-indicator); + --gray-track: var(--mauve-track); + } + + &:where([data-gray-color='olive']) { + --gray-1: var(--olive-1); + --gray-2: var(--olive-2); + --gray-3: var(--olive-3); + --gray-4: var(--olive-4); + --gray-5: var(--olive-5); + --gray-6: var(--olive-6); + --gray-7: var(--olive-7); + --gray-8: var(--olive-8); + --gray-9: var(--olive-9); + --gray-10: var(--olive-10); + --gray-11: var(--olive-11); + --gray-12: var(--olive-12); + + --gray-a1: var(--olive-a1); + --gray-a2: var(--olive-a2); + --gray-a3: var(--olive-a3); + --gray-a4: var(--olive-a4); + --gray-a5: var(--olive-a5); + --gray-a6: var(--olive-a6); + --gray-a7: var(--olive-a7); + --gray-a8: var(--olive-a8); + --gray-a9: var(--olive-a9); + --gray-a10: var(--olive-a10); + --gray-a11: var(--olive-a11); + --gray-a12: var(--olive-a12); + + --gray-contrast: var(--olive-contrast); + --gray-surface: var(--olive-surface); + --gray-indicator: var(--olive-indicator); + --gray-track: var(--olive-track); + } + + &:where([data-gray-color='sage']) { + --gray-1: var(--sage-1); + --gray-2: var(--sage-2); + --gray-3: var(--sage-3); + --gray-4: var(--sage-4); + --gray-5: var(--sage-5); + --gray-6: var(--sage-6); + --gray-7: var(--sage-7); + --gray-8: var(--sage-8); + --gray-9: var(--sage-9); + --gray-10: var(--sage-10); + --gray-11: var(--sage-11); + --gray-12: var(--sage-12); + + --gray-a1: var(--sage-a1); + --gray-a2: var(--sage-a2); + --gray-a3: var(--sage-a3); + --gray-a4: var(--sage-a4); + --gray-a5: var(--sage-a5); + --gray-a6: var(--sage-a6); + --gray-a7: var(--sage-a7); + --gray-a8: var(--sage-a8); + --gray-a9: var(--sage-a9); + --gray-a10: var(--sage-a10); + --gray-a11: var(--sage-a11); + --gray-a12: var(--sage-a12); + + --gray-contrast: var(--sage-contrast); + --gray-surface: var(--sage-surface); + --gray-indicator: var(--sage-indicator); + --gray-track: var(--sage-track); + } + + &:where([data-gray-color='sand']) { + --gray-1: var(--sand-1); + --gray-2: var(--sand-2); + --gray-3: var(--sand-3); + --gray-4: var(--sand-4); + --gray-5: var(--sand-5); + --gray-6: var(--sand-6); + --gray-7: var(--sand-7); + --gray-8: var(--sand-8); + --gray-9: var(--sand-9); + --gray-10: var(--sand-10); + --gray-11: var(--sand-11); + --gray-12: var(--sand-12); + + --gray-a1: var(--sand-a1); + --gray-a2: var(--sand-a2); + --gray-a3: var(--sand-a3); + --gray-a4: var(--sand-a4); + --gray-a5: var(--sand-a5); + --gray-a6: var(--sand-a6); + --gray-a7: var(--sand-a7); + --gray-a8: var(--sand-a8); + --gray-a9: var(--sand-a9); + --gray-a10: var(--sand-a10); + --gray-a11: var(--sand-a11); + --gray-a12: var(--sand-a12); + + --gray-contrast: var(--sand-contrast); + --gray-surface: var(--sand-surface); + --gray-indicator: var(--sand-indicator); + --gray-track: var(--sand-track); + } + + &:where([data-gray-color='slate']) { + --gray-1: var(--slate-1); + --gray-2: var(--slate-2); + --gray-3: var(--slate-3); + --gray-4: var(--slate-4); + --gray-5: var(--slate-5); + --gray-6: var(--slate-6); + --gray-7: var(--slate-7); + --gray-8: var(--slate-8); + --gray-9: var(--slate-9); + --gray-10: var(--slate-10); + --gray-11: var(--slate-11); + --gray-12: var(--slate-12); + + --gray-a1: var(--slate-a1); + --gray-a2: var(--slate-a2); + --gray-a3: var(--slate-a3); + --gray-a4: var(--slate-a4); + --gray-a5: var(--slate-a5); + --gray-a6: var(--slate-a6); + --gray-a7: var(--slate-a7); + --gray-a8: var(--slate-a8); + --gray-a9: var(--slate-a9); + --gray-a10: var(--slate-a10); + --gray-a11: var(--slate-a11); + --gray-a12: var(--slate-a12); + + --gray-contrast: var(--slate-contrast); + --gray-surface: var(--slate-surface); + --gray-indicator: var(--slate-indicator); + --gray-track: var(--slate-track); + } +} diff --git a/packages/ui-kit/src/themes/tokens/_cursor.scss b/packages/ui-kit/src/themes/tokens/_cursor.scss new file mode 100644 index 00000000..88782632 --- /dev/null +++ b/packages/ui-kit/src/themes/tokens/_cursor.scss @@ -0,0 +1,11 @@ +.propel-themes { + --cursor-button: pointer; + --cursor-checkbox: pointer; + --cursor-disabled: not-allowed; + --cursor-link: pointer; + --cursor-menu-item: default; + --cursor-radio: pointer; + --cursor-slider-thumb: default; + --cursor-slider-thumb-active: default; + --cursor-switch: pointer; +} diff --git a/packages/ui-kit/src/themes/tokens/_index.scss b/packages/ui-kit/src/themes/tokens/_index.scss new file mode 100644 index 00000000..00e374b3 --- /dev/null +++ b/packages/ui-kit/src/themes/tokens/_index.scss @@ -0,0 +1,8 @@ +@import 'colors'; +@import 'cursor'; +@import 'scaling'; +@import 'shadow'; +@import 'space'; +@import 'typography'; +@import 'radius'; +@import 'base'; diff --git a/packages/ui-kit/src/themes/tokens/_radius.scss b/packages/ui-kit/src/themes/tokens/_radius.scss new file mode 100644 index 00000000..1985f35c --- /dev/null +++ b/packages/ui-kit/src/themes/tokens/_radius.scss @@ -0,0 +1,38 @@ +[data-radius] { + --radius-1: calc(3px * var(--scaling) * var(--radius-factor)); + --radius-2: calc(4px * var(--scaling) * var(--radius-factor)); + --radius-3: calc(6px * var(--scaling) * var(--radius-factor)); + --radius-4: calc(8px * var(--scaling) * var(--radius-factor)); + --radius-5: calc(12px * var(--scaling) * var(--radius-factor)); + --radius-6: calc(16px * var(--scaling) * var(--radius-factor)); +} + +[data-radius='none'] { + --radius-factor: 0; + --radius-full: 0px; + --radius-thumb: 0.5px; +} + +[data-radius='small'] { + --radius-factor: 0.75; + --radius-full: 0px; + --radius-thumb: 0.5px; +} + +[data-radius='medium'] { + --radius-factor: 1; + --radius-full: 0px; + --radius-thumb: 9999px; +} + +[data-radius='large'] { + --radius-factor: 1.5; + --radius-full: 0px; + --radius-thumb: 9999px; +} + +[data-radius='full'] { + --radius-factor: 1.5; + --radius-full: 9999px; + --radius-thumb: 9999px; +} diff --git a/packages/ui-kit/src/themes/tokens/_scaling.scss b/packages/ui-kit/src/themes/tokens/_scaling.scss new file mode 100644 index 00000000..52904f24 --- /dev/null +++ b/packages/ui-kit/src/themes/tokens/_scaling.scss @@ -0,0 +1,17 @@ +.propel-themes { + &:where([data-scaling='90%']) { + --scaling: 0.9; + } + &:where([data-scaling='95%']) { + --scaling: 0.95; + } + &:where([data-scaling='100%']) { + --scaling: 1; + } + &:where([data-scaling='105%']) { + --scaling: 1.05; + } + &:where([data-scaling='110%']) { + --scaling: 1.1; + } +} diff --git a/packages/ui-kit/src/themes/tokens/_shadow.scss b/packages/ui-kit/src/themes/tokens/_shadow.scss new file mode 100644 index 00000000..b7c8ab41 --- /dev/null +++ b/packages/ui-kit/src/themes/tokens/_shadow.scss @@ -0,0 +1,155 @@ +/* prettier-ignore */ +:where(.propel-themes) { + --shadow-1: + inset 0 0 0 1px var(--gray-a5), + inset 0 1.5px 2px 0 var(--gray-a2), + inset 0 1.5px 2px 0 var(--black-a2); + + --shadow-2: + 0 0 0 1px var(--gray-a3), + 0 0 0 0.5px var(--black-a1), + 0 1px 1px 0 var(--gray-a2), + 0 2px 1px -1px var(--black-a1), + 0 1px 3px 0 var(--black-a1); + + --shadow-3: + 0 0 0 1px var(--gray-a3), + 0 2px 3px -2px var(--gray-a3), + 0 3px 12px -4px var(--black-a2), + 0 4px 16px -8px var(--black-a2); + + --shadow-4: + 0 0 0 1px var(--gray-a3), + 0 8px 40px var(--black-a1), + 0 12px 32px -16px var(--gray-a3); + + --shadow-5: + 0 0 0 1px var(--gray-a3), + 0 12px 60px var(--black-a3), + 0 12px 32px -16px var(--gray-a5); + + --shadow-6: + 0 0 0 1px var(--gray-a3), + 0 12px 60px var(--black-a3), + 0 16px 64px var(--gray-a2), + 0 16px 36px -20px var(--gray-a7); + } + +/* prettier-ignore */ +@supports (color: color-mix(in oklab, white, black)) { + :where(.propel-themes) { + --shadow-1: + inset 0 0 0 1px var(--gray-a5), + inset 0 1.5px 2px 0 var(--gray-a2), + inset 0 1.5px 2px 0 var(--black-a2); + + --shadow-2: + 0 0 0 1px color-mix(in oklab, var(--gray-a3), var(--gray-3) 25%), + 0 0 0 0.5px var(--black-a1), + 0 1px 1px 0 var(--gray-a2), + 0 2px 1px -1px var(--black-a1), + 0 1px 3px 0 var(--black-a1); + + --shadow-3: + 0 0 0 1px color-mix(in oklab, var(--gray-a3), var(--gray-3) 25%), + 0 2px 3px -2px var(--gray-a3), + 0 3px 12px -4px var(--black-a2), + 0 4px 16px -8px var(--black-a2); + + --shadow-4: + 0 0 0 1px color-mix(in oklab, var(--gray-a3), var(--gray-3) 25%), + 0 8px 40px var(--black-a1), + 0 12px 32px -16px var(--gray-a3); + + --shadow-5: + 0 0 0 1px color-mix(in oklab, var(--gray-a3), var(--gray-3) 25%), + 0 12px 60px var(--black-a3), + 0 12px 32px -16px var(--gray-a5); + + --shadow-6: + 0 0 0 1px color-mix(in oklab, var(--gray-a3), var(--gray-3) 25%), + 0 12px 60px var(--black-a3), + 0 16px 64px var(--gray-a2), + 0 16px 36px -20px var(--gray-a7); + } + } + +/* prettier-ignore */ +:is(.dark, .dark-theme), + :is(.dark, .dark-theme) :where(.propel-themes:not(.light, .light-theme)) { + --shadow-1: + inset 0 -1px 1px 0 var(--gray-a3), + inset 0 0 0 1px var(--gray-a3), + inset 0 3px 4px 0 var(--black-a5), + inset 0 0 0 1px var(--gray-a4); + + --shadow-2: + 0 0 0 1px var(--gray-a6), + 0 0 0 0.5px var(--black-a3), + 0 1px 1px 0 var(--black-a6), + 0 2px 1px -1px var(--black-a6), + 0 1px 3px 0 var(--black-a5); + + --shadow-3: + 0 0 0 1px var(--gray-a6), + 0 2px 3px -2px var(--black-a3), + 0 3px 8px -2px var(--black-a6), + 0 4px 12px -4px var(--black-a7); + + --shadow-4: + 0 0 0 1px var(--gray-a6), + 0 8px 40px var(--black-a3), + 0 12px 32px -16px var(--black-a5); + + --shadow-5: + 0 0 0 1px var(--gray-a6), + 0 12px 60px var(--black-a5), + 0 12px 32px -16px var(--black-a7); + + --shadow-6: + 0 0 0 1px var(--gray-a6), + 0 12px 60px var(--black-a4), + 0 16px 64px var(--black-a6), + 0 16px 36px -20px var(--black-a11); + } + +/* prettier-ignore */ +@supports (color: color-mix(in oklab, white, black)) { + :is(.dark, .dark-theme), + :is(.dark, .dark-theme) :where(.propel-themes:not(.light, .light-theme)) { + --shadow-1: + inset 0 -1px 1px 0 var(--gray-a3), + inset 0 0 0 1px var(--gray-a3), + inset 0 3px 4px 0 var(--black-a5), + inset 0 0 0 1px var(--gray-a4); + + --shadow-2: + 0 0 0 1px color-mix(in oklab, var(--gray-a6), var(--gray-6) 25%), + 0 0 0 0.5px var(--black-a3), + 0 1px 1px 0 var(--black-a6), + 0 2px 1px -1px var(--black-a6), + 0 1px 3px 0 var(--black-a5); + + --shadow-3: + 0 0 0 1px color-mix(in oklab, var(--gray-a6), var(--gray-6) 25%), + 0 2px 3px -2px var(--black-a3), + 0 3px 8px -2px var(--black-a6), + 0 4px 12px -4px var(--black-a7); + + --shadow-4: + 0 0 0 1px color-mix(in oklab, var(--gray-a6), var(--gray-6) 25%), + 0 8px 40px var(--black-a3), + 0 12px 32px -16px var(--black-a5); + + --shadow-5: + 0 0 0 1px color-mix(in oklab, var(--gray-a6), var(--gray-6) 25%), + 0 12px 60px var(--black-a5), + 0 12px 32px -16px var(--black-a7); + + --shadow-6: + 0 0 0 1px color-mix(in oklab, var(--gray-a6), var(--gray-6) 25%), + 0 12px 60px var(--black-a4), + 0 16px 64px var(--black-a6), + 0 16px 36px -20px var(--black-a11); + } + } diff --git a/packages/ui-kit/src/themes/tokens/_space.scss b/packages/ui-kit/src/themes/tokens/_space.scss new file mode 100644 index 00000000..12987810 --- /dev/null +++ b/packages/ui-kit/src/themes/tokens/_space.scss @@ -0,0 +1,11 @@ +.propel-themes { + --space-1: calc(4px * var(--scaling)); + --space-2: calc(8px * var(--scaling)); + --space-3: calc(12px * var(--scaling)); + --space-4: calc(16px * var(--scaling)); + --space-5: calc(24px * var(--scaling)); + --space-6: calc(32px * var(--scaling)); + --space-7: calc(40px * var(--scaling)); + --space-8: calc(48px * var(--scaling)); + --space-9: calc(64px * var(--scaling)); +} diff --git a/packages/ui-kit/src/themes/tokens/_typography.scss b/packages/ui-kit/src/themes/tokens/_typography.scss new file mode 100644 index 00000000..d950de67 --- /dev/null +++ b/packages/ui-kit/src/themes/tokens/_typography.scss @@ -0,0 +1,128 @@ +.propel-themes { + --font-size-1: calc(12px * var(--scaling)); + --font-size-2: calc(14px * var(--scaling)); + --font-size-3: calc(16px * var(--scaling)); + --font-size-4: calc(18px * var(--scaling)); + --font-size-5: calc(20px * var(--scaling)); + --font-size-6: calc(24px * var(--scaling)); + --font-size-7: calc(28px * var(--scaling)); + --font-size-8: calc(35px * var(--scaling)); + --font-size-9: calc(60px * var(--scaling)); + + --font-weight-light: 300; + --font-weight-regular: 400; + --font-weight-medium: 500; + --font-weight-bold: 700; + + --line-height-1: calc(16px * var(--scaling)); + --line-height-2: calc(20px * var(--scaling)); + --line-height-3: calc(24px * var(--scaling)); + --line-height-4: calc(26px * var(--scaling)); + --line-height-5: calc(28px * var(--scaling)); + --line-height-6: calc(30px * var(--scaling)); + --line-height-7: calc(36px * var(--scaling)); + --line-height-8: calc(40px * var(--scaling)); + --line-height-9: calc(60px * var(--scaling)); + + --letter-spacing-1: 0.0025em; + --letter-spacing-2: 0em; + --letter-spacing-3: 0em; + --letter-spacing-4: -0.0025em; + --letter-spacing-5: -0.005em; + --letter-spacing-6: -0.00625em; + --letter-spacing-7: -0.0075em; + --letter-spacing-8: -0.01em; + --letter-spacing-9: -0.025em; + + /* default values */ + + --default-font-family: 'Inter', sans-serif; + // --default-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI (Custom)', Roboto, 'Helvetica Neue', + // 'Open Sans (Custom)', system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji'; + --default-font-size: var(--font-size-3); /* Same size used for `` */ + --default-font-style: normal; + --default-font-weight: var(--font-weight-regular); + --default-line-height: 1.5; /* Equivalent to the line-height used for `` 16px * 1.5 = 24px */ + --default-letter-spacing: 0em; + --default-leading-trim-start: 0.42em; + --default-leading-trim-end: 0.36em; + + /* Heading */ + + --heading-font-family: var(--default-font-family); + --heading-font-size-adjust: 1; + --heading-font-style: normal; + --heading-leading-trim-start: var(--default-leading-trim-start); + --heading-leading-trim-end: var(--default-leading-trim-end); + --heading-letter-spacing: 0em; + + --heading-line-height-1: calc(16px * var(--scaling)); + --heading-line-height-2: calc(18px * var(--scaling)); + --heading-line-height-3: calc(22px * var(--scaling)); + --heading-line-height-4: calc(24px * var(--scaling)); + --heading-line-height-5: calc(26px * var(--scaling)); + --heading-line-height-6: calc(30px * var(--scaling)); + --heading-line-height-7: calc(36px * var(--scaling)); + --heading-line-height-8: calc(40px * var(--scaling)); + --heading-line-height-9: calc(60px * var(--scaling)); + + /* Code */ + + --code-font-family: 'Inter', sans-serif; + // --code-font-family: 'Menlo', 'Consolas (Custom)', 'Bitstream Vera Sans Mono', monospace, 'Apple Color Emoji', + // 'Segoe UI Emoji'; + --code-font-size-adjust: 0.95; + --code-font-style: normal; + --code-font-weight: inherit; + --code-letter-spacing: -0.007em; + --code-padding-top: 0.1em; + --code-padding-bottom: 0.1em; + --code-padding-left: 0.25em; + --code-padding-right: 0.25em; + + /* Strong */ + + --strong-font-family: var(--default-font-family); + --strong-font-size-adjust: 1; + --strong-font-style: inherit; + --strong-font-weight: var(--font-weight-bold); + --strong-letter-spacing: 0em; + + /* Em */ + + // --em-font-family: 'Times New Roman', 'Times', serif; + --em-font-family: 'Inter', sans-serif; + --em-font-size-adjust: 1.18; + --em-font-style: italic; + --em-font-weight: inherit; + --em-letter-spacing: -0.025em; + + /* Quote */ + + // --quote-font-family: 'Times New Roman', 'Times', serif; + --quote-font-family: 'Inter', sans-serif; + --quote-font-size-adjust: 1.18; + --quote-font-style: italic; + --quote-font-weight: inherit; + --quote-letter-spacing: -0.025em; + + /* Tabs */ + + --tab-active-letter-spacing: -0.01em; + --tab-active-word-spacing: 0em; + --tab-inactive-letter-spacing: 0em; + --tab-inactive-word-spacing: 0em; +} + +.propel-themes { + overflow-wrap: break-word; + font-family: var(--default-font-family); + font-size: var(--default-font-size); + font-weight: var(--default-font-weight); + font-style: var(--default-font-style); + line-height: var(--default-line-height); + letter-spacing: var(--default-letter-spacing); + text-size-adjust: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} diff --git a/yarn.lock b/yarn.lock index acc9d854..107eec42 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4483,6 +4483,7 @@ __metadata: "@graphql-codegen/typescript-react-query": ^6.0.0 "@juggle/resize-observer": ^3.4.0 "@mui/base": ^5.0.0-beta.31 + "@radix-ui/colors": ^3.0.0 "@rollup/plugin-commonjs": ^25.0.7 "@rollup/plugin-node-resolve": ^15.2.3 "@rollup/plugin-terser": ^0.4.4 @@ -4535,6 +4536,13 @@ __metadata: languageName: unknown linkType: soft +"@radix-ui/colors@npm:^3.0.0": + version: 3.0.0 + resolution: "@radix-ui/colors@npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40radix-ui%2Fcolors%2F-%2Fcolors-3.0.0.tgz" + checksum: 5ac1b69df7a77525e2031c2d2948d6ef8d81c6b163809ee8e17a2138c4977678e3a9f67342595d2c88f0300f51fd2c64e24355008cda6c9db8dfd4ed3eaf9e8f + languageName: node + linkType: hard + "@radix-ui/number@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/number@npm:1.0.1::__archiveUrl=https%3A%2F%2Fregistry.npmjs.org%2F%40radix-ui%2Fnumber%2F-%2Fnumber-1.0.1.tgz" From a05d8d6e5e7c187b8f2bda05a223bf0d13681b76 Mon Sep 17 00:00:00 2001 From: Alexander Schwarzmann Date: Thu, 11 Jul 2024 15:16:29 +0200 Subject: [PATCH 2/3] chore(mix): ui-components and dashboard were migrated to radix/colors --- .../documentation/ui-kit/Theming.mdx | 3 - .../CounterConnected/CounterConnected.tsx | 17 +- .../CounterStatic/CounterStatic.tsx | 32 +- .../src/components/Dashboard/Dashboard.tsx | 94 ++- .../LeaderboardConnected.tsx | 69 +- .../LeaderboardStatic/LeaderboardStatic.tsx | 72 +- .../PieChartConnected/PieChartConnected.tsx | 55 +- .../PieChartStatic/PieChartStatic.tsx | 58 +- .../TimeSeriesConnected.tsx | 86 ++- .../TimeSeriesStatic/TimeSeriesStatic.tsx | 95 ++- .../examples/dashboard/src/styles/global.css | 4 +- packages/ui-kit/package.json | 10 +- .../ui-kit/scripts/parse-design-tokens.mts | 348 --------- packages/ui-kit/scripts/tsconfig.json | 12 - .../ui-kit/scripts/validate-design-tokens.mts | 106 --- .../Autocomplete/Autocomplete.module.scss | 68 +- .../Autocomplete/Autocomplete.stories.tsx | 21 - .../src/components/Button/Button.module.scss | 23 +- .../components/Counter/Counter.module.scss | 8 +- .../ui-kit/src/components/Counter/Counter.tsx | 2 +- .../components/Divider/Divider.module.scss | 4 +- .../ErrorFallback/ErrorFallback.module.scss | 7 +- .../ErrorFallback/ErrorFallback.tsx | 4 +- .../FormField/FormField.module.scss | 4 +- .../src/components/FormField/FormField.tsx | 2 +- .../src/components/Input/Input.module.scss | 56 +- .../src/components/Input/Input.stories.tsx | 3 +- .../ui-kit/src/components/Input/Input.tsx | 11 +- .../Leaderboard/Leaderboard.module.scss | 27 +- .../Leaderboard/Leaderboard.stories.css | 2 +- .../Leaderboard/Leaderboard.stories.tsx | 45 +- .../components/Leaderboard/Leaderboard.tsx | 22 +- .../Leaderboard/ValueBar/ValueBar.module.scss | 2 +- .../components/PieChart/PieChart.module.scss | 48 +- .../components/PieChart/PieChart.stories.tsx | 34 +- .../src/components/PieChart/PieChart.tsx | 28 +- .../Select/Option/Option.module.scss | 15 +- .../src/components/Select/Select.module.scss | 50 +- .../ui-kit/src/components/Select/Select.tsx | 2 + .../ui-kit/src/components/Select/index.ts | 1 + .../ThemeProvider/ThemeProvider.test.tsx | 34 +- .../ThemeProvider/ThemeProvider.tsx | 2 + .../DateTimeField/DateTimeField.module.scss | 2 +- .../DateTimeField/DateTimeField.tsx | 23 +- .../TimeRangePicker.module.scss | 104 +-- .../TimeRangePicker.stories.tsx | 2 +- .../TimeRangePicker/TimeRangePicker.tsx | 33 +- .../TimeRangePicker/TimeRangePicker.types.ts | 9 +- .../src/components/TimeSeries/TimeSeries.tsx | 2 - .../ui-kit/src/components/TimeSeries/utils.ts | 6 +- .../Typography/Typography.module.scss | 29 +- .../Typography/Typography.stories.tsx | 32 + .../components/Typography/Typography.test.tsx | 20 +- .../src/components/Typography/Typography.tsx | 10 +- packages/ui-kit/src/components/index.ts | 3 + .../src/helpers/chartUtils/chartUtils.ts | 44 +- .../src/helpers/themeUtils/themeUtils.test.ts | 32 +- .../src/helpers/themeUtils/themeUtils.ts | 2 +- packages/ui-kit/src/themes/theme.types.ts | 9 +- packages/ui-kit/src/themes/themeDict.ts | 3 - packages/ui-kit/src/themes/themeTokens.ts | 139 ++-- packages/ui-kit/src/themes/themes.module.scss | 2 - .../ui-kit/src/themes/tokens/_colors.scss | 671 ++++++++++++++++++ .../ui-kit/src/themes/tokens/_typography.scss | 80 +-- 64 files changed, 1482 insertions(+), 1361 deletions(-) delete mode 100644 packages/ui-kit/scripts/parse-design-tokens.mts delete mode 100644 packages/ui-kit/scripts/tsconfig.json delete mode 100644 packages/ui-kit/scripts/validate-design-tokens.mts create mode 100644 packages/ui-kit/src/components/Typography/Typography.stories.tsx diff --git a/app/storybook/documentation/ui-kit/Theming.mdx b/app/storybook/documentation/ui-kit/Theming.mdx index eb3b2a5f..5ab0ba92 100644 --- a/app/storybook/documentation/ui-kit/Theming.mdx +++ b/app/storybook/documentation/ui-kit/Theming.mdx @@ -4,9 +4,6 @@ import { prettier } from '../../src/utils' import { SourceCode } from '../../.storybook/blocks/SourceCode' import * as ThemeProviderStories from '../../../../packages/ui-kit/src/components/ThemeProvider/ThemeProvider.stories' import rawThemesScss from '!!raw-loader!../../../../packages/ui-kit/src/themes/themes.module.scss' -import rawCommonScss from '!!raw-loader!../../../../packages/ui-kit/src/themes/generated/_tokens.scss' -import rawLightThemeScss from '!!raw-loader!../../../../packages/ui-kit/src/themes/generated/_lightTheme.scss' -import rawDarkThemeScss from '!!raw-loader!../../../../packages/ui-kit/src/themes/generated/_darkTheme.scss' diff --git a/packages/examples/dashboard/src/components/CounterConnected/CounterConnected.tsx b/packages/examples/dashboard/src/components/CounterConnected/CounterConnected.tsx index 6d7e246e..d655389e 100644 --- a/packages/examples/dashboard/src/components/CounterConnected/CounterConnected.tsx +++ b/packages/examples/dashboard/src/components/CounterConnected/CounterConnected.tsx @@ -1,9 +1,8 @@ -import { Counter } from '@propeldata/ui-kit' +import { Button, Counter } from '@propeldata/ui-kit' import React from 'react' import { ConnectedComponentProps } from '../../shared.types' export const CounterConnected = ({ envs: { REACT_APP_METRIC_UNIQUE_NAME_1 }, timeRange }: ConnectedComponentProps) => { - const [fontColor, setFontColor] = React.useState('#101828') const [refetchInterval, setRefetchInterval] = React.useState(undefined) const handleSwitchRefetchInterval = () => { @@ -13,7 +12,7 @@ export const CounterConnected = ({ envs: { REACT_APP_METRIC_UNIQUE_NAME_1 }, tim return (

Counter Connected

-
+
- setFontColor(event.target.value)} - value={fontColor} - /> - +
) diff --git a/packages/examples/dashboard/src/components/CounterStatic/CounterStatic.tsx b/packages/examples/dashboard/src/components/CounterStatic/CounterStatic.tsx index 86270f15..fde74540 100644 --- a/packages/examples/dashboard/src/components/CounterStatic/CounterStatic.tsx +++ b/packages/examples/dashboard/src/components/CounterStatic/CounterStatic.tsx @@ -1,4 +1,4 @@ -import { Counter } from '@propeldata/ui-kit' +import { Button, Counter } from '@propeldata/ui-kit' import React from 'react' import { useFakeData } from '../../hooks/useFakeData' @@ -12,8 +12,6 @@ const mockData2 = { export const CounterStatic = () => { const [mockData, setMockData] = React.useState(mockData1) - const [fontColor, setFontColor] = React.useState('#101828') - const { data, isLoading, setIsLoading } = useFakeData(mockData) const handleReFetchMock = () => { @@ -27,37 +25,25 @@ export const CounterStatic = () => { return (

Counter Static

-
+
No Data
} card value={data?.value} loading={isLoading} - style={{ color: fontColor }} + style={{ color: 'var(--accent-11)' }} />
- - setFontColor(event.target.value)} - value={fontColor} - /> - + - + +
) diff --git a/packages/examples/dashboard/src/components/Dashboard/Dashboard.tsx b/packages/examples/dashboard/src/components/Dashboard/Dashboard.tsx index 50101dd7..a0b51e60 100644 --- a/packages/examples/dashboard/src/components/Dashboard/Dashboard.tsx +++ b/packages/examples/dashboard/src/components/Dashboard/Dashboard.tsx @@ -1,12 +1,18 @@ import { AccessTokenProvider, - DefaultThemes, + Button, + ThemeAppearances, FilterProvider, RelativeTimeRange, SimpleFilter, ThemeProvider, TimeRangePicker, DateRangeOptionsProps, + Card, + Typography, + Select, + Option, + accentColors, useTheme } from '@propeldata/ui-kit' import React from 'react' @@ -20,10 +26,12 @@ import { PieChartStatic } from '../PieChartStatic' import { TimeSeriesConnected } from '../TimeSeriesConnected' import { TimeSeriesStatic } from '../TimeSeriesStatic' +const accentColorOptions = accentColors.map((color) => ({ label: color, value: color })) + const GlobalStyles = () => { const theme = useTheme() if (document && theme) { - document.body.style.setProperty('--bg-color', theme.backgroundSecondary as string) + document.body.style.setProperty('--bg-color', theme.getVar('--accent-1') as string) } return null } @@ -33,16 +41,19 @@ interface DashboardProps extends DashboardCommonProps { } export const Dashboard = ({ fetchToken, envs }: DashboardProps) => { - const [theme, setTheme] = React.useState('lightTheme') + const [appearance, setAppearance] = React.useState('light') const [timeRange, setTimeRange] = React.useState({ - value: 'last-90-days' + value: 'last-30-days' }) + const [accentColor, setAccentColor] = React.useState(accentColorOptions.find((color) => color.value === 'purple')) + return ( (
No Data @@ -53,12 +64,7 @@ export const Dashboard = ({ fetchToken, envs }: DashboardProps) => {
-

- React {React.version} Testing App - -

+

React {React.version} Testing App


{ />
-
- {timeRange?.value && ( - <> - - - - - - - - - - )} +
+
+
+ {timeRange?.value && ( + <> + + + + + + + + + + )} +
+
+
+ + + Theme + + Accent color + + Appearance +
+ + +
+
+
diff --git a/packages/examples/dashboard/src/components/LeaderboardConnected/LeaderboardConnected.tsx b/packages/examples/dashboard/src/components/LeaderboardConnected/LeaderboardConnected.tsx index 2e1d83f4..9c5e241d 100644 --- a/packages/examples/dashboard/src/components/LeaderboardConnected/LeaderboardConnected.tsx +++ b/packages/examples/dashboard/src/components/LeaderboardConnected/LeaderboardConnected.tsx @@ -1,7 +1,17 @@ -import { Leaderboard, LeaderboardChartVariant } from '@propeldata/ui-kit' +import { Leaderboard, LeaderboardChartVariant, Button, Select, Option } from '@propeldata/ui-kit' import React from 'react' import { ConnectedComponentProps } from '../../shared.types' +type chartTypeOption = { + value: LeaderboardChartVariant + label: string +} + +const chartTypeOptions: chartTypeOption[] = [ + { value: 'bar', label: 'Bar' }, + { value: 'table', label: 'Table' } +] + export const LeaderboardConnected = ({ envs: { REACT_APP_METRIC_UNIQUE_NAME_1, @@ -11,8 +21,7 @@ export const LeaderboardConnected = ({ }, timeRange: timeRangeProp }: ConnectedComponentProps) => { - const [barsColor, setBarsColor] = React.useState('#75BFFF') - const [chartType, setChartType] = React.useState('bar') + const [chartType, setChartType] = React.useState(chartTypeOptions[0]) const [refetchInterval, setRefetchInterval] = React.useState(undefined) const [timeRange, setTimeRange] = React.useState(timeRangeProp) @@ -27,7 +36,7 @@ export const LeaderboardConnected = ({ return (

Leaderboard Connected

-
+
{ - // Custom bar color - config.data.datasets[0].backgroundColor = barsColor - return config - }} />
-
- {chartType === 'bar' && ( - setBarsColor(event.target.value)} - value={barsColor} - /> - )} - - - +
+
+ + +
+
+ +
) diff --git a/packages/examples/dashboard/src/components/LeaderboardStatic/LeaderboardStatic.tsx b/packages/examples/dashboard/src/components/LeaderboardStatic/LeaderboardStatic.tsx index 70f8fa78..a9a7fce7 100644 --- a/packages/examples/dashboard/src/components/LeaderboardStatic/LeaderboardStatic.tsx +++ b/packages/examples/dashboard/src/components/LeaderboardStatic/LeaderboardStatic.tsx @@ -1,4 +1,4 @@ -import { Leaderboard, LeaderboardChartVariant } from '@propeldata/ui-kit' +import { Leaderboard, LeaderboardChartVariant, Button, Select, Option } from '@propeldata/ui-kit' import React from 'react' import { useFakeData } from '../../hooks/useFakeData' @@ -22,10 +22,19 @@ const mockData2 = { ] } +type chartTypeOption = { + value: LeaderboardChartVariant + label: string +} + +const chartTypeOptions: chartTypeOption[] = [ + { value: 'bar', label: 'Bar' }, + { value: 'table', label: 'Table' } +] + export const LeaderboardStatic = () => { + const [chartType, setChartType] = React.useState(chartTypeOptions[0]) const [mockData, setMockData] = React.useState(mockData1) - const [barsColor, setBarsColor] = React.useState('#75BFFF') - const [chartType, setChartType] = React.useState('bar') const { data, isLoading, setIsLoading } = useFakeData(mockData) const handleReFetchMock = () => { @@ -39,48 +48,39 @@ export const LeaderboardStatic = () => { return (

Leaderboard Static

-
+
{ - // Custom bar color - config.data.datasets[0].backgroundColor = barsColor - return config - }} />
-
- - {chartType === 'bar' && ( - setBarsColor(event.target.value)} - value={barsColor} - /> - )} - - +
+
+ + +
+
+ +
) diff --git a/packages/examples/dashboard/src/components/PieChartConnected/PieChartConnected.tsx b/packages/examples/dashboard/src/components/PieChartConnected/PieChartConnected.tsx index c8927d4a..20f86a93 100644 --- a/packages/examples/dashboard/src/components/PieChartConnected/PieChartConnected.tsx +++ b/packages/examples/dashboard/src/components/PieChartConnected/PieChartConnected.tsx @@ -1,12 +1,22 @@ -import { PieChart, PieChartVariant } from '@propeldata/ui-kit' +import { PieChart, PieChartVariant, Button, Select, Option } from '@propeldata/ui-kit' import React from 'react' import { ConnectedComponentProps } from '../../shared.types' +type chartTypeOption = { + value: PieChartVariant + label: string +} + +const chartTypeOptions: chartTypeOption[] = [ + { value: 'pie', label: 'Pie' }, + { value: 'doughnut', label: 'Doughnut' } +] + export const PieChartConnected = ({ envs: { REACT_APP_METRIC_UNIQUE_NAME_1, REACT_APP_DIMENSION_1 = '' }, timeRange: timeRangeProp }: ConnectedComponentProps) => { - const [chartType, setChartType] = React.useState('pie') + const [chartType, setChartType] = React.useState(chartTypeOptions[0]) const [refetchInterval, setRefetchInterval] = React.useState(undefined) const [timeRange, setTimeRange] = React.useState(timeRangeProp) @@ -21,7 +31,7 @@ export const PieChartConnected = ({ return (

PieChart Connected

-
+
-
- - - +
+
+ + +
+
+ +
) diff --git a/packages/examples/dashboard/src/components/PieChartStatic/PieChartStatic.tsx b/packages/examples/dashboard/src/components/PieChartStatic/PieChartStatic.tsx index 2a77db03..aa6bbda6 100644 --- a/packages/examples/dashboard/src/components/PieChartStatic/PieChartStatic.tsx +++ b/packages/examples/dashboard/src/components/PieChartStatic/PieChartStatic.tsx @@ -1,4 +1,4 @@ -import { PieChart, PieChartVariant } from '@propeldata/ui-kit' +import { PieChart, PieChartVariant, Button, Select, Option } from '@propeldata/ui-kit' import React from 'react' import { useFakeData } from '../../hooks/useFakeData' @@ -22,9 +22,19 @@ const mockData2 = { ] } +type chartTypeOption = { + value: PieChartVariant + label: string +} + +const chartTypeOptions: chartTypeOption[] = [ + { value: 'pie', label: 'Pie' }, + { value: 'doughnut', label: 'Doughnut' } +] + export const PieChartStatic = () => { + const [chartType, setChartType] = React.useState(chartTypeOptions[0]) const [mockData, setMockData] = React.useState(mockData1) - const [chartType, setChartType] = React.useState('pie') const { data, isLoading, setIsLoading } = useFakeData(mockData) @@ -39,27 +49,31 @@ export const PieChartStatic = () => { return (

PieChart Static

-
- +
+
-
- - - +
+
+ + +
+
+ +
) diff --git a/packages/examples/dashboard/src/components/TimeSeriesConnected/TimeSeriesConnected.tsx b/packages/examples/dashboard/src/components/TimeSeriesConnected/TimeSeriesConnected.tsx index 09b788e9..c86575f9 100644 --- a/packages/examples/dashboard/src/components/TimeSeriesConnected/TimeSeriesConnected.tsx +++ b/packages/examples/dashboard/src/components/TimeSeriesConnected/TimeSeriesConnected.tsx @@ -1,13 +1,22 @@ -import { TimeSeries, TimeSeriesChartVariant, TimeSeriesGranularity } from '@propeldata/ui-kit' +import { TimeSeries, TimeSeriesChartVariant, TimeSeriesGranularity, Button, Select, Option } from '@propeldata/ui-kit' import React from 'react' import { ConnectedComponentProps } from '../../shared.types' +type chartTypeOption = { + value: TimeSeriesChartVariant + label: string +} + +const chartTypeOptions: chartTypeOption[] = [ + { value: 'bar', label: 'Bar' }, + { value: 'line', label: 'Line' } +] + export const TimeSeriesConnected = ({ envs: { REACT_APP_METRIC_UNIQUE_NAME_1 }, timeRange: timeRangeProp }: ConnectedComponentProps) => { - const [chartColor, setChartColor] = React.useState('#75BFFF') - const [chartType, setChartType] = React.useState('bar') + const [chartType, setChartType] = React.useState(chartTypeOptions[0]) const [pointStyle, setPointStyle] = React.useState('cross') const [refetchInterval, setRefetchInterval] = React.useState(undefined) const [timeRange, setTimeRange] = React.useState(timeRangeProp) @@ -23,7 +32,7 @@ export const TimeSeriesConnected = ({ return (

TimeSeries Connected

-
+
{ - // Custom bar color - config.data.datasets[0].backgroundColor = chartColor - - // Custom point settings - config.data.datasets[0].pointStyle = pointStyle - config.data.datasets[0].borderColor = chartColor - config.options.scales.y.beginAtZero = false - config.options.scales.y.scale = 'logarithmic' - return config - }} + variant={chartType.value} />
-
- setChartColor(event.target.value)} - /> - - {chartType === 'line' && ( - + )} + + +
+
+ +
) diff --git a/packages/examples/dashboard/src/components/TimeSeriesStatic/TimeSeriesStatic.tsx b/packages/examples/dashboard/src/components/TimeSeriesStatic/TimeSeriesStatic.tsx index 44be1e46..ab1e5cfe 100644 --- a/packages/examples/dashboard/src/components/TimeSeriesStatic/TimeSeriesStatic.tsx +++ b/packages/examples/dashboard/src/components/TimeSeriesStatic/TimeSeriesStatic.tsx @@ -1,4 +1,4 @@ -import { TimeSeries, TimeSeriesChartVariant } from '@propeldata/ui-kit' +import { TimeSeries, TimeSeriesChartVariant, Button, Select, Option } from '@propeldata/ui-kit' import React from 'react' import { useFakeData } from '../../hooks/useFakeData' @@ -45,10 +45,19 @@ const mockData2 = { values: [0, 200, 300, 400, 79187691, 248679, 131034] } +type chartTypeOption = { + value: TimeSeriesChartVariant + label: string +} + +const chartTypeOptions: chartTypeOption[] = [ + { value: 'bar', label: 'Bar' }, + { value: 'line', label: 'Line' } +] + export const TimeSeriesStatic = () => { const [mockData, setMockData] = React.useState(mockData1) - const [chartColor, setChartColor] = React.useState('#75BFFF') - const [chartType, setChartType] = React.useState('bar') + const [chartType, setChartType] = React.useState(chartTypeOptions[0]) const [pointStyle, setPointStyle] = React.useState('cross') const { data, isLoading, setIsLoading } = useFakeData(mockData) @@ -64,60 +73,36 @@ export const TimeSeriesStatic = () => { return (

TimeSeries Static

-
- { - // Custom bar color - config.data.datasets[0].backgroundColor = chartColor - - // Custom point settings - config.data.datasets[0].pointStyle = pointStyle - config.data.datasets[0].borderColor = chartColor - config.options.scales.y.beginAtZero = false - config.options.scales.y.scale = 'logarithmic' - return config - }} - /> +
+
-
- - setChartColor(event.target.value)} - /> - - {chartType === 'line' && ( - + {chartType.value === 'line' && ( + + )} + +
+
+ +
) diff --git a/packages/examples/dashboard/src/styles/global.css b/packages/examples/dashboard/src/styles/global.css index 9a7fa146..1f3f6ee9 100644 --- a/packages/examples/dashboard/src/styles/global.css +++ b/packages/examples/dashboard/src/styles/global.css @@ -6,11 +6,11 @@ body { height: 100vh; - background-color: var(--bg-color); + background-color: var(--color-background); } .border-2 { - border-color: var(--propel-border-primary); + border-color: var(--gray-6); background-color: transparent; } diff --git a/packages/ui-kit/package.json b/packages/ui-kit/package.json index ebacda8e..d543c052 100644 --- a/packages/ui-kit/package.json +++ b/packages/ui-kit/package.json @@ -7,15 +7,11 @@ "module": "dist/esm/index.module.js", "scripts": { "typecheck": "tsc --noEmit", - "build": "rm -rf dist && yarn graphql:build && yarn design-tokens:sync && yarn typecheck && rollup -c", + "build": "rm -rf dist && yarn graphql:build && yarn typecheck && rollup -c", "graphql:build": "rm -rf src/graphql/generated && yarn graphql:gen", "graphql:gen": "graphql-codegen --config src/graphql/codegen.yml && node src/graphql/script.cjs src/graphql/generated/index.ts", "test": "jest", - "test:coverage": "jest --ci --coverage --json --outputFile=coverage/coverage.json", - "design-tokens:sync": "yarn design-tokens:clean && tsc -p ./scripts/tsconfig.json && yarn design-tokens:parse && yarn design-tokens:validate", - "design-tokens:clean": "rm -rf ./scripts/dist && rm -rf ./src/generated && rm -rf ./src/themes/generated", - "design-tokens:parse": "node ./scripts/dist/parse-design-tokens.mjs", - "design-tokens:validate": "node ./scripts/dist/validate-design-tokens.mjs" + "test:coverage": "jest --ci --coverage --json --outputFile=coverage/coverage.json" }, "publishConfig": { "access": "public", @@ -27,6 +23,7 @@ ], "dependencies": { "@mui/base": "^5.0.0-beta.31", + "@radix-ui/colors": "^3.0.0", "@tanstack/react-query": "^4.29.17", "chart.js": "^4.1.2", "chartjs-adapter-luxon": "1.2.1", @@ -41,7 +38,6 @@ "@graphql-codegen/typescript-operations": "^4.0.1", "@graphql-codegen/typescript-react-query": "^6.0.0", "@juggle/resize-observer": "^3.4.0", - "@radix-ui/colors": "^3.0.0", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-terser": "^0.4.4", diff --git a/packages/ui-kit/scripts/parse-design-tokens.mts b/packages/ui-kit/scripts/parse-design-tokens.mts deleted file mode 100644 index e2d96341..00000000 --- a/packages/ui-kit/scripts/parse-design-tokens.mts +++ /dev/null @@ -1,348 +0,0 @@ -import fs, { promises as fsPromises } from 'fs' -import path from 'path' -import slugify from 'slugify' -import ora from 'ora' - -const GENERATED_WARNING = - 'This file is generated automatically by scripts/parse-design-tokens.js. Do not edit manually.' - -// Parse typography -const valueKeyPropMapping: Record = { - fontSize: 'font-size', - fontFamily: 'font-family', - fontWeight: 'font-weight', - lineHeight: 'line-height', - letterSpacing: 'letter-spacing' -} - -// Map font weight from string to number -const weightMapping: Record = { - Thin: '100', - 'Extra Light': '200', - Light: '300', - Regular: '400', - Medium: '500', - 'Semi Bold': '600', - Bold: '700', - 'Extra Bold': '800', - Black: '900' -} - -type VariableProps = { - name: string - type: string - isAlias: boolean - value: any -} - -type TokenDataProps = { - cssName: string - jsName: string - kind?: 'typography' - type: 'number' | 'string' - value: string -} - -type ThemeProps = { - name: string - variables: VariableProps[] -} - -type VariablesJSONProps = { - collections: { - name: string - modes: ThemeProps[] - }[] -} - -type TypographyClassProps = { - className: string - props: { prop: string; value: string }[] -} - -// Slugify string with strict mode -export const slugifyStr = (str: string): string => slugify(str.replaceAll('/', '-'), { lower: true, strict: true }) - -// Convert kebab-case to camelCase -export const kebabCaseToCamelCase = (kebabStr: string): string => - kebabStr - .split('-') - .map((word, index) => (index === 0 ? word : word[0].toUpperCase() + word.slice(1))) - .join('') - -// Convert camelCase to kebab-case -export const camelCaseToKebabCase = (camelStr: string): string => - camelStr.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase() - -// Parse Figma variable value -export const parseValue = (variable: VariableProps): string => { - const { type, value } = variable - switch (type) { - case 'color': - return `rgba(${value.r}, ${value.g}, ${value.b}, ${value.a})` - case 'number': - return `${value}px` - case 'effect': { - const { offset, radius, spread, color } = value.effects[0] - return `${offset.x}px ${offset.y}px ${radius}px ${spread}px rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})` - } - default: - return value.toString() - } -} - -// Parse Figma alias value -export const parseAlias = (variable: VariableProps, tokenData: TokenDataProps[]): string => { - const { value } = variable - const tokenKey = slugifyStr(value.name) - const tokenValue = tokenData.find((token) => token.cssName === `--propel-${tokenKey}`) - return tokenValue ? `var(${tokenValue.cssName})` : '' -} - -// Generate design token data -export const generateTokenValue = (key: string, value: any, tokenData: TokenDataProps[]): TokenDataProps => ({ - cssName: `--propel-${key}`, - jsName: kebabCaseToCamelCase(key), - kind: value.kind, - type: value.type === 'number' ? 'number' : 'string', - value: value.isAlias ? parseAlias(value, tokenData) : parseValue(value) -}) - -// Generate typography token data -export const generateTypographyValue = (key: string, type: 'number' | 'string', value: string): TokenDataProps => - generateTokenValue(key, { type, value, kind: 'typography' }, []) - -// Write design token content to file -export const writeToFileSync = (fileName: string, content: string): void => { - const fullPath = path.join('./src/themes/generated/', fileName) - const dirName = path.dirname(fullPath) - - // Check if the directory exists. If not, create it - if (!fs.existsSync(dirName)) { - fs.mkdirSync(dirName, { recursive: true }) - } - - fs.writeFileSync(fullPath, content) -} - -// Read Figma variables from JSON file -export const getJSONFromFile = async (): Promise => { - const data = await fsPromises.readFile('./src/themes/variables.json', 'utf-8') - const variablesJSON: VariablesJSONProps = JSON.parse(data) - - return variablesJSON -} - -// Get theme tokens - -export const getThemeTokens = ({ - name, - themes, - variables, - tokens -}: { - name: string - themes?: ThemeProps[] - variables: TokenDataProps[] - tokens: TokenDataProps[] -}) => - themes - ?.find((theme) => theme.name.toLowerCase() === name) - ?.variables.map((variable) => - generateTokenValue( - slugifyStr(variable.name.split('/').pop() ?? ''), - variable, - variable.isAlias ? variables : tokens - ) - ) - -const main = async () => { - const spinner = ora({ text: 'Parsing design variables and tokens...', color: 'yellow' }).start() - - try { - const variablesJSON = await getJSONFromFile() - - if (!variablesJSON) { - spinner.fail('Failed to parse variables.json') - throw new Error('Failed to parse variables.json') - } - - const variables: TokenDataProps[] = [] - const tokens: TokenDataProps[] = [] - - // Parse variables - variablesJSON.collections - .filter(({ name }) => ['_Primitives'].includes(name)) - .forEach((collection) => { - collection.modes[0].variables.forEach((variable) => { - variables.push(generateTokenValue(slugifyStr(variable.name), variable, variables)) - }) - }) - - // Parse tokens - variablesJSON.collections - .filter(({ name }) => ['2. Radius', '3. Spacing', '4. Widths', 'Effects'].includes(name)) - .forEach((collection) => { - collection.modes[0].variables.forEach((variable) => { - tokens.push(generateTokenValue(slugifyStr(variable.name), variable, variables)) - }) - }) - - const typographyClasses: TypographyClassProps[] = [] - - variablesJSON.collections - ?.find(({ name }) => name === 'Typography') - ?.modes?.find(({ name }) => name.toLowerCase() === 'style') - ?.variables?.forEach((variable) => { - const key = slugifyStr(variable.name) - const typographyClass: TypographyClassProps = { - className: kebabCaseToCamelCase(key), - props: [] - } - - for (const valueKey in variable.value) { - const propKey = slugifyStr(`${key}-${camelCaseToKebabCase(valueKey)}`) - let typographyValue: TokenDataProps | undefined - - if (['fontSize', 'fontFamily', 'fontWeight', 'lineHeight', 'letterSpacing'].includes(valueKey)) { - let value = variable.value[valueKey] - - // Wrap font family with quotes - if (valueKey === 'fontFamily') { - value = `'${value}', sans-serif` - } - - // Map font weight from string value to number - if (valueKey === 'fontWeight') { - value = weightMapping[value] ?? value - } - - if (valueKey === 'lineHeight' || valueKey === 'letterSpacing') { - value = `${value}${ - variable.value[valueKey === 'lineHeight' ? 'lineHeightUnit' : 'letterSpacingUnit'] === 'PIXELS' - ? 'px' - : '%' - }` - } - - typographyValue = generateTypographyValue(propKey, valueKey === 'fontSize' ? 'number' : 'string', value) - } - - if (typographyValue) { - variables.push(typographyValue) - typographyClass.props.push({ prop: valueKeyPropMapping[valueKey], value: `var(--propel-${propKey})` }) - } - } - - typographyClasses.push(typographyClass) - }) - - const themes = variablesJSON.collections.find(({ name }) => name === '1. Color Modes')?.modes - - // Parse theme tokens - const lightTheme = getThemeTokens({ name: 'light', themes, variables, tokens }) - const darkTheme = getThemeTokens({ name: 'dark', themes, variables, tokens }) - - // Generate _variables.scss - writeToFileSync( - '_variables.scss', - [ - `// ${GENERATED_WARNING}\n`, - '.variables {', - variables.map(({ cssName, value }) => ` ${cssName}: ${value};`).join('\n'), - '}' - ].join('\n') - ) - - // Generate _tokens.scss - writeToFileSync( - '_tokens.scss', - [ - `// ${GENERATED_WARNING}\n`, - "@use './variables';\n", - '.tokens {', - ' @extend .variables;\n', - tokens.map(({ cssName, value }) => ` ${cssName}: ${value};`).join('\n'), - '}\n', - typographyClasses - .map((typographyClass) => - [ - `.${typographyClass.className} {`, - ' @extend .variables;\n', - typographyClass.props.map(({ prop, value }) => ` ${prop}: ${value};`).join('\n'), - '}\n' - ].join('\n') - ) - .join('\n') - ].join('\n') - ) - - // Generate _lightTheme.scss and _darkTheme.scss - const themesList = [ - { name: 'lightTheme', theme: lightTheme }, - { name: 'darkTheme', theme: darkTheme } - ] - themesList.forEach(({ name, theme }) => { - writeToFileSync( - `_${name}.scss`, - [ - `// ${GENERATED_WARNING}\n`, - "@use './tokens';\n", - `.${name} {`, - ' @extend .tokens;\n', - theme?.map(({ cssName, value }) => ` ${cssName}: ${value};`).join('\n'), - '}' - ].join('\n') - ) - }) - - const tsItems = [...tokens, ...variables] - if (lightTheme) { - tsItems.push(...lightTheme) - } - - // Generate theme.types.ts - writeToFileSync( - 'theme.types.ts', - [ - `// ${GENERATED_WARNING}\n`, - 'export type ThemeTokenGeneratedProps = {', - tsItems.map(({ jsName }) => ` ${jsName}?: string;`).join('\n'), - '}\n', - 'export type ThemeCSSTokenGeneratedProps = {', - lightTheme?.map(({ cssName }) => ` '${cssName}'?: string;`).join('\n'), - '}' - ].join('\n') - ) - - // Generate themeTokens.ts - writeToFileSync( - 'themeTokens.ts', - [ - `// ${GENERATED_WARNING}\n`, - "import type { ThemeTokenGeneratedProps } from './theme.types'\n", - 'export const themeTokensGenerated: (keyof ThemeTokenGeneratedProps)[] = [', - tsItems.map(({ jsName }) => ` '${jsName}',`).join('\n'), - ']' - ].join('\n') - ) - - // Generate themeDict.ts - writeToFileSync( - 'themeDict.ts', - [ - `// ${GENERATED_WARNING}\n`, - 'export const themeDict = [', - tsItems.map(({ jsName, cssName }) => ` { name: '${jsName}', cssVarName: '${cssName}' },`).join('\n'), - ']' - ].join('\n') - ) - - spinner.succeed('Parse design variables and tokens') - } catch (err) { - console.error(err) - spinner.fail('Failed to parse design variables and tokens') - } -} - -main() diff --git a/packages/ui-kit/scripts/tsconfig.json b/packages/ui-kit/scripts/tsconfig.json deleted file mode 100644 index 22405983..00000000 --- a/packages/ui-kit/scripts/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "compilerOptions": { - "module": "ESNext", - "target": "ESNext", - "strict": true, - "outDir": "dist", - "lib": ["ESNext", "DOM"] - }, - "include": ["./**/*.mts"], - "exclude": ["dist"] -} diff --git a/packages/ui-kit/scripts/validate-design-tokens.mts b/packages/ui-kit/scripts/validate-design-tokens.mts deleted file mode 100644 index 6d2ebb40..00000000 --- a/packages/ui-kit/scripts/validate-design-tokens.mts +++ /dev/null @@ -1,106 +0,0 @@ -import fs from 'fs' -import path from 'path' -import ora, { Ora } from 'ora' -import { exec } from 'child_process' -import { promisify } from 'util' - -const FAILED_MESSAGE = 'Design tokens validation failed' - -const execAsync = promisify(exec) - -interface GetAllFilesProps { - dirPath: string - type: 'current' | 'new' - arrayOfFiles?: string[] -} - -// Recursive function to get all files in a given directory -export const getAllFiles = ({ dirPath, type, arrayOfFiles = [] }: GetAllFilesProps): string[] => { - const files = fs.readdirSync(dirPath) - - files.forEach((file) => { - const fullPath = path.join(dirPath, file) - if (fs.statSync(fullPath).isDirectory()) { - const options: GetAllFilesProps = { dirPath: fullPath, type, arrayOfFiles } - if (type === 'current' && file !== 'themes') { - arrayOfFiles = getAllFiles(options) - } else if (type === 'new' && file === 'generated') { - arrayOfFiles = getAllFiles(options) - } - } else if (file.endsWith('.css') || (type === 'new' && file.endsWith('.scss'))) { - arrayOfFiles.push(fullPath) - } - }) - - return arrayOfFiles -} - -// Extract CSS variables with --propel- prefix from a given file -export const extractCSSVariables = (file: string): string[] => { - const fileContent = fs.readFileSync(file, 'utf8') - const regex = /--propel-[\w-]+/g // Regex updated to match only variables starting with --propel- - return fileContent.match(regex) || [] -} - -// Get a list of propel's CSS variables from all CSS files in the given directory -export const getCSSVariables = (dirPath: string, type: 'current' | 'new'): string[] => { - const files = getAllFiles({ dirPath, type }) - const allVariables = new Set() - - files.forEach((file) => { - const variables = extractCSSVariables(file) - variables.forEach((variable) => { - allVariables.add(variable) - }) - }) - - return Array.from(allVariables) -} - -// Build SASS files into CSS -export const buildSASSFiles = async (spinner: Ora): Promise => { - try { - const { stderr } = await execAsync('sass src:src/generated') - if (stderr) throw new Error(stderr) - spinner.succeed('Build SASS files') - } catch (error) { - spinner.fail(`Building SASS files: ${error}`) - throw error - } -} - -// Compare current and new CSS variables, and log any missing variables -export const validateDesignTokens = (spinner: Ora): void => { - spinner.start('Validating design tokens...') - let validationFailed = false - - const currentVariablesList = getCSSVariables('./src', 'current') - const newVariablesList = getCSSVariables('./src/themes', 'new') - - currentVariablesList.forEach((variable) => { - if (!newVariablesList.includes(variable)) { - spinner.warn(`Design token '${variable}' is not defined`) - validationFailed = true - } - }) - - if (validationFailed) { - throw new Error(FAILED_MESSAGE) - } - - spinner.succeed('Validate design tokens') -} - -async function main() { - const spinner = ora({ text: 'Building SASS files...', color: 'yellow' }).start() - - try { - await buildSASSFiles(spinner) - validateDesignTokens(spinner) - } catch (error) { - spinner.fail(FAILED_MESSAGE) - console.error(error) - } -} - -main() diff --git a/packages/ui-kit/src/components/Autocomplete/Autocomplete.module.scss b/packages/ui-kit/src/components/Autocomplete/Autocomplete.module.scss index 91caa1ab..d119d93a 100644 --- a/packages/ui-kit/src/components/Autocomplete/Autocomplete.module.scss +++ b/packages/ui-kit/src/components/Autocomplete/Autocomplete.module.scss @@ -1,32 +1,40 @@ +@use '../../themes/tokens/typography'; + .rootAutocomplete { - box-shadow: var(--propel-shadows-shadow-xs); - border-radius: var(--propel-radius-xs); - color: var(--propel-text-primary); - background-color: var(--propel-background-primary); - border: 1px solid var(--propel-border-primary); + @extend %fontSize2; + + border-radius: var(--radius-2); + background-color: var(--color-background); + border: 1px solid var(--gray-6); display: flex; - gap: var(--propel-spacing-xs); - padding: var(--propel-spacing-xs); + gap: var(--space-1); + padding: var(--space-1); overflow: hidden; transition: all 100ms; box-sizing: border-box; + transition: background-color var(--transition-ease-time) ease, border-color var(--transition-ease-time) ease, + color var(--transition-ease-time) ease; + &:hover { - border: 1px solid var(--propel-border-brand); + background-color: var(--gray-a2); + border-color: var(--gray-10); } } .rootAutocomplete__focused { - border: 1px solid var(--propel-border-brand); - box-shadow: 0 0 0 3px #c7def7; + outline: none; + box-shadow: 0 0 0 3px var(--accent-a4); + border-color: var(--accent-8); } .autocompleteInput { - color: var(--propel-text-primary); + @extend %fontSize2; + background: inherit; border: none; border-radius: inherit; - padding: var(--propel-spacing-xs); + padding: var(--space-1); outline: 0; flex: 1 0 auto; width: 100%; @@ -43,32 +51,28 @@ margin-right: 4px; display: flex; align-items: center; - - &:hover { - background-color: var(--propel-background-secondary); - cursor: pointer; - } } .autocompleteList { + @extend %fontSize2; + box-sizing: border-box; - padding: var(--propel-spacing-xs); - margin: var(--propel-spacing-xs) 0; + padding: var(--space-1); + margin: var(--space-1) 0; width: 100%; - border-radius: var(--propel-radius-xs); + border-radius: var(--radius-2); overflow: auto; outline: 0px; max-height: 300px; z-index: 9999; - background-color: var(--propel-background-primary); - border: 1px solid var(--propel-border-primary); - color: var(--propel-text-primary); - box-shadow: var(--propel-shadows-shadow-xs); + background-color: var(--color-background); + border: 1px solid var(--gray-6); + box-shadow: var(--shadow-5); li { list-style: none; - padding: var(--propel-spacing-md); - border-radius: var(--propel-radius-xs); + padding: var(--space-2); + border-radius: var(--radius-2); cursor: default; &:last-of-type { @@ -76,22 +80,16 @@ } &:hover { - background-color: var(--propel-background-primary-hover); + background-color: var(--gray-2); cursor: pointer; } &[class^='Mui-focused'] { - background-color: var(--propel-brand-25); + background-color: var(--accent-11); } &[aria-selected='true'] { - background-color: var(--propel-background-brand-solid); - color: var(--propel-text-white); - } - - &[aria-selected='true']:hover { - background-color: var(--propel-background-brand-solid-hover); - color: var(--propel-text-white); + background-color: var(--gray-3); } } } diff --git a/packages/ui-kit/src/components/Autocomplete/Autocomplete.stories.tsx b/packages/ui-kit/src/components/Autocomplete/Autocomplete.stories.tsx index 1a034b1d..d77a232d 100644 --- a/packages/ui-kit/src/components/Autocomplete/Autocomplete.stories.tsx +++ b/packages/ui-kit/src/components/Autocomplete/Autocomplete.stories.tsx @@ -165,24 +165,3 @@ export const FreeSoloStory: Story = { }, render: (args) => } - -export const ConsoleImplementation: Story = { - name: 'Console SimpleFilter', - args: { - options: top100Films, - placeholder: 'Search or type', - freeSolo: true, - containerStyle: { - background: 'transparent', - boxShadow: 'none', - border: 'none', - borderBottom: '1px solid #9c9c9e', - borderRadius: 0 - } - }, - render: (args) => ( - - - - ) -} diff --git a/packages/ui-kit/src/components/Button/Button.module.scss b/packages/ui-kit/src/components/Button/Button.module.scss index 0ce58aaf..3269b4de 100644 --- a/packages/ui-kit/src/components/Button/Button.module.scss +++ b/packages/ui-kit/src/components/Button/Button.module.scss @@ -1,19 +1,17 @@ +@use '../../themes/tokens/typography'; + .rootButton { - font-family: var(--default-font-family); - font-style: normal; + @extend %fontSize2; font-weight: var(--font-weight-medium); - font-size: var(--font-size-2); - line-height: var(--line-height-2); - letter-spacing: var(--letter-spacing-2); padding: var(--space-2) var(--space-5); gap: var(--space-3); - background-color: var(--accent-contrast); + background-color: var(--color-background); border-radius: var(--radius-1); border-width: 1px; - border-color: var(--accent-9); + border-color: var(--gray-6); border-style: solid; - color: var(--accent-11); + color: var(--gray-11); cursor: var(--cursor-button); white-space: nowrap; display: flex; @@ -27,8 +25,9 @@ &:focus-visible, &.focus { outline: none; - background-color: var(--accent-a2); - border-color: var(--accent-10); + background-color: var(--gray-a2); + box-shadow: 0 0 0 3px var(--accent-a4); + border-color: var(--accent-8); } &.disabled { @@ -74,9 +73,7 @@ } &.small { - font-size: var(--font-size-1); - line-height: var(--line-height-1); - letter-spacing: var(--letter-spacing-1); + @extend %fontSize1; padding: var(--space-1) var(--space-3); diff --git a/packages/ui-kit/src/components/Counter/Counter.module.scss b/packages/ui-kit/src/components/Counter/Counter.module.scss index cf96db50..9f1bd7c9 100644 --- a/packages/ui-kit/src/components/Counter/Counter.module.scss +++ b/packages/ui-kit/src/components/Counter/Counter.module.scss @@ -1,11 +1,9 @@ +@use '../../themes/tokens/typography'; + %textSettings { + @extend %fontSize8; color: var(--gray-12); - font-family: var(--default-font-family); - font-style: normal; font-weight: var(--font-weight-bold); - font-size: var(--font-size-8); - line-height: var(--line-height-8); - letter-spacing: var(--letter-spacing-8); } .rootCounter { diff --git a/packages/ui-kit/src/components/Counter/Counter.tsx b/packages/ui-kit/src/components/Counter/Counter.tsx index 3e3d01ec..9354058d 100644 --- a/packages/ui-kit/src/components/Counter/Counter.tsx +++ b/packages/ui-kit/src/components/Counter/Counter.tsx @@ -20,7 +20,7 @@ export const CounterComponent = React.forwardRef( loading: isLoadingStatic = false, localize, className, - appearance, + appearance = 'light', loaderProps: loaderPropsInitial, renderLoader, errorFallbackProps: errorFallbackPropsInitial, diff --git a/packages/ui-kit/src/components/Divider/Divider.module.scss b/packages/ui-kit/src/components/Divider/Divider.module.scss index ece3bbb3..25120786 100644 --- a/packages/ui-kit/src/components/Divider/Divider.module.scss +++ b/packages/ui-kit/src/components/Divider/Divider.module.scss @@ -1,7 +1,7 @@ .rootDivider { - margin: var(--propel-spacing-md) 0; + margin: var(--space-2) 0; padding: 0 !important; height: 1px; - background-color: var(--propel-border-primary); + background-color: var(--gray-a6); border: none; } diff --git a/packages/ui-kit/src/components/ErrorFallback/ErrorFallback.module.scss b/packages/ui-kit/src/components/ErrorFallback/ErrorFallback.module.scss index c3787a22..373fffbe 100644 --- a/packages/ui-kit/src/components/ErrorFallback/ErrorFallback.module.scss +++ b/packages/ui-kit/src/components/ErrorFallback/ErrorFallback.module.scss @@ -1,10 +1,7 @@ -@use '../../themes/common'; - .rootErrorFallback { - @extend .textMdRegular; - color: var(--propel-text-secondary); + color: var(--gray-12); max-width: 263px; - height: var(--propel-component-height); + height: var(--component-height); margin: auto; display: flex; flex-direction: column; diff --git a/packages/ui-kit/src/components/ErrorFallback/ErrorFallback.tsx b/packages/ui-kit/src/components/ErrorFallback/ErrorFallback.tsx index 68fc1a14..a2006081 100644 --- a/packages/ui-kit/src/components/ErrorFallback/ErrorFallback.tsx +++ b/packages/ui-kit/src/components/ErrorFallback/ErrorFallback.tsx @@ -29,9 +29,9 @@ const Icon = ({ color }: { color?: string }) => ( ) export const ErrorFallback = React.forwardRef( - ({ error = serverErrorMessage, baseTheme, className, color, ...rest }, forwardedRef) => { + ({ error = serverErrorMessage, appearance, className, color, ...rest }, forwardedRef) => { const { componentContainer, setRef } = useForwardedRefCallback(forwardedRef) - useSetupTheme({ componentContainer, baseTheme }) + useSetupTheme({ componentContainer, appearance }) return (
(
- + {label} {children} diff --git a/packages/ui-kit/src/components/Input/Input.module.scss b/packages/ui-kit/src/components/Input/Input.module.scss index 3068cff1..f612dae7 100644 --- a/packages/ui-kit/src/components/Input/Input.module.scss +++ b/packages/ui-kit/src/components/Input/Input.module.scss @@ -1,16 +1,15 @@ -@use '../../themes/generated/tokens'; +@use '../../themes/tokens/typography'; .rootInput { - @extend .textMdRegular; + @extend %fontSize2; - padding: var(--propel-spacing-lg) var(--propel-spacing-xl); - gap: var(--propel-spacing-lg); - background-color: var(--propel-background-primary); - border-radius: var(--propel-radius-sm); + padding: var(--space-2) var(--space-4); + gap: var(--space-2); + background-color: var(--color-background); + border-radius: var(--radius-2); border-width: 1px; - border-color: var(--propel-border-primary); + border-color: var(--gray-6); border-style: solid; - color: var(--propel-text-primary); cursor: text; white-space: nowrap; display: flex; @@ -18,14 +17,15 @@ align-items: center; width: fit-content; box-sizing: border-box; - transition: border-color var(--propel-transition-ease-time) ease, box-shadow var(--propel-transition-ease-time) ease; + transition: border-color var(--transition-ease-time) ease, box-shadow var(--transition-ease-time) ease; & input { - @extend .textMdRegular; + @extend %fontSize2; border: none; padding: 0; width: 100%; + background-color: transparent; &:focus { outline: none; @@ -36,43 +36,45 @@ } &:hover { - color: var(--propel-text-primary); - border-color: var(--propel-border-brand); + border-color: var(--accent-8); } &.focus { outline: none; - box-shadow: 0 0 0 3px rgba(46, 144, 250, 0.2); - border-color: var(--propel-border-brand); + box-shadow: 0 0 0 3px var(--accent-a4); + border-color: var(--accent-8); } &.error { - border-color: var(--propel-border-error); + border-color: var(--color-error-border); + + & input { + color: var(--color-error-text); + } } &.disabled { - color: var(--propel-text-disabled); - border-color: var(--propel-border-disabled); + color: var(--gray-a8); + background-color: var(--gray-2); + border-color: var(--gray-a3); &:hover { - color: var(--propel-text-disabled); - border-color: var(--propel-border-disabled); cursor: default; } & svg { - color: var(--propel-text-disabled); + color: var(--gray-a8); } } -} -.small { - @extend .textSmRegular; + &.small { + @extend %fontSize1; - padding: var(--propel-spacing-md) var(--propel-spacing-lg); - gap: var(--propel-spacing-md); + padding: var(--space-1) var(--space-3); + gap: var(--space-1); - & input { - @extend .textSmRegular; + & input { + @extend %fontSize1; + } } } diff --git a/packages/ui-kit/src/components/Input/Input.stories.tsx b/packages/ui-kit/src/components/Input/Input.stories.tsx index 1e1a697e..4b83d9fe 100644 --- a/packages/ui-kit/src/components/Input/Input.stories.tsx +++ b/packages/ui-kit/src/components/Input/Input.stories.tsx @@ -9,7 +9,7 @@ const meta: Meta = { component: InputSource, tags: ['devOnly'], argTypes: { - baseTheme: { + appearance: { table: { disable: true } @@ -89,7 +89,6 @@ export const SmallEndAdornmentsStory: Story = { style: { width: 183 }, value: 'Input value', size: 'small', - disabled: true, endAdornment: () => }, render: (args) => diff --git a/packages/ui-kit/src/components/Input/Input.tsx b/packages/ui-kit/src/components/Input/Input.tsx index 81ab62e9..acaf0c4c 100644 --- a/packages/ui-kit/src/components/Input/Input.tsx +++ b/packages/ui-kit/src/components/Input/Input.tsx @@ -1,13 +1,14 @@ import { useInput } from '@mui/base/useInput' import classnames from 'classnames' import * as React from 'react' +import { ThemeAppearances } from 'src/themes' import { useCombinedRefsCallback } from '../../helpers' -import { DefaultThemes, ThemeStateProps, useSetupTheme } from '../ThemeProvider' +import { ThemeStateProps, useSetupTheme } from '../ThemeProvider' import componentStyles from './Input.module.scss' export interface InputProps extends Omit, 'size'> { size?: 'default' | 'small' - baseTheme?: DefaultThemes + appearance?: ThemeAppearances error?: boolean startAdornment?: ({ theme }: { theme: ThemeStateProps }) => React.ReactElement endAdornment?: ({ theme }: { theme: ThemeStateProps }) => React.ReactElement @@ -15,9 +16,9 @@ export interface InputProps extends Omit export const Input = React.forwardRef((props, forwardedRef) => { const { - baseTheme, + appearance = 'light', className, - disabled, + disabled = false, error, startAdornment, endAdornment, @@ -27,7 +28,7 @@ export const Input = React.forwardRef((props, forw } = props const innerRef = React.useRef(null) const { componentContainer, setRef, ref } = useCombinedRefsCallback({ forwardedRef, innerRef }) - const { theme } = useSetupTheme({ componentContainer, baseTheme }) + const { theme } = useSetupTheme({ componentContainer, appearance }) const { getRootProps, getInputProps, focused } = useInput(props) return ( diff --git a/packages/ui-kit/src/components/Leaderboard/Leaderboard.module.scss b/packages/ui-kit/src/components/Leaderboard/Leaderboard.module.scss index 6c158579..da3df9f5 100644 --- a/packages/ui-kit/src/components/Leaderboard/Leaderboard.module.scss +++ b/packages/ui-kit/src/components/Leaderboard/Leaderboard.module.scss @@ -1,8 +1,8 @@ -@use '../../themes/common'; +@use '../../themes/tokens/typography'; .rootLeaderboard { - @extend .textXxsRegular; - color: var(--propel-text-secondary); + @extend %fontSize1; + overflow: auto; padding: 0; @@ -19,14 +19,14 @@ .stickyColumn { position: sticky; - background-color: var(--propel-background-primary); + background-color: var(--color-background); right: 0; } [data-role='table-value'] { right: 0; text-align: right; - padding-left: var(--propel-spacing-md); + padding-left: var(--space-3); white-space: nowrap; width: 1%; } @@ -49,8 +49,8 @@ content: ''; left: 0; top: 0; - background-color: var(--propel-border-primary); - box-shadow: var(--propel-shadows-shadow-xs); + background-color: var(--gray-a8); + box-shadow: 0px 1px 2px 0px var(--gray-a8); width: 1px; height: 100%; z-index: 9999; @@ -66,20 +66,17 @@ th, td { text-align: left; - padding: var(--propel-spacing-md) var(--propel-spacing-md) var(--propel-spacing-md) 0; - color: var(--propel-text-secondary); - @extend .textXsRegular; + padding: var(--space-2) var(--space-2) var(--space-2) 0; + @extend %fontSize1; } td { - @extend .textXsRegular; - color: var(--propel-text-secondary); - border-bottom: 1px solid var(--propel-border-primary); + @extend %fontSize1; + border-bottom: 1px solid var(--gray-a6); } th { font-weight: 600; - color: var(--propel-text-secondary); } tr { @@ -95,7 +92,7 @@ .stickyHeader { tr { th { - background-color: var(--propel-background-primary); + background-color: var(--color-background); position: sticky; top: 0; z-index: 9999; diff --git a/packages/ui-kit/src/components/Leaderboard/Leaderboard.stories.css b/packages/ui-kit/src/components/Leaderboard/Leaderboard.stories.css index 2f419089..b78144fd 100644 --- a/packages/ui-kit/src/components/Leaderboard/Leaderboard.stories.css +++ b/packages/ui-kit/src/components/Leaderboard/Leaderboard.stories.css @@ -7,7 +7,7 @@ .custom-leaderboard table { height: 200px; - --propel-background-brand-solid: #1db954; + --accent-9: #1db954; } .custom-leaderboard table thead tr th { diff --git a/packages/ui-kit/src/components/Leaderboard/Leaderboard.stories.tsx b/packages/ui-kit/src/components/Leaderboard/Leaderboard.stories.tsx index d4ee7b8a..0f1bb7a6 100644 --- a/packages/ui-kit/src/components/Leaderboard/Leaderboard.stories.tsx +++ b/packages/ui-kit/src/components/Leaderboard/Leaderboard.stories.tsx @@ -1,11 +1,9 @@ import rawLeaderboardCss from '!!raw-loader!./Leaderboard.stories.css' import type { Meta, StoryContext, StoryObj } from '@storybook/react' -import React, { useState } from 'react' +import React from 'react' import axiosInstance from '../../../../../app/storybook/src/axios' import { RelativeTimeRange, Sort } from '../../graphql' import { quotedStringRegex, storybookCodeTemplate, useStorybookAccessToken } from '../../helpers' -import { ThemeTokenProps } from '../../themes' -import { DefaultThemes, ThemeProvider } from '../ThemeProvider' import { Leaderboard as LeaderboardSource, LeaderboardComponent } from './Leaderboard' import './Leaderboard.stories.css' import { LeaderboardQueryProps } from './Leaderboard.types' @@ -14,7 +12,7 @@ const meta: Meta = { title: 'Components/Leaderboard', component: LeaderboardComponent, argTypes: { - baseTheme: { + appearance: { table: { disable: true } @@ -304,42 +302,3 @@ export const CustomStyleStory: Story = { }, render: (args) => } - -export const ThemeStory: Story = { - name: 'Theme', - args: { - headers: barHeaders, - rows: barRows, - card: true - }, - decorators: [ - (Story) => { - const [baseTheme, setBaseTheme] = useState('lightTheme') - - const lightColors: ThemeTokenProps = { - accent: '#3d3d3d', - accentHover: '#3d3d3dc6' - } - - const darkColors: ThemeTokenProps = { - accent: '#adadad', - accentHover: '#ffffffc6' - } - - const theme = baseTheme === 'darkTheme' ? darkColors : lightColors - - return ( - -
- - {baseTheme} -
- -
- ) - } - ], - render: (args) => -} diff --git a/packages/ui-kit/src/components/Leaderboard/Leaderboard.tsx b/packages/ui-kit/src/components/Leaderboard/Leaderboard.tsx index 3bb55382..dc72add7 100644 --- a/packages/ui-kit/src/components/Leaderboard/Leaderboard.tsx +++ b/packages/ui-kit/src/components/Leaderboard/Leaderboard.tsx @@ -37,7 +37,7 @@ export const LeaderboardComponent = React.forwardRef({ componentContainer, - baseTheme, + appearance, renderLoader, errorFallback, renderEmpty @@ -122,7 +122,7 @@ export const LeaderboardComponent = React.forwardRef span { @@ -61,9 +38,8 @@ display: inline-block; width: 0.75rem; height: 0.75rem; - margin-right: var(--propel-spacing-md); + margin-right: var(--space-2); border-radius: 50%; - background-color: var(--color-blue-800); } } @@ -77,7 +53,7 @@ li:nth-child(#{9 - $i}) { & > span:first-child { &:before { - background-color: var(--propel-color-blue#{$i}00); + background-color: var(--accent-#{$i}); } } } @@ -86,7 +62,7 @@ li:nth-child(9) { & > span:first-child { &:before { - background-color: var(--propel-brand-50); + background-color: var(--accent-4); } } } @@ -94,7 +70,7 @@ li:nth-child(10) { & > span:first-child { &:before { - background-color: var(--propel-brand-25); + background-color: var(--accent-3); } } } diff --git a/packages/ui-kit/src/components/PieChart/PieChart.stories.tsx b/packages/ui-kit/src/components/PieChart/PieChart.stories.tsx index c39a78c0..d2c24c70 100644 --- a/packages/ui-kit/src/components/PieChart/PieChart.stories.tsx +++ b/packages/ui-kit/src/components/PieChart/PieChart.stories.tsx @@ -1,9 +1,8 @@ import type { Meta, StoryObj } from '@storybook/react' -import React, { useState } from 'react' +import React from 'react' import axiosInstance from '../../../../../app/storybook/src/axios' import { FilterOperator, RelativeTimeRange, Sort } from '../../graphql' import { quotedStringRegex, storybookCodeTemplate, useStorybookAccessToken } from '../../helpers' -import { DefaultThemes, ThemeProvider, useSetupTheme } from '../ThemeProvider' import { PieChart as PieChartSource, PieChartComponent } from './PieChart' import { PieChartQueryProps } from './PieChart.types' @@ -11,7 +10,7 @@ const meta: Meta = { title: 'Components/PieChart', component: PieChartComponent, argTypes: { - baseTheme: { + appearance: { table: { disable: true } @@ -254,35 +253,6 @@ export const ShowValuesDoughnutStory: Story = { render: (args) => } -export const ThemeStory: Story = { - name: 'Theme', - args: { - variant: 'pie', - headers: pieHeaders, - rows: pieRows, - card: true - }, - decorators: [ - (Story) => { - const [baseTheme, setBaseTheme] = useState('lightTheme') - const { theme } = useSetupTheme({ baseTheme }) - - return ( - -
- - {baseTheme} -
- -
- ) - } - ], - render: (args) => -} - export const EmptyPieStory: Story = { name: 'Empty State', args: { diff --git a/packages/ui-kit/src/components/PieChart/PieChart.tsx b/packages/ui-kit/src/components/PieChart/PieChart.tsx index 539de21e..7a4e3876 100644 --- a/packages/ui-kit/src/components/PieChart/PieChart.tsx +++ b/packages/ui-kit/src/components/PieChart/PieChart.tsx @@ -38,7 +38,7 @@ export const PieChartComponent = React.forwardRef card = false, className, style, - baseTheme = 'lightTheme', + appearance = 'light', loading: isLoadingStatic = false, chartProps, labelListClassName, @@ -59,7 +59,7 @@ export const PieChartComponent = React.forwardRef renderEmpty: renderEmptyComponent } = useSetupTheme({ componentContainer, - baseTheme, + appearance, renderLoader, errorFallback, renderEmpty @@ -113,16 +113,16 @@ export const PieChartComponent = React.forwardRef const defaultChartColorPalette = React.useMemo( () => [ - theme?.brand900, - theme?.brand700, - theme?.brand600, - theme?.brand500, - theme?.brand400, - theme?.brand300, - theme?.brand200, - theme?.brand100, - theme?.brand50, - theme?.brand25 + theme?.getVar('--accent-3'), + theme?.getVar('--accent-4'), + theme?.getVar('--accent-5'), + theme?.getVar('--accent-6'), + theme?.getVar('--accent-7'), + theme?.getVar('--accent-8'), + theme?.getVar('--accent-9'), + theme?.getVar('--accent-10'), + theme?.getVar('--accent-11'), + theme?.getVar('--accent-12') ], [theme] ) @@ -165,7 +165,7 @@ export const PieChartComponent = React.forwardRef const customPlugins = { customCanvasBackgroundColor: { - color: card ? theme?.backgroundPrimary : 'transparent' + color: card ? theme?.getVar('--color-background') : 'transparent' }, title: { display: isPie && !hideTotal, @@ -183,7 +183,7 @@ export const PieChartComponent = React.forwardRef } }, emptyDoughnut: { - color: theme?.backgroundBrandPrimary, + color: theme?.getVar('--accent-11'), width: 2, radiusDecrease: 20 }, diff --git a/packages/ui-kit/src/components/Select/Option/Option.module.scss b/packages/ui-kit/src/components/Select/Option/Option.module.scss index fcbf2921..cfb760f0 100644 --- a/packages/ui-kit/src/components/Select/Option/Option.module.scss +++ b/packages/ui-kit/src/components/Select/Option/Option.module.scss @@ -1,21 +1,22 @@ -@use '../../../themes/generated/tokens'; +@use '../../../themes/tokens/typography'; .rootOption { - @extend .textMdRegular; + @extend %fontSize2; + font-weight: var(--font-weight-medium); - padding: var(--propel-spacing-xl) var(--propel-spacing-4xl); + padding: var(--space-2) var(--space-4); margin: 0; cursor: pointer; &:hover { - background-color: var(--propel-background-active); - border-radius: var(--propel-radius-sm); + background-color: var(--gray-2); + border-radius: var(--radius-2); } &:focus, &:focus-visible { - background-color: var(--propel-background-secondary-hover); - border-radius: var(--propel-radius-sm); + background-color: var(--gray-3); + border-radius: var(--radius-2); outline: none; } } diff --git a/packages/ui-kit/src/components/Select/Select.module.scss b/packages/ui-kit/src/components/Select/Select.module.scss index a8c7db80..d744b02c 100644 --- a/packages/ui-kit/src/components/Select/Select.module.scss +++ b/packages/ui-kit/src/components/Select/Select.module.scss @@ -1,26 +1,50 @@ -@use '../../themes/generated/tokens'; +@use '../../themes/tokens/typography'; .rootButton { - @extend .textMdRegular; + border-color: var(--gray-6); + color: var(--gray-11); + + &.startAdornment { + padding-left: var(--space-3); + } + + &.endAdornment, + &.startAdornment.endAdornment { + padding-right: var(--space-3); + padding-left: var(--space-3); + } &.small { - @extend .textSmRegular; + font-size: var(--font-size-1); + letter-spacing: var(--letter-spacing-1); + + padding: var(--space-1) var(--space-3); + + &.startAdornment { + padding-left: var(--space-2); + } + + &.endAdornment, + &.startAdornment.endAdornment { + padding-right: var(--space-2); + padding-left: var(--space-2); + } } } .popper { z-index: 9999; - padding: var(--propel-spacing-lg); - background-color: var(--propel-background-primary); - border-radius: var(--propel-radius-sm); + padding: var(--space-3); + background-color: var(--color-background); + border-radius: var(--radius-2); border-width: 1px; - border-color: var(--propel-border-secondary); + border-color: var(--gray-6); border-style: solid; - color: var(--propel-text-secondary); + color: var(--gray-11); display: flex; min-width: fit-content; - box-shadow: var(--propel-shadows-shadow-xs); - margin-top: var(--propel-spacing-xxs) !important; + box-shadow: var(--shadow-5); + margin-top: var(--space-1) !important; ul { width: 100%; @@ -35,10 +59,10 @@ .small { ul { li { - @extend .textSmRegular; + @extend %fontSize1; - padding: var(--propel-spacing-md) var(--propel-spacing-xl); - gap: var(--propel-spacing-xxs); + padding: var(--space-2) var(--space-3); + gap: var(--space-1); } } } diff --git a/packages/ui-kit/src/components/Select/Select.tsx b/packages/ui-kit/src/components/Select/Select.tsx index 44d2c327..628a7179 100644 --- a/packages/ui-kit/src/components/Select/Select.tsx +++ b/packages/ui-kit/src/components/Select/Select.tsx @@ -106,6 +106,8 @@ const SelectComponent = ( size, value: value?.label ?? undefined, className: classNames(componentStyles.button, componentStyles.rootButton, { + [componentStyles.startAdornment]: startAdornment, + [componentStyles.endAdornment]: endAdornment, [componentStyles[size]]: size && size !== 'default' }) }), diff --git a/packages/ui-kit/src/components/Select/index.ts b/packages/ui-kit/src/components/Select/index.ts index 3e383f07..b169a058 100644 --- a/packages/ui-kit/src/components/Select/index.ts +++ b/packages/ui-kit/src/components/Select/index.ts @@ -1 +1,2 @@ +export * from './Option' export * from './Select' diff --git a/packages/ui-kit/src/components/ThemeProvider/ThemeProvider.test.tsx b/packages/ui-kit/src/components/ThemeProvider/ThemeProvider.test.tsx index 5e98ed35..fc2bde83 100644 --- a/packages/ui-kit/src/components/ThemeProvider/ThemeProvider.test.tsx +++ b/packages/ui-kit/src/components/ThemeProvider/ThemeProvider.test.tsx @@ -1,21 +1,21 @@ import React from 'react' import { render, screen } from '@testing-library/react' import { ThemeProvider, useSetupTheme } from './ThemeProvider' -import type { ThemeTokenProps } from '../../themes/theme.types' +// import type { ThemeTokenProps } from '../../themes/theme.types' import { FallbackComponents } from '../shared.types' import { Loader } from '../Loader' import { ErrorFallback } from '../ErrorFallback' -const theme: ThemeTokenProps = { - foregroundBrandPrimary: 'red', - borderPrimary: 'blue' -} +// const theme: ThemeTokenProps = { +// // foregroundBrandPrimary: 'red', +// // borderPrimary: 'blue' +// } describe('ThemeProvider', () => { it('should apply the provided theme class if a string is passed as theme prop', () => { const themeClass = 'customTheme' render( - +
) @@ -23,18 +23,18 @@ describe('ThemeProvider', () => { expect(screen.getByTestId('theme-provider')).toHaveClass(themeClass) }) - it('should apply the provided theme styles if an object is passed as theme prop', () => { - render( - -
- - ) + // it('should apply the provided theme styles if an object is passed as theme prop', () => { + // render( + // + //
+ // + // ) - const styles = getComputedStyle(screen.getByTestId('theme-provider')) + // const styles = getComputedStyle(screen.getByTestId('theme-provider')) - expect(styles.getPropertyValue('--propel-foreground-brand-primary')).toBe('red') - expect(styles.getPropertyValue('--propel-border-primary')).toBe('blue') - }) + // expect(styles.getPropertyValue('--propel-foreground-brand-primary')).toBe('red') + // expect(styles.getPropertyValue('--propel-border-primary')).toBe('blue') + // }) }) describe('useSetupTheme', () => { @@ -92,7 +92,7 @@ describe('useSetupTheme', () => { div.style.setProperty('--propel-border-primary', 'blue') render() - expect(screen.getByText(/Theme: {"borderPrimary":"blue","foregroundBrandPrimary":"red"}/)).toBeInTheDocument() + // expect(screen.getByText(/Theme: {"borderPrimary":"blue","foregroundBrandPrimary":"red"}/)).toBeInTheDocument() expect(screen.getByText(/ChartConfig:/)).toBeInTheDocument() // Adjust this based on expected chartConfig structure }) diff --git a/packages/ui-kit/src/components/ThemeProvider/ThemeProvider.tsx b/packages/ui-kit/src/components/ThemeProvider/ThemeProvider.tsx index 0e14e881..956702e8 100644 --- a/packages/ui-kit/src/components/ThemeProvider/ThemeProvider.tsx +++ b/packages/ui-kit/src/components/ThemeProvider/ThemeProvider.tsx @@ -33,6 +33,8 @@ const getAccentColors = (accentColor: AccentColors, appearance: ThemeAppearances return { ...radixColors.whiteA, ...radixColors.blackA, + ...radixColors[`red${appearanceSuffix}`], + ...radixColors[`red${appearanceSuffix}A`], ...radixColors[`slate${appearanceSuffix}`], // @TODO: fix this ...radixColors[`slate${appearanceSuffix}A`], // @TODO: fix this ...(radixColors[`${accentColor}${appearanceSuffix}`] as Record), diff --git a/packages/ui-kit/src/components/TimeRangePicker/DateTimeField/DateTimeField.module.scss b/packages/ui-kit/src/components/TimeRangePicker/DateTimeField/DateTimeField.module.scss index a6644b56..902de24c 100644 --- a/packages/ui-kit/src/components/TimeRangePicker/DateTimeField/DateTimeField.module.scss +++ b/packages/ui-kit/src/components/TimeRangePicker/DateTimeField/DateTimeField.module.scss @@ -1,6 +1,6 @@ .rootDateTimeField { display: flex; - gap: var(--propel-spacing-md); + gap: var(--space-2); flex: 1; } diff --git a/packages/ui-kit/src/components/TimeRangePicker/DateTimeField/DateTimeField.tsx b/packages/ui-kit/src/components/TimeRangePicker/DateTimeField/DateTimeField.tsx index 71545996..06754a5a 100644 --- a/packages/ui-kit/src/components/TimeRangePicker/DateTimeField/DateTimeField.tsx +++ b/packages/ui-kit/src/components/TimeRangePicker/DateTimeField/DateTimeField.tsx @@ -12,14 +12,18 @@ import { } from 'date-fns' import React, { Dispatch, SetStateAction } from 'react' import { DateRange } from 'react-day-picker' -import { useCombinedRefsCallback, getDateTimeFormatPattern } from '../../../helpers' +import { ThemeAppearances } from 'src/themes' +import { getDateTimeFormatPattern, useCombinedRefsCallback } from '../../../helpers' +import { ButtonProps } from '../../Button' import { FormField } from '../../FormField' import { Input } from '../../Input' -import { DefaultThemes, useSetupTheme } from '../../ThemeProvider' +import { useSetupTheme } from '../../ThemeProvider' import componentStyles from './DateTimeField.module.scss' -export interface DateTimeFieldProps extends Omit, 'onChange'> { - baseTheme?: DefaultThemes +export interface DateTimeFieldProps + extends Omit, 'onChange' | 'size'>, + Pick { + appearance?: ThemeAppearances dateRange?: DateRange | null rangeRole: 'from' | 'to' onChange?: Dispatch> @@ -33,10 +37,13 @@ const validateDateRange = (dateRange: DateRange | null | undefined, rangeRole: ' : isBefore(dateRange?.from ?? subDays(parsedValue, 1), parsedValue)) export const DateTimeField = React.forwardRef( - ({ baseTheme, className, dateRange, locale = 'en-US', rangeRole, onChange, ...rest }, forwardedRef) => { + ( + { appearance, className, size = 'default', dateRange, locale = 'en-US', rangeRole, onChange, ...rest }, + forwardedRef + ) => { const innerRef = React.useRef(null) const { componentContainer, setRef } = useCombinedRefsCallback({ forwardedRef, innerRef }) - useSetupTheme({ componentContainer, baseTheme }) + useSetupTheme({ componentContainer, appearance }) const dateFormatPattern = getDateTimeFormatPattern({ locale, @@ -210,7 +217,7 @@ export const DateTimeField = React.forwardRef = { component: TimeRangePickerSource, tags: ['tag'], argTypes: { - baseTheme: { + appearance: { table: { disable: true } diff --git a/packages/ui-kit/src/components/TimeRangePicker/TimeRangePicker.tsx b/packages/ui-kit/src/components/TimeRangePicker/TimeRangePicker.tsx index 1c9a495b..3a871b05 100644 --- a/packages/ui-kit/src/components/TimeRangePicker/TimeRangePicker.tsx +++ b/packages/ui-kit/src/components/TimeRangePicker/TimeRangePicker.tsx @@ -43,7 +43,7 @@ const formatDateTime = (value: Date | undefined, locale: string, valueFormat?: I export const TimeRangePicker = React.forwardRef( ( { - baseTheme, + appearance = 'light', disableDateUntilNow = false, disableCustomRange = false, disableCustomRelative = false, @@ -52,6 +52,7 @@ export const TimeRangePicker = React.forwardRef(null) const { theme } = useSetupTheme({ - baseTheme, + appearance, componentContainer }) @@ -310,7 +311,7 @@ export const TimeRangePicker = React.forwardRef setSelectOpen(listboxOpen)} listboxOpen={selectOpen} - size="small" + size={size} slotProps={{ popper: { className: componentStyles.timeRangePickerPopper } }} @@ -348,16 +349,16 @@ export const TimeRangePicker = React.forwardRef{' '}