diff --git a/.changeset/dull-pandas-build.md b/.changeset/dull-pandas-build.md new file mode 100644 index 00000000..86c8ef73 --- /dev/null +++ b/.changeset/dull-pandas-build.md @@ -0,0 +1,7 @@ +--- +"@cambly/syntax-design-tokens": minor +"@cambly/syntax-core": minor +"@syntax/storybook": minor +--- + +Add ThemeProvider & styles for Button / IconButton & LinkButton diff --git a/apps/storybook/.storybook/main.ts b/apps/storybook/.storybook/main.ts index 1245ca57..01744161 100644 --- a/apps/storybook/.storybook/main.ts +++ b/apps/storybook/.storybook/main.ts @@ -13,9 +13,10 @@ const config: StorybookConfig = { actions: false, }, }, + "@storybook/addon-a11y", "@storybook/addon-actions", + "@storybook/addon-toolbars", "storybook-addon-designs", - "@storybook/addon-a11y", "storybook-addon-rtl", ], staticDirs: ["../public"], diff --git a/apps/storybook/.storybook/preview.tsx b/apps/storybook/.storybook/preview.tsx index 13d11eaf..1beacaff 100644 --- a/apps/storybook/.storybook/preview.tsx +++ b/apps/storybook/.storybook/preview.tsx @@ -1,7 +1,32 @@ import React from "react"; -import "@cambly/syntax-design-tokens/dist/css/variables.css"; -import { initializeRTL } from "storybook-addon-rtl"; +import { Preview } from "@storybook/react"; +import ThemeProvider from "../../../packages/syntax-core/src/ThemeProvider/ThemeProvider"; -initializeRTL(); +const preview: Preview = { + globalTypes: { + theme: { + description: "Global theme for components", + defaultValue: "classic", + toolbar: { + title: "Theme", + icon: "circlehollow", + items: ["classic", "cambio"], + dynamicTitle: true, + }, + }, + }, + decorators: [ + (Story, context) => { + const theme = context.globals.theme; + return ( + + + + ); + }, + ], +}; + +export default preview; export const decorators = [(Story) => ]; diff --git a/apps/storybook/package.json b/apps/storybook/package.json index 4209dccc..3b14fcd9 100644 --- a/apps/storybook/package.json +++ b/apps/storybook/package.json @@ -27,6 +27,7 @@ "@storybook/addon-docs": "7.0.7", "@storybook/addon-essentials": "7.0.7", "@storybook/addon-links": "7.0.7", + "@storybook/addon-toolbars": "^7.6.17", "@storybook/addons": "7.0.7", "@storybook/react": "7.0.7", "@storybook/react-vite": "7.0.7", @@ -36,6 +37,7 @@ "serve": "14.2.0", "storybook": "7.0.7", "storybook-addon-designs": "7.0.0-beta.2", + "storybook-addon-rtl": "^1.0.0", "storybook-dark-mode": "3.0.0", "typescript": "5.0.4", "vite": "4.3.4" diff --git a/apps/storybook/stories/Colors.tsx b/apps/storybook/stories/Colors.tsx index 886c689b..42b4674b 100644 --- a/apps/storybook/stories/Colors.tsx +++ b/apps/storybook/stories/Colors.tsx @@ -4,7 +4,10 @@ import variables from "../../../packages/syntax-design-tokens/dist/json/variable export default function Colors() { const groupColors = Object.entries(variables).reduce( (acc, [key, value]) => { - if ( + if (key.includes("cambio")) { + // @ts-expect-error + acc["Cambio"].push({ key, value }); + } else if ( key.includes("black") || key.includes("white") || key.includes("gray") @@ -25,6 +28,7 @@ export default function Colors() { return acc; }, { + Cambio: [], Grayscale: [], Primary: [], Destructive: [], @@ -46,8 +50,15 @@ export default function Colors() { style={{ color: [ + "color-cambio-white", + "color-cambio-cream", + "color-cambio-pink", + "color-cambio-sky", + "color-cambio-yellow-700", + "color-cambio-transparent-full", "color-base-gray-10", "color-base-gray-30", + "color-base-yellow-700", "color-base-white", ].includes(key) || (number && parseInt(number) < 400) diff --git a/package.json b/package.json index 871a6a0b..aeebc033 100755 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ "glob": "10.3.10", "jsdom": "22.0.0", "prettier": "2.8.8", - "storybook-addon-rtl": "^0.5.0", "stylelint": "15.6.0", "stylelint-config-css-modules": "4.2.0", "stylelint-config-standard": "33.0.0", diff --git a/packages/syntax-core/src/Button/Button.module.css b/packages/syntax-core/src/Button/Button.module.css index 51bc9901..2ae0cd6a 100644 --- a/packages/syntax-core/src/Button/Button.module.css +++ b/packages/syntax-core/src/Button/Button.module.css @@ -72,6 +72,27 @@ border-radius: 16px; } +.smCambio { + min-width: 52px; + height: 32px; + padding: 0 16px; + border-radius: 100px; +} + +.mdCambio { + min-width: 78px; + height: 48px; + padding: 0 24px; + border-radius: 100px; +} + +.lgCambio { + min-width: 104px; + height: 64px; + padding: 0 32px; + border-radius: 100px; +} + .icon { color: inherit; } diff --git a/packages/syntax-core/src/Button/Button.stories.tsx b/packages/syntax-core/src/Button/Button.stories.tsx index 74f5df43..aa75c506 100644 --- a/packages/syntax-core/src/Button/Button.stories.tsx +++ b/packages/syntax-core/src/Button/Button.stories.tsx @@ -21,6 +21,9 @@ export default { "destructive-secondary", "destructive-tertiary", "success", + "success-primary", + "success-secondary", + "success-tertiary", "branded", "inverse", ], diff --git a/packages/syntax-core/src/Button/Button.tsx b/packages/syntax-core/src/Button/Button.tsx index 20a34d77..da7f3669 100644 --- a/packages/syntax-core/src/Button/Button.tsx +++ b/packages/syntax-core/src/Button/Button.tsx @@ -1,18 +1,23 @@ import React, { forwardRef } from "react"; import classNames from "classnames"; - -import backgroundColor from "../colors//backgroundColor"; -import foregroundColor from "../colors/foregroundColor"; -import foregroundTypographyColor from "../colors/foregroundTypographyColor"; import { type Size } from "../constants"; import Typography from "../Typography/Typography"; import Box from "../Box/Box"; - import iconSize from "./constants/iconSize"; import textVariant from "./constants/textVariant"; import loadingIconSize from "./constants/loadingIconSize"; import styles from "./Button.module.css"; import useIsHydrated from "../useIsHydrated"; +import { useTheme } from "../ThemeProvider/ThemeProvider"; +import { classicColor, cambioColor } from "./constants/color"; +import { + classicBackgroundColor, + cambioBackgroundColor, +} from "../colors/backgroundColor"; +import { + classicForegroundColor, + cambioForegroundColor, +} from "../colors/foregroundColor"; type ButtonProps = { /** @@ -30,6 +35,15 @@ type ButtonProps = { /** * The color of the button * + * Classic only: + * * `inverse` + * * `success` + * + * Cambio only: + * * `success-primary` + * * `success-secondary` + * * `success-tertiary` + * * @defaultValue "primary" */ color?: @@ -41,14 +55,23 @@ type ButtonProps = { | "destructive-tertiary" | "branded" | "success" + | "success-primary" + | "success-secondary" + | "success-tertiary" | "inverse"; /** * The size of the button * + * Classic: * * `sm`: 32px * * `md`: 40px * * `lg`: 48px * + * Cambio: + * * `sm`: 32px + * * `md`: 48px + * * `lg`: 64px + * * @defaultValue "md" */ size?: (typeof Size)[number]; @@ -76,10 +99,12 @@ type ButtonProps = { fullWidth?: boolean; /** * The icon to be displayed at the start of the button. Please use a [Rounded Material Icon](https://material.io/resources/icons/?style=round) + * Note: startIcon is not supported in the Cambio theme */ startIcon?: React.ComponentType<{ className?: string }>; /** * The icon to be displayed at the end of the button. Please use a [Rounded Material Icon](https://material.io/resources/icons/?style=round) + * Note: endIcon is not supported in the Cambio theme */ endIcon?: React.ComponentType<{ className?: string }>; /** @@ -120,6 +145,17 @@ const Button = forwardRef( ref, ) => { const isHydrated = useIsHydrated(); + const { themeName } = useTheme(); + + const foregroundColorClass = + themeName === "classic" + ? classicForegroundColor(classicColor(color)) + : cambioForegroundColor(cambioColor(color)); + + const backgroundColorClass = + themeName === "classic" + ? classicBackgroundColor(classicColor(color)) + : cambioBackgroundColor(cambioColor(color)); return (