feat(ui): enable storybook snapshot tests

- adds a process-compose namespace for running `storybook` and `luakit` together to replicate the `webkit`-based rendering that happens inside of `webview`
- adds some helper scripts for running storybook tests and updating snapshots, with documentation in the README.
- adds a `clan-app-ui-storybook` package which builds and tests the storybook, checking for rendering changes

Currently, we’re only doing markup-based snapshot tests. We’re also using headless chromium for the tests by default as I couldn't get webkit to work in the nix build.

As we’re only markup-based for the time being, this should be ok. But eventually I'd like to get it working with webkit.
This commit is contained in:
Brian McGee
2025-05-28 16:08:05 +01:00
parent d863861793
commit 41f7ae08a8
13 changed files with 689 additions and 148 deletions

View File

@@ -26,7 +26,7 @@ direnv: export +AR +AS +CC +CLAN_CORE_PATH +CONFIG_SHELL +CXX +DETERMINISTIC_BUI
Once that has loaded, you can run the local dev environment by running: Once that has loaded, you can run the local dev environment by running:
``` ```
$ process-compose --use-uds --keep-project $ process-compose --use-uds --keep-project -n app
``` ```
This will start a [process-compose] instance containing two processes: This will start a [process-compose] instance containing two processes:
@@ -50,6 +50,24 @@ From there you can start `clan-app` again with `F7`.
Follow the instructions below to set up your development environment and start the application: Follow the instructions below to set up your development environment and start the application:
## Storybook
We use [Storybook] to develop UI components.
It can be started by running the following:
```console
$ process-compose --use-uds --keep-project -n storybook
```
This will start a [process-compose] instance containing two processes:
* `storybook` which is the main [storybook] process.
* `luakit` which is a [webkit]-based browser for viewing the stories with. This is the same underlying engine used when
rendering the app.
You can run storybook tests with `npm run test-storybook`.
If you change how a component(s) renders,
you will need to update the snapshots with `npm run test-storybook-update-snapshots`.
## Start clan-app without process-compose ## Start clan-app without process-compose
@@ -139,3 +157,5 @@ Here are some important documentation links related to the Clan App:
[process-compose]: https://f1bonacc1.github.io/process-compose/ [process-compose]: https://f1bonacc1.github.io/process-compose/
[vite]: https://vite.dev/ [vite]: https://vite.dev/
[webview]: https://github.com/webview/webview [webview]: https://github.com/webview/webview
[Storybook]: https://storybook.js.org/
[webkit]: https://webkit.org/

View File

@@ -29,6 +29,8 @@
fonts = config.packages.fonts; fonts = config.packages.fonts;
}; };
packages.clan-app-ui-storybook = self'.packages.clan-app-ui.storybook;
checks = config.packages.clan-app.tests; checks = config.packages.clan-app.tests;
}; };
} }

View File

@@ -1,7 +1,10 @@
version: "0.5" version: "0.5"
processes: processes:
# App Dev
clan-app-ui: clan-app-ui:
namespace: "app"
command: | command: |
cd $(git rev-parse --show-toplevel)/pkgs/clan-app/ui cd $(git rev-parse --show-toplevel)/pkgs/clan-app/ui
npm install npm install
@@ -9,6 +12,7 @@ processes:
ready_log_line: "VITE" ready_log_line: "VITE"
clan-app: clan-app:
namespace: "app"
command: | command: |
cd $(git rev-parse --show-toplevel)/pkgs/clan-app cd $(git rev-parse --show-toplevel)/pkgs/clan-app
./bin/clan-app --debug --content-uri http://localhost:3000 ./bin/clan-app --debug --content-uri http://localhost:3000
@@ -17,3 +21,19 @@ processes:
condition: "process_log_ready" condition: "process_log_ready"
is_foreground: true is_foreground: true
ready_log_line: "Debug mode enabled" ready_log_line: "Debug mode enabled"
# Storybook Dev
storybook:
namespace: "storybook"
command: |
cd $(git rev-parse --show-toplevel)/pkgs/clan-app/ui
npm run storybook-dev -- --ci
ready_log_line: "started"
luakit:
namespace: "storybook"
command: "luakit http://localhost:6006"
depends_on:
storybook:
condition: "process_log_ready"

