From a9d74e856a308559b59c76c8a41f112552986bd2 Mon Sep 17 00:00:00 2001 From: Sergiu Nica <104572860+ser888gio@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:37:31 +0200 Subject: [PATCH] Created a UI component for Storybook - Badge (#41) Co-authored-by: martinwenisch --- apps/design-system/stories/badge.stories.tsx | 40 +++++ package-lock.json | 166 +++++++++++++++++- package.json | 9 +- packages/design-system/config/borderRadius.ts | 2 +- packages/design-system/config/colors.ts | 2 +- packages/design-system/config/typography.ts | 4 + packages/design-system/package.json | 2 + .../design-system/src/Badge/BadgeStarIcon.tsx | 19 ++ packages/design-system/src/badge.tsx | 40 +++++ 9 files changed, 277 insertions(+), 7 deletions(-) create mode 100644 apps/design-system/stories/badge.stories.tsx create mode 100644 packages/design-system/src/Badge/BadgeStarIcon.tsx create mode 100644 packages/design-system/src/badge.tsx diff --git a/apps/design-system/stories/badge.stories.tsx b/apps/design-system/stories/badge.stories.tsx new file mode 100644 index 00000000..b1261ee3 --- /dev/null +++ b/apps/design-system/stories/badge.stories.tsx @@ -0,0 +1,40 @@ +import { Badge } from "../../../packages/design-system/src/badge"; +import { Meta, StoryObj } from "@storybook/react"; + +export default { + title: "Components/Badge", + component: Badge, + argTypes: { + color: { + control: { type: "select", options: ["neutral", "secondary"] }, + }, + icon: { control: "boolean" }, + }, + tags: ["autodocs"], +} as Meta; + +type Story = StoryObj; + +export const Neutral: Story = { + args: { + icon: false, + color: "neutral", + children: "Label", + }, +}; + +export const Primary: Story = { + args: { + icon: true, + color: "neutral", + children: "Label", + }, +}; + +export const Secondary: Story = { + args: { + icon: false, + color: "secondary", + children: "Label", + }, +}; diff --git a/package-lock.json b/package-lock.json index 7f944548..aa0178ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,15 @@ "apps/*", "packages/*" ], + "dependencies": { + "class-variance-authority": "^0.7.0", + "classnames": "^2.5.1", + "styled-components": "^6.1.12" + }, "devDependencies": { "@repo/eslint-config": "*", "@repo/typescript-config": "*", - "prettier": "^3.2.5", + "prettier": "^3.3.3", "prettier-plugin-tailwindcss": "^0.6.5", "turbo": "^2.0.6" }, @@ -2393,6 +2398,27 @@ "tslib": "^2.4.0" } }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", + "license": "MIT" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "license": "MIT" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -5775,6 +5801,12 @@ "@types/send": "*" } }, + "node_modules/@types/stylis": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", + "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==", + "license": "MIT" + }, "node_modules/@types/through": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.33.tgz", @@ -7707,6 +7739,15 @@ "node": ">= 6" } }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001642", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz", @@ -7976,6 +8017,33 @@ "dev": true, "license": "MIT" }, + "node_modules/class-variance-authority": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz", + "integrity": "sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "2.0.0" + }, + "funding": { + "url": "https://joebell.co.uk" + } + }, + "node_modules/class-variance-authority/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" + }, "node_modules/clean-css": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", @@ -8455,6 +8523,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, "node_modules/css-loader": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", @@ -8521,6 +8598,17 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "node_modules/css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", @@ -8558,7 +8646,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true, "license": "MIT" }, "node_modules/damerau-levenshtein": { @@ -16132,7 +16219,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true, "license": "MIT" }, "node_modules/prelude-ls": { @@ -17759,6 +17845,12 @@ "node": ">=8" } }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, "node_modules/sharp": { "version": "0.33.4", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.4.tgz", @@ -18734,6 +18826,68 @@ "webpack": "^5.0.0" } }, + "node_modules/styled-components": { + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.12.tgz", + "integrity": "sha512-n/O4PzRPhbYI0k1vKKayfti3C/IGcPf+DqcrOB7O/ab9x4u/zjqraneT5N45+sIe87cxrCApXM8Bna7NYxwoTA==", + "license": "MIT", + "dependencies": { + "@emotion/is-prop-valid": "1.2.2", + "@emotion/unitless": "0.8.1", + "@types/stylis": "4.2.5", + "css-to-react-native": "3.2.0", + "csstype": "3.1.3", + "postcss": "8.4.38", + "shallowequal": "1.1.0", + "stylis": "4.3.2", + "tslib": "2.6.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/styled-components/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "license": "0BSD" + }, "node_modules/styled-jsx": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", @@ -18757,6 +18911,12 @@ } } }, + "node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", + "license": "MIT" + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", diff --git a/package.json b/package.json index 33ae0162..cbd485ce 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "devDependencies": { "@repo/eslint-config": "*", "@repo/typescript-config": "*", - "prettier": "^3.2.5", + "prettier": "^3.3.3", "prettier-plugin-tailwindcss": "^0.6.5", "turbo": "^2.0.6" }, @@ -21,5 +21,10 @@ "workspaces": [ "apps/*", "packages/*" - ] + ], + "dependencies": { + "class-variance-authority": "^0.7.0", + "classnames": "^2.5.1", + "styled-components": "^6.1.12" + } } diff --git a/packages/design-system/config/borderRadius.ts b/packages/design-system/config/borderRadius.ts index b363369e..0cd8ef8d 100644 --- a/packages/design-system/config/borderRadius.ts +++ b/packages/design-system/config/borderRadius.ts @@ -4,7 +4,7 @@ const borderRadius: Pick, "borderRadius"> = { // !!! We replace the default Tailwind CSS borderRadius scale with our own borderRadius: { none: "0px", - DEFAULT: "1rem", + DEFAULT: "0.375rem", md: "1.5rem", lg: "2rem", full: "9999px", diff --git a/packages/design-system/config/colors.ts b/packages/design-system/config/colors.ts index aecb0dd8..7498684e 100644 --- a/packages/design-system/config/colors.ts +++ b/packages/design-system/config/colors.ts @@ -84,7 +84,7 @@ const backgroundColorSecondary = { const textColorSecondary = { secondary: secondaryColors[50], "secondary-hover": secondaryColors[30], - "secondary-strong": secondaryColors[10], + "secondary-strong": secondaryColors[30], }; const borderColorSecondary = { diff --git a/packages/design-system/config/typography.ts b/packages/design-system/config/typography.ts index 2227b8a7..4cd81b9b 100644 --- a/packages/design-system/config/typography.ts +++ b/packages/design-system/config/typography.ts @@ -8,6 +8,10 @@ const typography: Pick< fontFamily: { sans: ['"Radio Canada"', ...defaultTheme.fontFamily.sans], }, + fontSize: { + xs: "0.625rem", + sm: "0.812rem", + }, }; export default typography; diff --git a/packages/design-system/package.json b/packages/design-system/package.json index 6fb8e6b3..6394fe00 100644 --- a/packages/design-system/package.json +++ b/packages/design-system/package.json @@ -14,6 +14,8 @@ "build": "npm run fonts && npm run tailwind", "dev": "npm run fonts && npm run tailwind:watch", "fonts": "mkdir -p ./dist && cp -r ./src/fonts ./dist/fonts", + "format": "prettier . --check", + "format:fix": "prettier . --write", "generate:component": "turbo gen react-component", "lint": "eslint . --max-warnings 0", "lint:fix": "eslint . --fix", diff --git a/packages/design-system/src/Badge/BadgeStarIcon.tsx b/packages/design-system/src/Badge/BadgeStarIcon.tsx new file mode 100644 index 00000000..e4ccf78f --- /dev/null +++ b/packages/design-system/src/Badge/BadgeStarIcon.tsx @@ -0,0 +1,19 @@ +import React from "react"; + +export function BadgeStarIcon( + props: React.JSX.IntrinsicAttributes & React.SVGProps, +) { + return ( + + + + ); +} diff --git a/packages/design-system/src/badge.tsx b/packages/design-system/src/badge.tsx new file mode 100644 index 00000000..c596fa96 --- /dev/null +++ b/packages/design-system/src/badge.tsx @@ -0,0 +1,40 @@ +import React from "react"; +import { cva } from "class-variance-authority"; +import { BadgeStarIcon } from "./Badge/BadgeStarIcon"; + +export interface BadgeProps { + icon?: boolean; + color?: "neutral" | "secondary"; + children?: React.ReactNode; +} + +const badge = cva( + [ + "k1-inline-flex k1-rounded k1-px-xs k1-py-xxs k1-gap-1 k1-font-bold k1-text-xs k1-font-sans k1-flex-nowrap k1-items-center k1-uppercase k1-leading-4 k1-tracking-wider", + ], + { + variants: { + color: { + neutral: ["k1-text-neutral", "k1-bg-neutral"], + secondary: ["k1-text-secondary-strong k1-bg-secondary"], + }, + }, + }, +); + +const Badge: React.FC = ({ icon = false, color, children }) => { + const neutralVariant = color === "neutral"; + + return ( +
+ {icon && } +
{children}
+
+ ); +}; + +export { Badge };