From 79765b516d1ebe688ac8ccd3e6f8ee1a0a99195c Mon Sep 17 00:00:00 2001 From: Brian McGee Date: Fri, 20 Jun 2025 09:13:55 +0100 Subject: [PATCH 1/3] feat(ui): rename TagStatus to MachineStatus Standardizes naming and updates related props, classes, and types for clarity and consistency. --- .../ui/src/components/v2/MachineStatus/MachineStatus.css | 2 +- .../components/v2/MachineStatus/MachineStatus.stories.tsx | 6 +++--- .../ui/src/components/v2/MachineStatus/MachineStatus.tsx | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkgs/clan-app/ui/src/components/v2/MachineStatus/MachineStatus.css b/pkgs/clan-app/ui/src/components/v2/MachineStatus/MachineStatus.css index adb1f2f8e..a24ae0018 100644 --- a/pkgs/clan-app/ui/src/components/v2/MachineStatus/MachineStatus.css +++ b/pkgs/clan-app/ui/src/components/v2/MachineStatus/MachineStatus.css @@ -1,4 +1,4 @@ -span.tag-status { +span.machine-status { @apply flex items-center gap-1; .indicator { diff --git a/pkgs/clan-app/ui/src/components/v2/MachineStatus/MachineStatus.stories.tsx b/pkgs/clan-app/ui/src/components/v2/MachineStatus/MachineStatus.stories.tsx index 0c8a597ca..d9adc857d 100644 --- a/pkgs/clan-app/ui/src/components/v2/MachineStatus/MachineStatus.stories.tsx +++ b/pkgs/clan-app/ui/src/components/v2/MachineStatus/MachineStatus.stories.tsx @@ -1,10 +1,10 @@ import { MachineStatus, - TagStatusProps, + MachineStatusProps, } from "@/src/components/v2/MachineStatus/MachineStatus"; import { Meta, StoryObj } from "@kachurun/storybook-solid"; -const meta: Meta = { +const meta: Meta = { title: "Components/MachineStatus", component: MachineStatus, decorators: [ @@ -18,7 +18,7 @@ const meta: Meta = { export default meta; -type Story = StoryObj; +type Story = StoryObj; export const Online: Story = { args: { diff --git a/pkgs/clan-app/ui/src/components/v2/MachineStatus/MachineStatus.tsx b/pkgs/clan-app/ui/src/components/v2/MachineStatus/MachineStatus.tsx index 1fcb523d7..95ffa2e2d 100644 --- a/pkgs/clan-app/ui/src/components/v2/MachineStatus/MachineStatus.tsx +++ b/pkgs/clan-app/ui/src/components/v2/MachineStatus/MachineStatus.tsx @@ -12,14 +12,14 @@ export type MachineStatus = | "Installed" | "Not Installed"; -export interface TagStatusProps { +export interface MachineStatusProps { label?: boolean; status: MachineStatus; } -export const MachineStatus = (props: TagStatusProps) => ( +export const MachineStatus = (props: MachineStatusProps) => ( Date: Fri, 20 Jun 2025 09:23:03 +0100 Subject: [PATCH 2/3] feat(ui): add Tag component Adds a reusable `Tag` component with support for default and inverted styles. Also includes cleanup of unused dependencies in `package.json`. --- pkgs/clan-app/ui/package.json | 3 -- .../clan-app/ui/src/components/v2/Tag/Tag.css | 37 +++++++++++++ .../ui/src/components/v2/Tag/Tag.stories.tsx | 47 ++++++++++++++++ .../clan-app/ui/src/components/v2/Tag/Tag.tsx | 54 +++++++++++++++++++ 4 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 pkgs/clan-app/ui/src/components/v2/Tag/Tag.css create mode 100644 pkgs/clan-app/ui/src/components/v2/Tag/Tag.stories.tsx create mode 100644 pkgs/clan-app/ui/src/components/v2/Tag/Tag.tsx diff --git a/pkgs/clan-app/ui/package.json b/pkgs/clan-app/ui/package.json index 1d30e84b8..649a7e54d 100644 --- a/pkgs/clan-app/ui/package.json +++ b/pkgs/clan-app/ui/package.json @@ -28,10 +28,8 @@ "@storybook/addon-a11y": "^9.0.8", "@storybook/addon-docs": "^9.0.8", "@storybook/addon-links": "^9.0.8", - "@storybook/addon-onboarding": "^9.0.8", "@storybook/addon-viewport": "^9.0.8", "@storybook/addon-vitest": "^9.0.8", - "@tailwindcss/typography": "^0.5.13", "@types/node": "^22.15.19", "@types/three": "^0.176.0", "@typescript-eslint/parser": "^8.32.1", @@ -68,7 +66,6 @@ "@modular-forms/solid": "^0.25.1", "@solid-primitives/storage": "^4.3.2", "@solidjs/router": "^0.15.3", - "@solidjs/testing-library": "^0.8.10", "@tanstack/eslint-plugin-query": "^5.51.12", "@tanstack/solid-query": "^5.76.0", "solid-js": "^1.9.7", diff --git a/pkgs/clan-app/ui/src/components/v2/Tag/Tag.css b/pkgs/clan-app/ui/src/components/v2/Tag/Tag.css new file mode 100644 index 000000000..8c7d2c51c --- /dev/null +++ b/pkgs/clan-app/ui/src/components/v2/Tag/Tag.css @@ -0,0 +1,37 @@ +span.tag { + @apply flex items-center gap-1 w-fit px-2 py-1 rounded-full; + @apply bg-def-4; + + &:focus-visible { + @apply bg-def-acc-3 outline-none; + box-shadow: + 0 0 0 0.0625rem theme(colors.off.white), + 0 0 0 0.125rem theme(colors.border.semantic.info.1); + } + + &.active { + @apply bg-def-acc-4; + } + + &.inverted { + @apply bg-inv-1; + } + + &.has-action { + @apply pr-1.5; + + &:hover { + @apply bg-def-acc-3; + } + + &.inverted:hover { + @apply bg-inv-acc-3; + } + } + + & > .icon { + &:hover { + @apply cursor-pointer; + } + } +} diff --git a/pkgs/clan-app/ui/src/components/v2/Tag/Tag.stories.tsx b/pkgs/clan-app/ui/src/components/v2/Tag/Tag.stories.tsx new file mode 100644 index 000000000..29665e402 --- /dev/null +++ b/pkgs/clan-app/ui/src/components/v2/Tag/Tag.stories.tsx @@ -0,0 +1,47 @@ +import { Tag, TagProps } from "@/src/components/v2/Tag/Tag"; +import { Meta, type StoryContext, StoryObj } from "@kachurun/storybook-solid"; +import { expect, fn } from "storybook/test"; + +const meta: Meta = { + title: "Components/Tag", + component: Tag, +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + label: "Label", + }, +}; + +export const WithAction: Story = { + args: { + ...Default.args, + action: { + icon: "Close", + onClick: fn(), + }, + }, + play: async ({ canvas, step, userEvent, args }: StoryContext) => { + await userEvent.click(canvas.getByRole("button")); + await expect(args.action.onClick).toHaveBeenCalled(); + }, +}; + +export const Inverted: Story = { + args: { + label: "Label", + inverted: true, + }, +}; + +export const InvertedWithAction: Story = { + args: { + ...WithAction.args, + inverted: true, + }, + play: WithAction.play, +}; diff --git a/pkgs/clan-app/ui/src/components/v2/Tag/Tag.tsx b/pkgs/clan-app/ui/src/components/v2/Tag/Tag.tsx new file mode 100644 index 000000000..fe8657480 --- /dev/null +++ b/pkgs/clan-app/ui/src/components/v2/Tag/Tag.tsx @@ -0,0 +1,54 @@ +import "./Tag.css"; + +import cx from "classnames"; +import { Typography } from "@/src/components/v2/Typography/Typography"; +import { createSignal, Show } from "solid-js"; +import Icon, { IconVariant } from "../Icon/Icon"; + +export interface TagAction { + icon: IconVariant; + onClick: () => void; +} + +export interface TagProps { + label: string; + action?: TagAction; + inverted?: boolean; +} + +export const Tag = (props: TagProps) => { + const inverted = () => props.inverted || false; + + const [isActive, setIsActive] = createSignal(false); + + const handleActionClick = () => { + setIsActive(true); + props.action?.onClick(); + setTimeout(() => setIsActive(false), 150); + }; + + return ( + + + {props.label} + + + + + + ); +}; From 57c77e039d4b0c020dfc7fdb9b3b70e2ff7b73d1 Mon Sep 17 00:00:00 2001 From: Brian McGee Date: Fri, 20 Jun 2025 09:49:59 +0100 Subject: [PATCH 3/3] feat(ui): add TagGroup component Introduces a new `TagGroup` component for rendering grouped tags with optional inverted styling. --- .../src/components/v2/TagGroup/TagGroup.css | 3 ++ .../v2/TagGroup/TagGroup.stories.tsx | 43 +++++++++++++++++++ .../src/components/v2/TagGroup/TagGroup.tsx | 21 +++++++++ 3 files changed, 67 insertions(+) create mode 100644 pkgs/clan-app/ui/src/components/v2/TagGroup/TagGroup.css create mode 100644 pkgs/clan-app/ui/src/components/v2/TagGroup/TagGroup.stories.tsx create mode 100644 pkgs/clan-app/ui/src/components/v2/TagGroup/TagGroup.tsx diff --git a/pkgs/clan-app/ui/src/components/v2/TagGroup/TagGroup.css b/pkgs/clan-app/ui/src/components/v2/TagGroup/TagGroup.css new file mode 100644 index 000000000..59fef1eae --- /dev/null +++ b/pkgs/clan-app/ui/src/components/v2/TagGroup/TagGroup.css @@ -0,0 +1,3 @@ +div.tag-group { + @apply flex flex-wrap gap-x-1.5 gap-y-2; +} diff --git a/pkgs/clan-app/ui/src/components/v2/TagGroup/TagGroup.stories.tsx b/pkgs/clan-app/ui/src/components/v2/TagGroup/TagGroup.stories.tsx new file mode 100644 index 000000000..c0d660609 --- /dev/null +++ b/pkgs/clan-app/ui/src/components/v2/TagGroup/TagGroup.stories.tsx @@ -0,0 +1,43 @@ +import { TagGroup, TagGroupProps } from "@/src/components/v2/TagGroup/TagGroup"; +import { Meta, StoryObj } from "@kachurun/storybook-solid"; + +const meta: Meta = { + title: "Components/TagGroup", + component: TagGroup, + decorators: [ + (Story: StoryObj) => ( + /* for some reason w-x from tailwind was not working */ +
+ +
+ ), + ], +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + labels: [ + "Tag 1", + "Tag 2", + "Tag 3", + "Tag 4", + "Tag 5", + "Tag 6", + "Tag 7", + "Tag 8", + "Tag 9", + "Tag 10", + ], + }, +}; + +export const Inverted: Story = { + args: { + ...Default.args, + inverted: true, + }, +}; diff --git a/pkgs/clan-app/ui/src/components/v2/TagGroup/TagGroup.tsx b/pkgs/clan-app/ui/src/components/v2/TagGroup/TagGroup.tsx new file mode 100644 index 000000000..e118ecca4 --- /dev/null +++ b/pkgs/clan-app/ui/src/components/v2/TagGroup/TagGroup.tsx @@ -0,0 +1,21 @@ +import "./TagGroup.css"; +import cx from "classnames"; +import { For } from "solid-js"; +import { Tag } from "@/src/components/v2/Tag/Tag"; + +export interface TagGroupProps { + labels: string[]; + inverted?: boolean; +} + +export const TagGroup = (props: TagGroupProps) => { + const inverted = () => props.inverted || false; + + return ( +
+ + {(label) => } + +
+ ); +};