diff --git a/console/.storybook/main.ts b/console/.storybook/main.ts new file mode 100644 index 00000000..1287476b --- /dev/null +++ b/console/.storybook/main.ts @@ -0,0 +1,28 @@ +import type { StorybookConfig } from "@storybook/react-vite" +import { mergeConfig } from "vite" +import tailwindcss from "@tailwindcss/vite" +import path from "path" +import { fileURLToPath } from "url" + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) + +const config: StorybookConfig = { + stories: ["../src/components/**/*.stories.@(ts|tsx)"], + addons: [ + "@chromatic-com/storybook", + "@storybook/addon-a11y", + "@storybook/addon-docs", + "@storybook/addon-onboarding", + ], + framework: "@storybook/react-vite", + viteFinal: async (config) => { + return mergeConfig(config, { + plugins: [tailwindcss()], + resolve: { + alias: { "@": path.resolve(__dirname, "../src") }, + }, + }) + }, +} + +export default config diff --git a/console/.storybook/preview.ts b/console/.storybook/preview.ts new file mode 100644 index 00000000..f3d08525 --- /dev/null +++ b/console/.storybook/preview.ts @@ -0,0 +1,32 @@ +import "../src/index.css" +import type { Preview } from "@storybook/react-vite" + +const preview: Preview = { + parameters: { + // Controls: smart matchers for color/date fields + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + + // Docs: enable autodocs globally (stories already tagged with "autodocs") + docs: {}, + + // A11y: report violations in the panel without failing CI + a11y: { + test: "todo", + }, + + backgrounds: { + default: "light", + values: [ + { name: "light", value: "oklch(1 0 0)" }, + { name: "dark", value: "oklch(0.145 0 0)" }, + ], + }, + }, +} + +export default preview diff --git a/console/eslint.config.js b/console/eslint.config.js index 75aa3bf9..500cf9ec 100644 --- a/console/eslint.config.js +++ b/console/eslint.config.js @@ -1,54 +1,54 @@ -import js from "@eslint/js" -import globals from "globals" -import reactHooks from "eslint-plugin-react-hooks" -import reactRefresh from "eslint-plugin-react-refresh" -import prettier from "eslint-plugin-prettier" -import prettierConfig from "eslint-config-prettier" -import tseslint from "typescript-eslint" -import { defineConfig, globalIgnores } from "eslint/config" - -export default defineConfig([ - globalIgnores(["dist", "src/oapi/management.generated.ts"]), - { - files: ["**/*.{ts,tsx}"], - extends: [ - js.configs.recommended, - tseslint.configs.recommended, - reactHooks.configs.flat.recommended, - reactRefresh.configs.vite, - prettierConfig, - ], - plugins: { - prettier, - }, - rules: { - "prettier/prettier": "warn", - "@typescript-eslint/consistent-type-imports": [ - "error", - { - prefer: "type-imports", - fixStyle: "separate-type-imports", - }, - ], - - // 🧘 Relax noisy TS rules during migration - "@typescript-eslint/no-explicit-any": "warn", - "@typescript-eslint/no-empty-object-type": "off", - "@typescript-eslint/no-unsafe-function-type": "off", - "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }], - "react/react-in-jsx-scope": "off", - "react/prop-types": "off", - - // Disable React 19 compiler preflight rules (React 18 doesn’t use them) - "react-hooks/immutability": "off", - "react-hooks/refs": "off", - "react-hooks/set-state-in-effect": "off", - "react-hooks/preserve-manual-memoization": "off", - }, - languageOptions: { - ecmaVersion: 2020, - globals: globals.browser, - }, - }, -]) +// For more info, see https://github.com/storybookjs/eslint-plugin-storybook#configuration-flat-config-format +import storybook from "eslint-plugin-storybook"; + +import js from "@eslint/js" +import globals from "globals" +import reactHooks from "eslint-plugin-react-hooks" +import reactRefresh from "eslint-plugin-react-refresh" +import prettier from "eslint-plugin-prettier" +import prettierConfig from "eslint-config-prettier" +import tseslint from "typescript-eslint" +import { defineConfig, globalIgnores } from "eslint/config" + +export default defineConfig([globalIgnores(["dist", "src/oapi/management.generated.ts"]), { + files: ["**/*.{ts,tsx}"], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs.flat.recommended, + reactRefresh.configs.vite, + prettierConfig, + ], + plugins: { + prettier, + }, + rules: { + "prettier/prettier": "warn", + "@typescript-eslint/consistent-type-imports": [ + "error", + { + prefer: "type-imports", + fixStyle: "separate-type-imports", + }, + ], + + // 🧘 Relax noisy TS rules during migration + "@typescript-eslint/no-explicit-any": "warn", + "@typescript-eslint/no-empty-object-type": "off", + "@typescript-eslint/no-unsafe-function-type": "off", + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }], + "react/react-in-jsx-scope": "off", + "react/prop-types": "off", + + // Disable React 19 compiler preflight rules (React 18 doesn’t use them) + "react-hooks/immutability": "off", + "react-hooks/refs": "off", + "react-hooks/set-state-in-effect": "off", + "react-hooks/preserve-manual-memoization": "off", + }, + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, +}, ...storybook.configs["flat/recommended"]]) diff --git a/console/package.json b/console/package.json index 632b7b2f..0c519536 100644 --- a/console/package.json +++ b/console/package.json @@ -119,7 +119,9 @@ "lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"", "analyze:bundle": "pnpm build && npx source-map-explorer './dist/assets/*.js'", "generate": "pnpm run /^generate:/", - "generate:oapi": "openapi-typescript ../internal/http/controllers/v1/management/oapi/resources.yml -o ./src/oapi/management.generated.ts" + "generate:oapi": "openapi-typescript ../internal/http/controllers/v1/management/oapi/resources.yml -o ./src/oapi/management.generated.ts", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build" }, "types": "./lib/cjs/mod.d.ts", "main": "./lib/cjs/mod.js", @@ -168,7 +170,18 @@ "typescript": "^5.9.3", "typescript-eslint": "^8.54.0", "vite": "^7.3.1", - "vitest": "^4.0.18" + "vitest": "^4.0.18", + "storybook": "^10.3.4", + "@storybook/react-vite": "^10.3.4", + "@chromatic-com/storybook": "^5.1.1", + "@storybook/addon-vitest": "^10.3.4", + "@storybook/addon-a11y": "^10.3.4", + "@storybook/addon-docs": "^10.3.4", + "@storybook/addon-onboarding": "^10.3.4", + "eslint-plugin-storybook": "^10.3.4", + "playwright": "^1.59.1", + "@vitest/browser-playwright": "4.0.18", + "@vitest/coverage-v8": "4.0.18" }, "files": [ "lib" diff --git a/console/pnpm-lock.yaml b/console/pnpm-lock.yaml index 7f6141e5..24873dc3 100644 --- a/console/pnpm-lock.yaml +++ b/console/pnpm-lock.yaml @@ -321,6 +321,9 @@ importers: specifier: ^4.3.6 version: 4.3.6 devDependencies: + '@chromatic-com/storybook': + specifier: ^5.1.1 + version: 5.1.1(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@eslint/eslintrc': specifier: ^3 version: 3.3.3 @@ -330,6 +333,21 @@ importers: '@react-router/dev': specifier: ^7.13.0 version: 7.13.0(@react-router/serve@7.13.0(react-router@7.13.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3))(@types/node@22.19.9)(babel-plugin-macros@3.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(react-router@7.13.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(terser@5.46.0)(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)) + '@storybook/addon-a11y': + specifier: ^10.3.4 + version: 10.3.4(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@storybook/addon-docs': + specifier: ^10.3.4 + version: 10.3.4(@types/react@19.2.10)(esbuild@0.27.2)(rollup@4.57.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)) + '@storybook/addon-onboarding': + specifier: ^10.3.4 + version: 10.3.4(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@storybook/addon-vitest': + specifier: ^10.3.4 + version: 10.3.4(@vitest/browser-playwright@4.0.18)(@vitest/browser@4.0.18(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))(vitest@4.0.18))(@vitest/runner@4.0.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vitest@4.0.18) + '@storybook/react-vite': + specifier: ^10.3.4 + version: 10.3.4(esbuild@0.27.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.57.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)) '@testing-library/jest-dom': specifier: ^5.17.0 version: 5.17.0 @@ -366,6 +384,12 @@ importers: '@vitejs/plugin-react': specifier: ^5.1.3 version: 5.1.3(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)) + '@vitest/browser-playwright': + specifier: 4.0.18 + version: 4.0.18(playwright@1.59.1)(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))(vitest@4.0.18) + '@vitest/coverage-v8': + specifier: 4.0.18 + version: 4.0.18(@vitest/browser@4.0.18(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))(vitest@4.0.18))(vitest@4.0.18) copyfiles: specifier: ^2.4.1 version: 2.4.1 @@ -384,6 +408,9 @@ importers: eslint-plugin-react-refresh: specifier: ^0.5.0 version: 0.5.0(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-storybook: + specifier: ^10.3.4 + version: 10.3.4(eslint@9.39.2(jiti@2.6.1))(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3) globals: specifier: ^17.3.0 version: 17.3.0 @@ -396,6 +423,9 @@ importers: openapi-typescript: specifier: ^7.10.1 version: 7.10.1(typescript@5.9.3) + playwright: + specifier: ^1.59.1 + version: 1.59.1 prettier: specifier: ^3.8.1 version: 3.8.1 @@ -405,6 +435,9 @@ importers: source-map-explorer: specifier: 2.5.3 version: 2.5.3 + storybook: + specifier: ^10.3.4 + version: 10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) typescript: specifier: ^5.9.3 version: 5.9.3 @@ -416,7 +449,7 @@ importers: version: 7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0) vitest: specifier: ^4.0.18 - version: 4.0.18(@types/node@22.19.9)(happy-dom@20.5.0)(jiti@2.6.1)(jsdom@28.0.0)(lightningcss@1.30.2)(terser@5.46.0) + version: 4.0.18(@types/node@22.19.9)(@vitest/browser-playwright@4.0.18)(happy-dom@20.5.0)(jiti@2.6.1)(jsdom@28.0.0)(lightningcss@1.30.2)(terser@5.46.0) packages: @@ -580,6 +613,16 @@ packages: resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + + '@chromatic-com/storybook@5.1.1': + resolution: {integrity: sha512-BPoAXHM71XgeCK2u0jKr9i8apeQMm/Z9IWGyndA2FMijfQG9m8ox45DdWh/pxFkK5ClhGgirv5QwMhFIeHmThg==} + engines: {node: '>=20.0.0', yarn: '>=1.22.18'} + peerDependencies: + storybook: ^0.0.0-0 || ^10.1.0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 || ^10.4.0-0 + '@clerk/clerk-react@5.60.0': resolution: {integrity: sha512-P88FncsJpq/3WZJhhlj+md8mYb35BIXpr462C/figwsBGHsinr8VuBQUMcMZZ/6M34C8ABfLTPa6PHVp6+3D5Q==} engines: {node: '>=18.17.0'} @@ -1012,6 +1055,15 @@ packages: resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==} engines: {node: 20 || >=22} + '@joshwooding/vite-plugin-react-docgen-typescript@0.7.0': + resolution: {integrity: sha512-qvsTEwEFefhdirGOPnu9Wp6ChfIwy2dBCRuETU3uE+4cC+PFoxMSiiEhxk4lOluA34eARHA0OxqsEUYDqRMgeQ==} + peerDependencies: + typescript: '>= 4.3.x' + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + typescript: + optional: true + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -1083,6 +1135,12 @@ packages: '@marijn/find-cluster-break@1.0.2': resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==} + '@mdx-js/react@3.1.1': + resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + '@microsoft/fetch-event-source@2.0.1': resolution: {integrity: sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==} @@ -1176,10 +1234,16 @@ packages: '@types/react': optional: true + '@neoconfetti/react@1.0.0': + resolution: {integrity: sha512-klcSooChXXOzIm+SE5IISIAn3bYzYfPjbX7D7HoqZL84oAfgREeSg5vSIaSFH+DaGzzvImTyWe1OyrJ67vik4A==} + '@pkgr/core@0.2.9': resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} @@ -1987,6 +2051,15 @@ packages: '@rolldown/pluginutils@1.0.0-rc.2': resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/rollup-android-arm-eabi@4.57.1': resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==} cpu: [arm] @@ -2021,66 +2094,79 @@ packages: resolution: {integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.57.1': resolution: {integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.57.1': resolution: {integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.57.1': resolution: {integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.57.1': resolution: {integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.57.1': resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==} cpu: [loong64] os: [linux] + libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.57.1': resolution: {integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.57.1': resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==} cpu: [ppc64] os: [linux] + libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.57.1': resolution: {integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.57.1': resolution: {integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.57.1': resolution: {integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.57.1': resolution: {integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.57.1': resolution: {integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openbsd-x64@4.57.1': resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==} @@ -2121,6 +2207,98 @@ packages: '@standard-schema/utils@0.3.0': resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} + '@storybook/addon-a11y@10.3.4': + resolution: {integrity: sha512-TylBS2+MUPRfgzBKiygL1JoUBnTqEKo5oCEfjHneJZKzYE1UNgdMdk/fiyanaGKTZBKBxWbShxZhT2gLs8kqMA==} + peerDependencies: + storybook: ^10.3.4 + + '@storybook/addon-docs@10.3.4': + resolution: {integrity: sha512-ohS8fX8UIP3LN6+mDZJLCDS4Qd2rsmGwes6V6fD0sbLOmIyCVY5y68r6NHMMGJKFRwadDQOmtOt8Vc6snExrIQ==} + peerDependencies: + storybook: ^10.3.4 + + '@storybook/addon-onboarding@10.3.4': + resolution: {integrity: sha512-59BgxVX3FJxS+cruvk7gfm/0azRJokDeHNNubEhgKIS8ih0ol9vJ7YbAJEP7QWOf22RghWtQSO0yMmTyZTPTyQ==} + peerDependencies: + storybook: ^10.3.4 + + '@storybook/addon-vitest@10.3.4': + resolution: {integrity: sha512-lSn8opaHVzDxLtMy28FnSkyx6uP1oQVnGzodNunTjrbJ8Ue8JVK+fjWtC/JfErIio0avlq79mgC5tfHSWlPr9w==} + peerDependencies: + '@vitest/browser': ^3.0.0 || ^4.0.0 + '@vitest/browser-playwright': ^4.0.0 + '@vitest/runner': ^3.0.0 || ^4.0.0 + storybook: ^10.3.4 + vitest: ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + '@vitest/browser': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/runner': + optional: true + vitest: + optional: true + + '@storybook/builder-vite@10.3.4': + resolution: {integrity: sha512-dNQyBZpBKvwmhSTpjrsuxxY8FqFCh0hgu5+46h2WbgQ2Te3pO458heWkGb+QO7mC6FmkXO6j6zgYzXticD6F2A==} + peerDependencies: + storybook: ^10.3.4 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@storybook/csf-plugin@10.3.4': + resolution: {integrity: sha512-WPP0Z39o82WiohPkhPOs6z+9yJ+bVvqPz4d+QUPfE6FMvOOBLojlwOcGx6Xmclyn5H/CKwywFrjuz4mBO/nHhA==} + peerDependencies: + esbuild: '*' + rollup: '*' + storybook: ^10.3.4 + vite: '*' + webpack: '*' + peerDependenciesMeta: + esbuild: + optional: true + rollup: + optional: true + vite: + optional: true + webpack: + optional: true + + '@storybook/global@5.0.0': + resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} + + '@storybook/icons@2.0.1': + resolution: {integrity: sha512-/smVjw88yK3CKsiuR71vNgWQ9+NuY2L+e8X7IMrFjexjm6ZR8ULrV2DRkTA61aV6ryefslzHEGDInGpnNeIocg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@storybook/react-dom-shim@10.3.4': + resolution: {integrity: sha512-VIm9YzreGubnOtQOZ6iqEfj6KncHvAkrCR/IilqnJq7DidPWuykrFszyajTASRMiY+p+TElOW+O1PGpv55qNGw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.3.4 + + '@storybook/react-vite@10.3.4': + resolution: {integrity: sha512-xaMt7NdvlAb+CwXn5TOiluQ+0WkkMN3mZhCThocpblWGoyfmHH7bgQ5ZwzT+IIp8DGOsAi/HkNmSyS7Z8HRLJg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.3.4 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@storybook/react@10.3.4': + resolution: {integrity: sha512-I5ifYqjrqyuhOFjalpy47kMKMXX7QU/qmHj0h/547s9Bg6sEU7xRhJnneXx1RJsEJTySjC4SmGfEU+FJz4Foiw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.3.4 + typescript: '>= 4.9.x' + peerDependenciesMeta: + typescript: + optional: true + '@swc/helpers@0.5.18': resolution: {integrity: sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==} @@ -2162,24 +2340,28 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.1.18': resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.1.18': resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.1.18': resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.1.18': resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==} @@ -2262,6 +2444,10 @@ packages: resolution: {integrity: sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==} engines: {node: '>=8', npm: '>=6', yarn: '>=1'} + '@testing-library/jest-dom@6.9.1': + resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + '@testing-library/react@16.3.2': resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} engines: {node: '>=18'} @@ -2552,6 +2738,9 @@ packages: '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/doctrine@0.0.9': + resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} + '@types/estree-jsx@1.0.5': resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} @@ -2585,6 +2774,9 @@ packages: '@types/mdurl@2.0.0': resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} @@ -2610,6 +2802,9 @@ packages: '@types/react@19.2.10': resolution: {integrity: sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw==} + '@types/resolve@1.20.6': + resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==} + '@types/supercluster@7.1.3': resolution: {integrity: sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==} @@ -2705,6 +2900,29 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + '@vitest/browser-playwright@4.0.18': + resolution: {integrity: sha512-gfajTHVCiwpxRj1qh0Sh/5bbGLG4F/ZH/V9xvFVoFddpITfMta9YGow0W6ZpTTORv2vdJuz9TnrNSmjKvpOf4g==} + peerDependencies: + playwright: '*' + vitest: 4.0.18 + + '@vitest/browser@4.0.18': + resolution: {integrity: sha512-gVQqh7paBz3gC+ZdcCmNSWJMk70IUjDeVqi+5m5vYpEHsIwRgw3Y545jljtajhkekIpIp5Gg8oK7bctgY0E2Ng==} + peerDependencies: + vitest: 4.0.18 + + '@vitest/coverage-v8@4.0.18': + resolution: {integrity: sha512-7i+N2i0+ME+2JFZhfuz7Tg/FqKtilHjGyGvoHYQ6iLV0zahbsJ9sljC9OcFcPDbhYKCet+sG8SsVqlyGvPflZg==} + peerDependencies: + '@vitest/browser': 4.0.18 + vitest: 4.0.18 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + '@vitest/expect@4.0.18': resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} @@ -2719,6 +2937,9 @@ packages: vite: optional: true + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + '@vitest/pretty-format@4.0.18': resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==} @@ -2728,12 +2949,21 @@ packages: '@vitest/snapshot@4.0.18': resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==} + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + '@vitest/spy@4.0.18': resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==} + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + '@vitest/utils@4.0.18': resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} + '@webcontainer/env@1.1.1': + resolution: {integrity: sha512-6aN99yL695Hi9SuIk1oC88l9o0gmxL1nGWWQ/kNy81HigJ0FoaoTXpytCj6ItzgyCEwA9kF1wixsTuv5cjsgng==} + accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -2763,6 +2993,10 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -2802,6 +3036,13 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + + ast-v8-to-istanbul@0.3.12: + resolution: {integrity: sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==} + async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} @@ -2812,6 +3053,10 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + axe-core@4.11.2: + resolution: {integrity: sha512-byD6KPdvo72y/wj2T/4zGEvvlis+PsZsn/yPS3pEO+sFpcrqRpX/TJCxvVaEsNeMrfQbCr7w163YqoD9IYwHXw==} + engines: {node: '>=4'} + axios@1.13.4: resolution: {integrity: sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==} @@ -2862,6 +3107,10 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -2892,6 +3141,10 @@ packages: ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + engines: {node: '>=18'} + chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} @@ -2922,10 +3175,26 @@ packages: charenc@0.0.2: resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + check-error@2.1.3: + resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} + engines: {node: '>= 16'} + chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chromatic@13.3.5: + resolution: {integrity: sha512-MzPhxpl838qJUo0A55osCF2ifwPbjcIPeElr1d4SHcjnHoIcg7l1syJDrAYK/a+PcCBrOGi06jPNpQAln5hWgw==} + hasBin: true + peerDependencies: + '@chromatic-com/cypress': ^0.*.* || ^1.0.0 + '@chromatic-com/playwright': ^0.*.* || ^1.0.0 + peerDependenciesMeta: + '@chromatic-com/cypress': + optional: true + '@chromatic-com/playwright': + optional: true + class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} @@ -3190,6 +3459,10 @@ packages: resolution: {integrity: sha512-aWS3UIVH+NPGCD1kki+DCU9Dua032iSsO43LqQpcs4R3+dVv7tX0qBGjiVHJHjplsoUM2XRO/KB92glqc68awg==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deep-equal@2.2.3: resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} engines: {node: '>= 0.4'} @@ -3201,10 +3474,22 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.5.0: + resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} + engines: {node: '>=18'} + define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} @@ -3239,9 +3524,16 @@ packages: resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dom-helpers@5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} @@ -3285,6 +3577,10 @@ packages: emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + empathic@2.0.0: + resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} + engines: {node: '>=14'} + encodeurl@2.0.0: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} @@ -3377,6 +3673,12 @@ packages: peerDependencies: eslint: '>=9' + eslint-plugin-storybook@10.3.4: + resolution: {integrity: sha512-6jRb9ucYWKRkbuxpN+83YA3wAWuKn6rp+OVXivy0FPa82v8eciHG8OidbznmzrfcRJYkNWUb7GrPjG/rf4Vqaw==} + peerDependencies: + eslint: '>=8' + storybook: ^10.3.4 + eslint-scope@8.4.0: resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3403,6 +3705,11 @@ packages: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + esquery@1.7.0: resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} @@ -3418,6 +3725,9 @@ packages: estree-util-is-identifier-name@3.0.0: resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} @@ -3489,6 +3799,10 @@ packages: filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + filesize@10.1.6: + resolution: {integrity: sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==} + engines: {node: '>= 10.4.0'} + finalhandler@1.3.2: resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} engines: {node: '>= 0.8'} @@ -3539,6 +3853,11 @@ packages: fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -3673,6 +3992,9 @@ packages: resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + html-parse-stringify@3.0.1: resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} @@ -3817,6 +4139,11 @@ packages: engines: {node: '>=8'} hasBin: true + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -3832,6 +4159,11 @@ packages: is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} @@ -3879,6 +4211,10 @@ packages: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + isarray@0.0.1: resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} @@ -3895,6 +4231,18 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + jake@10.9.4: resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} engines: {node: '>=10'} @@ -3924,6 +4272,9 @@ packages: resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} engines: {node: '>=0.10.0'} + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -3973,6 +4324,9 @@ packages: engines: {node: '>=6'} hasBin: true + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + kdbush@4.0.2: resolution: {integrity: sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==} @@ -4021,24 +4375,28 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.30.2: resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.30.2: resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.30.2: resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.30.2: resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} @@ -4091,6 +4449,9 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + lru-cache@11.2.5: resolution: {integrity: sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==} engines: {node: 20 || >=22} @@ -4110,6 +4471,13 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + magicast@0.5.2: + resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + maplibre-gl@5.19.0: resolution: {integrity: sha512-REhYUN8gNP3HlcIZS6QU2uy8iovl31cXsrNDkCcqWSQbCkcpdYLczqDz5PVIwNH42UQNyvukjes/RoHPDrOUmQ==} engines: {node: '>=16.14.0', npm: '>=8.1.0'} @@ -4298,6 +4666,10 @@ packages: resolution: {integrity: sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==} engines: {node: '>= 0.8.0'} + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -4386,6 +4758,10 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} + engines: {node: '>=18'} + open@7.4.2: resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} engines: {node: '>=8'} @@ -4481,6 +4857,10 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pathval@2.0.1: + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} + engines: {node: '>= 14.16'} + pbf@4.0.1: resolution: {integrity: sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==} hasBin: true @@ -4499,13 +4879,31 @@ packages: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} + pixelmatch@7.1.0: + resolution: {integrity: sha512-1wrVzJ2STrpmONHKBy228LM1b84msXDUoAzVEl0R8Mz4Ce6EPr+IVtxm8+yvrqLYMHswREkjYFaMxnyGnaY3Ng==} + hasBin: true + pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + playwright-core@1.59.1: + resolution: {integrity: sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.59.1: + resolution: {integrity: sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==} + engines: {node: '>=18'} + hasBin: true + pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} + pngjs@7.0.0: + resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==} + engines: {node: '>=14.19.0'} + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -4644,6 +5042,15 @@ packages: react: '>=16.8.0' react-dom: '>=16.8.0' + react-docgen-typescript@2.4.0: + resolution: {integrity: sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==} + peerDependencies: + typescript: '>= 4.3.x' + + react-docgen@8.0.3: + resolution: {integrity: sha512-aEZ9qP+/M+58x2qgfSFEWH1BxLyHe5+qkLNJOZQb5iGS017jpbRnoKhNRrXPeA6RfBrZO5wZrT9DMC1UqE1f1w==} + engines: {node: ^20.9.0 || >=22} + react-dom@18.3.1: resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: @@ -4791,6 +5198,10 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + recast@0.23.11: + resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} + engines: {node: '>= 4'} + recharts-scale@0.4.5: resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} @@ -4857,6 +5268,10 @@ packages: rope-sequence@1.3.4: resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + rw@1.3.3: resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} @@ -4941,6 +5356,10 @@ packages: siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} + engines: {node: '>=18'} + sonner@2.0.7: resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==} peerDependencies: @@ -4991,6 +5410,15 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} + storybook@10.3.4: + resolution: {integrity: sha512-866YXZy9k59tLPl9SN3KZZOFeBC/swxkuBVtW8iQjJIzfCrvk7zXQd8RSQ4ignmCdArVvY4lGMCAT4yNaZSt1g==} + hasBin: true + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true + string-to-color@2.2.2: resolution: {integrity: sha512-XeA2goP7PNsSlz8RRn6KhYswnMf5Tl+38ajfy8n4oZJyMGC4qqKgHNHsZ/3qwvr42NRIjf9eSr721SyetDeMkA==} @@ -5011,10 +5439,22 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} + strip-indent@4.1.1: + resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==} + engines: {node: '>=12'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -5117,10 +5557,18 @@ packages: tinyqueue@3.0.0: resolution: {integrity: sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==} + tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} + engines: {node: '>=14.0.0'} + tinyrainbow@3.0.3: resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} engines: {node: '>=14.0.0'} + tinyspy@4.0.4: + resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} + engines: {node: '>=14.0.0'} + tldts-core@7.0.22: resolution: {integrity: sha512-KgbTDC5wzlL6j/x6np6wCnDSMUq4kucHNm00KXPbfNzmllCmtmvtykJHfmgdHntwIeupW04y8s1N/43S1PkQDw==} @@ -5135,6 +5583,10 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + tough-cookie@6.0.0: resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} engines: {node: '>=16'} @@ -5158,9 +5610,17 @@ packages: peerDependencies: typescript: '>=4.8.4' + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -5224,10 +5684,18 @@ packages: unist-util-visit@5.1.0: resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} + engines: {node: '>=18.12.0'} + untildify@4.0.0: resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} engines: {node: '>=8'} @@ -5411,6 +5879,9 @@ packages: resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} engines: {node: '>=20'} + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + whatwg-mimetype@3.0.0: resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} engines: {node: '>=12'} @@ -5474,6 +5945,10 @@ packages: utf-8-validate: optional: true + wsl-utils@0.1.0: + resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} + engines: {node: '>=18'} + xml-name-validator@5.0.0: resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} engines: {node: '>=18'} @@ -5782,6 +6257,20 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@bcoe/v8-coverage@1.0.2': {} + + '@chromatic-com/storybook@5.1.1(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + dependencies: + '@neoconfetti/react': 1.0.0 + chromatic: 13.3.5 + filesize: 10.1.6 + jsonfile: 6.2.0 + storybook: 10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + strip-ansi: 7.2.0 + transitivePeerDependencies: + - '@chromatic-com/cypress' + - '@chromatic-com/playwright' + '@clerk/clerk-react@5.60.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@clerk/shared': 3.44.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -6205,6 +6694,14 @@ snapshots: dependencies: '@isaacs/balanced-match': 4.0.1 + '@joshwooding/vite-plugin-react-docgen-typescript@0.7.0(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))': + dependencies: + glob: 13.0.1 + react-docgen-typescript: 2.4.0(typescript@5.9.3) + vite: 7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0) + optionalDependencies: + typescript: 5.9.3 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -6295,6 +6792,12 @@ snapshots: '@marijn/find-cluster-break@1.0.2': {} + '@mdx-js/react@3.1.1(@types/react@19.2.10)(react@18.3.1)': + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 19.2.10 + react: 18.3.1 + '@microsoft/fetch-event-source@2.0.1': {} '@mjackson/node-fetch-server@0.2.0': {} @@ -6386,8 +6889,12 @@ snapshots: optionalDependencies: '@types/react': 19.2.10 + '@neoconfetti/react@1.0.0': {} + '@pkgr/core@0.2.9': {} + '@polka/url@1.0.0-next.29': {} + '@popperjs/core@2.11.8': {} '@preact/signals-core@1.12.2': {} @@ -7292,6 +7799,14 @@ snapshots: '@rolldown/pluginutils@1.0.0-rc.2': {} + '@rollup/pluginutils@5.3.0(rollup@4.57.1)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.57.1 + '@rollup/rollup-android-arm-eabi@4.57.1': optional: true @@ -7376,6 +7891,116 @@ snapshots: '@standard-schema/utils@0.3.0': {} + '@storybook/addon-a11y@10.3.4(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + dependencies: + '@storybook/global': 5.0.0 + axe-core: 4.11.2 + storybook: 10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + + '@storybook/addon-docs@10.3.4(@types/react@19.2.10)(esbuild@0.27.2)(rollup@4.57.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))': + dependencies: + '@mdx-js/react': 3.1.1(@types/react@19.2.10)(react@18.3.1) + '@storybook/csf-plugin': 10.3.4(esbuild@0.27.2)(rollup@4.57.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)) + '@storybook/icons': 2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/react-dom-shim': 10.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + storybook: 10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + - esbuild + - rollup + - vite + - webpack + + '@storybook/addon-onboarding@10.3.4(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + dependencies: + storybook: 10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + + '@storybook/addon-vitest@10.3.4(@vitest/browser-playwright@4.0.18)(@vitest/browser@4.0.18(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))(vitest@4.0.18))(@vitest/runner@4.0.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vitest@4.0.18)': + dependencies: + '@storybook/global': 5.0.0 + '@storybook/icons': 2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + storybook: 10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + optionalDependencies: + '@vitest/browser': 4.0.18(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))(vitest@4.0.18) + '@vitest/browser-playwright': 4.0.18(playwright@1.59.1)(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))(vitest@4.0.18) + '@vitest/runner': 4.0.18 + vitest: 4.0.18(@types/node@22.19.9)(@vitest/browser-playwright@4.0.18)(happy-dom@20.5.0)(jiti@2.6.1)(jsdom@28.0.0)(lightningcss@1.30.2)(terser@5.46.0) + transitivePeerDependencies: + - react + - react-dom + + '@storybook/builder-vite@10.3.4(esbuild@0.27.2)(rollup@4.57.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))': + dependencies: + '@storybook/csf-plugin': 10.3.4(esbuild@0.27.2)(rollup@4.57.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)) + storybook: 10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + ts-dedent: 2.2.0 + vite: 7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0) + transitivePeerDependencies: + - esbuild + - rollup + - webpack + + '@storybook/csf-plugin@10.3.4(esbuild@0.27.2)(rollup@4.57.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))': + dependencies: + storybook: 10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + unplugin: 2.3.11 + optionalDependencies: + esbuild: 0.27.2 + rollup: 4.57.1 + vite: 7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0) + + '@storybook/global@5.0.0': {} + + '@storybook/icons@2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@storybook/react-dom-shim@10.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + storybook: 10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + + '@storybook/react-vite@10.3.4(esbuild@0.27.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.57.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))': + dependencies: + '@joshwooding/vite-plugin-react-docgen-typescript': 0.7.0(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)) + '@rollup/pluginutils': 5.3.0(rollup@4.57.1) + '@storybook/builder-vite': 10.3.4(esbuild@0.27.2)(rollup@4.57.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)) + '@storybook/react': 10.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3) + empathic: 2.0.0 + magic-string: 0.30.21 + react: 18.3.1 + react-docgen: 8.0.3 + react-dom: 18.3.1(react@18.3.1) + resolve: 1.22.11 + storybook: 10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + tsconfig-paths: 4.2.0 + vite: 7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0) + transitivePeerDependencies: + - esbuild + - rollup + - supports-color + - typescript + - webpack + + '@storybook/react@10.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3)': + dependencies: + '@storybook/global': 5.0.0 + '@storybook/react-dom-shim': 10.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + react: 18.3.1 + react-docgen: 8.0.3 + react-docgen-typescript: 2.4.0(typescript@5.9.3) + react-dom: 18.3.1(react@18.3.1) + storybook: 10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@swc/helpers@0.5.18': dependencies: tslib: 2.8.1 @@ -7507,6 +8132,15 @@ snapshots: lodash: 4.17.23 redent: 3.0.0 + '@testing-library/jest-dom@6.9.1': + dependencies: + '@adobe/css-tools': 4.4.4 + aria-query: 5.3.2 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + picocolors: 1.1.1 + redent: 3.0.0 + '@testing-library/react@16.3.2(@testing-library/dom@8.20.1)(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.28.6 @@ -7832,6 +8466,8 @@ snapshots: '@types/deep-eql@4.0.2': {} + '@types/doctrine@0.0.9': {} + '@types/estree-jsx@1.0.5': dependencies: '@types/estree': 1.0.8 @@ -7866,6 +8502,8 @@ snapshots: '@types/mdurl@2.0.0': {} + '@types/mdx@2.0.13': {} + '@types/ms@2.1.0': {} '@types/node@22.19.9': @@ -7888,6 +8526,8 @@ snapshots: dependencies: csstype: 3.2.3 + '@types/resolve@1.20.6': {} + '@types/supercluster@7.1.3': dependencies: '@types/geojson': 7946.0.16 @@ -8018,6 +8658,60 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitest/browser-playwright@4.0.18(playwright@1.59.1)(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))(vitest@4.0.18)': + dependencies: + '@vitest/browser': 4.0.18(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))(vitest@4.0.18) + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)) + playwright: 1.59.1 + tinyrainbow: 3.0.3 + vitest: 4.0.18(@types/node@22.19.9)(@vitest/browser-playwright@4.0.18)(happy-dom@20.5.0)(jiti@2.6.1)(jsdom@28.0.0)(lightningcss@1.30.2)(terser@5.46.0) + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + + '@vitest/browser@4.0.18(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))(vitest@4.0.18)': + dependencies: + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)) + '@vitest/utils': 4.0.18 + magic-string: 0.30.21 + pixelmatch: 7.1.0 + pngjs: 7.0.0 + sirv: 3.0.2 + tinyrainbow: 3.0.3 + vitest: 4.0.18(@types/node@22.19.9)(@vitest/browser-playwright@4.0.18)(happy-dom@20.5.0)(jiti@2.6.1)(jsdom@28.0.0)(lightningcss@1.30.2)(terser@5.46.0) + ws: 8.19.0 + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + + '@vitest/coverage-v8@4.0.18(@vitest/browser@4.0.18(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))(vitest@4.0.18))(vitest@4.0.18)': + dependencies: + '@bcoe/v8-coverage': 1.0.2 + '@vitest/utils': 4.0.18 + ast-v8-to-istanbul: 0.3.12 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.2.0 + magicast: 0.5.2 + obug: 2.1.1 + std-env: 3.10.0 + tinyrainbow: 3.0.3 + vitest: 4.0.18(@types/node@22.19.9)(@vitest/browser-playwright@4.0.18)(happy-dom@20.5.0)(jiti@2.6.1)(jsdom@28.0.0)(lightningcss@1.30.2)(terser@5.46.0) + optionalDependencies: + '@vitest/browser': 4.0.18(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))(vitest@4.0.18) + + '@vitest/expect@3.2.4': + dependencies: + '@types/chai': 5.2.3 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.3.3 + tinyrainbow: 2.0.0 + '@vitest/expect@4.0.18': dependencies: '@standard-schema/spec': 1.1.0 @@ -8035,6 +8729,10 @@ snapshots: optionalDependencies: vite: 7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0) + '@vitest/pretty-format@3.2.4': + dependencies: + tinyrainbow: 2.0.0 + '@vitest/pretty-format@4.0.18': dependencies: tinyrainbow: 3.0.3 @@ -8050,13 +8748,25 @@ snapshots: magic-string: 0.30.21 pathe: 2.0.3 + '@vitest/spy@3.2.4': + dependencies: + tinyspy: 4.0.4 + '@vitest/spy@4.0.18': {} + '@vitest/utils@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.1 + tinyrainbow: 2.0.0 + '@vitest/utils@4.0.18': dependencies: '@vitest/pretty-format': 4.0.18 tinyrainbow: 3.0.3 + '@webcontainer/env@1.1.1': {} + accepts@1.3.8: dependencies: mime-types: 2.1.35 @@ -8081,6 +8791,8 @@ snapshots: ansi-regex@5.0.1: {} + ansi-regex@6.2.2: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 @@ -8112,6 +8824,16 @@ snapshots: assertion-error@2.0.1: {} + ast-types@0.16.1: + dependencies: + tslib: 2.8.1 + + ast-v8-to-istanbul@0.3.12: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 10.0.0 + async@3.2.6: {} asynckit@0.4.0: {} @@ -8120,6 +8842,8 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 + axe-core@4.11.2: {} + axios@1.13.4: dependencies: follow-redirects: 1.15.11 @@ -8195,6 +8919,10 @@ snapshots: buffer-from@1.1.2: {} + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + bytes@3.1.2: {} cac@6.7.14: {} @@ -8222,6 +8950,14 @@ snapshots: ccount@2.0.1: {} + chai@5.3.3: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.3 + deep-eql: 5.0.2 + loupe: 3.2.1 + pathval: 2.0.1 + chai@6.2.2: {} chalk@3.0.0: @@ -8246,10 +8982,14 @@ snapshots: charenc@0.0.2: {} + check-error@2.1.3: {} + chokidar@4.0.3: dependencies: readdirp: 4.1.2 + chromatic@13.3.5: {} + class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 @@ -8517,6 +9257,8 @@ snapshots: deep-diff@1.0.2: {} + deep-eql@5.0.2: {} + deep-equal@2.2.3: dependencies: array-buffer-byte-length: 1.0.2 @@ -8542,12 +9284,21 @@ snapshots: deepmerge@4.3.1: {} + default-browser-id@5.0.1: {} + + default-browser@5.5.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + define-data-property@1.1.4: dependencies: es-define-property: 1.0.1 es-errors: 1.3.0 gopd: 1.2.0 + define-lazy-prop@3.0.0: {} + define-properties@1.2.1: dependencies: define-data-property: 1.1.4 @@ -8572,8 +9323,14 @@ snapshots: diff-sequences@27.5.1: {} + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + dom-accessibility-api@0.5.16: {} + dom-accessibility-api@0.6.3: {} + dom-helpers@5.2.1: dependencies: '@babel/runtime': 7.28.6 @@ -8621,6 +9378,8 @@ snapshots: emoji-regex@8.0.0: {} + empathic@2.0.0: {} + encodeurl@2.0.0: {} enhanced-resolve@5.18.4: @@ -8730,6 +9489,15 @@ snapshots: dependencies: eslint: 9.39.2(jiti@2.6.1) + eslint-plugin-storybook@10.3.4(eslint@9.39.2(jiti@2.6.1))(storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3): + dependencies: + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.2(jiti@2.6.1) + storybook: 10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + transitivePeerDependencies: + - supports-color + - typescript + eslint-scope@8.4.0: dependencies: esrecurse: 4.3.0 @@ -8786,6 +9554,8 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 4.2.1 + esprima@4.0.1: {} + esquery@1.7.0: dependencies: estraverse: 5.3.0 @@ -8798,6 +9568,8 @@ snapshots: estree-util-is-identifier-name@3.0.0: {} + estree-walker@2.0.2: {} + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.8 @@ -8878,6 +9650,8 @@ snapshots: dependencies: minimatch: 5.1.6 + filesize@10.1.6: {} + finalhandler@1.3.2: dependencies: debug: 2.6.9 @@ -8926,6 +9700,9 @@ snapshots: fs.realpath@1.0.0: {} + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true @@ -9082,6 +9859,8 @@ snapshots: transitivePeerDependencies: - '@noble/hashes' + html-escaper@2.0.2: {} + html-parse-stringify@3.0.1: dependencies: void-elements: 3.1.0 @@ -9239,6 +10018,8 @@ snapshots: is-docker@2.2.1: {} + is-docker@3.0.0: {} + is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -9249,6 +10030,10 @@ snapshots: is-hexadecimal@2.0.1: {} + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + is-map@2.0.3: {} is-number-object@1.1.1: @@ -9295,6 +10080,10 @@ snapshots: dependencies: is-docker: 2.2.1 + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + isarray@0.0.1: {} isarray@1.0.0: {} @@ -9305,6 +10094,19 @@ snapshots: isexe@2.0.0: {} + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + jake@10.9.4: dependencies: async: 3.2.6 @@ -9333,6 +10135,8 @@ snapshots: js-levenshtein@1.1.6: {} + js-tokens@10.0.0: {} + js-tokens@4.0.0: {} js-yaml@4.1.1: @@ -9383,6 +10187,12 @@ snapshots: json5@2.2.3: {} + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + kdbush@4.0.2: {} keyv@4.5.4: @@ -9473,6 +10283,8 @@ snapshots: dependencies: js-tokens: 4.0.0 + loupe@3.2.1: {} + lru-cache@11.2.5: {} lru-cache@5.1.1: @@ -9489,6 +10301,16 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + magicast@0.5.2: + dependencies: + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + source-map-js: 1.2.1 + + make-dir@4.0.0: + dependencies: + semver: 7.7.3 + maplibre-gl@5.19.0: dependencies: '@mapbox/geojson-rewind': 0.5.2 @@ -9820,6 +10642,8 @@ snapshots: transitivePeerDependencies: - supports-color + mrmime@2.0.1: {} + ms@2.0.0: {} ms@2.1.3: {} @@ -9891,6 +10715,13 @@ snapshots: dependencies: wrappy: 1.0.2 + open@10.2.0: + dependencies: + default-browser: 5.5.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + wsl-utils: 0.1.0 + open@7.4.2: dependencies: is-docker: 2.2.1 @@ -9994,6 +10825,8 @@ snapshots: pathe@2.0.3: {} + pathval@2.0.1: {} + pbf@4.0.1: dependencies: resolve-protobuf-schema: 2.1.0 @@ -10006,14 +10839,28 @@ snapshots: pirates@4.0.7: {} + pixelmatch@7.1.0: + dependencies: + pngjs: 7.0.0 + pkg-types@2.3.0: dependencies: confbox: 0.2.2 exsolve: 1.0.8 pathe: 2.0.3 + playwright-core@1.59.1: {} + + playwright@1.59.1: + dependencies: + playwright-core: 1.59.1 + optionalDependencies: + fsevents: 2.3.2 + pluralize@8.0.0: {} + pngjs@7.0.0: {} + possible-typed-array-names@1.1.0: {} postcss@8.5.6: @@ -10186,6 +11033,25 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + react-docgen-typescript@2.4.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + react-docgen@8.0.3: + dependencies: + '@babel/core': 7.29.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.28.0 + '@types/doctrine': 0.0.9 + '@types/resolve': 1.20.6 + doctrine: 3.0.0 + resolve: 1.22.11 + strip-indent: 4.1.1 + transitivePeerDependencies: + - supports-color + react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 @@ -10346,6 +11212,14 @@ snapshots: readdirp@4.1.2: {} + recast@0.23.11: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 + recharts-scale@0.4.5: dependencies: decimal.js-light: 2.5.1 @@ -10454,6 +11328,8 @@ snapshots: rope-sequence@1.3.4: {} + run-applescript@7.1.0: {} + rw@1.3.3: {} safe-buffer@5.1.2: {} @@ -10567,6 +11443,12 @@ snapshots: siginfo@2.0.0: {} + sirv@3.0.2: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + sonner@2.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: react: 18.3.1 @@ -10615,6 +11497,30 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 + storybook@10.3.4(@testing-library/dom@8.20.1)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@storybook/global': 5.0.0 + '@storybook/icons': 2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@testing-library/jest-dom': 6.9.1 + '@testing-library/user-event': 14.6.1(@testing-library/dom@8.20.1) + '@vitest/expect': 3.2.4 + '@vitest/spy': 3.2.4 + '@webcontainer/env': 1.1.1 + esbuild: 0.27.2 + open: 10.2.0 + recast: 0.23.11 + semver: 7.7.3 + use-sync-external-store: 1.6.0(react@18.3.1) + ws: 8.19.0 + optionalDependencies: + prettier: 3.8.1 + transitivePeerDependencies: + - '@testing-library/dom' + - bufferutil + - react + - react-dom + - utf-8-validate + string-to-color@2.2.2: dependencies: colornames: 1.1.1 @@ -10645,10 +11551,18 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + strip-bom@3.0.0: {} + strip-indent@3.0.0: dependencies: min-indent: 1.0.1 + strip-indent@4.1.1: {} + strip-json-comments@3.1.1: {} style-mod@4.1.3: {} @@ -10748,8 +11662,12 @@ snapshots: tinyqueue@3.0.0: {} + tinyrainbow@2.0.0: {} + tinyrainbow@3.0.3: {} + tinyspy@4.0.4: {} + tldts-core@7.0.22: {} tldts@7.0.22: @@ -10760,6 +11678,8 @@ snapshots: toidentifier@1.0.1: {} + totalist@3.0.1: {} + tough-cookie@6.0.0: dependencies: tldts: 7.0.22 @@ -10778,8 +11698,16 @@ snapshots: dependencies: typescript: 5.9.3 + ts-dedent@2.2.0: {} + ts-interface-checker@0.1.13: {} + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + tslib@2.8.1: {} tw-animate-css@1.4.0: {} @@ -10850,8 +11778,17 @@ snapshots: unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 + universalify@2.0.1: {} + unpipe@1.0.0: {} + unplugin@2.3.11: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.15.0 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + untildify@4.0.0: {} update-browserslist-db@1.2.3(browserslist@4.28.1): @@ -10962,7 +11899,7 @@ snapshots: lightningcss: 1.30.2 terser: 5.46.0 - vitest@4.0.18(@types/node@22.19.9)(happy-dom@20.5.0)(jiti@2.6.1)(jsdom@28.0.0)(lightningcss@1.30.2)(terser@5.46.0): + vitest@4.0.18(@types/node@22.19.9)(@vitest/browser-playwright@4.0.18)(happy-dom@20.5.0)(jiti@2.6.1)(jsdom@28.0.0)(lightningcss@1.30.2)(terser@5.46.0): dependencies: '@vitest/expect': 4.0.18 '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)) @@ -10986,6 +11923,7 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.19.9 + '@vitest/browser-playwright': 4.0.18(playwright@1.59.1)(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0))(vitest@4.0.18) happy-dom: 20.5.0 jsdom: 28.0.0 transitivePeerDependencies: @@ -11021,6 +11959,8 @@ snapshots: webidl-conversions@8.0.1: {} + webpack-virtual-modules@0.6.2: {} + whatwg-mimetype@3.0.0: {} whatwg-mimetype@5.0.0: {} @@ -11086,6 +12026,10 @@ snapshots: ws@8.19.0: {} + wsl-utils@0.1.0: + dependencies: + is-wsl: 3.1.1 + xml-name-validator@5.0.0: {} xmlchars@2.2.0: {} diff --git a/console/src/components/code-example.stories.tsx b/console/src/components/code-example.stories.tsx new file mode 100644 index 00000000..8883350c --- /dev/null +++ b/console/src/components/code-example.stories.tsx @@ -0,0 +1,64 @@ +import type { Meta, StoryObj } from "@storybook/react" +import CodeExample from "./code-example" + +const meta: Meta = { + title: "Components/CodeExample", + component: CodeExample, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +const jsonCode = `{ + "id": "usr_01j9x2k3m4n5p6q7", + "email": "alice@example.com", + "name": "Alice Smith", + "created_at": "2024-01-15T10:30:00Z", + "metadata": { + "plan": "pro", + "seats": 10 + } +}` + +const jsCode = `import { createClient } from "@myapp/sdk" + +const client = createClient({ + projectId: "proj_abc123", + secretKey: process.env.SECRET_KEY, +}) + +const user = await client.users.get("usr_01j9x2k3m4n5p6q7") +console.log(user.email)` + +export const JsonExample: Story = { + render: () => ( +
+ +
+ ), +} + +export const JavaScriptExample: Story = { + render: () => ( +
+ +
+ ), +} + +export const NoTitle: Story = { + render: () => ( +
+ +
+ ), +} diff --git a/console/src/components/data-table.stories.tsx b/console/src/components/data-table.stories.tsx new file mode 100644 index 00000000..37eb2150 --- /dev/null +++ b/console/src/components/data-table.stories.tsx @@ -0,0 +1,92 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { DataTable } from "./data-table" +import type { DataTableCol } from "./data-table" +import { PreferencesProvider } from "@/contexts/PreferencesContext" + +interface User { + id: string + name: string + email: string + role: string + active: boolean +} + +const columns: DataTableCol[] = [ + { key: "id", title: "ID" }, + { key: "name", title: "Name" }, + { key: "email", title: "Email" }, + { key: "role", title: "Role" }, + { key: "active", title: "Active" }, +] + +const sampleUsers: User[] = [ + { id: "usr_001", name: "Alice Smith", email: "alice@example.com", role: "Admin", active: true }, + { id: "usr_002", name: "Bob Jones", email: "bob@example.com", role: "Editor", active: true }, + { + id: "usr_003", + name: "Carol White", + email: "carol@example.com", + role: "Viewer", + active: false, + }, + { + id: "usr_004", + name: "David Brown", + email: "david@example.com", + role: "Editor", + active: true, + }, +] + +const meta: Meta = { + title: "Components/DataTable", + component: DataTable, + tags: ["autodocs"], + decorators: [ + (Story) => ( + + + + ), + ], +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( + columns={columns} items={sampleUsers} /> + ), +} + +export const Loading: Story = { + render: () => ( + columns={columns} isLoading /> + ), +} + +export const Empty: Story = { + render: () => ( + + columns={columns} + items={[]} + emptyMessage="No users found. Add a user to get started." + /> + ), +} + +export const Sortable: Story = { + render: () => ( + + columns={[ + { key: "id", title: "ID" }, + { key: "name", title: "Name", sortable: true }, + { key: "email", title: "Email", sortable: true }, + { key: "role", title: "Role" }, + { key: "active", title: "Active" }, + ]} + items={sampleUsers} + /> + ), +} diff --git a/console/src/components/heading.stories.tsx b/console/src/components/heading.stories.tsx new file mode 100644 index 00000000..1d8cfd8f --- /dev/null +++ b/console/src/components/heading.stories.tsx @@ -0,0 +1,59 @@ +import type { Meta, StoryObj } from "@storybook/react" +import Heading from "./heading" +import { Button } from "@/components/ui/button" + +const meta: Meta = { + title: "Components/Heading", + component: Heading, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const H2: Story = { + render: () => ( + Add User} + > + Manage all users in your organisation. + + ), +} + +export const H3: Story = { + render: () => ( + Edit} + /> + ), +} + +export const H4: Story = { + render: () => , +} + +export const H5: Story = { + render: () => , +} + +export const WithActionsAndChildren: Story = { + render: () => ( + + + + + } + > + View and manage your recent deployments. + + ), +} diff --git a/console/src/components/icon-mosaic.stories.tsx b/console/src/components/icon-mosaic.stories.tsx new file mode 100644 index 00000000..d45ffe8a --- /dev/null +++ b/console/src/components/icon-mosaic.stories.tsx @@ -0,0 +1,60 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { StaggeredMosaic } from "./icon-mosaic" + +const meta: Meta = { + title: "Components/IconMosaic", + component: StaggeredMosaic, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const WithProvider: Story = { + render: () => ( +
+ +
+ ), +} + +export const CustomColor: Story = { + render: () => ( +
+ +
+ ), +} + +export const NoProvider: Story = { + render: () => ( +
+ +
+ ), +} + +export const SmallGrid: Story = { + render: () => ( +
+ +
+ ), +} diff --git a/console/src/components/menu.stories.tsx b/console/src/components/menu.stories.tsx new file mode 100644 index 00000000..32d0bcc0 --- /dev/null +++ b/console/src/components/menu.stories.tsx @@ -0,0 +1,76 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Edit, Trash2, Copy, ExternalLink } from "lucide-react" +import Menu, { MenuItem } from "./menu" +import { Button } from "@/components/ui/button" + +const meta: Meta = { + title: "Components/Menu", + component: Menu, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( +
+ + console.log("Edit")}> + + Edit + + console.log("Duplicate")}> + + Duplicate + + console.log("Open")}> + + Open in new tab + + console.log("Delete")}> + + Delete + + +
+ ), +} + +export const CustomButton: Story = { + render: () => ( +
+ Actions}> + console.log("Edit")}> + + Edit + + console.log("Delete")}> + + Delete + + +
+ ), +} + +export const GhostVariant: Story = { + render: () => ( +
+ + console.log("Copy")}> + + Copy ID + + console.log("Edit")}> + + Edit record + + console.log("Delete")}> + + Remove + + +
+ ), +} diff --git a/console/src/components/modal.stories.tsx b/console/src/components/modal.stories.tsx new file mode 100644 index 00000000..c8edd88c --- /dev/null +++ b/console/src/components/modal.stories.tsx @@ -0,0 +1,115 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { useState } from "react" +import Modal from "./modal" +import { Button } from "@/components/ui/button" + +const meta: Meta = { + title: "Components/Modal", + component: Modal, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const Small: Story = { + render: () => { + const [open, setOpen] = useState(false) + return ( +
+ + + + +
+ } + /> + + ) + }, +} + +export const Regular: Story = { + render: () => { + const [open, setOpen] = useState(false) + return ( +
+ + + + +
+ } + > +
+
+ + +
+
+ + +
+
+ + + ) + }, +} + +export const Large: Story = { + render: () => { + const [open, setOpen] = useState(false) + return ( +
+ + + + +
+ } + > +
+ Drop a file here or click to browse +
+ + + ) + }, +} diff --git a/console/src/components/pagination.stories.tsx b/console/src/components/pagination.stories.tsx new file mode 100644 index 00000000..463bd8c7 --- /dev/null +++ b/console/src/components/pagination.stories.tsx @@ -0,0 +1,42 @@ +import type { Meta, StoryObj } from "@storybook/react" +import CursorPagination from "./pagination" + +const meta: Meta = { + title: "Components/CursorPagination", + component: CursorPagination, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const BothCursors: Story = { + render: () => ( + console.log("Prev:", cursor)} + onNext={(cursor) => console.log("Next:", cursor)} + /> + ), +} + +export const NextOnly: Story = { + render: () => ( + console.log("Prev:", cursor)} + onNext={(cursor) => console.log("Next:", cursor)} + /> + ), +} + +export const PrevOnly: Story = { + render: () => ( + console.log("Prev:", cursor)} + onNext={(cursor) => console.log("Next:", cursor)} + /> + ), +} diff --git a/console/src/components/stack.stories.tsx b/console/src/components/stack.stories.tsx new file mode 100644 index 00000000..45f4c0f8 --- /dev/null +++ b/console/src/components/stack.stories.tsx @@ -0,0 +1,46 @@ +import type { Meta, StoryObj } from "@storybook/react" +import Stack from "./stack" +import { Button } from "@/components/ui/button" + +const meta: Meta = { + title: "Components/Stack", + component: Stack, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const Horizontal: Story = { + render: () => ( + + + + + + ), +} + +export const Vertical: Story = { + render: () => ( + + + + + + ), +} + +export const HorizontalWrapping: Story = { + render: () => ( +
+ + + + + + + +
+ ), +} diff --git a/console/src/components/tile.stories.tsx b/console/src/components/tile.stories.tsx new file mode 100644 index 00000000..843b85ed --- /dev/null +++ b/console/src/components/tile.stories.tsx @@ -0,0 +1,69 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { useState } from "react" +import Tile, { TileGrid } from "./tile" + +const meta: Meta = { + title: "Components/Tile", + component: Tile, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + Authenticate users with a classic email and password combination. + + ), +} + +export const Selected: Story = { + render: () => ( + + Allow users to sign in with their existing social accounts. + + ), +} + +export const Clickable: Story = { + render: () => { + const [selected, setSelected] = useState(null) + return ( + + {["Email", "Google", "GitHub", "SAML"].map((option) => ( + setSelected(option)} + > + Connect with {option}. + + ))} + + ) + }, +} + +export const LargeSize: Story = { + render: () => ( + + Everything in Starter, plus advanced analytics, priority support, and unlimited + integrations. + + ), +} + +export const Grid: Story = { + render: () => ( + + Classic authentication method. + + Sign in with Google. + + Enterprise single sign-on. + + ), +} diff --git a/console/src/components/ui/alert.stories.tsx b/console/src/components/ui/alert.stories.tsx new file mode 100644 index 00000000..067ac47c --- /dev/null +++ b/console/src/components/ui/alert.stories.tsx @@ -0,0 +1,40 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Alert, AlertTitle, AlertDescription } from "./alert" + +const meta: Meta = { + component: Alert, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + Heads up! + + You can add components to your app using the cli. + + + ), +} + +export const Destructive: Story = { + render: () => ( + + Error + + Your session has expired. Please log in again. + + + ), +} + +export const TitleOnly: Story = { + render: () => ( + + Note + + ), +} diff --git a/console/src/components/ui/attribute-editor.stories.tsx b/console/src/components/ui/attribute-editor.stories.tsx new file mode 100644 index 00000000..be3cdb4c --- /dev/null +++ b/console/src/components/ui/attribute-editor.stories.tsx @@ -0,0 +1,56 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { useState } from "react" +import { AttributeEditor } from "./attribute-editor" + +const meta: Meta = { + title: "UI/AttributeEditor", + component: AttributeEditor, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => { + const [value, setValue] = useState>({ + name: "John", + age: 30, + active: true, + }) + return ( +
+ +
+                    {JSON.stringify(value, null, 2)}
+                
+
+ ) + }, +} + +export const StartInCodeMode: Story = { + render: () => { + const [value, setValue] = useState>({ + plan: "pro", + seats: 10, + features: { analytics: true, exports: false }, + }) + return ( +
+ +
+ ) + }, +} + +export const Empty: Story = { + render: () => { + const [value, setValue] = useState>({}) + return ( +
+ +
+ ) + }, +} diff --git a/console/src/components/ui/avatar.stories.tsx b/console/src/components/ui/avatar.stories.tsx new file mode 100644 index 00000000..61fc6e0e --- /dev/null +++ b/console/src/components/ui/avatar.stories.tsx @@ -0,0 +1,44 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Avatar, AvatarImage, AvatarFallback } from "./avatar" + +const meta: Meta = { + component: Avatar, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const WithImage: Story = { + render: () => ( + + + CN + + ), +} + +export const FallbackOnly: Story = { + render: () => ( + + + AB + + ), +} + +export const Initials: Story = { + render: () => ( +
+ + JD + + + MK + + + SB + +
+ ), +} diff --git a/console/src/components/ui/badge.stories.tsx b/console/src/components/ui/badge.stories.tsx new file mode 100644 index 00000000..51992d55 --- /dev/null +++ b/console/src/components/ui/badge.stories.tsx @@ -0,0 +1,48 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Badge } from "./badge" + +const meta: Meta = { + component: Badge, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + args: { + children: "Badge", + }, +} + +export const Secondary: Story = { + args: { + variant: "secondary", + children: "Secondary", + }, +} + +export const Destructive: Story = { + args: { + variant: "destructive", + children: "Destructive", + }, +} + +export const Outline: Story = { + args: { + variant: "outline", + children: "Outline", + }, +} + +export const AllVariants: Story = { + render: () => ( +
+ Default + Secondary + Destructive + Outline +
+ ), +} diff --git a/console/src/components/ui/button.stories.tsx b/console/src/components/ui/button.stories.tsx new file mode 100644 index 00000000..33116cf6 --- /dev/null +++ b/console/src/components/ui/button.stories.tsx @@ -0,0 +1,75 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Button } from "./button" + +const meta: Meta = { + component: Button, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + args: { + children: "Button", + }, +} + +export const Destructive: Story = { + args: { + variant: "destructive", + children: "Delete", + }, +} + +export const Outline: Story = { + args: { + variant: "outline", + children: "Outline", + }, +} + +export const Secondary: Story = { + args: { + variant: "secondary", + children: "Secondary", + }, +} + +export const Ghost: Story = { + args: { + variant: "ghost", + children: "Ghost", + }, +} + +export const Link: Story = { + args: { + variant: "link", + children: "Link", + }, +} + +export const Loading: Story = { + args: { + isLoading: true, + children: "Saving...", + }, +} + +export const Disabled: Story = { + args: { + disabled: true, + children: "Disabled", + }, +} + +export const AllSizes: Story = { + render: () => ( +
+ + + +
+ ), +} diff --git a/console/src/components/ui/card.stories.tsx b/console/src/components/ui/card.stories.tsx new file mode 100644 index 00000000..675b3531 --- /dev/null +++ b/console/src/components/ui/card.stories.tsx @@ -0,0 +1,49 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { + Card, + CardHeader, + CardTitle, + CardDescription, + CardContent, + CardFooter, +} from "./card" +import { Button } from "./button" + +const meta: Meta = { + component: Card, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + + Card Title + Card description goes here. + + +

This is the main content of the card.

+
+ + + + +
+ ), +} + +export const SimpleContent: Story = { + render: () => ( + + + Notifications + + +

You have 3 unread messages.

+
+
+ ), +} diff --git a/console/src/components/ui/checkbox.stories.tsx b/console/src/components/ui/checkbox.stories.tsx new file mode 100644 index 00000000..c5135fb5 --- /dev/null +++ b/console/src/components/ui/checkbox.stories.tsx @@ -0,0 +1,61 @@ +import { useState } from "react" +import type { Meta, StoryObj } from "@storybook/react" +import { Checkbox } from "./checkbox" + +const meta: Meta = { + component: Checkbox, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: () => { + const [checked, setChecked] = useState(false) + return ( +
+ setChecked(!!val)} + /> + +
+ ) + }, +} + +export const Checked: Story = { + render: () => { + const [checked, setChecked] = useState(true) + return ( +
+ setChecked(!!val)} + /> + +
+ ) + }, +} + +export const Disabled: Story = { + args: { + disabled: true, + checked: false, + }, +} + +export const DisabledChecked: Story = { + args: { + disabled: true, + checked: true, + }, +} diff --git a/console/src/components/ui/code-editor.stories.tsx b/console/src/components/ui/code-editor.stories.tsx new file mode 100644 index 00000000..f825be83 --- /dev/null +++ b/console/src/components/ui/code-editor.stories.tsx @@ -0,0 +1,101 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { useState } from "react" +import { CodeEditor } from "./code-editor" + +const meta: Meta = { + title: "UI/CodeEditor", + component: CodeEditor, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +const sampleJson = JSON.stringify( + { + name: "Alice", + age: 30, + roles: ["admin", "editor"], + settings: { + theme: "dark", + notifications: true, + }, + }, + null, + 2, +) + +export const JsonMode: Story = { + render: () => { + const [value, setValue] = useState(sampleJson) + return ( +
+ +
+ ) + }, +} + +export const AutoDetect: Story = { + render: () => { + const [value, setValue] = useState(sampleJson) + return ( +
+ +
+ ) + }, +} + +export const PlainText: Story = { + render: () => { + const [value, setValue] = useState("Hello World\nThis is plain text content.") + return ( +
+ +
+ ) + }, +} + +export const ReadOnly: Story = { + render: () => ( +
+ {}} language="json" readOnly /> +
+ ), +} + +export const WithPlaceholder: Story = { + render: () => { + const [value, setValue] = useState("") + return ( +
+ +
+ ) + }, +} + +export const CustomHeight: Story = { + render: () => { + const [value, setValue] = useState(sampleJson) + return ( +
+ +
+ ) + }, +} diff --git a/console/src/components/ui/collapsible.stories.tsx b/console/src/components/ui/collapsible.stories.tsx new file mode 100644 index 00000000..f864ebad --- /dev/null +++ b/console/src/components/ui/collapsible.stories.tsx @@ -0,0 +1,60 @@ +import { useState } from "react" +import type { Meta, StoryObj } from "@storybook/react" +import { Collapsible, CollapsibleTrigger, CollapsibleContent } from "./collapsible" +import { Button } from "./button" + +const meta: Meta = { + component: Collapsible, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: () => { + const [open, setOpen] = useState(false) + return ( + +
+ Advanced options + + + +
+ +
+

Option 1: Enable feature flags

+

Option 2: Debug mode

+

Option 3: Verbose logging

+
+
+
+ ) + }, +} + +export const DefaultOpen: Story = { + render: () => { + const [open, setOpen] = useState(true) + return ( + +
+ Details + + + +
+ +

+ This section starts expanded by default. +

+
+
+ ) + }, +} diff --git a/console/src/components/ui/color-picker.stories.tsx b/console/src/components/ui/color-picker.stories.tsx new file mode 100644 index 00000000..9e23959e --- /dev/null +++ b/console/src/components/ui/color-picker.stories.tsx @@ -0,0 +1,57 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { useState } from "react" +import { ColorPicker } from "./color-picker" + +const meta: Meta = { + title: "UI/ColorPicker", + component: ColorPicker, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => { + const [color, setColor] = useState("#3b82f6") + return ( +
+ +

Selected: {color}

+
+ ) + }, +} + +export const WithClear: Story = { + render: () => { + const [color, setColor] = useState("#22c55e") + return ( +
+ setColor("#000000")} + /> +

Selected: {color}

+
+ ) + }, +} + +export const Inline: Story = { + render: () => { + const [color, setColor] = useState("#a855f7") + return ( +
+ setColor("#000000")} + inline + /> +

Selected: {color}

+
+ ) + }, +} diff --git a/console/src/components/ui/combobox.stories.tsx b/console/src/components/ui/combobox.stories.tsx new file mode 100644 index 00000000..6a15c40a --- /dev/null +++ b/console/src/components/ui/combobox.stories.tsx @@ -0,0 +1,66 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { useState } from "react" +import { Combobox } from "./combobox" + +const meta: Meta = { + title: "UI/Combobox", + component: Combobox, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +const options = [ + { path: "production" }, + { path: "staging" }, + { path: "development" }, + { path: "testing" }, + { path: "preview" }, +] + +export const Default: Story = { + render: () => { + const [value, setValue] = useState("") + return ( +
+ +
+ ) + }, +} + +export const WithSelectedValue: Story = { + render: () => { + const [value, setValue] = useState("production") + return ( +
+ +
+ ) + }, +} + +export const Disabled: Story = { + render: () => ( +
+ {}} + placeholder="Select environment..." + disabled + /> +
+ ), +} diff --git a/console/src/components/ui/command.stories.tsx b/console/src/components/ui/command.stories.tsx new file mode 100644 index 00000000..da481f10 --- /dev/null +++ b/console/src/components/ui/command.stories.tsx @@ -0,0 +1,57 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { + Command, + CommandInput, + CommandList, + CommandEmpty, + CommandGroup, + CommandItem, + CommandShortcut, + CommandSeparator, +} from "./command" + +const meta: Meta = { + component: Command, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + + + No results found. + + + Calendar + ⌘C + + + Search + ⌘S + + Settings + + + + New File + New Folder + + + + ), +} + +export const EmptyState: Story = { + render: () => ( + + + + No results found. + + + ), +} diff --git a/console/src/components/ui/datetime-edit.stories.tsx b/console/src/components/ui/datetime-edit.stories.tsx new file mode 100644 index 00000000..92efaa07 --- /dev/null +++ b/console/src/components/ui/datetime-edit.stories.tsx @@ -0,0 +1,67 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { useState } from "react" +import { DateTimeEdit } from "./datetime-edit" + +const meta: Meta = { + title: "UI/DateTimeEdit", + component: DateTimeEdit, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => { + const [value, setValue] = useState("2024-01-15T10:30:00.000Z") + return ( +
+

Click the date to edit:

+ { + await new Promise((r) => setTimeout(r, 500)) + setValue(v) + }} + /> +

ISO value: {value}

+
+ ) + }, +} + +export const AlignCenter: Story = { + render: () => { + const [value, setValue] = useState("2024-01-15T10:30:00.000Z") + return ( +
+ { + await new Promise((r) => setTimeout(r, 300)) + setValue(v) + }} + align="center" + /> +
+ ) + }, +} + +export const AlignEnd: Story = { + render: () => { + const [value, setValue] = useState("2024-06-30T23:59:00.000Z") + return ( +
+ { + await new Promise((r) => setTimeout(r, 300)) + setValue(v) + }} + align="end" + /> +
+ ) + }, +} diff --git a/console/src/components/ui/dialog.stories.tsx b/console/src/components/ui/dialog.stories.tsx new file mode 100644 index 00000000..d4604f82 --- /dev/null +++ b/console/src/components/ui/dialog.stories.tsx @@ -0,0 +1,67 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { + Dialog, + DialogTrigger, + DialogContent, + DialogHeader, + DialogFooter, + DialogTitle, + DialogDescription, + DialogClose, +} from "./dialog" +import { Button } from "./button" + +const meta: Meta = { + component: Dialog, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + + + + + + Confirm Action + + Are you sure you want to proceed? This action cannot be undone. + + + + + + + + + + + ), +} + +export const WithoutCloseButton: Story = { + render: () => ( + + + + + + + No Close Icon + + This dialog hides the default close icon. Use the button below to dismiss. + + + + + + + + + + ), +} diff --git a/console/src/components/ui/dropdown-menu.stories.tsx b/console/src/components/ui/dropdown-menu.stories.tsx new file mode 100644 index 00000000..d4c785a5 --- /dev/null +++ b/console/src/components/ui/dropdown-menu.stories.tsx @@ -0,0 +1,130 @@ +import { useState } from "react" +import type { Meta, StoryObj } from "@storybook/react" +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuGroup, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuCheckboxItem, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, +} from "./dropdown-menu" +import { Button } from "./button" + +const meta: Meta = { + component: DropdownMenu, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + + + + + My Account + + + + Profile + ⇧⌘P + + + Settings + ⌘, + + + + + Log out + ⇧⌘Q + + + + ), +} + +export const WithSubMenu: Story = { + render: () => ( + + + + + + Edit + + Share + + Email + Copy link + + + + Delete + + + ), +} + +export const WithCheckboxItems: Story = { + render: () => { + const [showStatus, setShowStatus] = useState(true) + const [showPanel, setShowPanel] = useState(false) + return ( + + + + + + View Options + + + Show Status Bar + + + Show Side Panel + + + + ) + }, +} + +export const WithRadioItems: Story = { + render: () => { + const [position, setPosition] = useState("bottom") + return ( + + + + + + Panel Position + + + Top + Bottom + Right + + + + ) + }, +} diff --git a/console/src/components/ui/field.stories.tsx b/console/src/components/ui/field.stories.tsx new file mode 100644 index 00000000..9b77b958 --- /dev/null +++ b/console/src/components/ui/field.stories.tsx @@ -0,0 +1,114 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { + Field, + FieldLabel, + FieldDescription, + FieldError, + FieldGroup, + FieldSet, + FieldContent, + FieldTitle, + FieldLegend, + FieldSeparator, +} from "./field" +import { Input } from "./input" + +const meta: Meta = { + title: "UI/Field", + component: Field, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const Vertical: Story = { + render: () => ( + + Name + + + + Your full name. + + ), +} + +export const Horizontal: Story = { + render: () => ( + + Email + + + + We will never share your email. + + ), +} + +export const Responsive: Story = { + render: () => ( + + + Username + + + + Your public display name. + + + Website + + + + + + ), +} + +export const WithError: Story = { + render: () => ( + + Password + + + + + + ), +} + +export const WithFieldSet: Story = { + render: () => ( +
+ Personal Info + + + First Name + + + + + + + Last Name + + + + + +
+ ), +} + +export const WithFieldTitle: Story = { + render: () => ( + + API Key + + + + Keep this secret. Never share it publicly. + + ), +} diff --git a/console/src/components/ui/form.stories.tsx b/console/src/components/ui/form.stories.tsx new file mode 100644 index 00000000..c0922ba8 --- /dev/null +++ b/console/src/components/ui/form.stories.tsx @@ -0,0 +1,169 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { useForm } from "react-hook-form" +import { + Form, + FormField, + FormItem, + FormLabel, + FormControl, + FormDescription, + FormMessage, +} from "./form" +import { Input } from "./input" +import { Button } from "./button" + +const meta: Meta = { + title: "UI/Form", + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +interface LoginFormValues { + email: string + password: string +} + +export const LoginForm: Story = { + render: () => { + const form = useForm({ + defaultValues: { email: "", password: "" }, + }) + + const onSubmit = (values: LoginFormValues) => { + console.log("Form submitted:", values) + } + + return ( +
+

Sign in

+
+ + ( + + Email + + + + + We will never share your email. + + + + )} + /> + ( + + Password + + + + + + )} + /> + + + +
+ ) + }, +} + +export const WithValidationErrors: Story = { + render: () => { + const form = useForm({ + defaultValues: { email: "not-an-email", password: "123" }, + mode: "onChange", + }) + + // Trigger validation immediately + const onSubmit = (values: LoginFormValues) => { + console.log("Form submitted:", values) + } + + return ( +
+

Sign in — with errors

+
+ + ( + + Email + + + + + + )} + /> + ( + + Password + + + + + + )} + /> + + + +
+ ) + }, +} diff --git a/console/src/components/ui/inline-edit.stories.tsx b/console/src/components/ui/inline-edit.stories.tsx new file mode 100644 index 00000000..6f142e70 --- /dev/null +++ b/console/src/components/ui/inline-edit.stories.tsx @@ -0,0 +1,86 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { useState } from "react" +import { InlineEdit } from "./inline-edit" + +const meta: Meta = { + title: "UI/InlineEdit", + component: InlineEdit, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => { + const [value, setValue] = useState("Alice Smith") + return ( +
+

Click the name to edit:

+ { + await new Promise((r) => setTimeout(r, 500)) + setValue(v) + }} + placeholder="Enter a name" + /> +
+ ) + }, +} + +export const Empty: Story = { + render: () => { + const [value, setValue] = useState("") + return ( +
+

Empty — click to set a value:

+ { + await new Promise((r) => setTimeout(r, 300)) + setValue(v) + }} + placeholder="Click to add a description" + /> +
+ ) + }, +} + +export const AlignCenter: Story = { + render: () => { + const [value, setValue] = useState("Centered popover") + return ( +
+ { + await new Promise((r) => setTimeout(r, 300)) + setValue(v) + }} + align="center" + /> +
+ ) + }, +} + +export const AlignEnd: Story = { + render: () => { + const [value, setValue] = useState("End-aligned popover") + return ( +
+ { + await new Promise((r) => setTimeout(r, 300)) + setValue(v) + }} + align="end" + /> +
+ ) + }, +} diff --git a/console/src/components/ui/input-group.stories.tsx b/console/src/components/ui/input-group.stories.tsx new file mode 100644 index 00000000..ffa85e57 --- /dev/null +++ b/console/src/components/ui/input-group.stories.tsx @@ -0,0 +1,82 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Search } from "lucide-react" +import { + InputGroup, + InputGroupAddon, + InputGroupInput, + InputGroupText, + InputGroupButton, + InputGroupTextarea, +} from "./input-group" + +const meta: Meta = { + title: "UI/InputGroup", + component: InputGroup, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const CurrencyAmount: Story = { + render: () => ( + + + $ + + + + .00 + + + ), +} + +export const SearchWithButton: Story = { + render: () => ( + + + + + + + + + Go + + + ), +} + +export const UrlInput: Story = { + render: () => ( + + + https:// + + + + ), +} + +export const BlockStartLabel: Story = { + render: () => ( + + + Message + + + + ), +} + +export const BlockEndLabel: Story = { + render: () => ( + + + + characters remaining: 100 + + + ), +} diff --git a/console/src/components/ui/input.stories.tsx b/console/src/components/ui/input.stories.tsx new file mode 100644 index 00000000..a102c5b0 --- /dev/null +++ b/console/src/components/ui/input.stories.tsx @@ -0,0 +1,44 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Input } from "./input" + +const meta: Meta = { + component: Input, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + args: { + placeholder: "Enter text...", + }, +} + +export const WithValue: Story = { + args: { + defaultValue: "Hello, world!", + }, +} + +export const Password: Story = { + args: { + type: "password", + placeholder: "Enter password...", + }, +} + +export const Disabled: Story = { + args: { + disabled: true, + placeholder: "Disabled input", + defaultValue: "Cannot edit this", + }, +} + +export const Email: Story = { + args: { + type: "email", + placeholder: "user@example.com", + }, +} diff --git a/console/src/components/ui/item.stories.tsx b/console/src/components/ui/item.stories.tsx new file mode 100644 index 00000000..67e396ed --- /dev/null +++ b/console/src/components/ui/item.stories.tsx @@ -0,0 +1,160 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Settings, User, Bell } from "lucide-react" +import { + Item, + ItemMedia, + ItemContent, + ItemActions, + ItemGroup, + ItemSeparator, + ItemTitle, + ItemDescription, + ItemHeader, + ItemFooter, +} from "./item" +import { Button } from "./button" + +const meta: Meta = { + title: "UI/Item", + component: Item, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + + + + + John Doe + Administrator account with full access. + + + + + + ), +} + +export const Outline: Story = { + render: () => ( + + + + + + Settings + Configure your application preferences. + + + + + + ), +} + +export const Muted: Story = { + render: () => ( + + + + + + Notifications + Manage your notification preferences. + + + ), +} + +export const Small: Story = { + render: () => ( + + + + + + Compact Item + A smaller size variant. + + + + + + ), +} + +export const ItemGroupExample: Story = { + render: () => ( + + + + + + + Alice Smith + alice@example.com + + + + + + + + + + + + Bob Jones + bob@example.com + + + + + + + + + + + + Carol White + carol@example.com + + + + + + + ), +} + +export const WithHeaderAndFooter: Story = { + render: () => ( + + + Project Alpha + Active + + + + A long-running project with multiple contributors and ongoing deployments. + + + + Last updated 2 hours ago + + + + ), +} diff --git a/console/src/components/ui/json-view.stories.tsx b/console/src/components/ui/json-view.stories.tsx new file mode 100644 index 00000000..9370fa34 --- /dev/null +++ b/console/src/components/ui/json-view.stories.tsx @@ -0,0 +1,84 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { JsonView, JsonInline } from "./json-view" + +const meta: Meta = { + title: "UI/JsonView", + component: JsonView, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +const sampleData = { + id: "usr_01j9x2k3m4n5p6q7", + name: "Alice Smith", + email: "alice@example.com", + active: true, + age: 29, + roles: ["admin", "editor"], + address: { + street: "123 Main St", + city: "Springfield", + country: "US", + }, + metadata: { + created_at: "2024-01-15T10:30:00Z", + website: "https://alice.example.com", + }, +} + +export const Default: Story = { + render: () => ( +
+ +
+ ), +} + +export const WithTitle: Story = { + render: () => ( +
+ +
+ ), +} + +export const Collapsed: Story = { + render: () => ( +
+ +
+ ), +} + +export const SimpleObject: Story = { + render: () => ( +
+ +
+ ), +} + +export const Inline: StoryObj = { + render: () => ( +
+

+ Payload: +

+

+ Tags: +

+

+ Truncated:{" "} + +

+
+ ), +} diff --git a/console/src/components/ui/key-value-editor.stories.tsx b/console/src/components/ui/key-value-editor.stories.tsx new file mode 100644 index 00000000..d95642f3 --- /dev/null +++ b/console/src/components/ui/key-value-editor.stories.tsx @@ -0,0 +1,66 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { useState } from "react" +import { KeyValueEditor } from "./key-value-editor" + +const meta: Meta = { + title: "UI/KeyValueEditor", + component: KeyValueEditor, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => { + const [value, setValue] = useState>({ + Content_Type: "application/json", + Authorization: "Bearer token", + }) + return ( +
+ +
+                    {JSON.stringify(value, null, 2)}
+                
+
+ ) + }, +} + +export const Empty: Story = { + render: () => { + const [value, setValue] = useState>({}) + return ( +
+ +
+ ) + }, +} + +export const CustomLabels: Story = { + render: () => { + const [value, setValue] = useState>({ + NODE_ENV: "production", + PORT: "3000", + DATABASE_URL: "postgres://localhost/mydb", + }) + return ( +
+ +
+ ) + }, +} diff --git a/console/src/components/ui/label.stories.tsx b/console/src/components/ui/label.stories.tsx new file mode 100644 index 00000000..c1e899a4 --- /dev/null +++ b/console/src/components/ui/label.stories.tsx @@ -0,0 +1,37 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Label } from "./label" +import { Input } from "./input" + +const meta: Meta = { + component: Label, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + args: { + children: "Email address", + }, +} + +export const WithInput: Story = { + render: () => ( +
+ + +
+ ), +} + +export const Required: Story = { + render: () => ( +
+ + +
+ ), +} diff --git a/console/src/components/ui/multi-select.stories.tsx b/console/src/components/ui/multi-select.stories.tsx new file mode 100644 index 00000000..1994c643 --- /dev/null +++ b/console/src/components/ui/multi-select.stories.tsx @@ -0,0 +1,84 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { useState } from "react" +import { MultiSelect } from "./multi-select" + +const meta: Meta = { + title: "UI/MultiSelect", + component: MultiSelect, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +const options = [ + { value: "react", label: "React" }, + { value: "vue", label: "Vue" }, + { value: "angular", label: "Angular" }, + { value: "svelte", label: "Svelte" }, + { value: "solid", label: "Solid" }, + { value: "qwik", label: "Qwik" }, +] + +export const Default: Story = { + render: () => { + const [value, setValue] = useState([]) + return ( +
+ +
+ ) + }, +} + +export const WithPreselected: Story = { + render: () => { + const [value, setValue] = useState(["react", "vue"]) + return ( +
+ +
+ ) + }, +} + +export const MaxDisplayTwo: Story = { + render: () => { + const [value, setValue] = useState(["react", "vue", "angular", "svelte"]) + return ( +
+ +
+ ) + }, +} + +export const Disabled: Story = { + render: () => ( +
+ {}} + placeholder="Select frameworks..." + disabled + /> +
+ ), +} diff --git a/console/src/components/ui/nav-tabs.stories.tsx b/console/src/components/ui/nav-tabs.stories.tsx new file mode 100644 index 00000000..778e37c8 --- /dev/null +++ b/console/src/components/ui/nav-tabs.stories.tsx @@ -0,0 +1,58 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { useState } from "react" +import { Home, Settings, Users, Bell } from "lucide-react" +import { NavTabs } from "./nav-tabs" +import type { NavTab } from "./nav-tabs" + +const meta: Meta = { + title: "UI/NavTabs", + component: NavTabs, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +const tabs: NavTab[] = [ + { key: "overview", label: "Overview", icon: Home }, + { key: "members", label: "Members", icon: Users, badge: 3 }, + { key: "settings", label: "Settings", icon: Settings }, + { key: "notifications", label: "Notifications", icon: Bell, badge: 12 }, +] + +export const StateBased: Story = { + render: () => { + const [value, setValue] = useState("overview") + return ( +
+ +
+ ) + }, +} + +export const WithBadges: Story = { + render: () => { + const [value, setValue] = useState("members") + return ( +
+ +
+ ) + }, +} + +export const TwoTabs: Story = { + render: () => { + const [value, setValue] = useState("general") + const simpleTabs: NavTab[] = [ + { key: "general", label: "General", icon: Settings }, + { key: "security", label: "Security", icon: Bell }, + ] + return ( +
+ +
+ ) + }, +} diff --git a/console/src/components/ui/pagination.stories.tsx b/console/src/components/ui/pagination.stories.tsx new file mode 100644 index 00000000..faa98379 --- /dev/null +++ b/console/src/components/ui/pagination.stories.tsx @@ -0,0 +1,75 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { + Pagination, + PaginationContent, + PaginationItem, + PaginationLink, + PaginationPrevious, + PaginationNext, + PaginationEllipsis, +} from "./pagination" + +const meta: Meta = { + component: Pagination, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + + + + + + 1 + + + 2 + + + 3 + + + + + + + ), +} + +export const WithEllipsis: Story = { + render: () => ( + + + + + + + 1 + + + + + + 5 + + + 6 + + + + + + 10 + + + + + + + ), +} diff --git a/console/src/components/ui/popover.stories.tsx b/console/src/components/ui/popover.stories.tsx new file mode 100644 index 00000000..77b10aaa --- /dev/null +++ b/console/src/components/ui/popover.stories.tsx @@ -0,0 +1,51 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Popover, PopoverTrigger, PopoverContent } from "./popover" +import { Button } from "./button" + +const meta: Meta = { + component: Popover, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + + + + +
+

Dimensions

+

+ Set the dimensions for the layer. +

+
+
+
+ ), +} + +export const WithForm: Story = { + render: () => ( + + + + + +
+

Quick Settings

+ +
+
+
+ ), +} diff --git a/console/src/components/ui/resizable.stories.tsx b/console/src/components/ui/resizable.stories.tsx new file mode 100644 index 00000000..cd34ab86 --- /dev/null +++ b/console/src/components/ui/resizable.stories.tsx @@ -0,0 +1,79 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from "./resizable" + +const meta: Meta = { + component: ResizablePanelGroup, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Horizontal: Story = { + render: () => ( + + +
+ Left Panel +
+
+ + +
+ Right Panel +
+
+
+ ), +} + +export const Vertical: Story = { + render: () => ( + + +
+ Top Panel +
+
+ + +
+ Bottom Panel +
+
+
+ ), +} + +export const ThreeColumns: Story = { + render: () => ( + + +
+ Sidebar +
+
+ + +
+ Content +
+
+ + +
+ Inspector +
+
+
+ ), +} diff --git a/console/src/components/ui/scroll-area.stories.tsx b/console/src/components/ui/scroll-area.stories.tsx new file mode 100644 index 00000000..26156fb3 --- /dev/null +++ b/console/src/components/ui/scroll-area.stories.tsx @@ -0,0 +1,51 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { ScrollArea, ScrollBar } from "./scroll-area" + +const meta: Meta = { + component: ScrollArea, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +const tags = Array.from({ length: 50 }, (_, i) => `Item ${i + 1}`) + +export const Vertical: Story = { + render: () => ( + + {tags.map((tag) => ( +
+ {tag} +
+ ))} +
+ ), +} + +export const Horizontal: Story = { + render: () => ( + +
+ {Array.from({ length: 20 }, (_, i) => ( +
+ Card {i + 1} +
+ ))} +
+ +
+ ), +} diff --git a/console/src/components/ui/select.stories.tsx b/console/src/components/ui/select.stories.tsx new file mode 100644 index 00000000..f138390f --- /dev/null +++ b/console/src/components/ui/select.stories.tsx @@ -0,0 +1,84 @@ +import { useState } from "react" +import type { Meta, StoryObj } from "@storybook/react" +import { + Select, + SelectTrigger, + SelectValue, + SelectContent, + SelectItem, + SelectLabel, + SelectGroup, + SelectSeparator, +} from "./select" + +const meta: Meta = { + component: Select, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: () => { + const [value, setValue] = useState("") + return ( + + ) + }, +} + +export const WithGroups: Story = { + render: () => { + const [value, setValue] = useState("") + return ( + + ) + }, +} + +export const WithPreselectedValue: Story = { + render: () => { + const [value, setValue] = useState("banana") + return ( + + ) + }, +} diff --git a/console/src/components/ui/separator.stories.tsx b/console/src/components/ui/separator.stories.tsx new file mode 100644 index 00000000..f7fdb943 --- /dev/null +++ b/console/src/components/ui/separator.stories.tsx @@ -0,0 +1,32 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Separator } from "./separator" + +const meta: Meta = { + component: Separator, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Horizontal: Story = { + render: () => ( +
+

Above the separator

+ +

Below the separator

+
+ ), +} + +export const Vertical: Story = { + render: () => ( +
+ Home + + About + + Contact +
+ ), +} diff --git a/console/src/components/ui/sheet.stories.tsx b/console/src/components/ui/sheet.stories.tsx new file mode 100644 index 00000000..89a513d2 --- /dev/null +++ b/console/src/components/ui/sheet.stories.tsx @@ -0,0 +1,89 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { + Sheet, + SheetTrigger, + SheetContent, + SheetHeader, + SheetTitle, + SheetDescription, + SheetFooter, + SheetClose, +} from "./sheet" +import { Button } from "./button" + +const meta: Meta = { + component: Sheet, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Right: Story = { + render: () => ( + + + + + + + Edit Profile + + Make changes to your profile here. Click save when done. + + + + + + + + + + + ), +} + +export const Left: Story = { + render: () => ( + + + + + + + Navigation + Main application navigation. + +
+ + + +
+
+
+ ), +} + +export const Bottom: Story = { + render: () => ( + + + + + + + Confirm Deletion + + This action cannot be undone. The item will be permanently deleted. + + + + + + + + + + + ), +} diff --git a/console/src/components/ui/sidebar.stories.tsx b/console/src/components/ui/sidebar.stories.tsx new file mode 100644 index 00000000..95952c6d --- /dev/null +++ b/console/src/components/ui/sidebar.stories.tsx @@ -0,0 +1,152 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Home, Settings, Users, Bell, LogOut } from "lucide-react" +import { + SidebarProvider, + Sidebar, + SidebarContent, + SidebarGroup, + SidebarGroupLabel, + SidebarGroupContent, + SidebarMenu, + SidebarMenuItem, + SidebarMenuButton, + SidebarHeader, + SidebarFooter, + SidebarTrigger, + SidebarInset, +} from "./sidebar" + +const meta: Meta = { + title: "UI/Sidebar", + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( + +
+ + + My App + + + + Navigation + + + + + + Home + + + + + + Users + + + + + + Notifications + + + + + + + System + + + + + + Settings + + + + + + + + + + + + Sign out + + + + + + +
+ +

Dashboard

+
+
+

+ Main content area. Toggle the sidebar with the trigger button. +

+
+
+
+
+ ), +} + +export const CollapsedByDefault: Story = { + render: () => ( + +
+ + + My App + + + + Navigation + + + + + + Home + + + + + + Users + + + + + + Settings + + + + + + + + +
+ +

Dashboard

+
+
+

+ Sidebar is collapsed by default. Click the trigger to expand it. +

+
+
+
+
+ ), +} diff --git a/console/src/components/ui/skeleton.stories.tsx b/console/src/components/ui/skeleton.stories.tsx new file mode 100644 index 00000000..6937ad30 --- /dev/null +++ b/console/src/components/ui/skeleton.stories.tsx @@ -0,0 +1,39 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Skeleton } from "./skeleton" + +const meta: Meta = { + component: Skeleton, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + args: { + style: { width: "200px", height: "20px" }, + }, +} + +export const CardSkeleton: Story = { + render: () => ( +
+ + + + +
+ ), +} + +export const ProfileSkeleton: Story = { + render: () => ( +
+ +
+ + +
+
+ ), +} diff --git a/console/src/components/ui/sonner.stories.tsx b/console/src/components/ui/sonner.stories.tsx new file mode 100644 index 00000000..866e4f34 --- /dev/null +++ b/console/src/components/ui/sonner.stories.tsx @@ -0,0 +1,46 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { toast } from "sonner" +import { Toaster } from "./sonner" +import { Button } from "./button" + +const meta: Meta = { + component: Toaster, + tags: ["autodocs"], + decorators: [ + (Story) => ( + <> + +
+ + + + + +
+ + ), + ], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: () => , +} + +export const RichColors: Story = { + render: () => , +} + +export const TopCenter: Story = { + render: () => , +} diff --git a/console/src/components/ui/switch.stories.tsx b/console/src/components/ui/switch.stories.tsx new file mode 100644 index 00000000..0cd20679 --- /dev/null +++ b/console/src/components/ui/switch.stories.tsx @@ -0,0 +1,61 @@ +import { useState } from "react" +import type { Meta, StoryObj } from "@storybook/react" +import { Switch } from "./switch" + +const meta: Meta = { + component: Switch, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: () => { + const [checked, setChecked] = useState(false) + return ( +
+ + +
+ ) + }, +} + +export const Enabled: Story = { + render: () => { + const [checked, setChecked] = useState(true) + return ( +
+ + +
+ ) + }, +} + +export const Disabled: Story = { + args: { + disabled: true, + checked: false, + }, +} + +export const DisabledChecked: Story = { + args: { + disabled: true, + checked: true, + }, +} diff --git a/console/src/components/ui/table.stories.tsx b/console/src/components/ui/table.stories.tsx new file mode 100644 index 00000000..d79373d8 --- /dev/null +++ b/console/src/components/ui/table.stories.tsx @@ -0,0 +1,82 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { + Table, + TableHeader, + TableBody, + TableHead, + TableRow, + TableCell, + TableCaption, +} from "./table" + +const meta: Meta = { + component: Table, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +const invoices = [ + { id: "INV-001", status: "Paid", method: "Credit Card", amount: "$250.00" }, + { id: "INV-002", status: "Pending", method: "PayPal", amount: "$150.00" }, + { id: "INV-003", status: "Unpaid", method: "Bank Transfer", amount: "$350.00" }, + { id: "INV-004", status: "Paid", method: "Credit Card", amount: "$450.00" }, +] + +export const Default: Story = { + render: () => ( + + A list of your recent invoices. + + + Invoice + Status + Method + Amount + + + + {invoices.map((invoice) => ( + + {invoice.id} + {invoice.status} + {invoice.method} + {invoice.amount} + + ))} + +
+ ), +} + +export const Simple: Story = { + render: () => ( + + + + Name + Role + Status + + + + + Alice Johnson + Admin + Active + + + Bob Smith + Editor + Inactive + + + Carol White + Viewer + Active + + +
+ ), +} diff --git a/console/src/components/ui/tabs.stories.tsx b/console/src/components/ui/tabs.stories.tsx new file mode 100644 index 00000000..353dd4c3 --- /dev/null +++ b/console/src/components/ui/tabs.stories.tsx @@ -0,0 +1,52 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Tabs, TabsList, TabsTrigger, TabsContent } from "./tabs" + +const meta: Meta = { + component: Tabs, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + + Account + Password + + +

+ Make changes to your account here. Click save when you are done. +

+
+ +

+ Change your password here. After saving, you will be logged out. +

+
+
+ ), +} + +export const ThreeTabs: Story = { + render: () => ( + + + Overview + Analytics + Settings + + +

Overview content goes here.

+
+ +

Analytics content goes here.

+
+ +

Settings content goes here.

+
+
+ ), +} diff --git a/console/src/components/ui/template-input.stories.tsx b/console/src/components/ui/template-input.stories.tsx new file mode 100644 index 00000000..c365e25f --- /dev/null +++ b/console/src/components/ui/template-input.stories.tsx @@ -0,0 +1,69 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { useState } from "react" +import { TemplateInput } from "./template-input" + +const meta: Meta = { + title: "UI/TemplateInput", + component: TemplateInput, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => { + const [value, setValue] = useState("Hello, world!") + return ( +
+ +

{value}

+
+ ) + }, +} + +export const WithInitialTemplate: Story = { + render: () => { + const [value, setValue] = useState("Welcome back, {{ user.name }}!") + return ( +
+ +

{value}

+
+ ) + }, +} + +export const Compact: Story = { + render: () => { + const [value, setValue] = useState("{{ event.type }}") + return ( +
+ +
+ ) + }, +} + +export const Disabled: Story = { + render: () => ( +
+ {}} + placeholder="Enter a message..." + disabled + /> +
+ ), +} diff --git a/console/src/components/ui/textarea.stories.tsx b/console/src/components/ui/textarea.stories.tsx new file mode 100644 index 00000000..54135803 --- /dev/null +++ b/console/src/components/ui/textarea.stories.tsx @@ -0,0 +1,38 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Textarea } from "./textarea" + +const meta: Meta = { + component: Textarea, + tags: ["autodocs"], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + args: { + placeholder: "Type your message here...", + }, +} + +export const WithValue: Story = { + args: { + defaultValue: "This is some pre-filled content.\nIt spans multiple lines.", + rows: 4, + }, +} + +export const Disabled: Story = { + args: { + disabled: true, + placeholder: "This textarea is disabled", + defaultValue: "Read-only content", + }, +} + +export const Tall: Story = { + args: { + placeholder: "Write a detailed description...", + rows: 8, + }, +} diff --git a/console/src/components/ui/tooltip.stories.tsx b/console/src/components/ui/tooltip.stories.tsx new file mode 100644 index 00000000..4c16bf73 --- /dev/null +++ b/console/src/components/ui/tooltip.stories.tsx @@ -0,0 +1,57 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "./tooltip" +import { Button } from "./button" + +const meta: Meta = { + component: Tooltip, + tags: ["autodocs"], + decorators: [ + (Story) => ( + + + + ), + ], +} +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + + + + +

