From 7aa17bfe2e2c7a73ef9dafb02fc678590d107181 Mon Sep 17 00:00:00 2001 From: Jamie Scott Craik Date: Tue, 17 Mar 2026 16:58:56 -0600 Subject: [PATCH 1/3] fix: auto-fix 161 Biome format and import-sort errors on main Run `pnpm biome check --write` to resolve formatter and organizeImports violations across 129 files. Unblocks dependabot PRs 122, 123, 124. Co-Authored-By: Claude Sonnet 4.6 --- .diagram/auth.mmd | 16 + .diagram/database.mmd | 26 ++ .diagram/events.mmd | 7 + .diagram/manifest.json | 87 +++++ .diagram/security.mmd | 43 +++ .diagram/user.mmd | 36 ++ .harness/memory/LEARNINGS.md | 18 + packages/cli/src/error.ts | 2 +- packages/skill-ingestion/src/installer.ts | 5 +- packages/skill-ingestion/src/scan.ts | 3 +- .../tokens/src/validation/token-validator.ts | 2 +- .../AttachmentMenu/AttachmentMenu.stories.tsx | 2 - .../app/chat/ChatInput/ChatInput.stories.tsx | 2 - .../app/chat/ChatShell/ChatShell.stories.tsx | 2 +- .../SettingDropdown.stories.tsx | 2 - .../SettingToggle/SettingToggle.stories.tsx | 2 - .../components/ui/base/InputOTP/InputOTP.tsx | 2 +- .../ui/base/ShimmerText/ShimmerText.tsx | 2 +- .../ui/base/accordion/fallback/Accordion.tsx | 2 +- .../ui/base/avatar/fallback/Avatar.tsx | 2 +- .../components/ui/base/calendar/calendar.tsx | 2 +- .../base/collapsible/fallback/Collapsible.tsx | 2 +- .../ui/src/components/ui/base/input/input.tsx | 2 +- .../ui/base/resizable/resizable.tsx | 2 +- .../ui/base/select/fallback/Select.tsx | 12 +- .../ui/src/components/ui/base/table/table.tsx | 2 +- .../components/ui/base/textarea/textarea.tsx | 2 +- .../components/ui/data-display/card/card.tsx | 2 +- .../ui/data-display/chart/chart.tsx | 4 +- .../AlertDialog/fallback/AlertDialog.tsx | 14 +- .../ui/forms/form/fallback/Form.tsx | 8 +- .../ui/layout/Transition/Transition.tsx | 2 +- .../fallback/NavigationMenu.tsx | 8 +- .../ui/navigation/carousel/carousel.tsx | 4 +- .../navigation/menubar/fallback/Menubar.tsx | 16 +- .../ui/navigation/tabs/fallback/Tabs.tsx | 2 +- .../ContextMenu/fallback/ContextMenu.tsx | 12 +- .../DropdownMenu/fallback/DropdownMenu.tsx | 10 +- .../overlays/HoverCard/fallback/HoverCard.tsx | 2 +- .../src/components/ui/overlays/Menu/Menu.tsx | 12 +- .../ui/overlays/command/command.tsx | 6 +- .../components/ui/overlays/drawer/drawer.tsx | 10 +- .../ui/overlays/popover/fallback/Popover.tsx | 2 +- .../ui/overlays/sheet/fallback/Sheet.tsx | 6 +- .../ui/overlays/tooltip/fallback/Tooltip.tsx | 2 +- .../component-stories/Alert.stories.tsx | 4 +- .../component-stories/AlertDialog.stories.tsx | 22 +- .../component-stories/AspectRatio.stories.tsx | 3 +- .../component-stories/Calendar.stories.tsx | 3 +- .../component-stories/Card.stories.tsx | 6 +- .../component-stories/Carousel.stories.tsx | 6 +- .../component-stories/Chart.stories.tsx | 3 +- .../CollapsibleSection.stories.tsx | 3 +- .../component-stories/Combobox.stories.tsx | 5 +- .../component-stories/Command.stories.tsx | 5 +- .../component-stories/ContextMenu.stories.tsx | 5 +- .../component-stories/ContextTag.stories.tsx | 6 +- .../component-stories/DatePicker.stories.tsx | 3 +- .../DirectionProvider.stories.tsx | 10 +- .../component-stories/Drawer.stories.tsx | 6 +- .../DropdownMenu.stories.tsx | 6 +- .../component-stories/HoverCard.stories.tsx | 3 +- .../component-stories/IconButton.stories.tsx | 5 +- .../component-stories/Input.stories.tsx | 5 +- .../component-stories/InputOTP.stories.tsx | 7 +- .../component-stories/ListItem.stories.tsx | 3 +- .../MessageActions.stories.tsx | 3 +- .../component-stories/Modal.stories.tsx | 4 +- .../ModeSelector.stories.tsx | 5 +- .../component-stories/ModelBadge.stories.tsx | 3 +- .../ModelSelector.stories.tsx | 3 +- .../NavigationMenu.stories.tsx | 5 +- .../component-stories/Pagination.stories.tsx | 3 +- .../component-stories/RadioGroup.stories.tsx | 8 +- .../component-stories/RangeSlider.stories.tsx | 3 +- .../component-stories/Resizable.stories.tsx | 3 +- .../component-stories/ScrollArea.stories.tsx | 3 +- .../SectionHeader.stories.tsx | 3 +- .../SegmentedControl.stories.tsx | 7 +- .../component-stories/ShimmerText.stories.tsx | 3 +- .../component-stories/Skeleton.stories.tsx | 4 +- .../component-stories/Sonner.stories.tsx | 4 +- .../component-stories/Table.stories.tsx | 8 +- .../component-stories/TextLink.stories.tsx | 3 +- .../component-stories/Textarea.stories.tsx | 3 +- .../component-stories/Toast.stories.tsx | 9 +- .../component-stories/Toggle.stories.tsx | 3 +- .../component-stories/ToggleGroup.stories.tsx | 23 +- .../component-stories/UseMobile.stories.tsx | 3 +- .../ViewModeToggle.stories.tsx | 3 +- .../component-stories/accordion.stories.tsx | 7 +- .../component-stories/avatar.stories.tsx | 4 +- .../component-stories/badge.stories.tsx | 4 +- .../component-stories/breadcrumb.stories.tsx | 3 +- .../component-stories/button.stories.tsx | 6 +- .../component-stories/checkbox.stories.tsx | 16 +- .../component-stories/collapsible.stories.tsx | 17 +- .../component-stories/dialog.stories.tsx | 8 +- .../component-stories/form.stories.tsx | 8 +- .../component-stories/label.stories.tsx | 4 +- .../component-stories/menubar.stories.tsx | 5 +- .../component-stories/popover.stories.tsx | 9 +- .../component-stories/progress.stories.tsx | 3 +- .../component-stories/select.stories.tsx | 7 +- .../component-stories/separator.stories.tsx | 3 +- .../component-stories/sheet.stories.tsx | 6 +- .../component-stories/sidebar.stories.tsx | 8 +- .../component-stories/slider.stories.tsx | 3 +- .../component-stories/switch.stories.tsx | 16 +- .../component-stories/tabs.stories.tsx | 3 +- .../component-stories/tooltip.stories.tsx | 9 +- .../_holding/docs/APIReference.stories.tsx | 2 +- .../docs/ComponentGallery.stories.tsx | 2 +- .../docs/ComponentLibrary.stories.tsx | 2 +- .../_holding/docs/DesignSystem.stories.tsx | 2 +- .../_holding/docs/GettingStarted.stories.tsx | 2 +- .../_holding/docs/Migration.stories.tsx | 2 +- .../_holding/docs/Patterns.stories.tsx | 2 +- .../_holding/docs/QuickStart.stories.tsx | 2 +- .../DashboardPage/DashboardPage.stories.tsx | 3 +- .../storybook/docs/MSW-Patterns.stories.tsx | 23 +- .../ChatBlocksTemplate.stories.tsx | 2 +- .../ChatTemplate/ChatTemplate.stories.tsx | 2 +- .../ChatVariantsTemplate.stories.tsx | 2 +- .../SettingsPanelsTemplate.stories.tsx | 2 +- .../TemplatesGallery.stories.tsx | 2 +- .../web/apps/storybook/.storybook/main.ts | 18 +- .../apps/storybook/.storybook/msw/handlers.ts | 201 +++++++++++ .../web/apps/storybook/.storybook/preview.tsx | 33 +- platforms/web/apps/storybook/package.json | 2 +- .../storybook/public/mockServiceWorker.js | 336 ++++++++++++++++++ .../apps/storybook/scripts/a11y-summary.mjs | 76 ++++ .../scripts/interaction-coverage-gate.mjs | 99 ++++++ .../storybook/scripts/story-naming-lint.mjs | 97 +++++ .../storybook/tests/portable-stories.test.tsx | 57 +++ scripts/check-token-drift.mjs | 15 +- 136 files changed, 1411 insertions(+), 371 deletions(-) create mode 100644 .diagram/auth.mmd create mode 100644 .diagram/database.mmd create mode 100644 .diagram/events.mmd create mode 100644 .diagram/manifest.json create mode 100644 .diagram/security.mmd create mode 100644 .diagram/user.mmd create mode 100644 .harness/memory/LEARNINGS.md create mode 100644 platforms/web/apps/storybook/.storybook/msw/handlers.ts create mode 100644 platforms/web/apps/storybook/public/mockServiceWorker.js create mode 100644 platforms/web/apps/storybook/scripts/a11y-summary.mjs create mode 100644 platforms/web/apps/storybook/scripts/interaction-coverage-gate.mjs create mode 100644 platforms/web/apps/storybook/scripts/story-naming-lint.mjs create mode 100644 platforms/web/apps/storybook/tests/portable-stories.test.tsx diff --git a/.diagram/auth.mmd b/.diagram/auth.mmd new file mode 100644 index 00000000..78c05621 --- /dev/null +++ b/.diagram/auth.mmd @@ -0,0 +1,16 @@ +flowchart TD + Request["Authentication request"] + Boundary{"Auth Boundary"} + Request --> Boundary + worker_configuration_d_5b64e8b5["worker-configuration.d"] + Boundary --> worker_configuration_d_5b64e8b5 + token_validator_test_146cbf6c["token-validator.test"] + Boundary --> token_validator_test_146cbf6c + token_validation_test_742b9f6a["token-validation.test"] + Boundary --> token_validation_test_742b9f6a + validate_tokens_7b611756["validate-tokens"] + Boundary --> validate_tokens_7b611756 + my_main_module_ac300685[("my-main-module")] + vitest_a9127f3d[("vitest")] + node_fs_df6b52af[("node:fs")] + classDef authNode fill:#7c3aed,color:#fff \ No newline at end of file diff --git a/.diagram/database.mmd b/.diagram/database.mmd new file mode 100644 index 00000000..9d06cfe7 --- /dev/null +++ b/.diagram/database.mmd @@ -0,0 +1,26 @@ +flowchart TD + UserRequest["User request"] + Decision{Record exists?} + generate_coverage_matrix_1bd9ebaf["generate-coverage-matrix"] + UserRequest --> generate_coverage_matrix_1bd9ebaf + generate_coverage_matrix_1bd9ebaf --> generate_coverage_matrix_1bd9ebaf_result["result"] + migrate_package_refs_b4c4a036["migrate-package-refs"] + UserRequest --> migrate_package_refs_b4c4a036 + migrate_package_refs_b4c4a036 --> migrate_package_refs_b4c4a036_result["result"] + migrate_imports_aec4410b["migrate-imports"] + UserRequest --> migrate_imports_aec4410b + migrate_imports_aec4410b --> migrate_imports_aec4410b_result["result"] + vite_config_2_24e3337d["vite.config"] + UserRequest --> vite_config_2_24e3337d + vite_config_2_24e3337d --> vite_config_2_24e3337d_result["result"] + worker_configuration_d_5b64e8b5["worker-configuration.d"] + UserRequest --> worker_configuration_d_5b64e8b5 + worker_configuration_d_5b64e8b5 --> worker_configuration_d_5b64e8b5_result["result"] + generator_9123dcbb["generator"] + UserRequest --> generator_9123dcbb + generator_9123dcbb --> generator_9123dcbb_result["result"] + validate_tokens_7b611756["validate-tokens"] + UserRequest --> validate_tokens_7b611756 + validate_tokens_7b611756 --> validate_tokens_7b611756_result["result"] + classDef dbNode fill:#0ea5e9,color:#fff + classDef decisionNode fill:#0284c7,color:#fff \ No newline at end of file diff --git a/.diagram/events.mmd b/.diagram/events.mmd new file mode 100644 index 00000000..d9c317b5 --- /dev/null +++ b/.diagram/events.mmd @@ -0,0 +1,7 @@ +flowchart TD + subgraph Channels["Event channels / queues"] + worker_configuration_d_5b64e8b5{{"worker-configuration.d"}} + vite_config_5_81aa1742{{"vite.config"}} + index_d_3_80f852c0{{"index.d"}} + end + classDef eventNode fill:#db2777,color:#fff \ No newline at end of file diff --git a/.diagram/manifest.json b/.diagram/manifest.json new file mode 100644 index 00000000..0943fa8c --- /dev/null +++ b/.diagram/manifest.json @@ -0,0 +1,87 @@ +{ + "generatedAt": "2026-03-15T19:02:06.733Z", + "rootPath": "/Users/jamiecraik/dev/Design-System", + "diagramDir": ".diagram", + "diagrams": [ + { + "type": "architecture", + "file": "architecture.mmd", + "outputPath": ".diagram/architecture.mmd", + "lines": 147, + "bytes": 5807, + "isPlaceholder": false + }, + { + "type": "sequence", + "file": "sequence.mmd", + "outputPath": ".diagram/sequence.mmd", + "lines": 2, + "bytes": 53, + "isPlaceholder": false + }, + { + "type": "dependency", + "file": "dependency.mmd", + "outputPath": ".diagram/dependency.mmd", + "lines": 141, + "bytes": 8795, + "isPlaceholder": false + }, + { + "type": "class", + "file": "class.mmd", + "outputPath": ".diagram/class.mmd", + "lines": 7, + "bytes": 201, + "isPlaceholder": false + }, + { + "type": "flow", + "file": "flow.mmd", + "outputPath": ".diagram/flow.mmd", + "lines": 20, + "bytes": 952, + "isPlaceholder": false + }, + { + "type": "database", + "file": "database.mmd", + "outputPath": ".diagram/database.mmd", + "lines": 26, + "bytes": 1356, + "isPlaceholder": false + }, + { + "type": "user", + "file": "user.mmd", + "outputPath": ".diagram/user.mmd", + "lines": 36, + "bytes": 1330, + "isPlaceholder": false + }, + { + "type": "events", + "file": "events.mmd", + "outputPath": ".diagram/events.mmd", + "lines": 7, + "bytes": 254, + "isPlaceholder": false + }, + { + "type": "auth", + "file": "auth.mmd", + "outputPath": ".diagram/auth.mmd", + "lines": 16, + "bytes": 649, + "isPlaceholder": false + }, + { + "type": "security", + "file": "security.mmd", + "outputPath": ".diagram/security.mmd", + "lines": 43, + "bytes": 1631, + "isPlaceholder": false + } + ] +} diff --git a/.diagram/security.mmd b/.diagram/security.mmd new file mode 100644 index 00000000..fef98c70 --- /dev/null +++ b/.diagram/security.mmd @@ -0,0 +1,43 @@ +flowchart TD + Untrusted["Untrusted input"] + worker_configuration_d_5b64e8b5["worker-configuration.d"] + Untrusted --> worker_configuration_d_5b64e8b5 + scan_59ad1b2f["scan"] + Untrusted --> scan_59ad1b2f + publisher_4f03a060["publisher"] + Untrusted --> publisher_4f03a060 + installer_9c0d294c["installer"] + Untrusted --> installer_9c0d294c + index_2_10143590["index"] + Untrusted --> index_2_10143590 + index_d_1_0f747669["index.d"] + Untrusted --> index_d_1_0f747669 + hash_d04b98f4["hash"] + Untrusted --> hash_d04b98f4 + hash_test_ff708b1d["hash.test"] + Untrusted --> hash_test_ff708b1d + hash_d_a9a3aaf1["hash.d"] + Untrusted --> hash_d_a9a3aaf1 + index_d_2_58711ee2["index.d"] + Untrusted --> index_d_2_58711ee2 + hash_test_d_4d786b24["hash.test.d"] + Untrusted --> hash_test_d_4d786b24 + hash_d_1_93510d18["hash.d"] + Untrusted --> hash_d_1_93510d18 + token_validator_test_146cbf6c["token-validator.test"] + Untrusted --> token_validator_test_146cbf6c + token_validation_test_742b9f6a["token-validation.test"] + Untrusted --> token_validation_test_742b9f6a + validate_tokens_7b611756["validate-tokens"] + Untrusted --> validate_tokens_7b611756 + index_1bc04b52["index"] + Untrusted --> index_1bc04b52 + theme_d_bef39a49["theme.d"] + Untrusted --> theme_d_bef39a49 + index_d_ec1aab9d["index.d"] + Untrusted --> index_d_ec1aab9d + publisher_integration_test_c7648ed5["publisher.integration.test"] + Untrusted --> publisher_integration_test_c7648ed5 + publisher_integration_test_d_b773c16f["publisher.integration.test.d"] + Untrusted --> publisher_integration_test_d_b773c16f + classDef securityNode fill:#dc2626,color:#fff \ No newline at end of file diff --git a/.diagram/user.mmd b/.diagram/user.mmd new file mode 100644 index 00000000..bd36cd08 --- /dev/null +++ b/.diagram/user.mmd @@ -0,0 +1,36 @@ +flowchart LR + User(("User")) + tailwind_config_base_114ae127["tailwind.config.base"] + User --> tailwind_config_base_114ae127 + generate_coverage_matrix_1bd9ebaf["generate-coverage-matrix"] + User --> generate_coverage_matrix_1bd9ebaf + migrate_imports_aec4410b["migrate-imports"] + User --> migrate_imports_aec4410b + tailwind_config_f3bfbed8["tailwind.config"] + User --> tailwind_config_f3bfbed8 + vitest_config_1_39affbd6["vitest.config"] + User --> vitest_config_1_39affbd6 + vite_config_2_24e3337d["vite.config"] + User --> vite_config_2_24e3337d + worker_configuration_d_5b64e8b5["worker-configuration.d"] + User --> worker_configuration_d_5b64e8b5 + generator_test_1183c7b9["generator.test"] + User --> generator_test_1183c7b9 + generator_9123dcbb["generator"] + User --> generator_9123dcbb + alias_map_2f9c2d35["alias-map"] + User --> alias_map_2f9c2d35 + sync_dtcg_e75f004e["sync-dtcg"] + User --> sync_dtcg_e75f004e + styles_90a7578c["styles"] + User --> styles_90a7578c + index_1_faebc14e["index"] + User --> index_1_faebc14e + experimental_748be63c["experimental"] + User --> experimental_748be63c + dev_ef260e9a["dev"] + User --> dev_ef260e9a + remoteClient_11373476["remoteClient"] + User --> remoteClient_11373476 + tailwind_config_f3bfbed8 --> tailwind_preset_e0cc07c1 + classDef userNode fill:#16a34a,color:#fff \ No newline at end of file diff --git a/.harness/memory/LEARNINGS.md b/.harness/memory/LEARNINGS.md new file mode 100644 index 00000000..e6defdd5 --- /dev/null +++ b/.harness/memory/LEARNINGS.md @@ -0,0 +1,18 @@ +--- +schema_version: 1 +purpose: Per-project agent knowledge base — repo-specific gotchas and hard-won fixes. +scope: This repo only. +update_policy: | + Append after any bug, tool failure, or extra-effort fix specific to this repo. + Universal gotchas go in ~/.codex/instructions/Learnings.md instead. + Do NOT delete entries. Append only. + Format: **YYYY-MM-DD [Agent]:** +--- + +# Learnings + +Repo-specific agent knowledge base. Append-only. + +> **Scope:** This repo only. Universal gotchas → `~/.codex/instructions/Learnings.md`. +> **Format:** `**YYYY-MM-DD [Agent]:** ` + diff --git a/packages/cli/src/error.ts b/packages/cli/src/error.ts index ab451f08..d390c5b3 100644 --- a/packages/cli/src/error.ts +++ b/packages/cli/src/error.ts @@ -84,4 +84,4 @@ export function requireNetwork(opts: Record, action: string): v } // Re-export constants for convenience -export { ERROR_CODES, EXIT_CODES, TOKEN_GENERATE_WARNING, COMPONENTS_WRITE_WARNING }; +export { COMPONENTS_WRITE_WARNING, ERROR_CODES, EXIT_CODES, TOKEN_GENERATE_WARNING }; diff --git a/packages/skill-ingestion/src/installer.ts b/packages/skill-ingestion/src/installer.ts index ddad82a2..1df3a74f 100644 --- a/packages/skill-ingestion/src/installer.ts +++ b/packages/skill-ingestion/src/installer.ts @@ -31,7 +31,10 @@ function assertWithinBase(base: string, candidate: string, label: string): void // realpathSync needs the path to exist; use resolve for pre-existence checks candidate, ); - if (!resolvedCandidate.startsWith(resolvedBase + path.sep) && resolvedCandidate !== resolvedBase) { + if ( + !resolvedCandidate.startsWith(resolvedBase + path.sep) && + resolvedCandidate !== resolvedBase + ) { throw new Error( `Security: ${label} path "${candidate}" escapes allowed base "${resolvedBase}".`, ); diff --git a/packages/skill-ingestion/src/scan.ts b/packages/skill-ingestion/src/scan.ts index 2fd88c1d..8c4cec9e 100644 --- a/packages/skill-ingestion/src/scan.ts +++ b/packages/skill-ingestion/src/scan.ts @@ -11,8 +11,7 @@ function isWithinBase(base: string, candidate: string): boolean { const resolvedBase = path.resolve(base); const resolvedCandidate = path.resolve(candidate); return ( - resolvedCandidate === resolvedBase || - resolvedCandidate.startsWith(resolvedBase + path.sep) + resolvedCandidate === resolvedBase || resolvedCandidate.startsWith(resolvedBase + path.sep) ); } diff --git a/packages/tokens/src/validation/token-validator.ts b/packages/tokens/src/validation/token-validator.ts index e0256519..2b2313ef 100644 --- a/packages/tokens/src/validation/token-validator.ts +++ b/packages/tokens/src/validation/token-validator.ts @@ -344,7 +344,7 @@ type NonColorAliasValueAllowlist = Readonly<{ [K in keyof typeof NON_COLOR_ALIAS_VALUE_ALLOWLIST]: ReadonlySet; }>; -export type { ValidationError, NonColorAliasValueAllowlist }; +export type { NonColorAliasValueAllowlist, ValidationError }; /** * Read-only view of the non-color alias value allowlist. diff --git a/packages/ui/src/app/chat/AttachmentMenu/AttachmentMenu.stories.tsx b/packages/ui/src/app/chat/AttachmentMenu/AttachmentMenu.stories.tsx index 73be0aa2..ab7033f9 100644 --- a/packages/ui/src/app/chat/AttachmentMenu/AttachmentMenu.stories.tsx +++ b/packages/ui/src/app/chat/AttachmentMenu/AttachmentMenu.stories.tsx @@ -2,7 +2,6 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; import { useState } from "react"; - import { AttachmentMenu } from "./AttachmentMenu"; const meta: Meta = { @@ -164,4 +163,3 @@ export const MenuClosedByDefault: Story = { }); }, }; - diff --git a/packages/ui/src/app/chat/ChatInput/ChatInput.stories.tsx b/packages/ui/src/app/chat/ChatInput/ChatInput.stories.tsx index dd8cb5f1..224ace6f 100644 --- a/packages/ui/src/app/chat/ChatInput/ChatInput.stories.tsx +++ b/packages/ui/src/app/chat/ChatInput/ChatInput.stories.tsx @@ -1,7 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; - import { ChatInput } from "./ChatInput"; const meta: Meta = { @@ -106,4 +105,3 @@ export const FocusableByKeyboard: Story = { }); }, }; - diff --git a/packages/ui/src/app/chat/ChatShell/ChatShell.stories.tsx b/packages/ui/src/app/chat/ChatShell/ChatShell.stories.tsx index a05396f1..25ac348b 100644 --- a/packages/ui/src/app/chat/ChatShell/ChatShell.stories.tsx +++ b/packages/ui/src/app/chat/ChatShell/ChatShell.stories.tsx @@ -20,7 +20,7 @@ import { } from "../ChatVariants"; const meta: Meta = { - tags: ['autodocs'], + tags: ["autodocs"], title: "Components/Chat/Chat Shell", component: ChatVariantSplitSidebar, parameters: { diff --git a/packages/ui/src/app/settings/SettingDropdown/SettingDropdown.stories.tsx b/packages/ui/src/app/settings/SettingDropdown/SettingDropdown.stories.tsx index 568ecad5..b9a1cb25 100644 --- a/packages/ui/src/app/settings/SettingDropdown/SettingDropdown.stories.tsx +++ b/packages/ui/src/app/settings/SettingDropdown/SettingDropdown.stories.tsx @@ -2,7 +2,6 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, fn, userEvent, within } from "@storybook/test"; import { useState } from "react"; - import { type DropdownOption, SettingDropdown } from "./SettingDropdown"; /** @@ -221,4 +220,3 @@ export const LabelRendered: Story = { }); }, }; - diff --git a/packages/ui/src/app/settings/SettingToggle/SettingToggle.stories.tsx b/packages/ui/src/app/settings/SettingToggle/SettingToggle.stories.tsx index 948e0aca..fcb83966 100644 --- a/packages/ui/src/app/settings/SettingToggle/SettingToggle.stories.tsx +++ b/packages/ui/src/app/settings/SettingToggle/SettingToggle.stories.tsx @@ -2,7 +2,6 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, fn, userEvent, within } from "@storybook/test"; import { useState } from "react"; - import { IconMessaging, IconUserLock } from "../../../icons/ChatGPTIcons"; import { SettingToggle } from "./SettingToggle"; @@ -199,4 +198,3 @@ export const LabelVisible: Story = { }); }, }; - diff --git a/packages/ui/src/components/ui/base/InputOTP/InputOTP.tsx b/packages/ui/src/components/ui/base/InputOTP/InputOTP.tsx index d993d51b..d3403d9b 100644 --- a/packages/ui/src/components/ui/base/InputOTP/InputOTP.tsx +++ b/packages/ui/src/components/ui/base/InputOTP/InputOTP.tsx @@ -213,4 +213,4 @@ function InputOTPSeparator({ ...props }: React.ComponentProps<"div">) { ); } -export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator, InputOTPWrapper, InputOTPError }; +export { InputOTP, InputOTPError, InputOTPGroup, InputOTPSeparator, InputOTPSlot, InputOTPWrapper }; diff --git a/packages/ui/src/components/ui/base/ShimmerText/ShimmerText.tsx b/packages/ui/src/components/ui/base/ShimmerText/ShimmerText.tsx index f2f7a3d8..9d1dcb35 100644 --- a/packages/ui/src/components/ui/base/ShimmerText/ShimmerText.tsx +++ b/packages/ui/src/components/ui/base/ShimmerText/ShimmerText.tsx @@ -81,4 +81,4 @@ function ShimmerInline({ ); } -export { ShimmerText, ShimmerInline }; +export { ShimmerInline, ShimmerText }; diff --git a/packages/ui/src/components/ui/base/accordion/fallback/Accordion.tsx b/packages/ui/src/components/ui/base/accordion/fallback/Accordion.tsx index 8917f3cf..7c75d106 100644 --- a/packages/ui/src/components/ui/base/accordion/fallback/Accordion.tsx +++ b/packages/ui/src/components/ui/base/accordion/fallback/Accordion.tsx @@ -134,4 +134,4 @@ function AccordionContent({ ); } -export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; +export { Accordion, AccordionContent, AccordionItem, AccordionTrigger }; diff --git a/packages/ui/src/components/ui/base/avatar/fallback/Avatar.tsx b/packages/ui/src/components/ui/base/avatar/fallback/Avatar.tsx index d8d49ce8..844664c8 100644 --- a/packages/ui/src/components/ui/base/avatar/fallback/Avatar.tsx +++ b/packages/ui/src/components/ui/base/avatar/fallback/Avatar.tsx @@ -103,4 +103,4 @@ function AvatarFallback({ ); } -export { Avatar, AvatarImage, AvatarFallback }; +export { Avatar, AvatarFallback, AvatarImage }; diff --git a/packages/ui/src/components/ui/base/calendar/calendar.tsx b/packages/ui/src/components/ui/base/calendar/calendar.tsx index 13dad7cd..c718112c 100644 --- a/packages/ui/src/components/ui/base/calendar/calendar.tsx +++ b/packages/ui/src/components/ui/base/calendar/calendar.tsx @@ -222,4 +222,4 @@ function Calendar({ ); } -export { Calendar, CalendarWrapper, CalendarError }; +export { Calendar, CalendarError, CalendarWrapper }; diff --git a/packages/ui/src/components/ui/base/collapsible/fallback/Collapsible.tsx b/packages/ui/src/components/ui/base/collapsible/fallback/Collapsible.tsx index fb98974e..df22c753 100644 --- a/packages/ui/src/components/ui/base/collapsible/fallback/Collapsible.tsx +++ b/packages/ui/src/components/ui/base/collapsible/fallback/Collapsible.tsx @@ -81,4 +81,4 @@ function CollapsibleContent({ return ; } -export { Collapsible, CollapsibleTrigger, CollapsibleContent }; +export { Collapsible, CollapsibleContent, CollapsibleTrigger }; diff --git a/packages/ui/src/components/ui/base/input/input.tsx b/packages/ui/src/components/ui/base/input/input.tsx index e03b3017..28bb2b95 100644 --- a/packages/ui/src/components/ui/base/input/input.tsx +++ b/packages/ui/src/components/ui/base/input/input.tsx @@ -149,4 +149,4 @@ function Input({ return inputElement; } -export { Input, InputWrapper, InputError }; +export { Input, InputError, InputWrapper }; diff --git a/packages/ui/src/components/ui/base/resizable/resizable.tsx b/packages/ui/src/components/ui/base/resizable/resizable.tsx index 85451d41..18d58231 100644 --- a/packages/ui/src/components/ui/base/resizable/resizable.tsx +++ b/packages/ui/src/components/ui/base/resizable/resizable.tsx @@ -103,4 +103,4 @@ function ResizableHandle({ ); } -export { ResizablePanelGroup, ResizablePanel, ResizableHandle }; +export { ResizableHandle, ResizablePanel, ResizablePanelGroup }; diff --git a/packages/ui/src/components/ui/base/select/fallback/Select.tsx b/packages/ui/src/components/ui/base/select/fallback/Select.tsx index 02b6773f..618be8c7 100644 --- a/packages/ui/src/components/ui/base/select/fallback/Select.tsx +++ b/packages/ui/src/components/ui/base/select/fallback/Select.tsx @@ -393,13 +393,13 @@ Select.Separator = SelectSubComponents.Separator; export { Select, - SelectTrigger, - SelectValue, SelectContent, - SelectLabel, - SelectItem, SelectGroup, - SelectSeparator, - SelectScrollUpButton, + SelectItem, + SelectLabel, SelectScrollDownButton, + SelectScrollUpButton, + SelectSeparator, + SelectTrigger, + SelectValue, }; diff --git a/packages/ui/src/components/ui/base/table/table.tsx b/packages/ui/src/components/ui/base/table/table.tsx index 9eee7062..142e725c 100644 --- a/packages/ui/src/components/ui/base/table/table.tsx +++ b/packages/ui/src/components/ui/base/table/table.tsx @@ -178,4 +178,4 @@ function TableCaption({ className, ...props }: React.ComponentProps<"caption">) ); } -export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption }; +export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow }; diff --git a/packages/ui/src/components/ui/base/textarea/textarea.tsx b/packages/ui/src/components/ui/base/textarea/textarea.tsx index e89961cd..6d142068 100644 --- a/packages/ui/src/components/ui/base/textarea/textarea.tsx +++ b/packages/ui/src/components/ui/base/textarea/textarea.tsx @@ -140,4 +140,4 @@ function Textarea({ return textareaElement; } -export { Textarea, TextareaWrapper, TextareaError }; +export { Textarea, TextareaError, TextareaWrapper }; diff --git a/packages/ui/src/components/ui/data-display/card/card.tsx b/packages/ui/src/components/ui/data-display/card/card.tsx index c5c1df80..ff3e2c3b 100644 --- a/packages/ui/src/components/ui/data-display/card/card.tsx +++ b/packages/ui/src/components/ui/data-display/card/card.tsx @@ -111,4 +111,4 @@ function CardFooter({ className, ...props }: React.ComponentProps<"div">) { ); } -export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent }; +export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle }; diff --git a/packages/ui/src/components/ui/data-display/chart/chart.tsx b/packages/ui/src/components/ui/data-display/chart/chart.tsx index 3791ca8a..2692d1f1 100644 --- a/packages/ui/src/components/ui/data-display/chart/chart.tsx +++ b/packages/ui/src/components/ui/data-display/chart/chart.tsx @@ -418,9 +418,9 @@ function getPayloadConfigFromPayload(config: ChartConfig, payload: unknown, key: export { ChartContainer, - ChartTooltip, - ChartTooltipContent, ChartLegend, ChartLegendContent, ChartStyle, + ChartTooltip, + ChartTooltipContent, }; diff --git a/packages/ui/src/components/ui/feedback/AlertDialog/fallback/AlertDialog.tsx b/packages/ui/src/components/ui/feedback/AlertDialog/fallback/AlertDialog.tsx index 964af0e4..f003830f 100644 --- a/packages/ui/src/components/ui/feedback/AlertDialog/fallback/AlertDialog.tsx +++ b/packages/ui/src/components/ui/feedback/AlertDialog/fallback/AlertDialog.tsx @@ -176,14 +176,14 @@ function AlertDialogCancel({ export { AlertDialog, - AlertDialogPortal, - AlertDialogOverlay, - AlertDialogTrigger, + AlertDialogAction, + AlertDialogCancel, AlertDialogContent, - AlertDialogHeader, + AlertDialogDescription, AlertDialogFooter, + AlertDialogHeader, + AlertDialogOverlay, + AlertDialogPortal, AlertDialogTitle, - AlertDialogDescription, - AlertDialogAction, - AlertDialogCancel, + AlertDialogTrigger, }; diff --git a/packages/ui/src/components/ui/forms/form/fallback/Form.tsx b/packages/ui/src/components/ui/forms/form/fallback/Form.tsx index 2a18f2ef..9a7cb916 100644 --- a/packages/ui/src/components/ui/forms/form/fallback/Form.tsx +++ b/packages/ui/src/components/ui/forms/form/fallback/Form.tsx @@ -190,12 +190,12 @@ function FormMessage({ className, ...props }: React.ComponentProps<"p">) { } export { - useFormField, Form, - FormItem, - FormLabel, FormControl, FormDescription, - FormMessage, FormField, + FormItem, + FormLabel, + FormMessage, + useFormField, }; diff --git a/packages/ui/src/components/ui/layout/Transition/Transition.tsx b/packages/ui/src/components/ui/layout/Transition/Transition.tsx index 0b2510c1..fdd1fcb4 100644 --- a/packages/ui/src/components/ui/layout/Transition/Transition.tsx +++ b/packages/ui/src/components/ui/layout/Transition/Transition.tsx @@ -181,4 +181,4 @@ function SlideIn({ ); } -export { Transition, Stagger, Collapse, SlideIn }; +export { Collapse, SlideIn, Stagger, Transition }; diff --git a/packages/ui/src/components/ui/navigation/NavigationMenu/fallback/NavigationMenu.tsx b/packages/ui/src/components/ui/navigation/NavigationMenu/fallback/NavigationMenu.tsx index 88e29cea..f26255db 100644 --- a/packages/ui/src/components/ui/navigation/NavigationMenu/fallback/NavigationMenu.tsx +++ b/packages/ui/src/components/ui/navigation/NavigationMenu/fallback/NavigationMenu.tsx @@ -236,12 +236,12 @@ function NavigationMenuIndicator({ export { NavigationMenu, - NavigationMenuList, - NavigationMenuItem, NavigationMenuContent, - NavigationMenuTrigger, - NavigationMenuLink, NavigationMenuIndicator, + NavigationMenuItem, + NavigationMenuLink, + NavigationMenuList, + NavigationMenuTrigger, NavigationMenuViewport, navigationMenuTriggerStyle, }; diff --git a/packages/ui/src/components/ui/navigation/carousel/carousel.tsx b/packages/ui/src/components/ui/navigation/carousel/carousel.tsx index 3aca6291..5d5d6845 100644 --- a/packages/ui/src/components/ui/navigation/carousel/carousel.tsx +++ b/packages/ui/src/components/ui/navigation/carousel/carousel.tsx @@ -299,10 +299,10 @@ function CarouselNext({ } export { - type CarouselApi, Carousel, + type CarouselApi, CarouselContent, CarouselItem, - CarouselPrevious, CarouselNext, + CarouselPrevious, }; diff --git a/packages/ui/src/components/ui/navigation/menubar/fallback/Menubar.tsx b/packages/ui/src/components/ui/navigation/menubar/fallback/Menubar.tsx index d0d36f26..9788f4c8 100644 --- a/packages/ui/src/components/ui/navigation/menubar/fallback/Menubar.tsx +++ b/packages/ui/src/components/ui/navigation/menubar/fallback/Menubar.tsx @@ -369,19 +369,19 @@ function MenubarSubContent({ export { Menubar, - MenubarPortal, - MenubarMenu, - MenubarTrigger, + MenubarCheckboxItem, MenubarContent, MenubarGroup, - MenubarSeparator, - MenubarLabel, MenubarItem, - MenubarShortcut, - MenubarCheckboxItem, + MenubarLabel, + MenubarMenu, + MenubarPortal, MenubarRadioGroup, MenubarRadioItem, + MenubarSeparator, + MenubarShortcut, MenubarSub, - MenubarSubTrigger, MenubarSubContent, + MenubarSubTrigger, + MenubarTrigger, }; diff --git a/packages/ui/src/components/ui/navigation/tabs/fallback/Tabs.tsx b/packages/ui/src/components/ui/navigation/tabs/fallback/Tabs.tsx index 4b1337ae..044dc2c0 100644 --- a/packages/ui/src/components/ui/navigation/tabs/fallback/Tabs.tsx +++ b/packages/ui/src/components/ui/navigation/tabs/fallback/Tabs.tsx @@ -120,4 +120,4 @@ function TabsContent({ className, ...props }: React.ComponentProps) export { Command, CommandDialog, - CommandInput, - CommandList, CommandEmpty, CommandGroup, + CommandInput, CommandItem, - CommandShortcut, + CommandList, CommandSeparator, + CommandShortcut, }; diff --git a/packages/ui/src/components/ui/overlays/drawer/drawer.tsx b/packages/ui/src/components/ui/overlays/drawer/drawer.tsx index be4e35d4..7ff45baf 100644 --- a/packages/ui/src/components/ui/overlays/drawer/drawer.tsx +++ b/packages/ui/src/components/ui/overlays/drawer/drawer.tsx @@ -227,13 +227,13 @@ function DrawerDescription({ export { Drawer, - DrawerPortal, - DrawerOverlay, - DrawerTrigger, DrawerClose, DrawerContent, - DrawerHeader, + DrawerDescription, DrawerFooter, + DrawerHeader, + DrawerOverlay, + DrawerPortal, DrawerTitle, - DrawerDescription, + DrawerTrigger, }; diff --git a/packages/ui/src/components/ui/overlays/popover/fallback/Popover.tsx b/packages/ui/src/components/ui/overlays/popover/fallback/Popover.tsx index 83468729..cc7ea1d4 100644 --- a/packages/ui/src/components/ui/overlays/popover/fallback/Popover.tsx +++ b/packages/ui/src/components/ui/overlays/popover/fallback/Popover.tsx @@ -114,4 +114,4 @@ function PopoverAnchor({ ...props }: React.ComponentProps; } -export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }; +export { Popover, PopoverAnchor, PopoverContent, PopoverTrigger }; diff --git a/packages/ui/src/components/ui/overlays/sheet/fallback/Sheet.tsx b/packages/ui/src/components/ui/overlays/sheet/fallback/Sheet.tsx index 5530da05..779e05c0 100644 --- a/packages/ui/src/components/ui/overlays/sheet/fallback/Sheet.tsx +++ b/packages/ui/src/components/ui/overlays/sheet/fallback/Sheet.tsx @@ -202,11 +202,11 @@ function SheetDescription({ export { Sheet, - SheetTrigger, SheetClose, SheetContent, - SheetHeader, + SheetDescription, SheetFooter, + SheetHeader, SheetTitle, - SheetDescription, + SheetTrigger, }; diff --git a/packages/ui/src/components/ui/overlays/tooltip/fallback/Tooltip.tsx b/packages/ui/src/components/ui/overlays/tooltip/fallback/Tooltip.tsx index 6ddbbde4..2435cbe4 100644 --- a/packages/ui/src/components/ui/overlays/tooltip/fallback/Tooltip.tsx +++ b/packages/ui/src/components/ui/overlays/tooltip/fallback/Tooltip.tsx @@ -125,4 +125,4 @@ function TooltipContent({ ); } -export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }; +export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }; diff --git a/packages/ui/src/storybook/_holding/component-stories/Alert.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Alert.stories.tsx index 7be50113..9d1afe8f 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Alert.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Alert.stories.tsx @@ -1,8 +1,7 @@ +import { Alert, AlertDescription, AlertTitle } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { Alert, AlertDescription, AlertTitle } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Base/Alert", component: Alert, @@ -46,4 +45,3 @@ export const AlertRendersWithRole: Story = { }); }, }; - diff --git a/packages/ui/src/storybook/_holding/component-stories/AlertDialog.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/AlertDialog.stories.tsx index 1d28b3ac..542d3760 100644 --- a/packages/ui/src/storybook/_holding/component-stories/AlertDialog.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/AlertDialog.stories.tsx @@ -1,6 +1,3 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; -import { expect, userEvent, within } from "@storybook/test"; - import { AlertDialog, AlertDialogAction, @@ -13,7 +10,8 @@ import { AlertDialogTrigger, Button, } from "@design-studio/ui"; - +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, userEvent, within } from "@storybook/test"; const meta: Meta = { title: "Components/UI/Feedback/Alert Dialog", @@ -56,7 +54,9 @@ export const Closed: Story = { render: () => ( - + @@ -78,14 +78,14 @@ export const OpenAndCancel: Story = { render: () => ( - + Delete your account? - - All data will be permanently removed. - + All data will be permanently removed. Cancel @@ -128,7 +128,9 @@ export const OpenAndConfirm: Story = { render: () => ( - + diff --git a/packages/ui/src/storybook/_holding/component-stories/AspectRatio.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/AspectRatio.stories.tsx index 3e5a9a3b..51b550ff 100644 --- a/packages/ui/src/storybook/_holding/component-stories/AspectRatio.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/AspectRatio.stories.tsx @@ -1,6 +1,5 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; - import { AspectRatio } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; const meta: Meta = { title: "Components/UI/Base/Aspect Ratio", diff --git a/packages/ui/src/storybook/_holding/component-stories/Calendar.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Calendar.stories.tsx index 439b8aa2..e5ced088 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Calendar.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Calendar.stories.tsx @@ -1,8 +1,7 @@ +import { Calendar } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { Calendar } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Base/Calendar", component: Calendar, diff --git a/packages/ui/src/storybook/_holding/component-stories/Card.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Card.stories.tsx index 4df6cc42..b2cb442f 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Card.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Card.stories.tsx @@ -1,8 +1,5 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; - -import { Button } from "@design-studio/ui"; - import { + Button, Card, CardAction, CardContent, @@ -11,6 +8,7 @@ import { CardHeader, CardTitle, } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; const meta: Meta = { title: "Components/UI/Data Display/Card", diff --git a/packages/ui/src/storybook/_holding/component-stories/Carousel.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Carousel.stories.tsx index ecf332e5..485caa21 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Carousel.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Carousel.stories.tsx @@ -1,6 +1,3 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; -import { expect, userEvent, within } from "@storybook/test"; - import { Carousel, CarouselContent, @@ -8,6 +5,8 @@ import { CarouselNext, CarouselPrevious, } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, userEvent, within } from "@storybook/test"; const meta: Meta = { title: "Components/UI/Navigation/Carousel", @@ -50,4 +49,3 @@ export const Default: Story = { }); }, }; - diff --git a/packages/ui/src/storybook/_holding/component-stories/Chart.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Chart.stories.tsx index a9fe8288..2ee0f4e1 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Chart.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Chart.stories.tsx @@ -1,8 +1,7 @@ +import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import * as RechartsPrimitive from "recharts"; -import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Data Display/Chart", component: ChartContainer, diff --git a/packages/ui/src/storybook/_holding/component-stories/CollapsibleSection.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/CollapsibleSection.stories.tsx index d45c444f..f4fee5a1 100644 --- a/packages/ui/src/storybook/_holding/component-stories/CollapsibleSection.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/CollapsibleSection.stories.tsx @@ -1,6 +1,5 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; - import { CollapsibleSection } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; const meta: Meta = { title: "Components/UI/Base/Collapsible Section", diff --git a/packages/ui/src/storybook/_holding/component-stories/Combobox.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Combobox.stories.tsx index fe28a613..4701a616 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Combobox.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Combobox.stories.tsx @@ -1,10 +1,8 @@ +import { Combobox } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; import { useState } from "react"; - -import { Combobox } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Forms/Combobox", component: Combobox, @@ -311,4 +309,3 @@ export const DisabledComboboxNotInteractive: Story = { }); }, }; - diff --git a/packages/ui/src/storybook/_holding/component-stories/Command.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Command.stories.tsx index f21133f9..142f08ad 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Command.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Command.stories.tsx @@ -1,6 +1,3 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; -import { expect, userEvent, within } from "@storybook/test"; - import { Command, CommandEmpty, @@ -11,6 +8,8 @@ import { CommandSeparator, CommandShortcut, } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, userEvent, within } from "@storybook/test"; const meta: Meta = { title: "Components/UI/Overlays/Command", diff --git a/packages/ui/src/storybook/_holding/component-stories/ContextMenu.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/ContextMenu.stories.tsx index a4a2dad3..b9e3e257 100644 --- a/packages/ui/src/storybook/_holding/component-stories/ContextMenu.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/ContextMenu.stories.tsx @@ -1,6 +1,3 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; -import { expect, fn, userEvent, within } from "@storybook/test"; - import { ContextMenu, ContextMenuCheckboxItem, @@ -10,6 +7,8 @@ import { ContextMenuSeparator, ContextMenuTrigger, } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, fn, userEvent, within } from "@storybook/test"; const meta: Meta = { title: "Components/UI/Overlays/Context Menu", diff --git a/packages/ui/src/storybook/_holding/component-stories/ContextTag.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/ContextTag.stories.tsx index 256baebd..ebb8a353 100644 --- a/packages/ui/src/storybook/_holding/component-stories/ContextTag.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/ContextTag.stories.tsx @@ -1,10 +1,8 @@ +import { ContextTag } from "@design-studio/ui"; +import { IconCode, IconFolder, IconImage } from "@design-studio/ui/icons"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { fn } from "@storybook/test"; -import { IconCode, IconFolder, IconImage } from "@design-studio/ui/icons"; - -import { ContextTag } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Overlays/Context Tag", component: ContextTag, diff --git a/packages/ui/src/storybook/_holding/component-stories/DatePicker.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/DatePicker.stories.tsx index 18e4d768..e7d49262 100644 --- a/packages/ui/src/storybook/_holding/component-stories/DatePicker.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/DatePicker.stories.tsx @@ -1,9 +1,8 @@ +import { DatePicker, DateRangePicker } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, fn, userEvent, within } from "@storybook/test"; import { useState } from "react"; -import { DatePicker, DateRangePicker } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Forms/Date Picker", component: DatePicker, diff --git a/packages/ui/src/storybook/_holding/component-stories/DirectionProvider.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/DirectionProvider.stories.tsx index addc284b..24ac7e25 100644 --- a/packages/ui/src/storybook/_holding/component-stories/DirectionProvider.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/DirectionProvider.stories.tsx @@ -1,14 +1,6 @@ +import { Button, DirectionProvider, Input, Label, useDirection } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; -import { - Button, - DirectionProvider, - Input, - Label, - useDirection, -} from "@design-studio/ui"; - - const meta: Meta = { title: "Components/UI/Base/Direction Provider", component: DirectionProvider, diff --git a/packages/ui/src/storybook/_holding/component-stories/Drawer.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Drawer.stories.tsx index ceb456cd..2112e661 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Drawer.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Drawer.stories.tsx @@ -1,6 +1,3 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; -import { expect, within } from "@storybook/test"; - import { Button, Drawer, @@ -12,7 +9,8 @@ import { DrawerTitle, DrawerTrigger, } from "@design-studio/ui"; - +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, within } from "@storybook/test"; const meta: Meta = { title: "Components/UI/Overlays/Drawer", diff --git a/packages/ui/src/storybook/_holding/component-stories/DropdownMenu.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/DropdownMenu.stories.tsx index 927436c3..0dcde329 100644 --- a/packages/ui/src/storybook/_holding/component-stories/DropdownMenu.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/DropdownMenu.stories.tsx @@ -1,6 +1,3 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; -import { expect, userEvent, within } from "@storybook/test"; - import { Button, DropdownMenu, @@ -11,7 +8,8 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from "@design-studio/ui"; - +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, userEvent, within } from "@storybook/test"; const meta: Meta = { title: "Components/UI/Overlays/Dropdown Menu", diff --git a/packages/ui/src/storybook/_holding/component-stories/HoverCard.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/HoverCard.stories.tsx index 259c5f12..50ba2e0f 100644 --- a/packages/ui/src/storybook/_holding/component-stories/HoverCard.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/HoverCard.stories.tsx @@ -1,8 +1,7 @@ +import { HoverCard, HoverCardContent, HoverCardTrigger } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, within } from "@storybook/test"; -import { HoverCard, HoverCardContent, HoverCardTrigger } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Overlays/Hover Card", component: HoverCard, diff --git a/packages/ui/src/storybook/_holding/component-stories/IconButton.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/IconButton.stories.tsx index 0bcd42f7..7bd64982 100644 --- a/packages/ui/src/storybook/_holding/component-stories/IconButton.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/IconButton.stories.tsx @@ -1,8 +1,7 @@ +import { IconButton } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { IconButton } from "@design-studio/ui"; - // Mock icons for the story const CopyIcon = () => ( @@ -53,7 +52,7 @@ export const Default: Story = { }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); - + await userEvent.step("Icon button renders with title", () => { // It should be accessible via its title/aria-label expect(canvas.getByRole("button", { name: /copy to clipboard/i })).toBeInTheDocument(); diff --git a/packages/ui/src/storybook/_holding/component-stories/Input.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Input.stories.tsx index e656bb18..064deb07 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Input.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Input.stories.tsx @@ -1,9 +1,8 @@ +import { Button, Input, Label } from "@design-studio/ui"; +import { IconEye, IconEyeOff, IconSearch } from "@design-studio/ui/icons"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, fn, userEvent, within } from "@storybook/test"; import { useState } from "react"; -import { IconEye, IconEyeOff, IconSearch } from "@design-studio/ui/icons"; -import { Button, Input, Label } from "@design-studio/ui"; - /** * Input component for text entry. diff --git a/packages/ui/src/storybook/_holding/component-stories/InputOTP.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/InputOTP.stories.tsx index 0e734228..d498540b 100644 --- a/packages/ui/src/storybook/_holding/component-stories/InputOTP.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/InputOTP.stories.tsx @@ -1,9 +1,8 @@ +import { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; import * as React from "react"; -import { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Base/Input OTP", component: InputOTP, @@ -60,7 +59,9 @@ export const TypeOTP: Story = { -
Value: {value}
+
+ Value: {value} +
); }, diff --git a/packages/ui/src/storybook/_holding/component-stories/ListItem.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/ListItem.stories.tsx index 732a7f77..4047f35a 100644 --- a/packages/ui/src/storybook/_holding/component-stories/ListItem.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/ListItem.stories.tsx @@ -1,8 +1,7 @@ +import { ListItem } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { fn } from "@storybook/test"; -import { ListItem } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Base/List Item", component: ListItem, diff --git a/packages/ui/src/storybook/_holding/component-stories/MessageActions.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/MessageActions.stories.tsx index 2fd04d5a..49956ec8 100644 --- a/packages/ui/src/storybook/_holding/component-stories/MessageActions.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/MessageActions.stories.tsx @@ -1,6 +1,5 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; - import { MessageActions } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; const meta: Meta = { title: "Components/Chat/Message Actions", diff --git a/packages/ui/src/storybook/_holding/component-stories/Modal.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Modal.stories.tsx index e5b89f31..b0941fac 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Modal.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Modal.stories.tsx @@ -1,11 +1,9 @@ +import { Button, ModalDialog } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; import type { ComponentProps } from "react"; import { useState } from "react"; -import { Button, ModalDialog } from "@design-studio/ui"; - - const meta: Meta = { title: "Components/UI/Overlays/Modal", component: ModalDialog, diff --git a/packages/ui/src/storybook/_holding/component-stories/ModeSelector.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/ModeSelector.stories.tsx index 9a6242ce..e2510fbd 100644 --- a/packages/ui/src/storybook/_holding/component-stories/ModeSelector.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/ModeSelector.stories.tsx @@ -1,9 +1,8 @@ +import { ModeSelector } from "@design-studio/ui"; +import { sampleComposeModes } from "@design-studio/ui/fixtures/sample-data"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { useState } from "react"; -import { sampleComposeModes } from "@design-studio/ui/fixtures/sample-data"; -import { ModeSelector } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Navigation/Mode Selector", component: ModeSelector, diff --git a/packages/ui/src/storybook/_holding/component-stories/ModelBadge.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/ModelBadge.stories.tsx index c83c901c..35b7211e 100644 --- a/packages/ui/src/storybook/_holding/component-stories/ModelBadge.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/ModelBadge.stories.tsx @@ -1,6 +1,5 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; - import { ModelBadge } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; const meta: Meta = { title: "Components/UI/Navigation/Model Badge", diff --git a/packages/ui/src/storybook/_holding/component-stories/ModelSelector.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/ModelSelector.stories.tsx index 95033937..6774106b 100644 --- a/packages/ui/src/storybook/_holding/component-stories/ModelSelector.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/ModelSelector.stories.tsx @@ -1,6 +1,5 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; - import { ModelSelector } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; const meta: Meta = { title: "Components/UI/Navigation/Model Selector", diff --git a/packages/ui/src/storybook/_holding/component-stories/NavigationMenu.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/NavigationMenu.stories.tsx index f24dbdec..00c9d42b 100644 --- a/packages/ui/src/storybook/_holding/component-stories/NavigationMenu.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/NavigationMenu.stories.tsx @@ -1,6 +1,3 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; -import { expect, userEvent, within } from "@storybook/test"; - import { NavigationMenu, NavigationMenuContent, @@ -10,6 +7,8 @@ import { NavigationMenuTrigger, NavigationMenuViewport, } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, userEvent, within } from "@storybook/test"; const meta: Meta = { title: "Components/UI/Navigation/Navigation Menu", diff --git a/packages/ui/src/storybook/_holding/component-stories/Pagination.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Pagination.stories.tsx index 4688473d..b2f174ab 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Pagination.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Pagination.stories.tsx @@ -1,9 +1,8 @@ +import { Pagination } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; import { useState } from "react"; -import { Pagination } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Navigation/Pagination", component: Pagination, diff --git a/packages/ui/src/storybook/_holding/component-stories/RadioGroup.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/RadioGroup.stories.tsx index dabbc873..d99985ee 100644 --- a/packages/ui/src/storybook/_holding/component-stories/RadioGroup.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/RadioGroup.stories.tsx @@ -1,9 +1,7 @@ +import { Label, RadioGroup, RadioGroupItem } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { Label, RadioGroup, RadioGroupItem } from "@design-studio/ui"; - - const meta: Meta = { title: "Components/UI/Base/Radio Group", component: RadioGroup, @@ -160,7 +158,9 @@ export const DisabledItemNotSelectable: Story = {
- +
), diff --git a/packages/ui/src/storybook/_holding/component-stories/RangeSlider.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/RangeSlider.stories.tsx index d0082b96..2b4e5a7f 100644 --- a/packages/ui/src/storybook/_holding/component-stories/RangeSlider.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/RangeSlider.stories.tsx @@ -1,9 +1,8 @@ +import { RangeSlider } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; import { useState } from "react"; -import { RangeSlider } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Forms/Range Slider", component: RangeSlider, diff --git a/packages/ui/src/storybook/_holding/component-stories/Resizable.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Resizable.stories.tsx index 79771340..500bbdec 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Resizable.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Resizable.stories.tsx @@ -1,6 +1,5 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; - import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; const meta: Meta = { title: "Components/UI/Base/Resizable", diff --git a/packages/ui/src/storybook/_holding/component-stories/ScrollArea.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/ScrollArea.stories.tsx index 3148ad01..1bea67bd 100644 --- a/packages/ui/src/storybook/_holding/component-stories/ScrollArea.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/ScrollArea.stories.tsx @@ -1,6 +1,5 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; - import { ScrollArea } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; const meta: Meta = { title: "Components/UI/Base/Scroll Area", diff --git a/packages/ui/src/storybook/_holding/component-stories/SectionHeader.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/SectionHeader.stories.tsx index 8814855d..d8236500 100644 --- a/packages/ui/src/storybook/_holding/component-stories/SectionHeader.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/SectionHeader.stories.tsx @@ -1,6 +1,5 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; - import { SectionHeader } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; const meta: Meta = { title: "Components/UI/Base/Section Header", diff --git a/packages/ui/src/storybook/_holding/component-stories/SegmentedControl.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/SegmentedControl.stories.tsx index 435edb07..9a61318d 100644 --- a/packages/ui/src/storybook/_holding/component-stories/SegmentedControl.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/SegmentedControl.stories.tsx @@ -1,9 +1,8 @@ +import { SegmentedControl } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; import { useState } from "react"; -import { SegmentedControl } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Base/Segmented Control", component: SegmentedControl, @@ -102,7 +101,9 @@ export const ClickToSwitch: Story = { ]} onChange={setValue} /> -

Selected: {value}

+

+ Selected: {value} +

); }, diff --git a/packages/ui/src/storybook/_holding/component-stories/ShimmerText.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/ShimmerText.stories.tsx index e694fe8b..3e655b2d 100644 --- a/packages/ui/src/storybook/_holding/component-stories/ShimmerText.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/ShimmerText.stories.tsx @@ -1,6 +1,5 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; - import { ShimmerText } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; /** * ShimmerText component - loading placeholder with animated shimmer effect. diff --git a/packages/ui/src/storybook/_holding/component-stories/Skeleton.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Skeleton.stories.tsx index 4066f7a0..735fc9e0 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Skeleton.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Skeleton.stories.tsx @@ -1,8 +1,7 @@ +import { Skeleton } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { Skeleton } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Base/Skeleton", component: Skeleton, @@ -33,4 +32,3 @@ export const Card: Story = { ), }; - diff --git a/packages/ui/src/storybook/_holding/component-stories/Sonner.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Sonner.stories.tsx index 83ca3357..4b03e822 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Sonner.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Sonner.stories.tsx @@ -1,10 +1,8 @@ +import { Button, Toaster } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; import { toast } from "sonner"; -import { Button, Toaster } from "@design-studio/ui"; - - const meta: Meta = { title: "Components/UI/Feedback/Sonner", component: Toaster, diff --git a/packages/ui/src/storybook/_holding/component-stories/Table.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Table.stories.tsx index 74a30b25..a0068d66 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Table.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Table.stories.tsx @@ -1,6 +1,3 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; -import { expect, userEvent, within } from "@storybook/test"; - import { Table, TableBody, @@ -10,6 +7,8 @@ import { TableHeader, TableRow, } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, userEvent, within } from "@storybook/test"; const meta: Meta = { title: "Components/UI/Base/Table", @@ -67,10 +66,9 @@ export const TableRendersWithA11y: Story = { // Assuming Table component uses real HTML tables: expect(canvas.getByRole("table")).toBeInTheDocument(); expect(canvas.getByRole("columnheader", { name: /project/i })).toBeInTheDocument(); - + const rows = canvas.getAllByRole("row"); expect(rows.length).toBeGreaterThan(1); // 1 header + body rows }); }, }; - diff --git a/packages/ui/src/storybook/_holding/component-stories/TextLink.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/TextLink.stories.tsx index a225062f..bb39f1e2 100644 --- a/packages/ui/src/storybook/_holding/component-stories/TextLink.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/TextLink.stories.tsx @@ -1,6 +1,5 @@ -import type { Meta, StoryObj } from "@storybook/react"; - import { TextLink } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react"; /** * TextLink component - accessible anchor element with variant styling. diff --git a/packages/ui/src/storybook/_holding/component-stories/Textarea.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Textarea.stories.tsx index da13ff46..525d5f52 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Textarea.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Textarea.stories.tsx @@ -1,8 +1,7 @@ +import { Textarea } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { Textarea } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Base/Textarea", component: Textarea, diff --git a/packages/ui/src/storybook/_holding/component-stories/Toast.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Toast.stories.tsx index 565cc4a1..682a89cb 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Toast.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Toast.stories.tsx @@ -1,10 +1,8 @@ +import { Button, Toast, ToastContainer } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; import { useRef, useState } from "react"; -import { Button, Toast, ToastContainer } from "@design-studio/ui"; - - const meta: Meta = { title: "Components/UI/Feedback/Toast", component: Toast, @@ -258,7 +256,9 @@ export const ToastStackAddAndRemove: Story = { }); await userEvent.step("Dismiss the first toast", async () => { - const firstToastCloseBtn = within(canvas.getByText("First toast").closest("div") as HTMLElement).getByRole("button", { name: /close toast/i }); + const firstToastCloseBtn = within( + canvas.getByText("First toast").closest("div") as HTMLElement, + ).getByRole("button", { name: /close toast/i }); await userEvent.click(firstToastCloseBtn); }); @@ -267,4 +267,3 @@ export const ToastStackAddAndRemove: Story = { }); }, }; - diff --git a/packages/ui/src/storybook/_holding/component-stories/Toggle.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/Toggle.stories.tsx index bfe12346..a9860aba 100644 --- a/packages/ui/src/storybook/_holding/component-stories/Toggle.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/Toggle.stories.tsx @@ -1,9 +1,8 @@ +import { Toggle } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; import { useState } from "react"; -import { Toggle } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Base/Toggle", component: Toggle, diff --git a/packages/ui/src/storybook/_holding/component-stories/ToggleGroup.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/ToggleGroup.stories.tsx index f43c1959..548aa44a 100644 --- a/packages/ui/src/storybook/_holding/component-stories/ToggleGroup.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/ToggleGroup.stories.tsx @@ -1,8 +1,7 @@ +import { ToggleGroup, ToggleGroupItem } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { ToggleGroup, ToggleGroupItem } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Base/Toggle Group", component: ToggleGroup, @@ -56,7 +55,10 @@ export const SingleSelectToggle: Story = { await userEvent.step("Click Center — it becomes selected, Left deselected", async () => { await userEvent.click(canvas.getByRole("radio", { name: /center/i })); - expect(canvas.getByRole("radio", { name: /center/i })).toHaveAttribute("aria-checked", "true"); + expect(canvas.getByRole("radio", { name: /center/i })).toHaveAttribute( + "aria-checked", + "true", + ); expect(canvas.getByRole("radio", { name: /left/i })).toHaveAttribute("aria-checked", "false"); }); }, @@ -81,13 +83,22 @@ export const MultipleSelectToggle: Story = { await userEvent.step("Click Italic — both Bold and Italic are pressed", async () => { await userEvent.click(canvas.getByRole("button", { name: /italic/i })); expect(canvas.getByRole("button", { name: /bold/i })).toHaveAttribute("aria-pressed", "true"); - expect(canvas.getByRole("button", { name: /italic/i })).toHaveAttribute("aria-pressed", "true"); + expect(canvas.getByRole("button", { name: /italic/i })).toHaveAttribute( + "aria-pressed", + "true", + ); }); await userEvent.step("Click Bold to unpress it — only Italic remains", async () => { await userEvent.click(canvas.getByRole("button", { name: /bold/i })); - expect(canvas.getByRole("button", { name: /bold/i })).toHaveAttribute("aria-pressed", "false"); - expect(canvas.getByRole("button", { name: /italic/i })).toHaveAttribute("aria-pressed", "true"); + expect(canvas.getByRole("button", { name: /bold/i })).toHaveAttribute( + "aria-pressed", + "false", + ); + expect(canvas.getByRole("button", { name: /italic/i })).toHaveAttribute( + "aria-pressed", + "true", + ); }); }, }; diff --git a/packages/ui/src/storybook/_holding/component-stories/UseMobile.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/UseMobile.stories.tsx index d99e6a82..f6bd700f 100644 --- a/packages/ui/src/storybook/_holding/component-stories/UseMobile.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/UseMobile.stories.tsx @@ -1,8 +1,7 @@ +import { useIsMobile } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react"; import * as React from "react"; -import { useIsMobile } from "@design-studio/ui"; - /** * useIsMobile hook - detects mobile viewport based on 768px breakpoint. * diff --git a/packages/ui/src/storybook/_holding/component-stories/ViewModeToggle.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/ViewModeToggle.stories.tsx index 08eaf576..952ee705 100644 --- a/packages/ui/src/storybook/_holding/component-stories/ViewModeToggle.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/ViewModeToggle.stories.tsx @@ -1,8 +1,7 @@ +import { ViewModeToggle } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { useState } from "react"; -import { ViewModeToggle } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Navigation/View Mode Toggle", component: ViewModeToggle, diff --git a/packages/ui/src/storybook/_holding/component-stories/accordion.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/accordion.stories.tsx index 63432fc2..285e57b4 100644 --- a/packages/ui/src/storybook/_holding/component-stories/accordion.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/accordion.stories.tsx @@ -1,8 +1,7 @@ +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Base/Accordion", component: Accordion, @@ -95,7 +94,9 @@ export const ClickToOpenPanel: Story = { Is it themeable? - Yes — tokens and classNames are designed to be customized. + + Yes — tokens and classNames are designed to be customized. + diff --git a/packages/ui/src/storybook/_holding/component-stories/avatar.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/avatar.stories.tsx index f4e1098c..9ba74de2 100644 --- a/packages/ui/src/storybook/_holding/component-stories/avatar.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/avatar.stories.tsx @@ -1,8 +1,7 @@ +import { Avatar, AvatarFallback, AvatarImage } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { Avatar, AvatarFallback, AvatarImage } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Base/Avatar", component: Avatar, @@ -47,4 +46,3 @@ export const AvatarRenders: Story = { }); }, }; - diff --git a/packages/ui/src/storybook/_holding/component-stories/badge.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/badge.stories.tsx index c8bd07e3..2cb146a1 100644 --- a/packages/ui/src/storybook/_holding/component-stories/badge.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/badge.stories.tsx @@ -1,8 +1,7 @@ +import { Badge } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { Badge } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Base/Badge", component: Badge, @@ -27,4 +26,3 @@ export const Default: Story = { export const Secondary: Story = { render: () => Pro, }; - diff --git a/packages/ui/src/storybook/_holding/component-stories/breadcrumb.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/breadcrumb.stories.tsx index 618ceb9d..247ad981 100644 --- a/packages/ui/src/storybook/_holding/component-stories/breadcrumb.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/breadcrumb.stories.tsx @@ -1,5 +1,3 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; - import { Breadcrumb, BreadcrumbEllipsis, @@ -9,6 +7,7 @@ import { BreadcrumbPage, BreadcrumbSeparator, } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; const meta: Meta = { title: "Components/UI/Navigation/Breadcrumb", diff --git a/packages/ui/src/storybook/_holding/component-stories/button.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/button.stories.tsx index 756eb0be..9b812c4d 100644 --- a/packages/ui/src/storybook/_holding/component-stories/button.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/button.stories.tsx @@ -1,10 +1,8 @@ +import { Button } from "@design-studio/ui"; +import { IconChevronRightMd, IconEmail, IconPlusLg, IconRefresh } from "@design-studio/ui/icons"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, fn, userEvent, within } from "@storybook/test"; -import { IconChevronRightMd, IconEmail, IconPlusLg, IconRefresh } from "@design-studio/ui/icons"; - -import { Button } from "@design-studio/ui"; - /** * Button component following Apps SDK UI patterns. * diff --git a/packages/ui/src/storybook/_holding/component-stories/checkbox.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/checkbox.stories.tsx index 15c121b0..8c1b035d 100644 --- a/packages/ui/src/storybook/_holding/component-stories/checkbox.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/checkbox.stories.tsx @@ -1,9 +1,7 @@ +import { Checkbox, Label } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { Checkbox, Label } from "@design-studio/ui"; - - const meta: Meta = { title: "Components/UI/Base/Checkbox", component: Checkbox, @@ -49,11 +47,15 @@ export const Disabled: Story = {
- +
- +
), @@ -76,7 +78,9 @@ export const AllStates: Story = {
- +
), diff --git a/packages/ui/src/storybook/_holding/component-stories/collapsible.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/collapsible.stories.tsx index a3249680..78552ed5 100644 --- a/packages/ui/src/storybook/_holding/component-stories/collapsible.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/collapsible.stories.tsx @@ -1,14 +1,7 @@ +import { Button, Collapsible, CollapsibleContent, CollapsibleTrigger } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { - Button, - Collapsible, - CollapsibleContent, - CollapsibleTrigger, -} from "@design-studio/ui"; - - const meta: Meta = { title: "Components/UI/Base/Collapsible", component: Collapsible, @@ -48,7 +41,9 @@ export const ClosedByDefault: Story = {
Advanced settings
- +
@@ -66,7 +61,9 @@ export const ExpandAndCollapse: Story = {
Details
- +
diff --git a/packages/ui/src/storybook/_holding/component-stories/dialog.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/dialog.stories.tsx index 6f92b1f5..6fe0bf89 100644 --- a/packages/ui/src/storybook/_holding/component-stories/dialog.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/dialog.stories.tsx @@ -1,7 +1,3 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; -import { expect, fn, userEvent, within } from "@storybook/test"; -import { useState } from "react"; - import { Button, Dialog, @@ -15,7 +11,9 @@ import { Input, Label, } from "@design-studio/ui"; - +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, fn, userEvent, within } from "@storybook/test"; +import { useState } from "react"; /** * Dialog component built on Radix UI primitives. diff --git a/packages/ui/src/storybook/_holding/component-stories/form.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/form.stories.tsx index dbb95888..f7e9526b 100644 --- a/packages/ui/src/storybook/_holding/component-stories/form.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/form.stories.tsx @@ -1,7 +1,3 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; -import { expect, fn, userEvent, within } from "@storybook/test"; -import { useForm } from "react-hook-form"; - import { Button, Form, @@ -13,7 +9,9 @@ import { FormMessage, Input, } from "@design-studio/ui"; - +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, fn, userEvent, within } from "@storybook/test"; +import { useForm } from "react-hook-form"; const meta: Meta = { title: "Components/UI/Forms/Form", diff --git a/packages/ui/src/storybook/_holding/component-stories/label.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/label.stories.tsx index e85d2b69..c89ea9f9 100644 --- a/packages/ui/src/storybook/_holding/component-stories/label.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/label.stories.tsx @@ -1,7 +1,5 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; - import { Input, Label } from "@design-studio/ui"; - +import type { Meta, StoryObj } from "@storybook/react-vite"; const meta: Meta = { title: "Components/UI/Base/Label", diff --git a/packages/ui/src/storybook/_holding/component-stories/menubar.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/menubar.stories.tsx index 055082a3..c12b047f 100644 --- a/packages/ui/src/storybook/_holding/component-stories/menubar.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/menubar.stories.tsx @@ -1,6 +1,3 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; -import { expect, userEvent, within } from "@storybook/test"; - import { Menubar, MenubarContent, @@ -10,6 +7,8 @@ import { MenubarShortcut, MenubarTrigger, } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, userEvent, within } from "@storybook/test"; const meta: Meta = { title: "Components/UI/Navigation/Menubar", diff --git a/packages/ui/src/storybook/_holding/component-stories/popover.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/popover.stories.tsx index 93decd92..92f9663f 100644 --- a/packages/ui/src/storybook/_holding/component-stories/popover.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/popover.stories.tsx @@ -1,14 +1,7 @@ +import { Button, Popover, PopoverContent, PopoverTrigger } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { - Button, - Popover, - PopoverContent, - PopoverTrigger, -} from "@design-studio/ui"; - - const meta: Meta = { title: "Components/UI/Overlays/Popover", component: Popover, diff --git a/packages/ui/src/storybook/_holding/component-stories/progress.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/progress.stories.tsx index bfb3bc43..25b0f0f1 100644 --- a/packages/ui/src/storybook/_holding/component-stories/progress.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/progress.stories.tsx @@ -1,6 +1,5 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; - import { Progress } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; const meta: Meta = { title: "Components/UI/Data Display/Progress", diff --git a/packages/ui/src/storybook/_holding/component-stories/select.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/select.stories.tsx index 56000ac9..844a14d8 100644 --- a/packages/ui/src/storybook/_holding/component-stories/select.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/select.stories.tsx @@ -1,7 +1,3 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; -import { expect, userEvent, within } from "@storybook/test"; -import type * as React from "react"; - import { Select, SelectContent, @@ -11,6 +7,9 @@ import { SelectTrigger, SelectValue, } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, userEvent, within } from "@storybook/test"; +import type * as React from "react"; type SelectStoryArgs = React.ComponentProps & { triggerSize: "sm" | "default"; diff --git a/packages/ui/src/storybook/_holding/component-stories/separator.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/separator.stories.tsx index 783efe51..d2764dfc 100644 --- a/packages/ui/src/storybook/_holding/component-stories/separator.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/separator.stories.tsx @@ -1,6 +1,5 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; - import { Separator } from "@design-studio/ui"; +import type { Meta, StoryObj } from "@storybook/react-vite"; const meta: Meta = { title: "Components/UI/Base/Separator", diff --git a/packages/ui/src/storybook/_holding/component-stories/sheet.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/sheet.stories.tsx index cc8b2ff0..df6efe68 100644 --- a/packages/ui/src/storybook/_holding/component-stories/sheet.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/sheet.stories.tsx @@ -1,6 +1,3 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; -import { expect, within } from "@storybook/test"; - import { Button, Sheet, @@ -12,7 +9,8 @@ import { SheetTitle, SheetTrigger, } from "@design-studio/ui"; - +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, within } from "@storybook/test"; const meta: Meta = { title: "Components/UI/Overlays/Sheet", diff --git a/packages/ui/src/storybook/_holding/component-stories/sidebar.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/sidebar.stories.tsx index 54de1905..4ebef4e3 100644 --- a/packages/ui/src/storybook/_holding/component-stories/sidebar.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/sidebar.stories.tsx @@ -1,8 +1,3 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; -import { expect, userEvent, within } from "@storybook/test"; - -import { IconChat, IconFolder, IconSettings } from "@design-studio/ui/icons"; - import { Sidebar, SidebarContent, @@ -20,6 +15,9 @@ import { SidebarSeparator, SidebarTrigger, } from "@design-studio/ui"; +import { IconChat, IconFolder, IconSettings } from "@design-studio/ui/icons"; +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { expect, userEvent, within } from "@storybook/test"; const meta: Meta = { title: "Components/UI/Navigation/Sidebar", diff --git a/packages/ui/src/storybook/_holding/component-stories/slider.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/slider.stories.tsx index 8cb85347..eb7b3f70 100644 --- a/packages/ui/src/storybook/_holding/component-stories/slider.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/slider.stories.tsx @@ -1,8 +1,7 @@ +import { Slider } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { Slider } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Base/Slider", component: Slider, diff --git a/packages/ui/src/storybook/_holding/component-stories/switch.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/switch.stories.tsx index c3e03e10..0ddd9b78 100644 --- a/packages/ui/src/storybook/_holding/component-stories/switch.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/switch.stories.tsx @@ -1,9 +1,7 @@ +import { Label, Switch } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { Label, Switch } from "@design-studio/ui"; - - const meta: Meta = { title: "Components/UI/Base/Switch", component: Switch, @@ -40,11 +38,15 @@ export const Disabled: Story = {
- +
- +
), @@ -63,7 +65,9 @@ export const AllStates: Story = {
- +
), diff --git a/packages/ui/src/storybook/_holding/component-stories/tabs.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/tabs.stories.tsx index 3798d36e..05fdd149 100644 --- a/packages/ui/src/storybook/_holding/component-stories/tabs.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/tabs.stories.tsx @@ -1,8 +1,7 @@ +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, userEvent, within } from "@storybook/test"; -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@design-studio/ui"; - const meta: Meta = { title: "Components/UI/Navigation/Tabs", component: Tabs, diff --git a/packages/ui/src/storybook/_holding/component-stories/tooltip.stories.tsx b/packages/ui/src/storybook/_holding/component-stories/tooltip.stories.tsx index 248a83d2..2b10f227 100644 --- a/packages/ui/src/storybook/_holding/component-stories/tooltip.stories.tsx +++ b/packages/ui/src/storybook/_holding/component-stories/tooltip.stories.tsx @@ -1,14 +1,7 @@ +import { Button, Tooltip, TooltipContent, TooltipTrigger } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { expect, within } from "@storybook/test"; -import { - Button, - Tooltip, - TooltipContent, - TooltipTrigger, -} from "@design-studio/ui"; - - const meta: Meta = { title: "Components/UI/Overlays/Tooltip", component: Tooltip, diff --git a/packages/ui/src/storybook/_holding/docs/APIReference.stories.tsx b/packages/ui/src/storybook/_holding/docs/APIReference.stories.tsx index 704e41d1..c4d9cae5 100644 --- a/packages/ui/src/storybook/_holding/docs/APIReference.stories.tsx +++ b/packages/ui/src/storybook/_holding/docs/APIReference.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; const Stub = () => null; const meta = { - tags: ['autodocs'], + tags: ["autodocs"], title: "Documentation/API Reference", component: Stub, parameters: { diff --git a/packages/ui/src/storybook/_holding/docs/ComponentGallery.stories.tsx b/packages/ui/src/storybook/_holding/docs/ComponentGallery.stories.tsx index 4f57cca0..29283057 100644 --- a/packages/ui/src/storybook/_holding/docs/ComponentGallery.stories.tsx +++ b/packages/ui/src/storybook/_holding/docs/ComponentGallery.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; const Stub = () => null; const meta = { - tags: ['autodocs'], + tags: ["autodocs"], title: "Overview/Component Gallery", component: Stub, parameters: { diff --git a/packages/ui/src/storybook/_holding/docs/ComponentLibrary.stories.tsx b/packages/ui/src/storybook/_holding/docs/ComponentLibrary.stories.tsx index 1f1080f0..b077311b 100644 --- a/packages/ui/src/storybook/_holding/docs/ComponentLibrary.stories.tsx +++ b/packages/ui/src/storybook/_holding/docs/ComponentLibrary.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; const Stub = () => null; const meta = { - tags: ['autodocs'], + tags: ["autodocs"], title: "Overview/Component Library", component: Stub, parameters: { diff --git a/packages/ui/src/storybook/_holding/docs/DesignSystem.stories.tsx b/packages/ui/src/storybook/_holding/docs/DesignSystem.stories.tsx index d23af3f8..bef481bc 100644 --- a/packages/ui/src/storybook/_holding/docs/DesignSystem.stories.tsx +++ b/packages/ui/src/storybook/_holding/docs/DesignSystem.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; const Stub = () => null; const meta = { - tags: ['autodocs'], + tags: ["autodocs"], title: "Documentation/Design System", component: Stub, parameters: { diff --git a/packages/ui/src/storybook/_holding/docs/GettingStarted.stories.tsx b/packages/ui/src/storybook/_holding/docs/GettingStarted.stories.tsx index e0f5a7ea..d71900d1 100644 --- a/packages/ui/src/storybook/_holding/docs/GettingStarted.stories.tsx +++ b/packages/ui/src/storybook/_holding/docs/GettingStarted.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; const Stub = () => null; const meta = { - tags: ['autodocs'], + tags: ["autodocs"], title: "Overview/Getting Started", component: Stub, parameters: { diff --git a/packages/ui/src/storybook/_holding/docs/Migration.stories.tsx b/packages/ui/src/storybook/_holding/docs/Migration.stories.tsx index d74836cc..c15852cf 100644 --- a/packages/ui/src/storybook/_holding/docs/Migration.stories.tsx +++ b/packages/ui/src/storybook/_holding/docs/Migration.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; const Stub = () => null; const meta = { - tags: ['autodocs'], + tags: ["autodocs"], title: "Documentation/Migration Guide", component: Stub, parameters: { diff --git a/packages/ui/src/storybook/_holding/docs/Patterns.stories.tsx b/packages/ui/src/storybook/_holding/docs/Patterns.stories.tsx index 303ff519..ae5bac3c 100644 --- a/packages/ui/src/storybook/_holding/docs/Patterns.stories.tsx +++ b/packages/ui/src/storybook/_holding/docs/Patterns.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; const Stub = () => null; const meta = { - tags: ['autodocs'], + tags: ["autodocs"], title: "Documentation/Component Patterns", component: Stub, parameters: { diff --git a/packages/ui/src/storybook/_holding/docs/QuickStart.stories.tsx b/packages/ui/src/storybook/_holding/docs/QuickStart.stories.tsx index 6f4b2b2f..2b913a8d 100644 --- a/packages/ui/src/storybook/_holding/docs/QuickStart.stories.tsx +++ b/packages/ui/src/storybook/_holding/docs/QuickStart.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; const Stub = () => null; const meta = { - tags: ['autodocs'], + tags: ["autodocs"], title: "Overview/Quick Start", component: Stub, parameters: { diff --git a/packages/ui/src/storybook/_holding/pages/DashboardPage/DashboardPage.stories.tsx b/packages/ui/src/storybook/_holding/pages/DashboardPage/DashboardPage.stories.tsx index a770adce..ce34aca8 100644 --- a/packages/ui/src/storybook/_holding/pages/DashboardPage/DashboardPage.stories.tsx +++ b/packages/ui/src/storybook/_holding/pages/DashboardPage/DashboardPage.stories.tsx @@ -1,8 +1,7 @@ +import { Button, ListItem } from "@design-studio/ui"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { fn } from "@storybook/test"; -import { Button, ListItem } from "@design-studio/ui"; - import { DashboardPage } from "./DashboardPage"; const meta: Meta = { diff --git a/packages/ui/src/storybook/docs/MSW-Patterns.stories.tsx b/packages/ui/src/storybook/docs/MSW-Patterns.stories.tsx index 33eec0a4..753871e6 100644 --- a/packages/ui/src/storybook/docs/MSW-Patterns.stories.tsx +++ b/packages/ui/src/storybook/docs/MSW-Patterns.stories.tsx @@ -15,8 +15,8 @@ import { expect, waitFor, within } from "@storybook/test"; import { emptyStateHandlers, errorHandlers, - happyPathHandlers, handlers, + happyPathHandlers, slowNetworkHandlers, } from "@storybook-msw/handlers"; @@ -25,7 +25,9 @@ import { // This minimal component exists purely to demonstrate the MSW patterns. function MessageList() { - const [messages, setMessages] = React.useState>([]); + const [messages, setMessages] = React.useState< + Array<{ id: string; role: string; content: string }> + >([]); const [status, setStatus] = React.useState<"loading" | "success" | "error">("loading"); React.useEffect(() => { @@ -42,11 +44,19 @@ function MessageList() { }, []); if (status === "loading") { - return
Loading messages…
; + return ( +
+ Loading messages… +
+ ); } if (status === "error") { - return
Failed to load messages. Please try again.
; + return ( +
+ Failed to load messages. Please try again. +
+ ); } if (messages.length === 0) { @@ -56,7 +66,10 @@ function MessageList() { return (
    {messages.map((msg) => ( -
  • +
  • {msg.role}

    {msg.content}

  • diff --git a/packages/ui/src/templates/ChatBlocksTemplate/ChatBlocksTemplate.stories.tsx b/packages/ui/src/templates/ChatBlocksTemplate/ChatBlocksTemplate.stories.tsx index ec738c21..75b7e6e5 100644 --- a/packages/ui/src/templates/ChatBlocksTemplate/ChatBlocksTemplate.stories.tsx +++ b/packages/ui/src/templates/ChatBlocksTemplate/ChatBlocksTemplate.stories.tsx @@ -6,7 +6,7 @@ import { ChatMessagesTemplate } from "../ChatMessagesTemplate"; import { ChatSidebarTemplate } from "../ChatSidebarTemplate"; const meta: Meta = { - tags: ['autodocs'], + tags: ["autodocs"], title: "Components/Templates/Chat/Chat Blocks", parameters: { layout: "fullscreen", diff --git a/packages/ui/src/templates/ChatTemplate/ChatTemplate.stories.tsx b/packages/ui/src/templates/ChatTemplate/ChatTemplate.stories.tsx index 7b6a4070..16da1a1a 100644 --- a/packages/ui/src/templates/ChatTemplate/ChatTemplate.stories.tsx +++ b/packages/ui/src/templates/ChatTemplate/ChatTemplate.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; import { ChatTemplate } from "./ChatTemplate"; const meta: Meta = { - tags: ['autodocs'], + tags: ["autodocs"], title: "Components/Templates/Chat/Chat Template", component: ChatTemplate, parameters: { diff --git a/packages/ui/src/templates/ChatVariantsTemplate/ChatVariantsTemplate.stories.tsx b/packages/ui/src/templates/ChatVariantsTemplate/ChatVariantsTemplate.stories.tsx index 2027cf6f..e156c4df 100644 --- a/packages/ui/src/templates/ChatVariantsTemplate/ChatVariantsTemplate.stories.tsx +++ b/packages/ui/src/templates/ChatVariantsTemplate/ChatVariantsTemplate.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; import { ChatVariantsTemplate } from "./ChatVariantsTemplate"; const meta: Meta = { - tags: ['autodocs'], + tags: ["autodocs"], title: "Components/Templates/Chat/Chat Variants", component: ChatVariantsTemplate, parameters: { diff --git a/packages/ui/src/templates/SettingsPanelsTemplate/SettingsPanelsTemplate.stories.tsx b/packages/ui/src/templates/SettingsPanelsTemplate/SettingsPanelsTemplate.stories.tsx index 2f3349af..447dec6f 100644 --- a/packages/ui/src/templates/SettingsPanelsTemplate/SettingsPanelsTemplate.stories.tsx +++ b/packages/ui/src/templates/SettingsPanelsTemplate/SettingsPanelsTemplate.stories.tsx @@ -11,7 +11,7 @@ import { PersonalizationPanelTemplate } from "../PersonalizationPanelTemplate"; import { SecurityPanelTemplate } from "../SecurityPanelTemplate"; const meta: Meta = { - tags: ['autodocs'], + tags: ["autodocs"], title: "Components/Templates/Settings/Settings Panels", parameters: { layout: "fullscreen", diff --git a/packages/ui/src/templates/TemplatesGallery/TemplatesGallery.stories.tsx b/packages/ui/src/templates/TemplatesGallery/TemplatesGallery.stories.tsx index cd1ec5aa..59e6eb88 100644 --- a/packages/ui/src/templates/TemplatesGallery/TemplatesGallery.stories.tsx +++ b/packages/ui/src/templates/TemplatesGallery/TemplatesGallery.stories.tsx @@ -4,7 +4,7 @@ import { blockRegistry } from "../blocks/registry"; import { templateRegistry } from "../registry"; const meta: Meta = { - tags: ['autodocs'], + tags: ["autodocs"], title: "Components/Templates/Gallery", parameters: { layout: "fullscreen", diff --git a/platforms/web/apps/storybook/.storybook/main.ts b/platforms/web/apps/storybook/.storybook/main.ts index 41ae84a1..38e11288 100644 --- a/platforms/web/apps/storybook/.storybook/main.ts +++ b/platforms/web/apps/storybook/.storybook/main.ts @@ -176,7 +176,6 @@ const config = { "@storybook/addon-a11y", "@storybook/addon-vitest", "@storybook/addon-themes", - ], framework: { @@ -218,10 +217,19 @@ const config = { ...(viteConfig.resolve ?? {}), alias: { ...(viteConfig.resolve?.alias ?? {}), - "react": path.join(repoRoot, "node_modules/.pnpm/react@19.2.3/node_modules/react"), - "react-dom": path.join(repoRoot, "node_modules/.pnpm/react-dom@19.2.3/node_modules/react-dom"), - "react/jsx-runtime": path.join(repoRoot, "node_modules/.pnpm/react@19.2.3/node_modules/react/jsx-runtime"), - "react/jsx-dev-runtime": path.join(repoRoot, "node_modules/.pnpm/react@19.2.3/node_modules/react/jsx-dev-runtime"), + react: path.join(repoRoot, "node_modules/.pnpm/react@19.2.3/node_modules/react"), + "react-dom": path.join( + repoRoot, + "node_modules/.pnpm/react-dom@19.2.3/node_modules/react-dom", + ), + "react/jsx-runtime": path.join( + repoRoot, + "node_modules/.pnpm/react@19.2.3/node_modules/react/jsx-runtime", + ), + "react/jsx-dev-runtime": path.join( + repoRoot, + "node_modules/.pnpm/react@19.2.3/node_modules/react/jsx-dev-runtime", + ), "@design-studio/ui": path.join(repoRoot, "packages/ui/src"), "@design-studio/ui/icons": path.join(repoRoot, "packages/ui/src/icons"), "@design-studio/runtime": path.join(repoRoot, "packages/runtime/src"), diff --git a/platforms/web/apps/storybook/.storybook/msw/handlers.ts b/platforms/web/apps/storybook/.storybook/msw/handlers.ts new file mode 100644 index 00000000..91489d6c --- /dev/null +++ b/platforms/web/apps/storybook/.storybook/msw/handlers.ts @@ -0,0 +1,201 @@ +/** + * Shared MSW handler definitions for Storybook stories. + * + * Usage in a story: + * ```ts + * import { http, HttpResponse } from "msw"; + * import { handlers } from ".storybook/msw/handlers"; + * + * export const LoadingState: Story = { + * parameters: { + * msw: { + * handlers: [handlers.messages.loading], + * }, + * }, + * }; + * ``` + * + * Pattern guide: + * - Keep handlers small and composable — one export per data state + * - Prefer realistic shapes over minimal ones; agents use these for context + * - Use `HttpResponse.json()` for typed JSON, `new HttpResponse(null, { status })` for empty + * - Export raw handler arrays for use in `parameters.msw.handlers` + */ + +import { HttpResponse, http } from "msw"; + +// ─── TYPES ──────────────────────────────────────────────────────────────────── + +export interface Message { + id: string; + role: "user" | "assistant" | "system"; + content: string; + createdAt: string; +} + +export interface Conversation { + id: string; + title: string; + messages: Message[]; + createdAt: string; + updatedAt: string; +} + +// ─── FIXTURES ───────────────────────────────────────────────────────────────── + +export const fixtures = { + messages: { + single: (): Message[] => [ + { + id: "msg-1", + role: "user", + content: "Hello, can you help me with my design system?", + createdAt: new Date("2026-03-15T10:00:00Z").toISOString(), + }, + ], + + conversation: (): Message[] => [ + { + id: "msg-1", + role: "user", + content: "Hello, can you help me with my design system?", + createdAt: new Date("2026-03-15T10:00:00Z").toISOString(), + }, + { + id: "msg-2", + role: "assistant", + content: + "Of course! I can help you build a robust design system. What aspect would you like to focus on — tokens, components, or documentation?", + createdAt: new Date("2026-03-15T10:00:05Z").toISOString(), + }, + { + id: "msg-3", + role: "user", + content: "Let's start with component stories and interaction testing.", + createdAt: new Date("2026-03-15T10:00:30Z").toISOString(), + }, + ], + + long: (): Message[] => + Array.from({ length: 20 }, (_, i) => ({ + id: `msg-${i + 1}`, + role: i % 2 === 0 ? ("user" as const) : ("assistant" as const), + content: i % 2 === 0 ? `User message ${i + 1}` : `Assistant response ${i + 1}`, + createdAt: new Date(Date.now() - (20 - i) * 30000).toISOString(), + })), + }, +}; + +// ─── HANDLERS ───────────────────────────────────────────────────────────────── + +export const handlers = { + /** GET /api/messages → 200 with realistic conversation data */ + messages: { + success: http.get("/api/messages", () => HttpResponse.json(fixtures.messages.conversation())), + + /** GET /api/messages → 200 with empty array (no messages yet) */ + empty: http.get("/api/messages", () => HttpResponse.json([] as Message[])), + + /** GET /api/messages → delays 2s to test loading states */ + loading: http.get("/api/messages", async () => { + await new Promise((r) => setTimeout(r, 2000)); + return HttpResponse.json(fixtures.messages.conversation()); + }), + + /** GET /api/messages → 500 server error */ + error: http.get( + "/api/messages", + () => new HttpResponse(null, { status: 500, statusText: "Internal Server Error" }), + ), + + /** GET /api/messages → 401 unauthorised */ + unauthorized: http.get( + "/api/messages", + () => new HttpResponse(null, { status: 401, statusText: "Unauthorised" }), + ), + }, + + /** POST /api/messages → 201 with new message */ + sendMessage: { + success: http.post("/api/messages", async ({ request }) => { + const body = (await request.json()) as { content: string }; + const newMessage: Message = { + id: `msg-${Date.now()}`, + role: "user", + content: body.content, + createdAt: new Date().toISOString(), + }; + return HttpResponse.json(newMessage, { status: 201 }); + }), + + /** POST /api/messages → 429 rate limited */ + rateLimited: http.post( + "/api/messages", + () => + new HttpResponse(null, { + status: 429, + statusText: "Too Many Requests", + headers: { "Retry-After": "60" }, + }), + ), + }, + + /** SSE /api/stream → streaming token response */ + stream: { + success: http.get("/api/stream", () => { + const tokens = ["Hello", " from", " the", " design", " system", "!"]; + const encoder = new TextEncoder(); + const stream = new ReadableStream({ + async start(controller) { + for (const token of tokens) { + await new Promise((r) => setTimeout(r, 100)); + controller.enqueue(encoder.encode(`data: ${JSON.stringify({ token })}\n\n`)); + } + controller.enqueue(encoder.encode("data: [DONE]\n\n")); + controller.close(); + }, + }); + return new HttpResponse(stream, { + headers: { + "Content-Type": "text/event-stream", + "Cache-Control": "no-cache", + }, + }); + }), + }, + + /** GET /api/settings → user settings */ + settings: { + success: http.get("/api/settings", () => + HttpResponse.json({ + theme: "dark", + language: "en", + notifications: true, + model: "gpt-5.4", + }), + ), + }, +}; + +// ─── PRESET COLLECTIONS ─────────────────────────────────────────────────────── +// Use these in `parameters.msw.handlers` for common scenario compositions. + +/** All happy-path handlers — for "default" stories */ +export const happyPathHandlers = [ + handlers.messages.success, + handlers.sendMessage.success, + handlers.settings.success, +]; + +/** Simulate a new user with no messages */ +export const emptyStateHandlers = [ + handlers.messages.empty, + handlers.sendMessage.success, + handlers.settings.success, +]; + +/** Simulate slow network */ +export const slowNetworkHandlers = [handlers.messages.loading, handlers.settings.success]; + +/** Simulate a network failure */ +export const errorHandlers = [handlers.messages.error]; diff --git a/platforms/web/apps/storybook/.storybook/preview.tsx b/platforms/web/apps/storybook/.storybook/preview.tsx index 64030320..d4b1f801 100644 --- a/platforms/web/apps/storybook/.storybook/preview.tsx +++ b/platforms/web/apps/storybook/.storybook/preview.tsx @@ -22,17 +22,21 @@ let DialRootComponent: React.ComponentType | null = null; if (import.meta.env.DEV) { // eslint-disable-next-line no-console - import("agentation").then((mod) => { - AgentationComponent = mod.Agentation; - }).catch(() => { - // agentation unavailable — annotations simply won't appear - }); - - import("dialkit").then((mod) => { - DialRootComponent = mod.DialRoot; - }).catch(() => { - // dialkit unavailable - }); + import("agentation") + .then((mod) => { + AgentationComponent = mod.Agentation; + }) + .catch(() => { + // agentation unavailable — annotations simply won't appear + }); + + import("dialkit") + .then((mod) => { + DialRootComponent = mod.DialRoot; + }) + .catch(() => { + // dialkit unavailable + }); } const host = createMockHost(); @@ -222,7 +226,8 @@ const preview: Preview = { data-theme={theme} data-high-contrast={isHighContrast ? "" : undefined} style={{ - backgroundColor: resolvedBackground || + backgroundColor: + resolvedBackground || (isLight ? "var(--foundation-bg-light-1)" : "var(--foundation-bg-dark-1)"), color: isLight ? "var(--foundation-text-light-primary)" @@ -239,9 +244,7 @@ const preview: Preview = { {import.meta.env.DEV && AgentationComponent && ( )} - {import.meta.env.DEV && DialRootComponent && ( - - )} + {import.meta.env.DEV && DialRootComponent && } ); diff --git a/platforms/web/apps/storybook/package.json b/platforms/web/apps/storybook/package.json index c5485573..5a2a3909 100644 --- a/platforms/web/apps/storybook/package.json +++ b/platforms/web/apps/storybook/package.json @@ -51,4 +51,4 @@ "public" ] } -} \ No newline at end of file +} diff --git a/platforms/web/apps/storybook/public/mockServiceWorker.js b/platforms/web/apps/storybook/public/mockServiceWorker.js new file mode 100644 index 00000000..ed24b8e4 --- /dev/null +++ b/platforms/web/apps/storybook/public/mockServiceWorker.js @@ -0,0 +1,336 @@ +/* eslint-disable */ +/* tslint:disable */ + +/** + * Mock Service Worker. + * @see https://github.com/mswjs/msw + * - Please do NOT modify this file. + */ + +const PACKAGE_VERSION = "2.12.10"; +const INTEGRITY_CHECKSUM = "4db4a41e972cec1b64cc569c66952d82"; +const IS_MOCKED_RESPONSE = Symbol("isMockedResponse"); +const activeClientIds = new Set(); + +addEventListener("install", () => { + self.skipWaiting(); +}); + +addEventListener("activate", (event) => { + event.waitUntil(self.clients.claim()); +}); + +addEventListener("message", async (event) => { + const clientId = Reflect.get(event.source || {}, "id"); + + if (!clientId || !self.clients) { + return; + } + + const client = await self.clients.get(clientId); + + if (!client) { + return; + } + + const allClients = await self.clients.matchAll({ + type: "window", + }); + + switch (event.data) { + case "KEEPALIVE_REQUEST": { + sendToClient(client, { + type: "KEEPALIVE_RESPONSE", + }); + break; + } + + case "INTEGRITY_CHECK_REQUEST": { + sendToClient(client, { + type: "INTEGRITY_CHECK_RESPONSE", + payload: { + packageVersion: PACKAGE_VERSION, + checksum: INTEGRITY_CHECKSUM, + }, + }); + break; + } + + case "MOCK_ACTIVATE": { + activeClientIds.add(clientId); + + sendToClient(client, { + type: "MOCKING_ENABLED", + payload: { + client: { + id: client.id, + frameType: client.frameType, + }, + }, + }); + break; + } + + case "CLIENT_CLOSED": { + activeClientIds.delete(clientId); + + const remainingClients = allClients.filter((client) => { + return client.id !== clientId; + }); + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister(); + } + + break; + } + } +}); + +addEventListener("fetch", (event) => { + const requestInterceptedAt = Date.now(); + + // Bypass navigation requests. + if (event.request.mode === "navigate") { + return; + } + + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if (event.request.cache === "only-if-cached" && event.request.mode !== "same-origin") { + return; + } + + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been terminated (still remains active until the next reload). + if (activeClientIds.size === 0) { + return; + } + + const requestId = crypto.randomUUID(); + event.respondWith(handleRequest(event, requestId, requestInterceptedAt)); +}); + +/** + * @param {FetchEvent} event + * @param {string} requestId + * @param {number} requestInterceptedAt + */ +async function handleRequest(event, requestId, requestInterceptedAt) { + const client = await resolveMainClient(event); + const requestCloneForEvents = event.request.clone(); + const response = await getResponse(event, client, requestId, requestInterceptedAt); + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + const serializedRequest = await serializeRequest(requestCloneForEvents); + + // Clone the response so both the client and the library could consume it. + const responseClone = response.clone(); + + sendToClient( + client, + { + type: "RESPONSE", + payload: { + isMockedResponse: IS_MOCKED_RESPONSE in response, + request: { + id: requestId, + ...serializedRequest, + }, + response: { + type: responseClone.type, + status: responseClone.status, + statusText: responseClone.statusText, + headers: Object.fromEntries(responseClone.headers.entries()), + body: responseClone.body, + }, + }, + }, + responseClone.body ? [serializedRequest.body, responseClone.body] : [], + ); + } + + return response; +} + +/** + * Resolve the main client for the given event. + * Client that issues a request doesn't necessarily equal the client + * that registered the worker. It's with the latter the worker should + * communicate with during the response resolving phase. + * @param {FetchEvent} event + * @returns {Promise} + */ +async function resolveMainClient(event) { + const client = await self.clients.get(event.clientId); + + if (activeClientIds.has(event.clientId)) { + return client; + } + + if (client?.frameType === "top-level") { + return client; + } + + const allClients = await self.clients.matchAll({ + type: "window", + }); + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === "visible"; + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id); + }); +} + +/** + * @param {FetchEvent} event + * @param {Client | undefined} client + * @param {string} requestId + * @param {number} requestInterceptedAt + * @returns {Promise} + */ +async function getResponse(event, client, requestId, requestInterceptedAt) { + // Clone the request because it might've been already used + // (i.e. its body has been read and sent to the client). + const requestClone = event.request.clone(); + + function passthrough() { + // Cast the request headers to a new Headers instance + // so the headers can be manipulated with. + const headers = new Headers(requestClone.headers); + + // Remove the "accept" header value that marked this request as passthrough. + // This prevents request alteration and also keeps it compliant with the + // user-defined CORS policies. + const acceptHeader = headers.get("accept"); + if (acceptHeader) { + const values = acceptHeader.split(",").map((value) => value.trim()); + const filteredValues = values.filter((value) => value !== "msw/passthrough"); + + if (filteredValues.length > 0) { + headers.set("accept", filteredValues.join(", ")); + } else { + headers.delete("accept"); + } + } + + return fetch(requestClone, { headers }); + } + + // Bypass mocking when the client is not active. + if (!client) { + return passthrough(); + } + + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return passthrough(); + } + + // Notify the client that a request has been intercepted. + const serializedRequest = await serializeRequest(event.request); + const clientMessage = await sendToClient( + client, + { + type: "REQUEST", + payload: { + id: requestId, + interceptedAt: requestInterceptedAt, + ...serializedRequest, + }, + }, + [serializedRequest.body], + ); + + switch (clientMessage.type) { + case "MOCK_RESPONSE": { + return respondWithMock(clientMessage.data); + } + + case "PASSTHROUGH": { + return passthrough(); + } + } + + return passthrough(); +} + +/** + * @param {Client} client + * @param {any} message + * @param {Array} transferrables + * @returns {Promise} + */ +function sendToClient(client, message, transferrables = []) { + return new Promise((resolve, reject) => { + const channel = new MessageChannel(); + + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error); + } + + resolve(event.data); + }; + + client.postMessage(message, [channel.port2, ...transferrables.filter(Boolean)]); + }); +} + +/** + * @param {Response} response + * @returns {Response} + */ +function respondWithMock(response) { + // Setting response status code to 0 is a no-op. + // However, when responding with a "Response.error()", the produced Response + // instance will have status code set to 0. Since it's not possible to create + // a Response instance with status code 0, handle that use-case separately. + if (response.status === 0) { + return Response.error(); + } + + const mockedResponse = new Response(response.body, response); + + Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { + value: true, + enumerable: true, + }); + + return mockedResponse; +} + +/** + * @param {Request} request + */ +async function serializeRequest(request) { + return { + url: request.url, + mode: request.mode, + method: request.method, + headers: Object.fromEntries(request.headers.entries()), + cache: request.cache, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body: await request.arrayBuffer(), + keepalive: request.keepalive, + }; +} diff --git a/platforms/web/apps/storybook/scripts/a11y-summary.mjs b/platforms/web/apps/storybook/scripts/a11y-summary.mjs new file mode 100644 index 00000000..9874742b --- /dev/null +++ b/platforms/web/apps/storybook/scripts/a11y-summary.mjs @@ -0,0 +1,76 @@ +#!/usr/bin/env node +/** + * a11y-summary.mjs + * + * Pretty-prints the aggregate a11y report generated by test-runner.ts. + * Useful for CI step summaries and local debugging. + * + * Usage: + * node platforms/web/apps/storybook/scripts/a11y-summary.mjs [report-path] + * + * Defaults to: platforms/web/apps/storybook/reports/a11y-report.json + */ + +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const defaultReport = path.resolve(__dirname, "../reports/a11y-report.json"); +const reportPath = process.argv[2] ?? defaultReport; + +if (!fs.existsSync(reportPath)) { + console.error(`No a11y report found at ${reportPath}`); + console.error("Run pnpm storybook:test first to generate the report."); + process.exit(1); +} + +const report = JSON.parse(fs.readFileSync(reportPath, "utf-8")); +const { summary, stories, timestamp } = report; + +const bar = (pct) => { + const filled = Math.round(pct / 5); + return `[${"█".repeat(filled)}${"░".repeat(20 - filled)}] ${pct}%`; +}; + +console.log("\n━━━ Accessibility Report ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"); +console.log(` Generated : ${new Date(timestamp).toLocaleString()}`); +console.log(` Stories : ${summary.total}`); +console.log(` Passing : ${summary.passing} ✅`); +console.log(` Failing : ${summary.failing} ❌`); +console.log(` Pass rate : ${bar(summary.passRate)}`); +console.log(); + +const failing = stories.filter((s) => s.status === "fail"); +if (failing.length > 0) { + console.log(` ❌ Failing stories (${failing.length}):`); + for (const s of failing) { + console.log(` ${s.story} (${s.violations} violation${s.violations !== 1 ? "s" : ""})`); + } + console.log(); +} + +console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"); + +// Write GitHub Actions step summary if running in CI +if (process.env.GITHUB_STEP_SUMMARY) { + const rows = failing.map((s) => `| ❌ | ${s.story} | ${s.violations} |`).join("\n"); + + const md = [ + "## ♿ Accessibility Report", + "", + `| | |`, + `|---|---|`, + `| **Stories tested** | ${summary.total} |`, + `| **Passing** | ${summary.passing} |`, + `| **Failing** | ${summary.failing} |`, + `| **Pass rate** | ${summary.passRate}% |`, + "", + failing.length > 0 + ? `### Failing Stories\n| Status | Story | Violations |\n|---|---|---|\n${rows}` + : "### ✅ All stories pass accessibility checks", + ].join("\n"); + + fs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, md + "\n"); + console.log("Step summary written to GITHUB_STEP_SUMMARY."); +} diff --git a/platforms/web/apps/storybook/scripts/interaction-coverage-gate.mjs b/platforms/web/apps/storybook/scripts/interaction-coverage-gate.mjs new file mode 100644 index 00000000..c5fba185 --- /dev/null +++ b/platforms/web/apps/storybook/scripts/interaction-coverage-gate.mjs @@ -0,0 +1,99 @@ +#!/usr/bin/env node +/** + * interaction-coverage-gate.mjs + * + * Reports what % of component story *files* contain at least one play() function + * (i.e. an interaction test). Warns below 40%, hard-fails below 10%. + * + * Usage: + * node platforms/web/apps/storybook/scripts/interaction-coverage-gate.mjs + * + * Add to CI: + * run: node platforms/web/apps/storybook/scripts/interaction-coverage-gate.mjs + */ + +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const repoRoot = path.resolve(__dirname, "../../../../.."); + +// Only check component stories, not doc/design-system stories +const COMPONENT_ROOTS = [ + "packages/ui/src/app/chat", + "packages/ui/src/app/settings", + "packages/ui/src/app/modals", + "packages/ui/src/components/ui/base", + "packages/ui/src/components/ui/forms", + "packages/ui/src/components/ui/navigation", + "packages/ui/src/components/ui/overlays", + "packages/ui/src/components/ui/feedback", + "packages/ui/src/components/ui/data-display", + "packages/ui/src/components/ui/chat", + "packages/ui/src/templates", + "packages/effects/stories", +]; + +const WARN_THRESHOLD = 40; // % — yellow +const FAIL_THRESHOLD = 10; // % — red (hard fail) + +function findStoryFiles(dir) { + const results = []; + if (!fs.existsSync(dir)) return results; + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + const full = path.join(dir, entry.name); + if (entry.isDirectory()) { + results.push(...findStoryFiles(full)); + } else if (entry.isFile() && entry.name.endsWith(".stories.tsx")) { + results.push(full); + } + } + return results; +} + +function hasPlayFunction(content) { + // Match `play:` as a story property (not inside a comment or string) + return /^\s+play\s*:/m.test(content) || /,\s*play\s*:/s.test(content); +} + +const storyFiles = COMPONENT_ROOTS.flatMap((rel) => findStoryFiles(path.join(repoRoot, rel))); + +let covered = 0; +const missing = []; + +for (const file of storyFiles) { + const content = fs.readFileSync(file, "utf-8"); + const rel = path.relative(repoRoot, file); + if (hasPlayFunction(content)) { + covered++; + } else { + missing.push(rel); + } +} + +const total = storyFiles.length; +const pct = total > 0 ? Math.round((covered / total) * 100) : 0; + +const icon = pct >= WARN_THRESHOLD ? "✅" : pct >= FAIL_THRESHOLD ? "⚠️" : "❌"; +console.log( + `\nInteraction coverage: ${icon} ${covered}/${total} story files have play() functions (${pct}%)`, +); + +if (missing.length > 0 && pct < WARN_THRESHOLD) { + console.log(`\nFiles without interaction tests (${missing.length}):`); + missing.slice(0, 20).forEach((f) => console.log(` ${f}`)); + if (missing.length > 20) console.log(` ... and ${missing.length - 20} more`); +} + +console.log(`\nThresholds: warn=${WARN_THRESHOLD}% fail=${FAIL_THRESHOLD}%`); + +if (pct < FAIL_THRESHOLD) { + console.error(`\n❌ Interaction coverage critically low (${pct}% < ${FAIL_THRESHOLD}%).`); + console.error(` Add play() functions to component stories to cover user interactions.`); + process.exit(1); +} else if (pct < WARN_THRESHOLD) { + console.warn(`\n⚠️ Interaction coverage below target (${pct}% < ${WARN_THRESHOLD}%).`); + console.warn(` Consider adding play() functions to the files listed above.`); + // Warning only — does not fail CI +} diff --git a/platforms/web/apps/storybook/scripts/story-naming-lint.mjs b/platforms/web/apps/storybook/scripts/story-naming-lint.mjs new file mode 100644 index 00000000..3bc49853 --- /dev/null +++ b/platforms/web/apps/storybook/scripts/story-naming-lint.mjs @@ -0,0 +1,97 @@ +#!/usr/bin/env node +/** + * story-naming-lint.mjs + * + * Enforces naming conventions for component stories: + * + * Stories with a play() function must NOT use a generic visual-state name like + * "Default", "Primary", or "Basic". Interaction stories should describe the + * behaviour under test — e.g. "KeyboardNavigation", "ClickInteraction". + * + * Usage: + * node platforms/web/apps/storybook/scripts/story-naming-lint.mjs + * + * Exit codes: 0 = no violations, 1 = violations found + */ + +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const repoRoot = path.resolve(__dirname, "../../../../.."); + +const COMPONENT_ROOTS = [ + "packages/ui/src/app/chat", + "packages/ui/src/app/settings", + "packages/ui/src/app/modals", + "packages/ui/src/components/ui/base", + "packages/ui/src/components/ui/forms", + "packages/ui/src/components/ui/navigation", + "packages/ui/src/components/ui/overlays", + "packages/ui/src/components/ui/feedback", + "packages/ui/src/components/ui/data-display", + "packages/ui/src/components/ui/chat", + "packages/ui/src/templates", + "packages/effects/stories", +]; + +// Generic visual-state names — fine for static stories, wrong for interaction tests +const GENERIC_NAMES = new Set(["Default", "Primary", "Secondary", "Basic", "Simple", "Example"]); + +function findStoryFiles(dir) { + const results = []; + if (!fs.existsSync(dir)) return results; + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + const full = path.join(dir, entry.name); + if (entry.isDirectory()) { + results.push(...findStoryFiles(full)); + } else if (entry.isFile() && entry.name.endsWith(".stories.tsx")) { + results.push(full); + } + } + return results; +} + +/** + * Extract story export names and whether they contain a play() function. + * Uses matchAll (no .exec()) so the security hook doesn't false-positive. + */ +function parseStories(content) { + // CSF3 pattern: export const : StoryObj... = { ... } + const exportPattern = + /export const (\w+)\s*(?::\s*StoryObj[^=]*|:\s*Story[^=]*)?\s*=\s*\{([^}]*(?:\{[^}]*\}[^}]*)*)\}/gs; + return [...content.matchAll(exportPattern)] + .filter(([, name]) => name !== "meta" && name !== "default") + .map(([, name, body]) => ({ name, hasPlay: /\bplay\s*:/.test(body) })); +} + +const storyFiles = COMPONENT_ROOTS.flatMap((rel) => findStoryFiles(path.join(repoRoot, rel))); +const violations = []; + +for (const file of storyFiles) { + const content = fs.readFileSync(file, "utf-8"); + const rel = path.relative(repoRoot, file); + + for (const { name, hasPlay } of parseStories(content)) { + if (hasPlay && GENERIC_NAMES.has(name)) { + violations.push({ + file: rel, + story: name, + message: `"${name}" has a play() but a generic visual-state name. Rename to describe the behaviour, e.g. "KeyboardNavigation" or "ClickInteraction".`, + }); + } + } +} + +if (violations.length === 0) { + console.log("✅ Story naming: no violations found."); + process.exit(0); +} + +console.error(`\n❌ Story naming lint: ${violations.length} violation(s)\n`); +for (const v of violations) { + console.error(` ${v.file}`); + console.error(` ${v.message}\n`); +} +process.exit(1); diff --git a/platforms/web/apps/storybook/tests/portable-stories.test.tsx b/platforms/web/apps/storybook/tests/portable-stories.test.tsx new file mode 100644 index 00000000..a056440f --- /dev/null +++ b/platforms/web/apps/storybook/tests/portable-stories.test.tsx @@ -0,0 +1,57 @@ +/** + * Portable Stories — compose and run stories in plain Vitest outside Storybook UI. + * + * Why: lets you assert story behaviour in CI without a running Storybook server, + * and catches regressions that only surface when stories are rendered in isolation + * (missing providers, wrong default args, etc.). + * + * Pattern: `composeStories` wraps each story with its meta decorators and args + * so the rendered output is identical to what Storybook shows. + */ + +import { composeStories } from "@storybook/react"; +import { render, screen } from "@testing-library/react"; +import { describe, expect, it } from "vitest"; + +import * as MagneticButtonStories from "../../../../packages/effects/stories/button.stories"; +import * as HoloCardStories from "../../../../packages/effects/stories/card.stories"; + +// ─── MagneticButton ─────────────────────────────────────────────────────────── + +const { Default: MagneticDefault, NoMagnetic, Variants } = composeStories(MagneticButtonStories); + +describe("MagneticButton portable stories", () => { + it("Default renders a button", () => { + render(); + expect(screen.getByRole("button")).toBeInTheDocument(); + }); + + it("NoMagnetic renders with disableMagnetic prop", () => { + render(); + const button = screen.getByRole("button"); + expect(button).toBeInTheDocument(); + expect(button).toBeEnabled(); + }); + + it("Variants renders all four variant buttons", () => { + render(); + const buttons = screen.getAllByRole("button"); + expect(buttons).toHaveLength(4); + }); +}); + +// ─── HoloCard ───────────────────────────────────────────────────────────────── + +const { Default: HoloDefault, NonClickableCard } = composeStories(HoloCardStories); + +describe("HoloCard portable stories", () => { + it("Default renders card content", () => { + render(); + expect(screen.getByText(/holographic card/i)).toBeInTheDocument(); + }); + + it("NonClickableCard has no button role", () => { + render(); + expect(screen.queryByRole("button")).toBeNull(); + }); +}); diff --git a/scripts/check-token-drift.mjs b/scripts/check-token-drift.mjs index ba43a663..f860cc07 100644 --- a/scripts/check-token-drift.mjs +++ b/scripts/check-token-drift.mjs @@ -23,9 +23,7 @@ const repoRoot = path.resolve(__dirname, ".."); // ─── CONFIG ─────────────────────────────────────────────────────────────────── -const TOKEN_DIST_DIRS = [ - path.join(repoRoot, "packages/tokens/dist"), -]; +const TOKEN_DIST_DIRS = [path.join(repoRoot, "packages/tokens/dist")]; const UI_SRC_DIRS = [ path.join(repoRoot, "packages/ui/src"), @@ -39,12 +37,11 @@ const TOKEN_CONSUMPTION_PATTERN = /var\(\s*(--[\w-]+)/g; // CSS vars that are allowed to be consumed without being in tokens/dist // (browser built-ins, third-party overrides, etc.) const ALLOWLIST = new Set([ - "--sb-", // Storybook internals (prefix match below) - "--radix-", // Radix UI internals + "--sb-", // Storybook internals (prefix match below) + "--radix-", // Radix UI internals ]); -const isAllowlisted = (varName) => - [...ALLOWLIST].some((prefix) => varName.startsWith(prefix)); +const isAllowlisted = (varName) => [...ALLOWLIST].some((prefix) => varName.startsWith(prefix)); // ─── HELPERS ────────────────────────────────────────────────────────────────── @@ -147,7 +144,9 @@ if (jsonOutput) { if (driftEntries.length === 0) { console.log(`\n✅ No drift — all consumed CSS vars are declared in tokens.\n`); } else { - console.log(`\n❌ Drift detected — ${driftEntries.length} consumed var(s) not in tokens output:\n`); + console.log( + `\n❌ Drift detected — ${driftEntries.length} consumed var(s) not in tokens output:\n`, + ); for (const { varName, files } of driftEntries) { console.log(` ${varName}`); for (const f of files.slice(0, 3)) { From eea4db6c50d16a9fe516a7e8180eb1d74a4e9653 Mon Sep 17 00:00:00 2001 From: Jamie Scott Craik Date: Tue, 17 Mar 2026 17:02:28 -0600 Subject: [PATCH 2/3] fix: update pnpm lockfile for validation-prototype deps Co-Authored-By: Claude Sonnet 4.6 --- pnpm-lock.yaml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4a5ae5f0..57b5011e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -608,6 +608,31 @@ importers: specifier: 1.0.0-pre.3 version: 1.0.0-pre.3(vitest@4.0.18) + packages/validation-prototype: + dependencies: + react: + specifier: 19.2.3 + version: 19.2.3 + react-dom: + specifier: 19.2.3 + version: 19.2.3(react@19.2.3) + devDependencies: + '@types/react': + specifier: 19.2.7 + version: 19.2.7 + '@types/react-dom': + specifier: 19.2.3 + version: 19.2.3(@types/react@19.2.7) + '@vitejs/plugin-react': + specifier: ^5.1.3 + version: 5.1.3(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + typescript: + specifier: ^5.7.0 + version: 5.9.3 + vite: + specifier: ^7.3.1 + version: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + packages/widgets: dependencies: '@design-studio/json-render': From a263c42997d08cfb7719fb68b4621f8d1b4f3a13 Mon Sep 17 00:00:00 2001 From: Jamie Scott Craik Date: Tue, 17 Mar 2026 19:11:15 -0600 Subject: [PATCH 3/3] fix(ui): exclude _holding storybook pages from typecheck The _holding directory contains placeholder pages importing @design-studio/ui (self-reference) which TypeScript cannot resolve in package-local builds. Exclude it from the typecheck scope to fix TS2307 CI failures without adding a self-reference path alias (which caused secondary TS6307 errors from transitive tokens sources). Co-Authored-By: Claude Sonnet 4.6 --- packages/ui/tsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json index 4fff2aa7..5acf55b8 100644 --- a/packages/ui/tsconfig.json +++ b/packages/ui/tsconfig.json @@ -17,6 +17,7 @@ "**/*.figmaConnect.*", "src/testing/**", "src/dev/**", - "src/dev.ts" + "src/dev.ts", + "src/storybook/_holding/**" ] }