From 1cd8d2100c45d4c32116ee095e4db50cc82e6d62 Mon Sep 17 00:00:00 2001 From: Fabian Gaukler Date: Thu, 2 Jan 2025 11:06:03 +0100 Subject: [PATCH] feat: adds support for lucide icons --- .../elements/button/button-story-helpers.ts | 45 ++++------ .../src/elements/button/button.stories.ts | 12 +++ .../src/elements/icon/icon-story-helpers.ts | 41 +++++++++ .../src/elements/icon/icon.stories.ts | 87 +++++++++++++++++++ packages/foundation/src/elements/button.css | 10 +++ 5 files changed, 166 insertions(+), 29 deletions(-) create mode 100644 packages/documentation/src/elements/icon/icon-story-helpers.ts create mode 100644 packages/documentation/src/elements/icon/icon.stories.ts diff --git a/packages/documentation/src/elements/button/button-story-helpers.ts b/packages/documentation/src/elements/button/button-story-helpers.ts index 8d56e62..af478ea 100644 --- a/packages/documentation/src/elements/button/button-story-helpers.ts +++ b/packages/documentation/src/elements/button/button-story-helpers.ts @@ -1,6 +1,5 @@ import type { ArgTypes } from "@storybook/web-components"; import { html } from "lit"; -import { ArrowRight, Check, createIcons } from "lucide"; type ButtonSize = "default" | "small"; type ButtonVariant = "primary" | "secondary" | "tertiary" | "destructive"; @@ -72,31 +71,19 @@ export const renderButtons = (args: ButtonArgs, colorScheme: ColorScheme) => })} `; -const renderButton = (args: ButtonArgs) => { - createIcons({ - icons: { - Check, - ArrowRight, - }, - attrs: { - // TODO: make icons as high as line-height - }, - }); - - return html` - - `; -}; +const renderButton = (args: ButtonArgs) => html` + +`; diff --git a/packages/documentation/src/elements/button/button.stories.ts b/packages/documentation/src/elements/button/button.stories.ts index eb77ba8..38f8207 100644 --- a/packages/documentation/src/elements/button/button.stories.ts +++ b/packages/documentation/src/elements/button/button.stories.ts @@ -1,5 +1,6 @@ import type { Meta, StoryObj } from "@storybook/web-components"; import { html } from "lit"; +import { ArrowRight, Check, createIcons } from "lucide"; import { buttonArgs, buttonArgTypes, @@ -14,6 +15,17 @@ const meta: Meta = { html`
${renderButtons(args, "light")}${renderButtons(args, "dark")}
`, + + play: () => + createIcons({ + icons: { + Check, + ArrowRight, + }, + attrs: { + "stroke-width": 1.5, + }, + }), }; export default meta; diff --git a/packages/documentation/src/elements/icon/icon-story-helpers.ts b/packages/documentation/src/elements/icon/icon-story-helpers.ts new file mode 100644 index 0000000..49f8b61 --- /dev/null +++ b/packages/documentation/src/elements/icon/icon-story-helpers.ts @@ -0,0 +1,41 @@ +import type { ArgTypes } from "@storybook/web-components"; +import { html } from "lit"; + +export const iconArgs = ( + iconNames: string[], + size: string, + // default values for stroke according to design + strokeWidth = 1.5, + strokeOpacity = 0.8, +): IconArgs => ({ + iconNames, + size, + strokeWidth, + strokeOpacity, +}); + +export const iconArgTypes: Partial> = { + size: { + control: { type: "select" }, + options: ["default", "small"], + }, +}; + +export interface IconArgs { + iconNames: string[]; + size: string; + strokeWidth: number; + strokeOpacity: number; +} + +export const renderIcons = (args: IconArgs) => html` + ${args.iconNames.map((iconName) => html``)} +`; + +export const mapIconSizeToPx = (size: string): string => { + if (size === "small") { + return "16px"; + } + + return "24px"; +}; diff --git a/packages/documentation/src/elements/icon/icon.stories.ts b/packages/documentation/src/elements/icon/icon.stories.ts new file mode 100644 index 0000000..b5dca22 --- /dev/null +++ b/packages/documentation/src/elements/icon/icon.stories.ts @@ -0,0 +1,87 @@ +import type { Meta, StoryObj } from "@storybook/web-components"; +import { html } from "lit"; +import { createIcons, icons } from "lucide"; +import { + iconArgs, + iconArgTypes, + mapIconSizeToPx, + renderIcons, + type IconArgs, +} from "./icon-story-helpers.js"; + +const iconList = [ + "check", + "arrow-right", + "arrow-left", + "arrow-down", + "arrow-up", + "arrow-up-right", + "arrow-down-right", + "arrow-down-left", + "arrow-down-up", + "circle-x", + "chevron-down", + "chevron-up", + "chevron-left", + "chevron-right", + "plus", + "log-out", + "shopping-cart", + "user-round", + "clock", + "menu", + "search", + "eye", + "circle-alert", + "code", + "copy", + "circle-play", + "circle-help", + "settings", + "bell", + "building-2", + "file", + "calendar", + "trash-2", + "eye-off", + "sparkles", + "info", + "megaphone", + "circle-check", + "folder-open", + "mail", + "download", + "lock", +]; + +const meta: Meta = { + argTypes: iconArgTypes, + + render: (args) => + // html`
+ html`
+ ${renderIcons(args)} +
`, + play: (args) => { + createIcons({ + icons, + attrs: { + "stroke-width": args.initialArgs.strokeWidth, + "stroke-opacity": args.initialArgs.strokeOpacity, + height: mapIconSizeToPx(args.initialArgs.size), + width: mapIconSizeToPx(args.initialArgs.size), + // TODO should stroke color be declared in CSS directly? + color: "#141419CC", + }, + }); + }, +}; + +export default meta; + +export type Story = StoryObj; + +export const IconsDefault: Story = { args: iconArgs(iconList, "default") }; +export const IconsSmall: Story = { args: iconArgs(iconList, "small") }; diff --git a/packages/foundation/src/elements/button.css b/packages/foundation/src/elements/button.css index 7501cb1..5ead9e7 100644 --- a/packages/foundation/src/elements/button.css +++ b/packages/foundation/src/elements/button.css @@ -13,11 +13,21 @@ gap: var(--hap-spacing-sm); align-items: center; + svg { + height: var(--hap-typography-line-height-bodytext-standard-singleline); + width: var(--hap-typography-line-height-bodytext-standard-singleline); + } + &.small { padding: var(--hap-spacing-xs) var(--hap-spacing-sm); font-size: var(--hap-typography-font-size-bodytext-s); line-height: var(--hap-typography-line-height-bodytext-s-singleline); gap: var(--hap-spacing-xs); + + svg { + height: var(--hap-typography-line-height-bodytext-s-singleline); + width: var(--hap-typography-line-height-bodytext-s-singleline); + } } &:disabled {