This is a tooltip

+
+
+ ), +} + +export const WithLongText: Story = { + render: () => ( + + + + + +

This tooltip contains a longer description to explain something in detail.

+
+
+ ), +} + +export const AboveElement: Story = { + render: () => ( + + + + + +

Appears above

+
+
+ ), +} diff --git a/console/src/components/ui/user-import-dialog.stories.tsx b/console/src/components/ui/user-import-dialog.stories.tsx new file mode 100644 index 00000000..243f3c14 --- /dev/null +++ b/console/src/components/ui/user-import-dialog.stories.tsx @@ -0,0 +1,48 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { useState } from "react" +import { UserImportDialog } from "./user-import-dialog" +import { Button } from "./button" + +const meta: Meta = { + title: "UI/UserImportDialog", + component: UserImportDialog, + tags: ["autodocs"], +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => { + const [open, setOpen] = useState(false) + return ( +
+ + { + await new Promise((r) => setTimeout(r, 1500)) + console.log("Imported file:", file.name) + }} + /> +
+ ) + }, +} + +export const OpenByDefault: Story = { + render: () => { + const [open, setOpen] = useState(true) + return ( + { + await new Promise((r) => setTimeout(r, 1500)) + console.log("Imported file:", file.name) + }} + /> + ) + }, +} diff --git a/console/vitest.shims.d.ts b/console/vitest.shims.d.ts new file mode 100644 index 00000000..7782f28d --- /dev/null +++ b/console/vitest.shims.d.ts @@ -0,0 +1 @@ +/// \ No newline at end of file