View File

@@ -5,8 +5,11 @@
webview-lib, webview-lib,
clan-app-ui, clan-app-ui,
clan-ts-api, clan-ts-api,
ps,
process-compose, process-compose,
json2ts, json2ts,
playwright-driver,
luakit,
self', self',
}: }:
let let
@@ -25,11 +28,14 @@ mkShell {
packages = [ packages = [
# required for reload-python-api.sh script # required for reload-python-api.sh script
json2ts json2ts
# for viewing the storybook in a webkit-based browser to match webview
luakit
]; ];
inherit (clan-app) propagatedBuildInputs; inherit (clan-app) propagatedBuildInputs;
nativeBuildInputs = clan-app.nativeBuildInputs ++ [ nativeBuildInputs = clan-app.nativeBuildInputs ++ [
ps
process-compose process-compose
]; ];
@@ -56,7 +62,6 @@ mkShell {
# Add current package to PYTHONPATH # Add current package to PYTHONPATH
export PYTHONPATH="$(pwd)''${PYTHONPATH:+:$PYTHONPATH:}" export PYTHONPATH="$(pwd)''${PYTHONPATH:+:$PYTHONPATH:}"
popd popd
# Add clan-cli to the python path so that we can import it without building it in nix first # Add clan-cli to the python path so that we can import it without building it in nix first
@@ -77,6 +82,18 @@ mkShell {
chmod -R +w api chmod -R +w api
popd popd
# configure playwright for storybook snapshot testing
export PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
export PLAYWRIGHT_BROWSERS_PATH=${
playwright-driver.browsers.override {
withFfmpeg = false;
withFirefox = false;
withChromium = false;
withChromiumHeadlessShell = true;
}
}
export PLAYWRIGHT_HOST_PLATFORM_OVERRIDE="ubuntu-24.04"
# configure process-compose # configure process-compose
if test -f "$GIT_ROOT/pkgs/clan-app/.local.env"; then if test -f "$GIT_ROOT/pkgs/clan-app/.local.env"; then
source "$GIT_ROOT/pkgs/clan-app/.local.env" source "$GIT_ROOT/pkgs/clan-app/.local.env"

View File

@@ -2,11 +2,12 @@
buildNpmPackage, buildNpmPackage,
nodejs_22, nodejs_22,
importNpmLock, importNpmLock,
clan-ts-api, clan-ts-api,
playwright-driver,
ps,
fonts, fonts,
}: }:
buildNpmPackage { buildNpmPackage (finalAttrs: {
pname = "clan-app-ui"; pname = "clan-app-ui";
version = "0.0.1"; version = "0.0.1";
nodejs = nodejs_22; nodejs = nodejs_22;
@@ -15,6 +16,7 @@ buildNpmPackage {
npmDeps = importNpmLock { npmDeps = importNpmLock {
npmRoot = ./ui; npmRoot = ./ui;
}; };
npmConfigHook = importNpmLock.npmConfigHook; npmConfigHook = importNpmLock.npmConfigHook;
preBuild = '' preBuild = ''
@@ -22,4 +24,36 @@ buildNpmPackage {
cp -r ${clan-ts-api}/* api cp -r ${clan-ts-api}/* api
cp -r ${fonts} ".fonts" cp -r ${fonts} ".fonts"
''; '';
}
passthru = rec {
storybook = buildNpmPackage {
pname = "${finalAttrs.pname}-storybook";
inherit (finalAttrs)
version
nodejs
src
npmDeps
npmConfigHook
preBuild
;
nativeBuildInputs = finalAttrs.nativeBuildInputs ++ [
ps
];
npmBuildScript = "test-storybook-static";
env = finalAttrs.env // {
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD = 1;
PLAYWRIGHT_BROWSERS_PATH = "${playwright-driver.browsers.override {
withChromiumHeadlessShell = true;
}}";
PLAYWRIGHT_HOST_PLATFORM_OVERRIDE = "ubuntu-24.04";
};
postBuild = ''
mv storybook-static $out
'';
};
};
})

View File

@@ -1,4 +1,5 @@
app/api app/api
app/.fonts app/.fonts
.vite .vite
storybook-static

View File

@@ -12,7 +12,6 @@ const config: StorybookConfig = {
addons: [ addons: [
getAbsolutePath("@storybook/addon-links"), getAbsolutePath("@storybook/addon-links"),
getAbsolutePath("@storybook/addon-essentials"), getAbsolutePath("@storybook/addon-essentials"),
getAbsolutePath("@chromatic-com/storybook"),
getAbsolutePath("@storybook/addon-interactions"), getAbsolutePath("@storybook/addon-interactions"),
], ],
framework: { framework: {
@@ -27,6 +26,9 @@ const config: StorybookConfig = {
docs: { docs: {
autodocs: "tag", autodocs: "tag",
}, },
core: {
disableTelemetry: true,
},
}; };
export default config; export default config;

View File

@@ -0,0 +1,12 @@
import type { TestRunnerConfig } from "@storybook/test-runner";
const config: TestRunnerConfig = {
async postVisit(page, context) {
// the #storybook-root element wraps the story. In Storybook 6.x, the selector is #root
const elementHandler = await page.$("#storybook-root");
const innerHTML = await elementHandler.innerHTML();
expect(innerHTML).toMatchSnapshot();
},
};
export default config;

View File

@@ -2,6 +2,7 @@ import eslint from "@eslint/js";
import tseslint from "typescript-eslint"; import tseslint from "typescript-eslint";
import tailwind from "eslint-plugin-tailwindcss"; import tailwind from "eslint-plugin-tailwindcss";
import pluginQuery from "@tanstack/eslint-plugin-query"; import pluginQuery from "@tanstack/eslint-plugin-query";
import { globalIgnores } from "eslint/config";
const config = tseslint.config( const config = tseslint.config(
eslint.configs.recommended, eslint.configs.recommended,
@@ -9,6 +10,7 @@ const config = tseslint.config(
...tseslint.configs.strict, ...tseslint.configs.strict,
...tseslint.configs.stylistic, ...tseslint.configs.stylistic,
...tailwind.configs["flat/recommended"], ...tailwind.configs["flat/recommended"],
globalIgnores(["src/types/index.d.ts"]),
{ {
rules: { rules: {
"tailwindcss/no-contradicting-classname": [ "tailwindcss/no-contradicting-classname": [

View File

@@ -25,7 +25,6 @@
}, },
"devDependencies": { "devDependencies": {
"@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1",
"@chromatic-com/storybook": "^3.2.6",
"@eslint/js": "^9.3.0", "@eslint/js": "^9.3.0",
"@kachurun/storybook-solid": "^8.6.7", "@kachurun/storybook-solid": "^8.6.7",
"@kachurun/storybook-solid-vite": "^8.6.7", "@kachurun/storybook-solid-vite": "^8.6.7",
@@ -42,8 +41,10 @@
"@typescript-eslint/parser": "^8.32.1", "@typescript-eslint/parser": "^8.32.1",
"autoprefixer": "^10.4.19", "autoprefixer": "^10.4.19",
"classnames": "^2.5.1", "classnames": "^2.5.1",
"concurrently": "^9.1.2",
"eslint": "^9.27.0", "eslint": "^9.27.0",
"eslint-plugin-tailwindcss": "^3.17.0", "eslint-plugin-tailwindcss": "^3.17.0",
"http-server": "^14.1.1",
"jsdom": "^26.1.0", "jsdom": "^26.1.0",
"postcss": "^8.4.38", "postcss": "^8.4.38",
"postcss-url": "^10.1.3", "postcss-url": "^10.1.3",
@@ -56,7 +57,8 @@
"vite": "^6.3.5", "vite": "^6.3.5",
"vite-plugin-solid": "^2.8.2", "vite-plugin-solid": "^2.8.2",
"vite-plugin-solid-svg": "^0.8.1", "vite-plugin-solid-svg": "^0.8.1",
"vitest": "^3.1.4" "vitest": "^3.1.4",
"wait-on": "^8.0.3"
} }
}, },
"node_modules/@adobe/css-tools": { "node_modules/@adobe/css-tools": {
@@ -653,56 +655,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@chromatic-com/storybook": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/@chromatic-com/storybook/-/storybook-3.2.6.tgz",
"integrity": "sha512-FDmn5Ry2DzQdik+eq2sp/kJMMT36Ewe7ONXUXM2Izd97c7r6R/QyGli8eyh/F0iyqVvbLveNYFyF0dBOJNwLqw==",
"dev": true,
"license": "MIT",
"dependencies": {
"chromatic": "^11.15.0",
"filesize": "^10.0.12",
"jsonfile": "^6.1.0",
"react-confetti": "^6.1.0",
"strip-ansi": "^7.1.0"
},
"engines": {
"node": ">=16.0.0",
"yarn": ">=1.22.18"
},
"peerDependencies": {
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
}
},
"node_modules/@chromatic-com/storybook/node_modules/ansi-regex": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"node_modules/@chromatic-com/storybook/node_modules/strip-ansi": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/@corvu/accordion": { "node_modules/@corvu/accordion": {
"version": "0.2.5", "version": "0.2.5",
"resolved": "https://registry.npmjs.org/@corvu/accordion/-/accordion-0.2.5.tgz", "resolved": "https://registry.npmjs.org/@corvu/accordion/-/accordion-0.2.5.tgz",
@@ -4719,6 +4671,13 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/async": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
"dev": true,
"license": "MIT"
},
"node_modules/async-mutex": { "node_modules/async-mutex": {
"version": "0.5.0", "version": "0.5.0",
"resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.5.0.tgz", "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.5.0.tgz",
@@ -4988,6 +4947,26 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/basic-auth": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
"integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
"dev": true,
"license": "MIT",
"dependencies": {
"safe-buffer": "5.1.2"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/basic-auth/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true,
"license": "MIT"
},
"node_modules/better-opn": { "node_modules/better-opn": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz", "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz",
@@ -5345,30 +5324,6 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/chromatic": {
"version": "11.29.0",
"resolved": "https://registry.npmjs.org/chromatic/-/chromatic-11.29.0.tgz",
"integrity": "sha512-yisBlntp9hHVj19lIQdpTlcYIXuU9H/DbFuu6tyWHmj6hWT2EtukCCcxYXL78XdQt1vm2GfIrtgtKpj/Rzmo4A==",
"dev": true,
"license": "MIT",
"bin": {
"chroma": "dist/bin.js",
"chromatic": "dist/bin.js",
"chromatic-cli": "dist/bin.js"
},
"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
}
}
},
"node_modules/ci-info": { "node_modules/ci-info": {
"version": "3.9.0", "version": "3.9.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
@@ -5546,6 +5501,48 @@
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/concurrently": {
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.1.2.tgz",
"integrity": "sha512-H9MWcoPsYddwbOGM6difjVwVZHl63nwMEwDJG/L7VGtuaJhb12h2caPG2tVPWs7emuYix252iGfqOyrz1GczTQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"chalk": "^4.1.2",
"lodash": "^4.17.21",
"rxjs": "^7.8.1",
"shell-quote": "^1.8.1",
"supports-color": "^8.1.1",
"tree-kill": "^1.2.2",
"yargs": "^17.7.2"
},
"bin": {
"conc": "dist/bin/concurrently.js",
"concurrently": "dist/bin/concurrently.js"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/open-cli-tools/concurrently?sponsor=1"
}
},
"node_modules/concurrently/node_modules/supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/convert-source-map": { "node_modules/convert-source-map": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@@ -5553,6 +5550,16 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/corser": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz",
"integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/corvu": { "node_modules/corvu": {
"version": "0.7.2", "version": "0.7.2",
"resolved": "https://registry.npmjs.org/corvu/-/corvu-0.7.2.tgz", "resolved": "https://registry.npmjs.org/corvu/-/corvu-0.7.2.tgz",
@@ -6496,6 +6503,13 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
"dev": true,
"license": "MIT"
},
"node_modules/execa": { "node_modules/execa": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
@@ -6673,16 +6687,6 @@
"node": ">=16.0.0" "node": ">=16.0.0"
} }
}, },
"node_modules/filesize": {
"version": "10.1.6",
"resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.6.tgz",
"integrity": "sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">= 10.4.0"
}
},
"node_modules/fill-range": { "node_modules/fill-range": {
"version": "7.1.1", "version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -7260,6 +7264,16 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true,
"license": "MIT",
"bin": {
"he": "bin/he"
}
},
"node_modules/homedir-polyfill": { "node_modules/homedir-polyfill": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
@@ -7384,6 +7398,21 @@
"dev": true, "dev": true,
"license": "BSD-2-Clause" "license": "BSD-2-Clause"
}, },
"node_modules/http-proxy": {
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
"integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"eventemitter3": "^4.0.0",
"follow-redirects": "^1.0.0",
"requires-port": "^1.0.0"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/http-proxy-agent": { "node_modules/http-proxy-agent": {
"version": "7.0.2", "version": "7.0.2",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
@@ -7398,6 +7427,73 @@
"node": ">= 14" "node": ">= 14"
} }
}, },
"node_modules/http-server": {
"version": "14.1.1",
"resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz",
"integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==",
"dev": true,
"license": "MIT",
"dependencies": {
"basic-auth": "^2.0.1",
"chalk": "^4.1.2",
"corser": "^2.0.1",
"he": "^1.2.0",
"html-encoding-sniffer": "^3.0.0",
"http-proxy": "^1.18.1",
"mime": "^1.6.0",
"minimist": "^1.2.6",
"opener": "^1.5.1",
"portfinder": "^1.0.28",
"secure-compare": "3.0.1",
"union": "~0.5.0",
"url-join": "^4.0.1"
},
"bin": {
"http-server": "bin/http-server"
},
"engines": {
"node": ">=12"
}
},
"node_modules/http-server/node_modules/html-encoding-sniffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
"integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
"dev": true,
"license": "MIT",
"dependencies": {
"whatwg-encoding": "^2.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/http-server/node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"dev": true,
"license": "MIT",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/http-server/node_modules/whatwg-encoding": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
"integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
"dev": true,
"license": "MIT",
"dependencies": {
"iconv-lite": "0.6.3"
},
"engines": {
"node": ">=12"
}
},
"node_modules/https-proxy-agent": { "node_modules/https-proxy-agent": {
"version": "7.0.6", "version": "7.0.6",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
@@ -8608,6 +8704,26 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/jest-process-manager/node_modules/wait-on": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.2.0.tgz",
"integrity": "sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"axios": "^1.6.1",
"joi": "^17.11.0",
"lodash": "^4.17.21",
"minimist": "^1.2.8",
"rxjs": "^7.8.1"
},
"bin": {
"wait-on": "bin/wait-on"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/jest-regex-util": { "node_modules/jest-regex-util": {
"version": "29.6.3", "version": "29.6.3",
"resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
@@ -9201,19 +9317,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"universalify": "^2.0.0"
},
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
},
"node_modules/keyv": { "node_modules/keyv": {
"version": "4.5.4", "version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -10544,6 +10647,19 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/object-inspect": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/once": { "node_modules/once": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -10588,6 +10704,16 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/opener": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
"integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
"dev": true,
"license": "(WTFPL OR MIT)",
"bin": {
"opener": "bin/opener-bin.js"
}
},
"node_modules/optionator": { "node_modules/optionator": {
"version": "0.9.4", "version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -10982,6 +11108,20 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/portfinder": {
"version": "1.0.37",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.37.tgz",
"integrity": "sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw==",
"dev": true,
"license": "MIT",
"dependencies": {
"async": "^3.2.6",
"debug": "^4.3.6"
},
"engines": {
"node": ">= 10.12"
}
},
"node_modules/possible-typed-array-names": { "node_modules/possible-typed-array-names": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
@@ -11351,6 +11491,22 @@
], ],
"license": "MIT" "license": "MIT"
}, },
"node_modules/qs": {
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.1.0"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/queue-microtask": { "node_modules/queue-microtask": {
"version": "1.2.3", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -11381,22 +11537,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/react-confetti": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/react-confetti/-/react-confetti-6.4.0.tgz",
"integrity": "sha512-5MdGUcqxrTU26I2EU7ltkWPwxvucQTuqMm8dUz72z2YMqTD6s9vMcDUysk7n9jnC+lXuCPeJJ7Knf98VEYE9Rg==",
"dev": true,
"license": "MIT",
"dependencies": {
"tween-functions": "^1.2.0"
},
"engines": {
"node": ">=16"
},
"peerDependencies": {
"react": "^16.3.0 || ^17.0.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/react-dom": { "node_modules/react-dom": {
"version": "19.1.0", "version": "19.1.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
@@ -11549,6 +11689,13 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"dev": true,
"license": "MIT"
},
"node_modules/resolve": { "node_modules/resolve": {
"version": "1.22.10", "version": "1.22.10",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
@@ -11799,6 +11946,13 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/secure-compare": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz",
"integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==",
"dev": true,
"license": "MIT"
},
"node_modules/semver": { "node_modules/semver": {
"version": "7.7.1", "version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
@@ -11878,6 +12032,95 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/shell-quote": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz",
"integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3",
"side-channel-list": "^1.0.0",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-list": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-map": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3",
"side-channel-map": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/siginfo": { "node_modules/siginfo": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
@@ -12896,13 +13139,6 @@
"dev": true, "dev": true,
"license": "0BSD" "license": "0BSD"
}, },
"node_modules/tween-functions": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/tween-functions/-/tween-functions-1.2.0.tgz",
"integrity": "sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA==",
"dev": true,
"license": "BSD"
},
"node_modules/type-check": { "node_modules/type-check": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -13010,6 +13246,18 @@
"url": "https://opencollective.com/unified" "url": "https://opencollective.com/unified"
} }
}, },
"node_modules/union": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz",
"integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==",
"dev": true,
"dependencies": {
"qs": "^6.4.0"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/unist-util-is": { "node_modules/unist-util-is": {
"version": "5.2.1", "version": "5.2.1",
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz",
@@ -13096,16 +13344,6 @@
"integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/universalify": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 10.0.0"
}
},
"node_modules/unplugin": { "node_modules/unplugin": {
"version": "1.16.1", "version": "1.16.1",
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz", "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz",
@@ -13160,6 +13398,13 @@
"punycode": "^2.1.0" "punycode": "^2.1.0"
} }
}, },
"node_modules/url-join": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
"integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
"dev": true,
"license": "MIT"
},
"node_modules/util": { "node_modules/util": {
"version": "0.12.5", "version": "0.12.5",
"resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
@@ -13528,17 +13773,17 @@
} }
}, },
"node_modules/wait-on": { "node_modules/wait-on": {
"version": "7.2.0", "version": "8.0.3",
"resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.2.0.tgz", "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.3.tgz",
"integrity": "sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==", "integrity": "sha512-nQFqAFzZDeRxsu7S3C7LbuxslHhk+gnJZHyethuGKAn2IVleIbTB9I3vJSQiSR+DifUqmdzfPMoMPJfLqMF2vw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"axios": "^1.6.1", "axios": "^1.8.2",
"joi": "^17.11.0", "joi": "^17.13.3",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"minimist": "^1.2.8", "minimist": "^1.2.8",
"rxjs": "^7.8.1" "rxjs": "^7.8.2"
}, },
"bin": { "bin": {
"wait-on": "bin/wait-on" "wait-on": "bin/wait-on"

View File

@@ -11,12 +11,16 @@
"serve": "vite preview", "serve": "vite preview",
"check": "tsc --noEmit --skipLibCheck && eslint ./src", "check": "tsc --noEmit --skipLibCheck && eslint ./src",
"test": "vitest run --typecheck", "test": "vitest run --typecheck",
"storybook": "storybook dev -p 6006" "storybook": "storybook",
"storybook-build": "storybook build",
"storybook-dev": "storybook dev -p 6006",
"test-storybook": "test-storybook --browsers chromium --ci",
"test-storybook-update-snapshots": "npm run test-storybook -- --updateSnapshot",
"test-storybook-static": "npm run storybook-build && concurrently -k -s first -n 'SB,TEST' -c 'magenta,blue' 'http-server storybook-static --port 6006 --silent' 'wait-on tcp:127.0.0.1:6006 && npm run test-storybook'"
}, },
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1",
"@chromatic-com/storybook": "^3.2.6",
"@eslint/js": "^9.3.0", "@eslint/js": "^9.3.0",
"@kachurun/storybook-solid": "^8.6.7", "@kachurun/storybook-solid": "^8.6.7",
"@kachurun/storybook-solid-vite": "^8.6.7", "@kachurun/storybook-solid-vite": "^8.6.7",
@@ -33,8 +37,10 @@
"@typescript-eslint/parser": "^8.32.1", "@typescript-eslint/parser": "^8.32.1",
"autoprefixer": "^10.4.19", "autoprefixer": "^10.4.19",
"classnames": "^2.5.1", "classnames": "^2.5.1",
"concurrently": "^9.1.2",
"eslint": "^9.27.0", "eslint": "^9.27.0",
"eslint-plugin-tailwindcss": "^3.17.0", "eslint-plugin-tailwindcss": "^3.17.0",
"http-server": "^14.1.1",
"jsdom": "^26.1.0", "jsdom": "^26.1.0",
"postcss": "^8.4.38", "postcss": "^8.4.38",
"postcss-url": "^10.1.3", "postcss-url": "^10.1.3",
@@ -47,7 +53,8 @@
"vite": "^6.3.5", "vite": "^6.3.5",
"vite-plugin-solid": "^2.8.2", "vite-plugin-solid": "^2.8.2",
"vite-plugin-solid-svg": "^0.8.1", "vite-plugin-solid-svg": "^0.8.1",
"vitest": "^3.1.4" "vitest": "^3.1.4",
"wait-on": "^8.0.3"
}, },
"dependencies": { "dependencies": {
"@floating-ui/dom": "^1.6.8", "@floating-ui/dom": "^1.6.8",

View File

@@ -0,0 +1,89 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Components/Button Default smoke-test 1`] = `
<button class="button button--dark button--dark-hover button--dark-focus button--dark-active disabled:bg-secondary-200 disabled:text-secondary-700 disabled:border-secondary-300 button--default">
<span class="button__icon--start">
<svg xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewbox="0 0 48 48"
>
<path fill-rule="evenodd"
d="M24 6.4h3.2v12.8H40v6.4h-3.2v3.2h-3.2V32h-3.2v3.2h-3.2v3.2H24v3.2h-3.2V28.8H8v-6.4h3.2v-3.2h3.2V16h3.2v-3.2h3.2V9.6H24z"
clip-rule="evenodd"
>
</path>
</svg>
</span>
<span class="text-inherit fnt-clr--inverted fnt-label-default fnt-weight-medium button__label">
click me
</span>
</button>
`;
exports[`Components/Button Ghost smoke-test 1`] = `
<button class="button button--ghost-hover button--ghost-focus button--ghost-active button--default">
<span class="button__icon--start">
<svg xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewbox="0 0 48 48"
>
<path fill-rule="evenodd"
d="M24 6.4h3.2v12.8H40v6.4h-3.2v3.2h-3.2V32h-3.2v3.2h-3.2v3.2H24v3.2h-3.2V28.8H8v-6.4h3.2v-3.2h3.2V16h3.2v-3.2h3.2V9.6H24z"
clip-rule="evenodd"
>
</path>
</svg>
</span>
<span class="text-inherit fnt-label-default fnt-weight-medium button__label">
click me
</span>
</button>
`;
exports[`Components/Button Light smoke-test 1`] = `
<button class="button button--light button--light-hover button--light-focus button--light-active button--default">
<span class="button__icon--start">
<svg xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewbox="0 0 48 48"
>
<path fill-rule="evenodd"
d="M24 6.4h3.2v12.8H40v6.4h-3.2v3.2h-3.2V32h-3.2v3.2h-3.2v3.2H24v3.2h-3.2V28.8H8v-6.4h3.2v-3.2h3.2V16h3.2v-3.2h3.2V9.6H24z"
clip-rule="evenodd"
>
</path>
</svg>
</span>
<span class="text-inherit fnt-label-default fnt-weight-medium button__label">
click me
</span>
</button>
`;
exports[`Components/Button Small smoke-test 1`] = `
<button class="button button--dark button--dark-hover button--dark-focus button--dark-active disabled:bg-secondary-200 disabled:text-secondary-700 disabled:border-secondary-300 button button--small">
<span class="button__icon--start">
<svg xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewbox="0 0 48 48"
>
<path fill-rule="evenodd"
d="M24 6.4h3.2v12.8H40v6.4h-3.2v3.2h-3.2V32h-3.2v3.2h-3.2v3.2H24v3.2h-3.2V28.8H8v-6.4h3.2v-3.2h3.2V16h3.2v-3.2h3.2V9.6H24z"
clip-rule="evenodd"
>
</path>
</svg>
</span>
<span class="text-inherit fnt-clr--inverted fnt-label-s fnt-weight-medium button__label">
click me
</span>
</button>
`;

90
pkgs/clan-app/ui/src/types/index.d.ts vendored Normal file
View File

@@ -0,0 +1,90 @@
// @ts-nocheck
declare module "@kachurun/storybook-solid" {
import type { SolidRenderer } from "types";
import type {
AnnotatedStoryFn,
Args,
ArgsFromMeta,
ArgsStoryFn,
ComponentAnnotations,
DecoratorFunction,
LoaderFunction,
ProjectAnnotations,
StoryAnnotations,
StoryContext as GenericStoryContext,
StrictArgs,
} from "@storybook/types";
import type { Component as ComponentType, ComponentProps } from "solid-js";
import type { SetOptional, Simplify } from "type-fest";
export type {
ArgTypes,
Args,
Parameters,
StrictArgs,
} from "@storybook/types";
export type { SolidRenderer };
/**
* Metadata to configure the stories for a component.
*
* @see [Default export](https://storybook.js.org/docs/formats/component-story-format/#default-export)
*/
export type Meta<TCmpOrArgs = Args> =
TCmpOrArgs extends ComponentType<any>
? ComponentAnnotations<SolidRenderer, ComponentProps<TCmpOrArgs>>
: ComponentAnnotations<SolidRenderer, TCmpOrArgs>;
/**
* Story function that represents a CSFv2 component example.
*
* @see [Named Story exports](https://storybook.js.org/docs/formats/component-story-format/#named-story-exports)
*/
export type StoryFn<TCmpOrArgs = Args> =
TCmpOrArgs extends ComponentType<any>
? AnnotatedStoryFn<SolidRenderer, ComponentProps<TCmpOrArgs>>
: AnnotatedStoryFn<SolidRenderer, TCmpOrArgs>;
/**
* Story function that represents a CSFv3 component example.
*
* @see [Named Story exports](https://storybook.js.org/docs/formats/component-story-format/#named-story-exports)
*/
export type StoryObj<TMetaOrCmpOrArgs = Args> = TMetaOrCmpOrArgs extends {
render?: ArgsStoryFn<SolidRenderer, any>;
component?: infer Component;
args?: infer DefaultArgs;
}
? Simplify<
(Component extends ComponentType<any>
? ComponentProps<Component>
: unknown) &
ArgsFromMeta<SolidRenderer, TMetaOrCmpOrArgs>
> extends infer TArgs
? StoryAnnotations<
SolidRenderer,
TArgs,
SetOptional<
TArgs,
keyof TArgs & keyof (DefaultArgs & ActionArgs<TArgs>)
>
>
: never
: TMetaOrCmpOrArgs extends ComponentType<any>
? StoryAnnotations<SolidRenderer, ComponentProps<TMetaOrCmpOrArgs>>
: StoryAnnotations<SolidRenderer, TMetaOrCmpOrArgs>;
type ActionArgs<TArgs> = {
[P in keyof TArgs as TArgs[P] extends (...args: any[]) => any
? ((...args: any[]) => void) extends TArgs[P]
? P
: never
: never]: TArgs[P];
};
export type Decorator<TArgs = StrictArgs> = DecoratorFunction<
SolidRenderer,
TArgs
>;
export type Loader<TArgs = StrictArgs> = LoaderFunction<SolidRenderer, TArgs>;
export type StoryContext<TArgs = StrictArgs> = GenericStoryContext<
SolidRenderer,
TArgs
>;
export type Preview = ProjectAnnotations<SolidRenderer>;
}
//# sourceMappingURL=index.d.ts.map