From ea386c4ffdd88afe46beafdaaad33fd06fd5203c Mon Sep 17 00:00:00 2001 From: David Di Biase <1168397+davedbase@users.noreply.github.com> Date: Wed, 20 May 2026 09:28:11 -0400 Subject: [PATCH 01/24] Create SECURITY.md --- SECURITY.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..184f01571 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,27 @@ +Thanks for helping make Solid safe for everyone. + +# Security + +Solid Community takes the security of our software seriously, including all of the open source code repositories managed through [this GitHub organization](https://github.com/solidjs-community). + +## Reporting a Vulnerability + +**If you think you've found a security issue, please DO NOT report, discuss, or describe it on Discord or GitHub.** + +**All security-related issues, concerns, and problems must be reported via email to: security@solidjs.com** + +Please include everything necessary to reproduce the problem when sending over information, including an example repository on StackBlitz or GitHub. Please don't add explicit details about the security issue you are reporting in any of the repository's contents. + +**_This is detrimental to the safety of all Solid users. No exceptions._** + +## Embargo Policy + +SolidJS Community Security Team members must share information only within the Solid Core, relevant internal team members and security focused teams on a need-to-know basis to fix the related issue in Solid. The information members and others receive through participation in this group must not be made public, shared, or even hinted otherwise, except with prior explicit approval (which shall be handled on a case-by-case basis). This holds true until the agreed-upon public disclosure date/time is satisfied. + +As a clarifying example, this policy forbids Solid Security members from sharing list information with their employers; unless prior arrangements have been made directly with an employer. + +In the unfortunate event that you share the information beyond what is allowed by this policy, you must urgently inform the Solid Security Team of exactly what information leaked and to whom, as well as the steps that will be taken to prevent future leaks. + +SolidJS Community is not directly related to SolidJS as an organization but closely works with SolidJS Core. + +**Repeated offenses may lead to the removal from the Security or Solid team.** From 9d5eb6479cf0a0ad2369a23454af5482597f7c7b Mon Sep 17 00:00:00 2001 From: David Di Biase <1168397+davedbase@users.noreply.github.com> Date: Sun, 24 May 2026 22:12:20 -0400 Subject: [PATCH 02/24] Initial implementation of Storybook --- .gitignore | 1 + .storybook/main.ts | 43 + .storybook/preview.ts | 10 + .storybook/tsconfig.json | 10 + package.json | 8 +- packages/audio/dev/index.tsx | 133 -- packages/audio/package.json | 2 - .../audio/{dev => stories/assets}/sample1.mp3 | Bin .../audio/{dev => stories/assets}/sample2.mp3 | Bin .../audio/{dev => stories/assets}/sample3.mp3 | Bin packages/audio/stories/audio.stories.tsx | 304 +++++ pnpm-lock.yaml | 1107 ++++++++++++++++- template/stories/index.stories.tsx | 32 + 13 files changed, 1495 insertions(+), 155 deletions(-) create mode 100644 .storybook/main.ts create mode 100644 .storybook/preview.ts create mode 100644 .storybook/tsconfig.json delete mode 100644 packages/audio/dev/index.tsx rename packages/audio/{dev => stories/assets}/sample1.mp3 (100%) rename packages/audio/{dev => stories/assets}/sample2.mp3 (100%) rename packages/audio/{dev => stories/assets}/sample3.mp3 (100%) create mode 100644 packages/audio/stories/audio.stories.tsx create mode 100644 template/stories/index.stories.tsx diff --git a/.gitignore b/.gitignore index ffa46fd78..82c77b3bc 100644 --- a/.gitignore +++ b/.gitignore @@ -132,3 +132,4 @@ _temp_* # Local Netlify folder .netlify +storybook-static diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 000000000..8d1cd586b --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,43 @@ +import type { StorybookConfig } from "storybook-solidjs-vite"; +import { mergeConfig } from "vite"; + +const config: StorybookConfig = { + stories: ["../packages/*/stories/*.stories.{ts,tsx}"], + staticDirs: [{ from: "../packages/audio/stories/assets", to: "/audio" }], + addons: ["@storybook/addon-docs"], + framework: { + name: "storybook-solidjs-vite", + options: {}, + }, + docs: {}, + async viteFinal(config) { + return mergeConfig(config, { + plugins: [ + // babel-preset-solid JSX.Element; outline?: boolean; mini?: boolean }; -type IconProps = JSX.SvgSVGAttributes & { path: IconPath }; - -const Icon = (props: IconProps) => { - const [internal, external] = splitProps(props, ["path"]); - return ( - - {internal.path.path()} - - ); -}; - -const play: IconPath = { - path: () => ( - - ), -}; -const pause: IconPath = { - path: () => ( - - ), -}; -const speakerWave: IconPath = { - path: () => ( - - ), - outline: true, -}; - -const formatTime = (time: number) => new Date(time * 1000).toISOString().substr(14, 8); - -const Player: Component<{ source: () => string }> = props => { - const audio = createAudio(props.source); - - return ( -
- -
- - {formatTime(audio.currentTime())} / {formatTime(audio.duration())} - -
- }> - audio.seek(+evt.currentTarget.value)} - type="range" - min="0" - step="0.1" - max={audio.duration()} - value={audio.currentTime()} - class="form-range w-40 cursor-pointer appearance-none rounded-3xl bg-gray-200 transition hover:bg-gray-300 focus:ring-0 focus:outline-none" - /> - -
- - audio.setVolume(+evt.currentTarget.value)} - type="range" - min="0" - step="0.1" - max={1} - value={audio.volume()} - class="cursor w-10" - /> -
-
- ); -}; - -const App: Component = () => { - const [source, setSource] = createSignal("sample1.mp3"); - - return ( -
-
- -
- - {([label, url]) => ( - - )} - -
-
-
- ); -}; - -export default App; diff --git a/packages/audio/package.json b/packages/audio/package.json index e53ecff1d..f5367003c 100644 --- a/packages/audio/package.json +++ b/packages/audio/package.json @@ -37,8 +37,6 @@ }, "typesVersions": {}, "scripts": { - "start": "vite serve dev", - "dev": "node --import=@nothing-but/node-resolve-ts --experimental-transform-types ../../scripts/dev.ts", "build": "node --import=@nothing-but/node-resolve-ts --experimental-transform-types ../../scripts/build.ts", "vitest": "vitest -c ../../configs/vitest.config.ts", "test": "pnpm run vitest", diff --git a/packages/audio/dev/sample1.mp3 b/packages/audio/stories/assets/sample1.mp3 similarity index 100% rename from packages/audio/dev/sample1.mp3 rename to packages/audio/stories/assets/sample1.mp3 diff --git a/packages/audio/dev/sample2.mp3 b/packages/audio/stories/assets/sample2.mp3 similarity index 100% rename from packages/audio/dev/sample2.mp3 rename to packages/audio/stories/assets/sample2.mp3 diff --git a/packages/audio/dev/sample3.mp3 b/packages/audio/stories/assets/sample3.mp3 similarity index 100% rename from packages/audio/dev/sample3.mp3 rename to packages/audio/stories/assets/sample3.mp3 diff --git a/packages/audio/stories/audio.stories.tsx b/packages/audio/stories/audio.stories.tsx new file mode 100644 index 000000000..1a324070f --- /dev/null +++ b/packages/audio/stories/audio.stories.tsx @@ -0,0 +1,304 @@ +import { createSignal, For, Show } from "solid-js"; +import { Loading } from "@solidjs/web"; +import preview from "../../../.storybook/preview"; +import { createAudio, makeAudio, makeAudioPlayer } from "@solid-primitives/audio"; + +// Audio files are served from packages/audio/dev/ via storybook staticDirs → /audio/* +const SAMPLES = [ + { label: "Sample 1", url: "/audio/sample1.mp3" }, + { label: "Sample 2", url: "/audio/sample2.mp3" }, + { label: "Sample 3", url: "/audio/sample3.mp3" }, +] as const; + +// --------------------------------------------------------------------------- +// Small shared UI helpers +// --------------------------------------------------------------------------- + +const formatTime = (s: number) => { + const m = Math.floor(s / 60); + const sec = Math.floor(s % 60); + return `${m}:${sec.toString().padStart(2, "0")}`; +}; + +const VolumeSlider = (props: { value: () => number; onChange: (v: number) => void }) => ( + +); + +const SeekSlider = (props: { + current: () => number; + max: number; + onSeek: (t: number) => void; +}) => ( + props.onSeek(+e.currentTarget.value)} + style={{ width: "180px" }} + /> +); + +// --------------------------------------------------------------------------- +// Story meta +// --------------------------------------------------------------------------- + +const meta = preview.meta({ + title: "Display & Media/Audio", + tags: ["autodocs"], + parameters: { + layout: "centered", + docs: { + description: { + component: ` +**@solid-primitives/audio** provides three primitives for working with audio: + +| Primitive | Reactive? | Returns | +|-----------|-----------|---------| +| \`makeAudio\` | No | \`[HTMLAudioElement, cleanup]\` | +| \`makeAudioPlayer\` | No | \`[AudioControls, cleanup]\` | +| \`createAudio\` | Yes | \`AudioReturn\` with signals | + +\`createAudio\` accepts a static string **or** a reactive \`Accessor\` — it reconnects automatically when the source changes. +The \`duration\` signal throws \`NotReadyError\` until metadata loads, integrating with \`\`. + `.trim(), + }, + }, + }, +}); + +export default meta; + +// --------------------------------------------------------------------------- +// Stories +// --------------------------------------------------------------------------- + +export const Reactive = meta.story({ + name: "createAudio — reactive player", + parameters: { + docs: { + description: { + story: + "`createAudio` returns signals for `playing`, `volume`, `currentTime`, and `duration`. Switch tracks reactively — the source accessor reconnects the player automatically.", + }, + }, + }, + render: () => { + const [source, setSource] = createSignal(SAMPLES[0].url); + const audio = createAudio(source); + + return ( +
+

createAudio

+ + {/* Track selector */} +
+ + {s => ( + + )} + +
+ + {/* Play / Pause */} +
+ + + Loading…}> + + + {formatTime(audio.currentTime())} / {formatTime(audio.duration())} + + +
+ + +
+ ); + }, +}); + +export const ReactiveSource = meta.story({ + name: "createAudio — reactive source", + parameters: { + docs: { + description: { + story: + "When the source signal changes, `createAudio` seamlessly reconnects the player. `duration` resets to pending and re-suspends `` while the new track's metadata loads.", + }, + }, + }, + render: () => { + const [idx, setIdx] = createSignal(0); + const source = () => SAMPLES[idx()]!.url; + const audio = createAudio(source); + + return ( +
+

Reactive source swap

+ +
+ + {SAMPLES[idx()]?.label} + +
+ +
+ + + ⏳ Buffering…}> + + {formatTime(audio.currentTime())} / {formatTime(audio.duration())} + + +
+ + +
+ ); + }, +}); + +export const NonReactive = meta.story({ + name: "makeAudio — non-reactive", + parameters: { + docs: { + description: { + story: + "`makeAudio` creates a raw `HTMLAudioElement` with event handlers attached. No Solid owner required — you manage lifecycle yourself via the returned `cleanup` function.", + }, + }, + }, + render: () => { + const [playing, setPlaying] = createSignal(false); + const [volume, setVol] = createSignal(1); + + const [player, cleanup] = makeAudio("/audio/sample1.mp3", { + playing: () => setPlaying(true), + pause: () => setPlaying(false), + ended: () => setPlaying(false), + volumechange: () => setVol(player.volume), + }); + + // cleanup is called when the story owner disposes + // (storybook-solidjs-vite handles the root lifecycle) + + return ( +
+

makeAudio

+

+ Direct HTMLAudioElement — no reactive signals. +

+ +
+ + +
+ + { + player.volume = v; + }} + /> +
+ ); + }, +}); + +export const PlayerControls = meta.story({ + name: "makeAudioPlayer — controls", + parameters: { + docs: { + description: { + story: + "`makeAudioPlayer` wraps `makeAudio` with a `controls` object exposing `play`, `pause`, `seek`, and `setVolume` methods. Still non-reactive — useful when you want imperative control without signals.", + }, + }, + }, + render: () => { + const [playing, setPlaying] = createSignal(false); + const [currentTime, setCurrentTime] = createSignal(0); + const [duration, setDuration] = createSignal(0); + const [volume, setVolume] = createSignal(1); + + const [controls] = makeAudioPlayer("/audio/sample2.mp3", { + playing: () => setPlaying(true), + pause: () => setPlaying(false), + ended: () => setPlaying(false), + timeupdate: () => setCurrentTime(controls.player.currentTime), + loadeddata: () => setDuration(controls.player.duration), + volumechange: () => setVolume(controls.player.volume), + }); + + return ( +
+

makeAudioPlayer

+ +
+ + + 0} fallback={Loading…}> + + + {formatTime(currentTime())} / {formatTime(duration())} + + +
+ + +
+ ); + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7a8fd120a..8f7cd9f93 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,9 +17,15 @@ importers: '@nothing-but/node-resolve-ts': specifier: ^1.0.1 version: 1.0.1 + '@solidjs/signals': + specifier: 2.0.0-beta.14 + version: 2.0.0-beta.14 '@solidjs/web': specifier: 2.0.0-beta.14 version: 2.0.0-beta.14(solid-js@2.0.0-beta.14) + '@storybook/addon-docs': + specifier: ^10.4.1 + version: 10.4.1(@types/react@19.2.15)(esbuild@0.25.5)(rollup@4.43.0)(storybook@10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) '@types/jsdom': specifier: ^21.1.7 version: 21.1.7 @@ -77,6 +83,12 @@ importers: solid-js: specifier: 2.0.0-beta.14 version: 2.0.0-beta.14 + storybook: + specifier: ^10.4.1 + version: 10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + storybook-solidjs-vite: + specifier: ^10.1.0 + version: 10.1.0(@solidjs/web@2.0.0-beta.14(solid-js@2.0.0-beta.14))(esbuild@0.25.5)(rollup@4.43.0)(solid-js@2.0.0-beta.14)(storybook@10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(typescript@5.8.3)(vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.14(solid-js@2.0.0-beta.14))(@testing-library/jest-dom@6.9.1)(solid-js@2.0.0-beta.14)(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)))(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) typescript: specifier: ^5.8.3 version: 5.8.3 @@ -85,7 +97,7 @@ importers: version: 6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0) vite-plugin-solid: specifier: 3.0.0-next.5 - version: 3.0.0-next.5(@solidjs/web@2.0.0-beta.14(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14)(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) + version: 3.0.0-next.5(@solidjs/web@2.0.0-beta.14(solid-js@2.0.0-beta.14))(@testing-library/jest-dom@6.9.1)(solid-js@2.0.0-beta.14)(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) vitest: specifier: ^2.1.9 version: 2.1.9(@types/node@22.15.31)(jsdom@25.0.1)(lightningcss@1.32.0)(sass@1.77.8) @@ -466,7 +478,7 @@ importers: devDependencies: '@reduxjs/toolkit': specifier: ^1.9.7 - version: 1.9.7 + version: 1.9.7(react@19.2.6) redux: specifier: ^4.2.1 version: 4.2.1 @@ -1191,7 +1203,7 @@ importers: version: 2.0.0-beta.17(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14) '@tanstack/solid-start': specifier: ^2.0.0-beta.17 - version: 2.0.0-beta.18(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14)(vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)))(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) + version: 2.0.0-beta.18(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14)(vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(@testing-library/jest-dom@6.9.1)(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)))(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) clsx: specifier: ^2.0.0 version: 2.1.1 @@ -1252,10 +1264,13 @@ importers: version: 8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0) vite-plugin-solid: specifier: 3.0.0-next.5 - version: 3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) + version: 3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(@testing-library/jest-dom@6.9.1)(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) packages: + '@adobe/css-tools@4.5.0': + resolution: {integrity: sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==} + '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -1715,9 +1730,15 @@ packages: '@emnapi/core@1.10.0': resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + '@emnapi/core@1.9.2': + resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} + '@emnapi/runtime@1.10.0': resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + '@emnapi/runtime@1.9.2': + resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} + '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} @@ -2301,6 +2322,15 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@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==} @@ -2337,6 +2367,12 @@ packages: '@manypkg/get-packages@1.1.3': resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + '@mdx-js/react@3.1.1': + resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + '@napi-rs/wasm-runtime@1.1.4': resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} peerDependencies: @@ -2378,9 +2414,247 @@ packages: resolution: {integrity: sha512-hAX0pT/73190NLqBPPWSdBVGtbY6VOhWYK3qqHqtXQ1gK7kS2yz4+ivsN07hpJ6I3aeMtKP6J6npsEKOAzuTLA==} engines: {node: '>=20.0'} + '@oxc-parser/binding-android-arm-eabi@0.127.0': + resolution: {integrity: sha512-0LC7ye4hvqbIKxAzThzvswgHLFu2AURKzYLeSVvLdu2TBOYWQDmHnTqPLeA597BcUCxiLqLsS4CJ5uoI5WYWCQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-parser/binding-android-arm64@0.127.0': + resolution: {integrity: sha512-b5jtVTH6AU5CJXHNdj7Jj9IEiR9yVjjnwHzPJhGyHGPdcsZSzBCkS9GBbV33niRMvKthDwQRFRJfI4a+k4PvYg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-parser/binding-darwin-arm64@0.127.0': + resolution: {integrity: sha512-obCE8B7ISKkJidjlhv9xRGJPOSDG2Yu6PRga9Ruaz35uintHxbp1Ki/Yc71wx4rj3Edrm0a1kzG1TAwit0wFpg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-parser/binding-darwin-x64@0.127.0': + resolution: {integrity: sha512-JL6Xb5IwPQT8rUzlpsX7E+AgfcdNklXNPFp8pjCQQ5MQOQo5rtEB2ui+3Hgg9Sn7Y9Egj6YOLLiHhLpdAe12Aw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-parser/binding-freebsd-x64@0.127.0': + resolution: {integrity: sha512-SDQ/3MQFw58fqQz3Z1PhSKFF3JoCF4gmlNjziDm8X02tTahCw0qJbd7FGPDKw1i4VTBZene9JPyC3mHtSvi+wA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-parser/binding-linux-arm-gnueabihf@0.127.0': + resolution: {integrity: sha512-Av+D1MIqzV0YMGPT9we2SIZaMKD7Cxs4CvXSx/yxaWHewZjYEjScpOf5igc8IILASViw4WTnjlwUdI1KzVtDHQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm-musleabihf@0.127.0': + resolution: {integrity: sha512-Cs2fdJ8cPpFdeebj6p4dag8A4+56hPvZ0AhQQzlaLswGz1tz7bXt1nETLeorrM9+AMcWFFkqxcXwDGfTVidY8g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm64-gnu@0.127.0': + resolution: {integrity: sha512-qdOfTcT6SY8gsJrrV92uyEUyjqMGPpIB5JZUG6QN5dukYd+7/j0kX6MwK1DgQj39jtUYixxPiaRUiEN1+0CXgQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-arm64-musl@0.127.0': + resolution: {integrity: sha512-EoTCZneNFU/P2qrpEM+RHmQwt+CvDkyGESG6qhr7KaegXLZwePfbrkCDfAk8/rhxbDUVGsZILX+2tqPzFtoFWA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-ppc64-gnu@0.127.0': + resolution: {integrity: sha512-zALjmZYgxFLHjXeudcDF0xFGNydTAtkAeXAr2EuC17ywCyFxcmQra4w0BMde0Yi/re4Bi4iwEoEXtYN7l6eBLQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-gnu@0.127.0': + resolution: {integrity: sha512-fPP8M6zQLS7Jz7o9d5ArUSuAuSK3e+WCYVrCpdzeCOejidtZExJ9tjhDrAd3HEPqARBCPmdpqxESPFqy44vkBQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-musl@0.127.0': + resolution: {integrity: sha512-7IcC4Ao02oGpfnjt+X/oF4U2mllo2qoSkw5xxiXNKL9MCTsTiAC6616beOuehdxGcnz1bRoPC1RQ2f1GQDdN+g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-s390x-gnu@0.127.0': + resolution: {integrity: sha512-pbXIhiNFHoqWeqDNLiJ9JkpHz1IM9k4DXa66x+1GTWMG7iLxtkXgE53iiuKSXwmk3zIYmaPVfBvgcAhS583K4Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-x64-gnu@0.127.0': + resolution: {integrity: sha512-MYCguB9RvBvlSd6gbuNI7QwiLoCCAlGnlRJFPrzLI6U1/9wkC/WK6LtBAUln55H1Ctqw45PWmqrobKoMhsYQzQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-x64-musl@0.127.0': + resolution: {integrity: sha512-5eY0B/bxf1xIUxb4NOTvOI3KWtBQfPWYyKAzgcrCt0mDibSZygVpO1Pz8bkeiSZ5Jj9+M09dkggG3H8I5d0Uyg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-openharmony-arm64@0.127.0': + resolution: {integrity: sha512-Gld0ajrFTUXNtdw20fVBuTQx66FA75nIVg+//pPfR3sXkuABB4mTBhl3r9JNzrJpgW//qiwxf0nWXUWGJSL3UQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-parser/binding-wasm32-wasi@0.127.0': + resolution: {integrity: sha512-T6KVD7rhLzFlwGRXMnxUFfkCZD8FHnb968wVXW1mXzgRFc5RNXOBY2mPPDZ77x5Ln76ltLMgtPg0cOkU1NSrEQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@oxc-parser/binding-win32-arm64-msvc@0.127.0': + resolution: {integrity: sha512-Ujvw4X+LD1CCGULcsQcvb4YNVoBGqt+JHgNNzGGaCImELiZLk477ifUH53gIbE7EKd933NdTi25JWEr9K2HwXw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-parser/binding-win32-ia32-msvc@0.127.0': + resolution: {integrity: sha512-0cwxKO7KHQQQfo4Uf4B2SQrhgm+cJaP9OvFFhx52Tkg4bezsacu83GB2/In5bC415Ueeym+kXdnge/57rbSfTw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-parser/binding-win32-x64-msvc@0.127.0': + resolution: {integrity: sha512-rOrnSQSCbhI2kowr9XxE7m9a8oQXnBHjnS6j95LxxAnEZ0+Fz20WlRXG4ondQb+ejjt2KOsa65sE6++L6kUd+w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@oxc-project/types@0.127.0': + resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==} + '@oxc-project/types@0.130.0': resolution: {integrity: sha512-ibD2usx9JRu7f5pu2tMKMI4cpA4NgXJQoYRP4pQ7Pxmn1l6k/53qWtQWZayhYy3X4QZkt90Ot+mJEaeXouio6Q==} + '@oxc-resolver/binding-android-arm-eabi@11.19.1': + resolution: {integrity: sha512-aUs47y+xyXHUKlbhqHUjBABjvycq6YSD7bpxSW7vplUmdzAlJ93yXY6ZR0c1o1x5A/QKbENCvs3+NlY8IpIVzg==} + cpu: [arm] + os: [android] + + '@oxc-resolver/binding-android-arm64@11.19.1': + resolution: {integrity: sha512-oolbkRX+m7Pq2LNjr/kKgYeC7bRDMVTWPgxBGMjSpZi/+UskVo4jsMU3MLheZV55jL6c3rNelPl4oD60ggYmqA==} + cpu: [arm64] + os: [android] + + '@oxc-resolver/binding-darwin-arm64@11.19.1': + resolution: {integrity: sha512-nUC6d2i3R5B12sUW4O646qD5cnMXf2oBGPLIIeaRfU9doJRORAbE2SGv4eW6rMqhD+G7nf2Y8TTJTLiiO3Q/dQ==} + cpu: [arm64] + os: [darwin] + + '@oxc-resolver/binding-darwin-x64@11.19.1': + resolution: {integrity: sha512-cV50vE5+uAgNcFa3QY1JOeKDSkM/9ReIcc/9wn4TavhW/itkDGrXhw9jaKnkQnGbjJ198Yh5nbX/Gr2mr4Z5jQ==} + cpu: [x64] + os: [darwin] + + '@oxc-resolver/binding-freebsd-x64@11.19.1': + resolution: {integrity: sha512-xZOQiYGFxtk48PBKff+Zwoym7ScPAIVp4c14lfLxizO2LTTTJe5sx9vQNGrBymrf/vatSPNMD4FgsaaRigPkqw==} + cpu: [x64] + os: [freebsd] + + '@oxc-resolver/binding-linux-arm-gnueabihf@11.19.1': + resolution: {integrity: sha512-lXZYWAC6kaGe/ky2su94e9jN9t6M0/6c+GrSlCqL//XO1cxi5lpAhnJYdyrKfm0ZEr/c7RNyAx3P7FSBcBd5+A==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm-musleabihf@11.19.1': + resolution: {integrity: sha512-veG1kKsuK5+t2IsO9q0DErYVSw2azvCVvWHnfTOS73WE0STdLLB7Q1bB9WR+yHPQM76ASkFyRbogWo1GR1+WbQ==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm64-gnu@11.19.1': + resolution: {integrity: sha512-heV2+jmXyYnUrpUXSPugqWDRpnsQcDm2AX4wzTuvgdlZfoNYO0O3W2AVpJYaDn9AG4JdM6Kxom8+foE7/BcSig==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-arm64-musl@11.19.1': + resolution: {integrity: sha512-jvo2Pjs1c9KPxMuMPIeQsgu0mOJF9rEb3y3TdpsrqwxRM+AN6/nDDwv45n5ZrUnQMsdBy5gIabioMKnQfWo9ew==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-linux-ppc64-gnu@11.19.1': + resolution: {integrity: sha512-vLmdNxWCdN7Uo5suays6A/+ywBby2PWBBPXctWPg5V0+eVuzsJxgAn6MMB4mPlshskYbppjpN2Zg83ArHze9gQ==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-riscv64-gnu@11.19.1': + resolution: {integrity: sha512-/b+WgR+VTSBxzgOhDO7TlMXC1ufPIMR6Vj1zN+/x+MnyXGW7prTLzU9eW85Aj7Th7CCEG9ArCbTeqxCzFWdg2w==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-riscv64-musl@11.19.1': + resolution: {integrity: sha512-YlRdeWb9j42p29ROh+h4eg/OQ3dTJlpHSa+84pUM9+p6i3djtPz1q55yLJhgW9XfDch7FN1pQ/Vd6YP+xfRIuw==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-linux-s390x-gnu@11.19.1': + resolution: {integrity: sha512-EDpafVOQWF8/MJynsjOGFThcqhRHy417sRyLfQmeiamJ8qVhSKAn2Dn2VVKUGCjVB9C46VGjhNo7nOPUi1x6uA==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-gnu@11.19.1': + resolution: {integrity: sha512-NxjZe+rqWhr+RT8/Ik+5ptA3oz7tUw361Wa5RWQXKnfqwSSHdHyrw6IdcTfYuml9dM856AlKWZIUXDmA9kkiBQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-musl@11.19.1': + resolution: {integrity: sha512-cM/hQwsO3ReJg5kR+SpI69DMfvNCp+A/eVR4b4YClE5bVZwz8rh2Nh05InhwI5HR/9cArbEkzMjcKgTHS6UaNw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-openharmony-arm64@11.19.1': + resolution: {integrity: sha512-QF080IowFB0+9Rh6RcD19bdgh49BpQHUW5TajG1qvWHvmrQznTZZjYlgE2ltLXyKY+qs4F/v5xuX1XS7Is+3qA==} + cpu: [arm64] + os: [openharmony] + + '@oxc-resolver/binding-wasm32-wasi@11.19.1': + resolution: {integrity: sha512-w8UCKhX826cP/ZLokXDS6+milN8y4X7zidsAttEdWlVoamTNf6lhBJldaWr3ukTDiye7s4HRcuPEPOXNC432Vg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-resolver/binding-win32-arm64-msvc@11.19.1': + resolution: {integrity: sha512-nJ4AsUVZrVKwnU/QRdzPCCrO0TrabBqgJ8pJhXITdZGYOV28TIYystV1VFLbQ7DtAcaBHpocT5/ZJnF78YJPtQ==} + cpu: [arm64] + os: [win32] + + '@oxc-resolver/binding-win32-ia32-msvc@11.19.1': + resolution: {integrity: sha512-EW+ND5q2Tl+a3pH81l1QbfgbF3HmqgwLfDfVithRFheac8OTcnbXt/JxqD2GbDkb7xYEqy1zNaVFRr3oeG8npA==} + cpu: [ia32] + os: [win32] + + '@oxc-resolver/binding-win32-x64-msvc@11.19.1': + resolution: {integrity: sha512-6hIU3RQu45B+VNTY4Ru8ppFwjVS/S5qwYyGhBotmjxfEKk41I2DlGtRfGJndZ5+6lneE2pwloqunlOyZuX/XAw==} + cpu: [x64] + os: [win32] + '@peculiar/asn1-schema@2.3.13': resolution: {integrity: sha512-3Xq3a01WkHRZL8X04Zsfg//mGaA21xlL4tlVn4v2xGT0JStiztATRkMwa5b+f/HXmY2smsiLXYK46Gwgzvfg3g==} @@ -2716,9 +2990,6 @@ packages: peerDependencies: solid-js: '>=1.8.4' - '@solidjs/signals@2.0.0-beta.13': - resolution: {integrity: sha512-jc+wLRK+eyUFerH8Mjed4HikdJwz3z95TT7tqyG+K00IV9jfgZWvR1nZDUEZc6kXffmtW/z+w6PNn62ea5KjIw==} - '@solidjs/signals@2.0.0-beta.14': resolution: {integrity: sha512-y72nYtD7ogwX/UR5g2Y+meyeO6Q/xbQGtmvVTQX6USkMwEGOMnytqDnHj5amUzD7Fzqg32svwtCSx/q8hsOXAA==} @@ -2732,6 +3003,62 @@ packages: peerDependencies: solid-js: ^2.0.0-beta.14 + '@storybook/addon-docs@10.4.1': + resolution: {integrity: sha512-IYqUdjoZe4VO2LFZlKL/gwy7DsQSWCq6hX+zc1MBmZo04yycDASk1tte57n9pdlW3ajw9yYMF/+lVBi+xQjyvw==} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.4.1 + peerDependenciesMeta: + '@types/react': + optional: true + + '@storybook/builder-vite@10.4.1': + resolution: {integrity: sha512-/oyQrXoNOqN8SW5hNnYP+I1uvgFxKxWXj/EP6NXYzc5SQwImofgru+D2+6gDhL0+Q//+Hx05DJoQO2omvUJ8bQ==} + peerDependencies: + storybook: ^10.4.1 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@storybook/csf-plugin@10.4.1': + resolution: {integrity: sha512-WdPepGBxDGOUDjYd8KxMtcf+us/2PAcnBczl77XtrnxxHNs0jWesxKkiJ9yiuGrge4BPhDeAj6rxjbBoaHxLBA==} + peerDependencies: + esbuild: '*' + rollup: '*' + storybook: ^10.4.1 + 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.2': + resolution: {integrity: sha512-KZBCpXsshAIjczYNXR/rlxEtCUX/eAbpFNwKi8bcOomrLA4t/SyPz5RF+lVPO2oZBUE4sAkt43mfJUevQDSEEw==} + 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.4.1': + resolution: {integrity: sha512-6QFqfDNH4DMrt7yHKRfpqRopsVUc/Az+sXIdJ39IetYnHUxL3nW4NVaPc6uy/8Qi8urzUyEXL/nn7cpSIP2aPQ==} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + '@types/react-dom': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + 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.4.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@supabase/auth-js@2.67.3': resolution: {integrity: sha512-NJDaW8yXs49xMvWVOkSIr8j46jf+tYHV0wHhrwOaLLMZSFO4g6kKAf+MfzQ2RaD06OCUkUHIzctLAxjTgEVpzw==} @@ -2873,9 +3200,26 @@ packages: '@tauri-apps/plugin-store@2.0.0': resolution: {integrity: sha512-l4xsbxAXrKGdBdYNNswrLfcRv3v1kOatdycOcVPYW+jKwkznCr1HEOrPXkPhXsZLSLyYmNXpgfOmdSZNmcykDg==} + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} + engines: {node: '>=18'} + + '@testing-library/jest-dom@6.9.1': + resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + '@tybys/wasm-util@0.10.2': resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -2888,9 +3232,15 @@ packages: '@types/babel__traverse@7.20.7': resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/estree@1.0.7': resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} @@ -2924,6 +3274,9 @@ packages: '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} @@ -2936,6 +3289,9 @@ packages: '@types/phoenix@1.6.6': resolution: {integrity: sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==} + '@types/react@19.2.15': + resolution: {integrity: sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==} + '@types/sizzle@2.3.8': resolution: {integrity: sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==} @@ -3016,6 +3372,9 @@ packages: '@vitest/expect@2.1.9': resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + '@vitest/mocker@2.1.9': resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} peerDependencies: @@ -3030,6 +3389,9 @@ packages: '@vitest/pretty-format@2.1.9': resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + '@vitest/runner@2.1.9': resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} @@ -3039,9 +3401,18 @@ packages: '@vitest/spy@2.1.9': resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + '@vitest/utils@2.1.9': resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + + '@webcontainer/env@1.1.1': + resolution: {integrity: sha512-6aN99yL695Hi9SuIk1oC88l9o0gmxL1nGWWQ/kNy81HigJ0FoaoTXpytCj6ItzgyCEwA9kF1wixsTuv5cjsgng==} + '@whatwg-node/events@0.0.3': resolution: {integrity: sha512-IqnKIDWfXBJkvy/k6tzskWTc2NK3LcqHlb+KHGCrjOCH4jfQckRX0NAiIcC/vIqQkzLYw2r2CTSwAxcrtcD6lA==} @@ -3116,6 +3487,10 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} @@ -3140,6 +3515,13 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} @@ -3240,6 +3622,10 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -3263,6 +3649,10 @@ packages: brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@5.0.6: + resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + engines: {node: 18 || 20 || >=22} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -3278,6 +3668,10 @@ packages: buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -3489,6 +3883,9 @@ packages: resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} engines: {node: '>= 6'} + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -3501,6 +3898,9 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} @@ -3545,9 +3945,21 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + 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'} + defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + defined@1.0.1: resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==} @@ -3593,6 +4005,12 @@ packages: dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} @@ -3948,6 +4366,10 @@ packages: deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true + glob@13.0.6: + resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + engines: {node: 18 || 20 || >=22} + glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me @@ -4169,6 +4591,11 @@ packages: resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} engines: {node: '>= 0.4'} + 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'} @@ -4181,6 +4608,11 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + is-interactive@1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} @@ -4226,6 +4658,10 @@ packages: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + isbot@5.1.40: resolution: {integrity: sha512-yNeeynhhtIVRBk12tBV4eHNxwB42HzR4Q3Ea7vCOiJhImGaAIdIMrbJtacQlBizGLjUPw+akkFI5Dn9T70XoVQ==} engines: {node: '>=18'} @@ -4452,6 +4888,9 @@ packages: loupe@3.1.3: resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + lower-case-first@2.0.2: resolution: {integrity: sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg==} @@ -4464,9 +4903,17 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.5.0: + resolution: {integrity: sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} @@ -4634,6 +5081,14 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -4652,6 +5107,10 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -4753,6 +5212,10 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} + engines: {node: '>=18'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -4768,6 +5231,13 @@ packages: outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + oxc-parser@0.127.0: + resolution: {integrity: sha512-bkgD4qHlN7WxLdX8bLXdaU54TtQtAIg/ZBAfm0aje/mo3MRDo3P0hZSgr4U7O3xfX+fQmR5AP04JS/TGcZLcFA==} + engines: {node: ^20.19.0 || >=22.12.0} + + oxc-resolver@11.19.1: + resolution: {integrity: sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg==} + p-filter@2.1.0: resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} engines: {node: '>=8'} @@ -4863,6 +5333,10 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -5049,6 +5523,10 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + pretty-hrtime@1.0.3: resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} engines: {node: '>= 0.8'} @@ -5083,6 +5561,19 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + react-docgen-typescript@2.4.0: + resolution: {integrity: sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==} + peerDependencies: + typescript: '>= 4.3.x' + + react-dom@19.2.6: + resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} + peerDependencies: + react: ^19.2.6 + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react@19.2.6: resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} engines: {node: '>=0.10.0'} @@ -5106,6 +5597,10 @@ packages: resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} engines: {node: '>= 4'} + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + reduce-css-calc@2.1.8: resolution: {integrity: sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==} @@ -5216,6 +5711,10 @@ packages: rrweb-cssom@0.8.0: resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -5241,6 +5740,9 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + scuid@1.1.0: resolution: {integrity: sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg==} @@ -5253,6 +5755,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.8.1: + resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==} + engines: {node: '>=10'} + hasBin: true + sentence-case@3.0.4: resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} @@ -5383,6 +5890,36 @@ packages: std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + storybook-solidjs-vite@10.1.0: + resolution: {integrity: sha512-2weoGZkfybctPQ0DzMSrDkd3ha81N3nS+TwwgeiVSPNH76SN4Rld1vgvORuUBBlFZOSGj47aikydWjKCcxt6dQ==} + peerDependencies: + '@solidjs/web': ^2.0.0-0 + solid-js: ^1.8.0-0 || ^2.0.0-0 + storybook: ^0.0.0-0 || ^10.0.0 + typescript: ^4.0.0 || ^5.0.0 || ^6.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + vite-plugin-solid: ^2.0.0-0 || ^3.0.0-0 + peerDependenciesMeta: + '@solidjs/web': + optional: true + typescript: + optional: true + + storybook@10.4.1: + resolution: {integrity: sha512-V1Zd2e+gBFufqAQVZ1JR8KLqALsEZ3JYSBnWwQbKa6zCfWWanR6AFMyuOkLt2gZOgGp3h2Riuz88pGNVTQSG0A==} + hasBin: true + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + prettier: ^2 || ^3 + vite-plus: ^0.1.15 + peerDependenciesMeta: + '@types/react': + optional: true + prettier: + optional: true + vite-plus: + optional: true + streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} @@ -5416,6 +5953,10 @@ packages: 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-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -5499,10 +6040,18 @@ packages: resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} engines: {node: '>=14.0.0'} + tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} + engines: {node: '>=14.0.0'} + tinyspy@3.0.2: resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} engines: {node: '>=14.0.0'} + tinyspy@4.0.4: + resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} + engines: {node: '>=14.0.0'} + title-case@3.0.3: resolution: {integrity: sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==} @@ -5544,6 +6093,10 @@ 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==} @@ -5653,6 +6206,11 @@ packages: urlpattern-polyfill@8.0.2: resolution: {integrity: sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==} + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -5916,6 +6474,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'} @@ -5977,6 +6539,8 @@ packages: snapshots: + '@adobe/css-tools@4.5.0': {} + '@alloc/quick-lru@5.2.0': {} '@ampproject/remapping@2.3.0': @@ -6692,11 +7256,22 @@ snapshots: tslib: 2.8.1 optional: true + '@emnapi/core@1.9.2': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + '@emnapi/runtime@1.10.0': dependencies: tslib: 2.8.1 optional: true + '@emnapi/runtime@1.9.2': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/wasi-threads@1.2.1': dependencies: tslib: 2.8.1 @@ -7361,6 +7936,14 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@joshwooding/vite-plugin-react-docgen-typescript@0.7.0(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0))': + dependencies: + glob: 13.0.6 + react-docgen-typescript: 2.4.0(typescript@5.8.3) + vite: 6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0) + optionalDependencies: + typescript: 5.8.3 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -7411,6 +7994,12 @@ snapshots: globby: 11.1.0 read-yaml-file: 1.1.0 + '@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6)': + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 19.2.15 + react: 19.2.6 + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: '@emnapi/core': 1.10.0 @@ -7418,6 +8007,13 @@ snapshots: '@tybys/wasm-util': 0.10.2 optional: true + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@tybys/wasm-util': 0.10.2 + optional: true + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -7451,8 +8047,139 @@ snapshots: '@oozcitak/util@10.0.0': {} + '@oxc-parser/binding-android-arm-eabi@0.127.0': + optional: true + + '@oxc-parser/binding-android-arm64@0.127.0': + optional: true + + '@oxc-parser/binding-darwin-arm64@0.127.0': + optional: true + + '@oxc-parser/binding-darwin-x64@0.127.0': + optional: true + + '@oxc-parser/binding-freebsd-x64@0.127.0': + optional: true + + '@oxc-parser/binding-linux-arm-gnueabihf@0.127.0': + optional: true + + '@oxc-parser/binding-linux-arm-musleabihf@0.127.0': + optional: true + + '@oxc-parser/binding-linux-arm64-gnu@0.127.0': + optional: true + + '@oxc-parser/binding-linux-arm64-musl@0.127.0': + optional: true + + '@oxc-parser/binding-linux-ppc64-gnu@0.127.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-gnu@0.127.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-musl@0.127.0': + optional: true + + '@oxc-parser/binding-linux-s390x-gnu@0.127.0': + optional: true + + '@oxc-parser/binding-linux-x64-gnu@0.127.0': + optional: true + + '@oxc-parser/binding-linux-x64-musl@0.127.0': + optional: true + + '@oxc-parser/binding-openharmony-arm64@0.127.0': + optional: true + + '@oxc-parser/binding-wasm32-wasi@0.127.0': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + optional: true + + '@oxc-parser/binding-win32-arm64-msvc@0.127.0': + optional: true + + '@oxc-parser/binding-win32-ia32-msvc@0.127.0': + optional: true + + '@oxc-parser/binding-win32-x64-msvc@0.127.0': + optional: true + + '@oxc-project/types@0.127.0': {} + '@oxc-project/types@0.130.0': {} + '@oxc-resolver/binding-android-arm-eabi@11.19.1': + optional: true + + '@oxc-resolver/binding-android-arm64@11.19.1': + optional: true + + '@oxc-resolver/binding-darwin-arm64@11.19.1': + optional: true + + '@oxc-resolver/binding-darwin-x64@11.19.1': + optional: true + + '@oxc-resolver/binding-freebsd-x64@11.19.1': + optional: true + + '@oxc-resolver/binding-linux-arm-gnueabihf@11.19.1': + optional: true + + '@oxc-resolver/binding-linux-arm-musleabihf@11.19.1': + optional: true + + '@oxc-resolver/binding-linux-arm64-gnu@11.19.1': + optional: true + + '@oxc-resolver/binding-linux-arm64-musl@11.19.1': + optional: true + + '@oxc-resolver/binding-linux-ppc64-gnu@11.19.1': + optional: true + + '@oxc-resolver/binding-linux-riscv64-gnu@11.19.1': + optional: true + + '@oxc-resolver/binding-linux-riscv64-musl@11.19.1': + optional: true + + '@oxc-resolver/binding-linux-s390x-gnu@11.19.1': + optional: true + + '@oxc-resolver/binding-linux-x64-gnu@11.19.1': + optional: true + + '@oxc-resolver/binding-linux-x64-musl@11.19.1': + optional: true + + '@oxc-resolver/binding-openharmony-arm64@11.19.1': + optional: true + + '@oxc-resolver/binding-wasm32-wasi@11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + optional: true + + '@oxc-resolver/binding-win32-arm64-msvc@11.19.1': + optional: true + + '@oxc-resolver/binding-win32-ia32-msvc@11.19.1': + optional: true + + '@oxc-resolver/binding-win32-x64-msvc@11.19.1': + optional: true + '@peculiar/asn1-schema@2.3.13': dependencies: asn1js: 3.0.5 @@ -7474,12 +8201,14 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@reduxjs/toolkit@1.9.7': + '@reduxjs/toolkit@1.9.7(react@19.2.6)': dependencies: immer: 9.0.21 redux: 4.2.1 redux-thunk: 2.4.2(redux@4.2.1) reselect: 4.1.8 + optionalDependencies: + react: 19.2.6 '@repeaterjs/repeater@3.0.6': {} @@ -7727,8 +8456,6 @@ snapshots: dependencies: solid-js: 2.0.0-beta.14 - '@solidjs/signals@2.0.0-beta.13': {} - '@solidjs/signals@2.0.0-beta.14': {} '@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.13)': @@ -7749,6 +8476,60 @@ snapshots: seroval-plugins: 1.5.4(seroval@1.5.4) solid-js: 2.0.0-beta.14 + '@storybook/addon-docs@10.4.1(@types/react@19.2.15)(esbuild@0.25.5)(rollup@4.43.0)(storybook@10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0))': + dependencies: + '@mdx-js/react': 3.1.1(@types/react@19.2.15)(react@19.2.6) + '@storybook/csf-plugin': 10.4.1(esbuild@0.25.5)(rollup@4.43.0)(storybook@10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) + '@storybook/icons': 2.0.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/react-dom-shim': 10.4.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(storybook@10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + storybook: 10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + ts-dedent: 2.2.0 + optionalDependencies: + '@types/react': 19.2.15 + transitivePeerDependencies: + - '@types/react-dom' + - esbuild + - rollup + - vite + - webpack + + '@storybook/builder-vite@10.4.1(esbuild@0.25.5)(rollup@4.43.0)(storybook@10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0))': + dependencies: + '@storybook/csf-plugin': 10.4.1(esbuild@0.25.5)(rollup@4.43.0)(storybook@10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) + storybook: 10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + ts-dedent: 2.2.0 + vite: 6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0) + transitivePeerDependencies: + - esbuild + - rollup + - webpack + + '@storybook/csf-plugin@10.4.1(esbuild@0.25.5)(rollup@4.43.0)(storybook@10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0))': + dependencies: + storybook: 10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + unplugin: 2.3.5 + optionalDependencies: + esbuild: 0.25.5 + rollup: 4.43.0 + vite: 6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0) + + '@storybook/global@5.0.0': {} + + '@storybook/icons@2.0.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@storybook/react-dom-shim@10.4.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(storybook@10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))': + dependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + storybook: 10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + optionalDependencies: + '@types/react': 19.2.15 + '@supabase/auth-js@2.67.3': dependencies: '@supabase/node-fetch': 2.6.15 @@ -7825,7 +8606,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.167.12(vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)))(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0))': + '@tanstack/router-plugin@1.167.12(vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(@testing-library/jest-dom@6.9.1)(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)))(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) @@ -7842,7 +8623,7 @@ snapshots: zod: 3.25.63 optionalDependencies: vite: 8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0) - vite-plugin-solid: 3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) + vite-plugin-solid: 3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(@testing-library/jest-dom@6.9.1)(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) transitivePeerDependencies: - supports-color @@ -7891,14 +8672,14 @@ snapshots: transitivePeerDependencies: - crossws - '@tanstack/solid-start@2.0.0-beta.18(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14)(vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)))(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0))': + '@tanstack/solid-start@2.0.0-beta.18(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14)(vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(@testing-library/jest-dom@6.9.1)(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)))(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0))': dependencies: '@solidjs/web': 2.0.0-beta.13(solid-js@2.0.0-beta.14) '@tanstack/solid-router': 2.0.0-beta.17(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14) '@tanstack/solid-start-client': 2.0.0-beta.17(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14) '@tanstack/solid-start-server': 2.0.0-beta.17(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14) '@tanstack/start-client-core': 1.167.9 - '@tanstack/start-plugin-core': 1.167.17(vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)))(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) + '@tanstack/start-plugin-core': 1.167.17(vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(@testing-library/jest-dom@6.9.1)(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)))(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) '@tanstack/start-server-core': 1.167.9 pathe: 2.0.3 solid-js: 2.0.0-beta.14 @@ -7920,7 +8701,7 @@ snapshots: '@tanstack/start-fn-stubs@1.161.6': {} - '@tanstack/start-plugin-core@1.167.17(vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)))(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0))': + '@tanstack/start-plugin-core@1.167.17(vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(@testing-library/jest-dom@6.9.1)(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)))(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0))': dependencies: '@babel/code-frame': 7.27.1 '@babel/core': 7.29.0 @@ -7928,7 +8709,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.40 '@tanstack/router-core': 1.168.9 '@tanstack/router-generator': 1.166.24 - '@tanstack/router-plugin': 1.167.12(vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)))(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) + '@tanstack/router-plugin': 1.167.12(vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(@testing-library/jest-dom@6.9.1)(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)))(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) '@tanstack/router-utils': 1.161.6 '@tanstack/start-client-core': 1.167.9 '@tanstack/start-server-core': 1.167.9 @@ -7977,11 +8758,37 @@ snapshots: dependencies: '@tauri-apps/api': 2.0.1 + '@testing-library/dom@10.4.1': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/runtime': 7.27.6 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + picocolors: 1.1.1 + pretty-format: 27.5.1 + + '@testing-library/jest-dom@6.9.1': + dependencies: + '@adobe/css-tools': 4.5.0 + 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/user-event@14.6.1(@testing-library/dom@10.4.1)': + dependencies: + '@testing-library/dom': 10.4.1 + '@tybys/wasm-util@0.10.2': dependencies: tslib: 2.8.1 optional: true + '@types/aria-query@5.0.4': {} + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.29.3 @@ -8003,10 +8810,17 @@ snapshots: dependencies: '@babel/types': 7.29.0 + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + '@types/debug@4.1.12': dependencies: '@types/ms': 0.7.34 + '@types/deep-eql@4.0.2': {} + '@types/estree@1.0.7': {} '@types/estree@1.0.8': {} @@ -8043,6 +8857,8 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/mdx@2.0.13': {} + '@types/ms@0.7.34': {} '@types/node@12.20.55': {} @@ -8053,6 +8869,10 @@ snapshots: '@types/phoenix@1.6.6': {} + '@types/react@19.2.15': + dependencies: + csstype: 3.2.3 + '@types/sizzle@2.3.8': {} '@types/tough-cookie@4.0.5': {} @@ -8166,6 +8986,14 @@ snapshots: chai: 5.2.0 tinyrainbow: 1.2.0 + '@vitest/expect@3.2.4': + dependencies: + '@types/chai': 5.2.3 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.2.0 + tinyrainbow: 2.0.0 + '@vitest/mocker@2.1.9(vite@5.4.4(@types/node@22.15.31)(lightningcss@1.32.0)(sass@1.77.8))': dependencies: '@vitest/spy': 2.1.9 @@ -8178,6 +9006,10 @@ snapshots: dependencies: tinyrainbow: 1.2.0 + '@vitest/pretty-format@3.2.4': + dependencies: + tinyrainbow: 2.0.0 + '@vitest/runner@2.1.9': dependencies: '@vitest/utils': 2.1.9 @@ -8193,12 +9025,24 @@ snapshots: dependencies: tinyspy: 3.0.2 + '@vitest/spy@3.2.4': + dependencies: + tinyspy: 4.0.4 + '@vitest/utils@2.1.9': dependencies: '@vitest/pretty-format': 2.1.9 loupe: 3.1.3 tinyrainbow: 1.2.0 + '@vitest/utils@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.1 + tinyrainbow: 2.0.0 + + '@webcontainer/env@1.1.1': {} + '@whatwg-node/events@0.0.3': {} '@whatwg-node/fetch@0.8.8': @@ -8277,6 +9121,8 @@ snapshots: dependencies: color-convert: 2.0.1 + ansi-styles@5.2.0: {} + ansi-styles@6.2.1: {} ansis@4.1.0: {} @@ -8296,6 +9142,12 @@ snapshots: argparse@2.0.1: {} + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + aria-query@5.3.2: {} + array-union@2.1.0: {} asap@2.0.6: {} @@ -8436,6 +9288,8 @@ snapshots: balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + base64-js@1.5.1: {} better-path-resolve@1.0.0: @@ -8461,6 +9315,10 @@ snapshots: dependencies: balanced-match: 1.0.2 + brace-expansion@5.0.6: + dependencies: + balanced-match: 4.0.4 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -8481,6 +9339,10 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + busboy@1.6.0: dependencies: streamsearch: 1.1.0 @@ -8727,6 +9589,8 @@ snapshots: css-what@6.2.2: {} + css.escape@1.5.1: {} + cssesc@3.0.0: {} cssstyle@4.4.0: @@ -8736,6 +9600,8 @@ snapshots: csstype@3.1.3: {} + csstype@3.2.3: {} + data-uri-to-buffer@4.0.1: {} data-urls@5.0.0: @@ -8767,10 +9633,19 @@ snapshots: deep-is@0.1.4: {} + default-browser-id@5.0.1: {} + + default-browser@5.5.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + defaults@1.0.4: dependencies: clone: 1.0.4 + define-lazy-prop@3.0.0: {} + defined@1.0.1: {} delayed-stream@1.0.0: {} @@ -8803,6 +9678,10 @@ snapshots: dlv@1.1.3: {} + dom-accessibility-api@0.5.16: {} + + dom-accessibility-api@0.6.3: {} + dom-serializer@2.0.0: dependencies: domelementtype: 2.3.0 @@ -9229,6 +10108,12 @@ snapshots: package-json-from-dist: 1.0.0 path-scurry: 1.11.1 + glob@13.0.6: + dependencies: + minimatch: 10.2.5 + minipass: 7.1.3 + path-scurry: 2.0.2 + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -9476,6 +10361,8 @@ snapshots: dependencies: hasown: 2.0.2 + is-docker@3.0.0: {} + is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -9484,6 +10371,10 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + is-interactive@1.0.0: {} is-lower-case@2.0.2: @@ -9518,6 +10409,10 @@ snapshots: is-windows@1.0.2: {} + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + isbot@5.1.40: {} isexe@2.0.0: {} @@ -9723,6 +10618,8 @@ snapshots: loupe@3.1.3: {} + loupe@3.2.1: {} + lower-case-first@2.0.2: dependencies: tslib: 2.8.1 @@ -9739,10 +10636,14 @@ snapshots: lru-cache@10.4.3: {} + lru-cache@11.5.0: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 + lz-string@1.5.0: {} + magic-string@0.30.17: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -10081,6 +10982,12 @@ snapshots: mimic-fn@2.1.0: {} + min-indent@1.0.1: {} + + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.6 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 @@ -10097,6 +11004,8 @@ snapshots: minipass@7.1.2: {} + minipass@7.1.3: {} + mri@1.2.0: {} ms@2.1.3: {} @@ -10179,6 +11088,13 @@ snapshots: dependencies: mimic-fn: 2.1.0 + 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 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -10204,6 +11120,57 @@ snapshots: outdent@0.5.0: {} + oxc-parser@0.127.0: + dependencies: + '@oxc-project/types': 0.127.0 + optionalDependencies: + '@oxc-parser/binding-android-arm-eabi': 0.127.0 + '@oxc-parser/binding-android-arm64': 0.127.0 + '@oxc-parser/binding-darwin-arm64': 0.127.0 + '@oxc-parser/binding-darwin-x64': 0.127.0 + '@oxc-parser/binding-freebsd-x64': 0.127.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.127.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.127.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.127.0 + '@oxc-parser/binding-linux-arm64-musl': 0.127.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.127.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.127.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.127.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.127.0 + '@oxc-parser/binding-linux-x64-gnu': 0.127.0 + '@oxc-parser/binding-linux-x64-musl': 0.127.0 + '@oxc-parser/binding-openharmony-arm64': 0.127.0 + '@oxc-parser/binding-wasm32-wasi': 0.127.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.127.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.127.0 + '@oxc-parser/binding-win32-x64-msvc': 0.127.0 + + oxc-resolver@11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): + optionalDependencies: + '@oxc-resolver/binding-android-arm-eabi': 11.19.1 + '@oxc-resolver/binding-android-arm64': 11.19.1 + '@oxc-resolver/binding-darwin-arm64': 11.19.1 + '@oxc-resolver/binding-darwin-x64': 11.19.1 + '@oxc-resolver/binding-freebsd-x64': 11.19.1 + '@oxc-resolver/binding-linux-arm-gnueabihf': 11.19.1 + '@oxc-resolver/binding-linux-arm-musleabihf': 11.19.1 + '@oxc-resolver/binding-linux-arm64-gnu': 11.19.1 + '@oxc-resolver/binding-linux-arm64-musl': 11.19.1 + '@oxc-resolver/binding-linux-ppc64-gnu': 11.19.1 + '@oxc-resolver/binding-linux-riscv64-gnu': 11.19.1 + '@oxc-resolver/binding-linux-riscv64-musl': 11.19.1 + '@oxc-resolver/binding-linux-s390x-gnu': 11.19.1 + '@oxc-resolver/binding-linux-x64-gnu': 11.19.1 + '@oxc-resolver/binding-linux-x64-musl': 11.19.1 + '@oxc-resolver/binding-openharmony-arm64': 11.19.1 + '@oxc-resolver/binding-wasm32-wasi': 11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@oxc-resolver/binding-win32-arm64-msvc': 11.19.1 + '@oxc-resolver/binding-win32-ia32-msvc': 11.19.1 + '@oxc-resolver/binding-win32-x64-msvc': 11.19.1 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + p-filter@2.1.0: dependencies: p-map: 2.1.0 @@ -10302,6 +11269,11 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + path-scurry@2.0.2: + dependencies: + lru-cache: 11.5.0 + minipass: 7.1.2 + path-type@4.0.0: {} pathe@1.1.2: {} @@ -10420,6 +11392,12 @@ snapshots: prettier@3.5.3: {} + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + pretty-hrtime@1.0.3: {} promise@7.3.1: @@ -10449,6 +11427,17 @@ snapshots: queue-microtask@1.2.3: {} + react-docgen-typescript@2.4.0(typescript@5.8.3): + dependencies: + typescript: 5.8.3 + + react-dom@19.2.6(react@19.2.6): + dependencies: + react: 19.2.6 + scheduler: 0.27.0 + + react-is@17.0.2: {} + react@19.2.6: {} read-cache@1.0.0: @@ -10480,6 +11469,11 @@ snapshots: tiny-invariant: 1.3.3 tslib: 2.8.1 + redent@3.0.0: + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + reduce-css-calc@2.1.8: dependencies: css-unit-converter: 1.1.2 @@ -10665,6 +11659,8 @@ snapshots: rrweb-cssom@0.8.0: {} + run-applescript@7.1.0: {} + run-async@2.4.1: {} run-parallel@1.2.0: @@ -10689,12 +11685,16 @@ snapshots: dependencies: xmlchars: 2.2.0 + scheduler@0.27.0: {} + scuid@1.1.0: {} semver@6.3.1: {} semver@7.7.2: {} + semver@7.8.1: {} + sentence-case@3.0.4: dependencies: no-case: 3.0.4 @@ -10768,7 +11768,7 @@ snapshots: solid-js@2.0.0-beta.13: dependencies: - '@solidjs/signals': 2.0.0-beta.13 + '@solidjs/signals': 2.0.0-beta.14 csstype: 3.1.3 seroval: 1.5.4 seroval-plugins: 1.5.4(seroval@1.5.4) @@ -10823,6 +11823,53 @@ snapshots: std-env@3.9.0: {} + storybook-solidjs-vite@10.1.0(@solidjs/web@2.0.0-beta.14(solid-js@2.0.0-beta.14))(esbuild@0.25.5)(rollup@4.43.0)(solid-js@2.0.0-beta.14)(storybook@10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(typescript@5.8.3)(vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.14(solid-js@2.0.0-beta.14))(@testing-library/jest-dom@6.9.1)(solid-js@2.0.0-beta.14)(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)))(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)): + dependencies: + '@joshwooding/vite-plugin-react-docgen-typescript': 0.7.0(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) + '@storybook/builder-vite': 10.4.1(esbuild@0.25.5)(rollup@4.43.0)(storybook@10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) + '@storybook/global': 5.0.0 + semver: 7.8.1 + solid-js: 2.0.0-beta.14 + storybook: 10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + vite: 6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0) + vite-plugin-solid: 3.0.0-next.5(@solidjs/web@2.0.0-beta.14(solid-js@2.0.0-beta.14))(@testing-library/jest-dom@6.9.1)(solid-js@2.0.0-beta.14)(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) + optionalDependencies: + '@solidjs/web': 2.0.0-beta.14(solid-js@2.0.0-beta.14) + typescript: 5.8.3 + transitivePeerDependencies: + - esbuild + - rollup + - webpack + + storybook@10.4.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@testing-library/dom@10.4.1)(@types/react@19.2.15)(prettier@3.5.3)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + dependencies: + '@storybook/global': 5.0.0 + '@storybook/icons': 2.0.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@testing-library/jest-dom': 6.9.1 + '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1) + '@vitest/expect': 3.2.4 + '@vitest/spy': 3.2.4 + '@webcontainer/env': 1.1.1 + esbuild: 0.25.5 + open: 10.2.0 + oxc-parser: 0.127.0 + oxc-resolver: 11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + recast: 0.23.11 + semver: 7.8.1 + use-sync-external-store: 1.6.0(react@19.2.6) + ws: 8.18.2 + optionalDependencies: + '@types/react': 19.2.15 + prettier: 3.5.3 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + - '@testing-library/dom' + - bufferutil + - react + - react-dom + - utf-8-validate + streamsearch@1.1.0: {} string-env-interpolation@1.0.1: {} @@ -10858,6 +11905,10 @@ snapshots: strip-bom@3.0.0: {} + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + strip-json-comments@3.1.1: {} sucrase@3.35.0: @@ -10978,8 +12029,12 @@ snapshots: tinyrainbow@1.2.0: {} + tinyrainbow@2.0.0: {} + tinyspy@3.0.2: {} + tinyspy@4.0.4: {} + title-case@3.0.3: dependencies: tslib: 2.8.1 @@ -11016,6 +12071,8 @@ snapshots: dependencies: typescript: 5.8.3 + ts-dedent@2.2.0: {} + ts-interface-checker@0.1.13: {} ts-log@2.2.5: {} @@ -11127,6 +12184,10 @@ snapshots: urlpattern-polyfill@8.0.2: {} + use-sync-external-store@1.6.0(react@19.2.6): + dependencies: + react: 19.2.6 + util-deprecate@1.0.2: {} validate-html-nesting@1.2.4: {} @@ -11161,7 +12222,7 @@ snapshots: - supports-color - terser - vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)): + vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.13(solid-js@2.0.0-beta.14))(@testing-library/jest-dom@6.9.1)(solid-js@2.0.0-beta.14)(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)): dependencies: '@babel/core': 7.29.0 '@solidjs/web': 2.0.0-beta.13(solid-js@2.0.0-beta.14) @@ -11172,10 +12233,12 @@ snapshots: solid-refresh: 0.8.0-next.7(solid-js@2.0.0-beta.14) vite: 8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0) vitefu: 1.1.3(vite@8.0.13(@types/node@22.15.31)(esbuild@0.25.5)(jiti@1.21.7)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) + optionalDependencies: + '@testing-library/jest-dom': 6.9.1 transitivePeerDependencies: - supports-color - vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.14(solid-js@2.0.0-beta.14))(solid-js@2.0.0-beta.14)(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)): + vite-plugin-solid@3.0.0-next.5(@solidjs/web@2.0.0-beta.14(solid-js@2.0.0-beta.14))(@testing-library/jest-dom@6.9.1)(solid-js@2.0.0-beta.14)(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)): dependencies: '@babel/core': 7.29.0 '@solidjs/web': 2.0.0-beta.14(solid-js@2.0.0-beta.14) @@ -11186,6 +12249,8 @@ snapshots: solid-refresh: 0.8.0-next.7(solid-js@2.0.0-beta.14) vite: 6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0) vitefu: 1.1.3(vite@6.3.5(@types/node@22.15.31)(jiti@1.21.7)(lightningcss@1.32.0)(sass@1.77.8)(tsx@4.20.2)(yaml@2.5.0)) + optionalDependencies: + '@testing-library/jest-dom': 6.9.1 transitivePeerDependencies: - supports-color @@ -11352,6 +12417,10 @@ snapshots: ws@8.18.2: {} + wsl-utils@0.1.0: + dependencies: + is-wsl: 3.1.1 + xml-name-validator@5.0.0: {} xmlbuilder2@4.0.3: diff --git a/template/stories/index.stories.tsx b/template/stories/index.stories.tsx new file mode 100644 index 000000000..8d2b4567a --- /dev/null +++ b/template/stories/index.stories.tsx @@ -0,0 +1,32 @@ +import preview from "../../../.storybook/preview"; + +// Replace with your actual primitive imports, e.g.: +// import { createPrimitiveTemplate } from "@solid-primitives/template-primitive"; + +const meta = preview.meta({ + title: "Category/PackageName", + tags: ["autodocs"], + parameters: { + docs: { + description: { + component: "Short description of what this primitive does.", + }, + }, + }, +}); + +export default meta; + +export const Default = meta.story({ + name: "Default", + render: () => { + // Demonstrate the primitive here. + // This function runs inside a Solid reactive owner — use createSignal, + // createEffect, etc. freely. + return ( +
+

Replace this with your primitive demo.

+
+ ); + }, +}); From 8ead43a7fb1d40f54e8913f10873be57712ebb83 Mon Sep 17 00:00:00 2001 From: David Di Biase <1168397+davedbase@users.noreply.github.com> Date: Mon, 25 May 2026 08:39:08 -0400 Subject: [PATCH 03/24] Patch pathing --- packages/audio/stories/audio.stories.tsx | 2 +- template/stories/index.stories.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/audio/stories/audio.stories.tsx b/packages/audio/stories/audio.stories.tsx index 1a324070f..40a25bcd1 100644 --- a/packages/audio/stories/audio.stories.tsx +++ b/packages/audio/stories/audio.stories.tsx @@ -1,6 +1,6 @@ import { createSignal, For, Show } from "solid-js"; import { Loading } from "@solidjs/web"; -import preview from "../../../.storybook/preview"; +import preview from "../../../.storybook/preview.js"; import { createAudio, makeAudio, makeAudioPlayer } from "@solid-primitives/audio"; // Audio files are served from packages/audio/dev/ via storybook staticDirs → /audio/* diff --git a/template/stories/index.stories.tsx b/template/stories/index.stories.tsx index 8d2b4567a..32c43d17f 100644 --- a/template/stories/index.stories.tsx +++ b/template/stories/index.stories.tsx @@ -1,4 +1,4 @@ -import preview from "../../../.storybook/preview"; +import preview from "../../../.storybook/preview.js"; // Replace with your actual primitive imports, e.g.: // import { createPrimitiveTemplate } from "@solid-primitives/template-primitive"; From 02be3e777ee1291d86a66686b31df2fdd19ed5ff Mon Sep 17 00:00:00 2001 From: David Di Biase <1168397+davedbase@users.noreply.github.com> Date: Mon, 25 May 2026 09:04:02 -0400 Subject: [PATCH 04/24] Added documentation pages --- .storybook/preview.ts | 2 ++ .storybook/tsconfig.json | 3 ++- packages/audio/stories/audio.stories.tsx | 16 +++------------- template/stories/index.stories.tsx | 5 +++-- 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/.storybook/preview.ts b/.storybook/preview.ts index acac64b0a..de7d3799d 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -1,6 +1,8 @@ import { definePreview } from "storybook-solidjs-vite/next"; +import * as docsAnnotations from "@storybook/addon-docs/preview"; export default definePreview({ + addons: [docsAnnotations], parameters: { layout: "centered", docs: { diff --git a/.storybook/tsconfig.json b/.storybook/tsconfig.json index ef1f5af59..f80eda751 100644 --- a/.storybook/tsconfig.json +++ b/.storybook/tsconfig.json @@ -4,7 +4,8 @@ "module": "ESNext", "moduleResolution": "Bundler", "verbatimModuleSyntax": false, - "noUncheckedIndexedAccess": false + "noUncheckedIndexedAccess": false, + "types": ["vite/client"] }, "include": ["./**/*", "../packages/*/stories/**/*", "../template/stories/**/*"] } diff --git a/packages/audio/stories/audio.stories.tsx b/packages/audio/stories/audio.stories.tsx index 40a25bcd1..d4ac872f7 100644 --- a/packages/audio/stories/audio.stories.tsx +++ b/packages/audio/stories/audio.stories.tsx @@ -2,6 +2,7 @@ import { createSignal, For, Show } from "solid-js"; import { Loading } from "@solidjs/web"; import preview from "../../../.storybook/preview.js"; import { createAudio, makeAudio, makeAudioPlayer } from "@solid-primitives/audio"; +import readme from "../README.md?raw"; // Audio files are served from packages/audio/dev/ via storybook staticDirs → /audio/* const SAMPLES = [ @@ -63,18 +64,7 @@ const meta = preview.meta({ layout: "centered", docs: { description: { - component: ` -**@solid-primitives/audio** provides three primitives for working with audio: - -| Primitive | Reactive? | Returns | -|-----------|-----------|---------| -| \`makeAudio\` | No | \`[HTMLAudioElement, cleanup]\` | -| \`makeAudioPlayer\` | No | \`[AudioControls, cleanup]\` | -| \`createAudio\` | Yes | \`AudioReturn\` with signals | - -\`createAudio\` accepts a static string **or** a reactive \`Accessor\` — it reconnects automatically when the source changes. -The \`duration\` signal throws \`NotReadyError\` until metadata loads, integrating with \`\`. - `.trim(), + component: readme, }, }, }, @@ -97,7 +87,7 @@ export const Reactive = meta.story({ }, }, render: () => { - const [source, setSource] = createSignal(SAMPLES[0].url); + const [source, setSource] = createSignal(SAMPLES[0].url); const audio = createAudio(source); return ( diff --git a/template/stories/index.stories.tsx b/template/stories/index.stories.tsx index 32c43d17f..797df22d2 100644 --- a/template/stories/index.stories.tsx +++ b/template/stories/index.stories.tsx @@ -1,4 +1,5 @@ -import preview from "../../../.storybook/preview.js"; +import preview from "../../.storybook/preview.js"; +import readme from "../README.md?raw"; // Replace with your actual primitive imports, e.g.: // import { createPrimitiveTemplate } from "@solid-primitives/template-primitive"; @@ -9,7 +10,7 @@ const meta = preview.meta({ parameters: { docs: { description: { - component: "Short description of what this primitive does.", + component: readme, }, }, }, From 4b5c2a4947a5d6520f36a804a680c61de74b7ca8 Mon Sep 17 00:00:00 2001 From: David Di Biase <1168397+davedbase@users.noreply.github.com> Date: Mon, 25 May 2026 09:12:26 -0400 Subject: [PATCH 05/24] Separated stories --- packages/audio/stories/_helpers.tsx | 43 +++ packages/audio/stories/audio.stories.tsx | 294 ------------------ .../audio/stories/createAudio.stories.tsx | 124 ++++++++ packages/audio/stories/makeAudio.stories.tsx | 57 ++++ .../audio/stories/makeAudioPlayer.stories.tsx | 67 ++++ 5 files changed, 291 insertions(+), 294 deletions(-) create mode 100644 packages/audio/stories/_helpers.tsx delete mode 100644 packages/audio/stories/audio.stories.tsx create mode 100644 packages/audio/stories/createAudio.stories.tsx create mode 100644 packages/audio/stories/makeAudio.stories.tsx create mode 100644 packages/audio/stories/makeAudioPlayer.stories.tsx diff --git a/packages/audio/stories/_helpers.tsx b/packages/audio/stories/_helpers.tsx new file mode 100644 index 000000000..e51d24e46 --- /dev/null +++ b/packages/audio/stories/_helpers.tsx @@ -0,0 +1,43 @@ +export const SAMPLES = [ + { label: "Sample 1", url: "/audio/sample1.mp3" }, + { label: "Sample 2", url: "/audio/sample2.mp3" }, + { label: "Sample 3", url: "/audio/sample3.mp3" }, +] as const; + +export const formatTime = (s: number) => { + const m = Math.floor(s / 60); + const sec = Math.floor(s % 60); + return `${m}:${sec.toString().padStart(2, "0")}`; +}; + +export const VolumeSlider = (props: { value: () => number; onChange: (v: number) => void }) => ( + +); + +export const SeekSlider = (props: { + current: () => number; + max: number; + onSeek: (t: number) => void; +}) => ( + props.onSeek(+e.currentTarget.value)} + style={{ width: "180px" }} + /> +); diff --git a/packages/audio/stories/audio.stories.tsx b/packages/audio/stories/audio.stories.tsx deleted file mode 100644 index d4ac872f7..000000000 --- a/packages/audio/stories/audio.stories.tsx +++ /dev/null @@ -1,294 +0,0 @@ -import { createSignal, For, Show } from "solid-js"; -import { Loading } from "@solidjs/web"; -import preview from "../../../.storybook/preview.js"; -import { createAudio, makeAudio, makeAudioPlayer } from "@solid-primitives/audio"; -import readme from "../README.md?raw"; - -// Audio files are served from packages/audio/dev/ via storybook staticDirs → /audio/* -const SAMPLES = [ - { label: "Sample 1", url: "/audio/sample1.mp3" }, - { label: "Sample 2", url: "/audio/sample2.mp3" }, - { label: "Sample 3", url: "/audio/sample3.mp3" }, -] as const; - -// --------------------------------------------------------------------------- -// Small shared UI helpers -// --------------------------------------------------------------------------- - -const formatTime = (s: number) => { - const m = Math.floor(s / 60); - const sec = Math.floor(s % 60); - return `${m}:${sec.toString().padStart(2, "0")}`; -}; - -const VolumeSlider = (props: { value: () => number; onChange: (v: number) => void }) => ( - -); - -const SeekSlider = (props: { - current: () => number; - max: number; - onSeek: (t: number) => void; -}) => ( - props.onSeek(+e.currentTarget.value)} - style={{ width: "180px" }} - /> -); - -// --------------------------------------------------------------------------- -// Story meta -// --------------------------------------------------------------------------- - -const meta = preview.meta({ - title: "Display & Media/Audio", - tags: ["autodocs"], - parameters: { - layout: "centered", - docs: { - description: { - component: readme, - }, - }, - }, -}); - -export default meta; - -// --------------------------------------------------------------------------- -// Stories -// --------------------------------------------------------------------------- - -export const Reactive = meta.story({ - name: "createAudio — reactive player", - parameters: { - docs: { - description: { - story: - "`createAudio` returns signals for `playing`, `volume`, `currentTime`, and `duration`. Switch tracks reactively — the source accessor reconnects the player automatically.", - }, - }, - }, - render: () => { - const [source, setSource] = createSignal(SAMPLES[0].url); - const audio = createAudio(source); - - return ( -
-

createAudio

- - {/* Track selector */} -
- - {s => ( - - )} - -
- - {/* Play / Pause */} -
- - - Loading…}> - - - {formatTime(audio.currentTime())} / {formatTime(audio.duration())} - - -
- - -
- ); - }, -}); - -export const ReactiveSource = meta.story({ - name: "createAudio — reactive source", - parameters: { - docs: { - description: { - story: - "When the source signal changes, `createAudio` seamlessly reconnects the player. `duration` resets to pending and re-suspends `` while the new track's metadata loads.", - }, - }, - }, - render: () => { - const [idx, setIdx] = createSignal(0); - const source = () => SAMPLES[idx()]!.url; - const audio = createAudio(source); - - return ( -
-

Reactive source swap

- -
- - {SAMPLES[idx()]?.label} - -
- -
- - - ⏳ Buffering…}> - - {formatTime(audio.currentTime())} / {formatTime(audio.duration())} - - -
- - -
- ); - }, -}); - -export const NonReactive = meta.story({ - name: "makeAudio — non-reactive", - parameters: { - docs: { - description: { - story: - "`makeAudio` creates a raw `HTMLAudioElement` with event handlers attached. No Solid owner required — you manage lifecycle yourself via the returned `cleanup` function.", - }, - }, - }, - render: () => { - const [playing, setPlaying] = createSignal(false); - const [volume, setVol] = createSignal(1); - - const [player, cleanup] = makeAudio("/audio/sample1.mp3", { - playing: () => setPlaying(true), - pause: () => setPlaying(false), - ended: () => setPlaying(false), - volumechange: () => setVol(player.volume), - }); - - // cleanup is called when the story owner disposes - // (storybook-solidjs-vite handles the root lifecycle) - - return ( -
-

makeAudio

-

- Direct HTMLAudioElement — no reactive signals. -

- -
- - -
- - { - player.volume = v; - }} - /> -
- ); - }, -}); - -export const PlayerControls = meta.story({ - name: "makeAudioPlayer — controls", - parameters: { - docs: { - description: { - story: - "`makeAudioPlayer` wraps `makeAudio` with a `controls` object exposing `play`, `pause`, `seek`, and `setVolume` methods. Still non-reactive — useful when you want imperative control without signals.", - }, - }, - }, - render: () => { - const [playing, setPlaying] = createSignal(false); - const [currentTime, setCurrentTime] = createSignal(0); - const [duration, setDuration] = createSignal(0); - const [volume, setVolume] = createSignal(1); - - const [controls] = makeAudioPlayer("/audio/sample2.mp3", { - playing: () => setPlaying(true), - pause: () => setPlaying(false), - ended: () => setPlaying(false), - timeupdate: () => setCurrentTime(controls.player.currentTime), - loadeddata: () => setDuration(controls.player.duration), - volumechange: () => setVolume(controls.player.volume), - }); - - return ( -
-

makeAudioPlayer

- -
- - - 0} fallback={Loading…}> - - - {formatTime(currentTime())} / {formatTime(duration())} - - -
- - -
- ); - }, -}); diff --git a/packages/audio/stories/createAudio.stories.tsx b/packages/audio/stories/createAudio.stories.tsx new file mode 100644 index 000000000..a98470fd0 --- /dev/null +++ b/packages/audio/stories/createAudio.stories.tsx @@ -0,0 +1,124 @@ +import { createSignal, For } from "solid-js"; +import { Loading } from "@solidjs/web"; +import preview from "../../../.storybook/preview.js"; +import { createAudio } from "@solid-primitives/audio"; +import readme from "../README.md?raw"; +import { SAMPLES, formatTime, VolumeSlider, SeekSlider } from "./_helpers.js"; + +const meta = preview.meta({ + title: "Display & Media/Audio", + tags: ["autodocs"], + parameters: { + layout: "centered", + docs: { + description: { + component: readme, + }, + }, + }, +}); + +export default meta; + +export const ReactivePlayer = meta.story({ + name: "Reactive player", + parameters: { + docs: { + description: { + story: + "`createAudio` returns signals for `playing`, `volume`, `currentTime`, and `duration`. Switch tracks reactively — the source accessor reconnects the player automatically.", + }, + }, + }, + render: () => { + const [source, setSource] = createSignal(SAMPLES[0].url); + const audio = createAudio(source); + + return ( +
+

createAudio

+ +
+ + {s => ( + + )} + +
+ +
+ + + Loading…}> + + + {formatTime(audio.currentTime())} / {formatTime(audio.duration())} + + +
+ + +
+ ); + }, +}); + +export const ReactiveSource = meta.story({ + name: "Reactive source swap", + parameters: { + docs: { + description: { + story: + "When the source signal changes, `createAudio` seamlessly reconnects the player. `duration` resets to pending and re-suspends `` while the new track's metadata loads.", + }, + }, + }, + render: () => { + const [idx, setIdx] = createSignal(0); + const source = () => SAMPLES[idx()]!.url; + const audio = createAudio(source); + + return ( +
+

Reactive source swap

+ +
+ + {SAMPLES[idx()]?.label} + +
+ +
+ + + ⏳ Buffering…}> + + {formatTime(audio.currentTime())} / {formatTime(audio.duration())} + + +
+ + +
+ ); + }, +}); diff --git a/packages/audio/stories/makeAudio.stories.tsx b/packages/audio/stories/makeAudio.stories.tsx new file mode 100644 index 000000000..d240b1194 --- /dev/null +++ b/packages/audio/stories/makeAudio.stories.tsx @@ -0,0 +1,57 @@ +import { createSignal } from "solid-js"; +import preview from "../../../.storybook/preview.js"; +import { makeAudio } from "@solid-primitives/audio"; +import { VolumeSlider } from "./_helpers.js"; + +const meta = preview.meta({ + title: "Display & Media/Audio", + parameters: { + layout: "centered", + }, +}); + +export default meta; + +export const NonReactive = meta.story({ + name: "Non-reactive", + parameters: { + docs: { + description: { + story: + "`makeAudio` creates a raw `HTMLAudioElement` with event handlers attached. No Solid owner required — you manage lifecycle yourself via the returned `cleanup` function.", + }, + }, + }, + render: () => { + const [playing, setPlaying] = createSignal(false); + const [volume, setVol] = createSignal(1); + + const [player, cleanup] = makeAudio("/audio/sample1.mp3", { + playing: () => setPlaying(true), + pause: () => setPlaying(false), + ended: () => setPlaying(false), + volumechange: () => setVol(player.volume), + }); + + return ( +
+

makeAudio

+

+ Direct HTMLAudioElement — no reactive signals. +

+ +
+ + +
+ + { player.volume = v; }} /> +
+ ); + }, +}); diff --git a/packages/audio/stories/makeAudioPlayer.stories.tsx b/packages/audio/stories/makeAudioPlayer.stories.tsx new file mode 100644 index 000000000..d79a469c5 --- /dev/null +++ b/packages/audio/stories/makeAudioPlayer.stories.tsx @@ -0,0 +1,67 @@ +import { createSignal, Show } from "solid-js"; +import preview from "../../../.storybook/preview.js"; +import { makeAudioPlayer } from "@solid-primitives/audio"; +import { formatTime, VolumeSlider, SeekSlider } from "./_helpers.js"; + +const meta = preview.meta({ + title: "Display & Media/Audio", + parameters: { + layout: "centered", + }, +}); + +export default meta; + +export const Controls = meta.story({ + name: "Player controls", + parameters: { + docs: { + description: { + story: + "`makeAudioPlayer` wraps `makeAudio` with a `controls` object exposing `play`, `pause`, `seek`, and `setVolume` methods. Still non-reactive — useful when you want imperative control without signals.", + }, + }, + }, + render: () => { + const [playing, setPlaying] = createSignal(false); + const [currentTime, setCurrentTime] = createSignal(0); + const [duration, setDuration] = createSignal(0); + const [volume, setVolume] = createSignal(1); + + const [controls] = makeAudioPlayer("/audio/sample2.mp3", { + playing: () => setPlaying(true), + pause: () => setPlaying(false), + ended: () => setPlaying(false), + timeupdate: () => setCurrentTime(controls.player.currentTime), + loadeddata: () => setDuration(controls.player.duration), + volumechange: () => setVolume(controls.player.volume), + }); + + return ( +
+

makeAudioPlayer

+ +
+ + + 0} + fallback={Loading…} + > + + + {formatTime(currentTime())} / {formatTime(duration())} + + +
+ + +
+ ); + }, +}); From e2bae96f89a6ca34243537853eff7c9b8df00d85 Mon Sep 17 00:00:00 2001 From: David Di Biase <1168397+davedbase@users.noreply.github.com> Date: Mon, 25 May 2026 09:34:58 -0400 Subject: [PATCH 06/24] Patched types and lint details --- eslint.config.mjs | 4 ++-- packages/audio/stories/_helpers.tsx | 2 +- packages/audio/stories/createAudio.stories.tsx | 6 +++--- packages/audio/stories/tsconfig.json | 4 ++++ template/stories/tsconfig.json | 4 ++++ 5 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 packages/audio/stories/tsconfig.json create mode 100644 template/stories/tsconfig.json diff --git a/eslint.config.mjs b/eslint.config.mjs index ecb337067..06a8add90 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -21,8 +21,8 @@ export default { sourceType: "module", parserOptions: { - project: "./tsconfig.json", - tsconfigRootDir: ".", + project: true, + tsconfigRootDir: import.meta.dirname, }, }, diff --git a/packages/audio/stories/_helpers.tsx b/packages/audio/stories/_helpers.tsx index e51d24e46..2d208d26a 100644 --- a/packages/audio/stories/_helpers.tsx +++ b/packages/audio/stories/_helpers.tsx @@ -2,7 +2,7 @@ export const SAMPLES = [ { label: "Sample 1", url: "/audio/sample1.mp3" }, { label: "Sample 2", url: "/audio/sample2.mp3" }, { label: "Sample 3", url: "/audio/sample3.mp3" }, -] as const; +]; export const formatTime = (s: number) => { const m = Math.floor(s / 60); diff --git a/packages/audio/stories/createAudio.stories.tsx b/packages/audio/stories/createAudio.stories.tsx index a98470fd0..34e9e67eb 100644 --- a/packages/audio/stories/createAudio.stories.tsx +++ b/packages/audio/stories/createAudio.stories.tsx @@ -31,7 +31,7 @@ export const ReactivePlayer = meta.story({ }, }, render: () => { - const [source, setSource] = createSignal(SAMPLES[0].url); + const [source, setSource] = createSignal(SAMPLES.at(0)!.url); const audio = createAudio(source); return ( @@ -85,7 +85,7 @@ export const ReactiveSource = meta.story({ }, render: () => { const [idx, setIdx] = createSignal(0); - const source = () => SAMPLES[idx()]!.url; + const source = () => SAMPLES.at(idx())!.url; const audio = createAudio(source); return ( @@ -96,7 +96,7 @@ export const ReactiveSource = meta.story({ - {SAMPLES[idx()]?.label} + {SAMPLES.at(idx())?.label} + ))} + setTarget(new Date(e.currentTarget.value))} + style={{ "font-size": "0.85rem" }} + /> + + + + +
+ {now().toLocaleTimeString()} + {target().toLocaleString()} +
+ + + + ); + }, +}); diff --git a/packages/date/stories/createDate.stories.tsx b/packages/date/stories/createDate.stories.tsx new file mode 100644 index 000000000..8a9af9f04 --- /dev/null +++ b/packages/date/stories/createDate.stories.tsx @@ -0,0 +1,109 @@ +import { createSignal } from "solid-js"; +import preview from "../../../.storybook/preview.js"; +import { createDate, createDateNow } from "@solid-primitives/date"; +import readme from "../README.md?raw"; +import { Stat, container, toDatetimeLocal } from "./_helpers.js"; + +const meta = preview.meta({ + title: "Utilities/Date", + tags: ["autodocs"], + parameters: { + layout: "centered", + docs: { + description: { + component: readme, + }, + }, + }, +}); + +export default meta; + +export const CreateDate = meta.story({ + name: "Reactive date signal", + parameters: { + docs: { + description: { + story: + "`createDate` wraps a date value in a reactive signal. The setter accepts a `Date`, timestamp, or date string — and also an updater function `prev => newDate`.", + }, + }, + }, + render: () => { + const [date, setDate] = createDate(new Date()); + + return ( +
+

createDate

+ +
+ {date().toLocaleDateString()} + {date().toLocaleTimeString()} + {date().getTime()} +
+ + setDate(new Date(e.currentTarget.value))} + /> + +
+ + + + +
+
+ ); + }, +}); + +export const CreateDateNow = meta.story({ + name: "Auto-updating date", + parameters: { + docs: { + description: { + story: + "`createDateNow` returns an auto-updating `Date` signal. Pass an interval in ms, a reactive signal, or `() => false` to disable auto-updates and rely on the manual trigger instead.", + }, + }, + }, + render: () => { + const [interval, setInterval] = createSignal(1000); + const [now, update] = createDateNow(interval); + + return ( +
+

createDateNow

+ +
+ {now().toLocaleDateString()} + {now().toLocaleTimeString()} +
+ +
+ Interval: + {([250, 1000, 5000] as const).map(ms => ( + + ))} + +
+ + +
+ ); + }, +}); diff --git a/packages/date/stories/createTimeAgo.stories.tsx b/packages/date/stories/createTimeAgo.stories.tsx new file mode 100644 index 000000000..8619f3ac8 --- /dev/null +++ b/packages/date/stories/createTimeAgo.stories.tsx @@ -0,0 +1,76 @@ +import { createSignal, For } from "solid-js"; +import preview from "../../../.storybook/preview.js"; +import { createTimeAgo } from "@solid-primitives/date"; +import { Stat, container, toDatetimeLocal } from "./_helpers.js"; + +const PRESETS = [ + { label: "30 seconds ago", offset: -30_000 }, + { label: "5 minutes ago", offset: -5 * 60_000 }, + { label: "2 hours ago", offset: -2 * 3_600_000 }, + { label: "Yesterday", offset: -86_400_000 }, + { label: "Last month", offset: -30 * 86_400_000 }, + { label: "Last year", offset: -365 * 86_400_000 }, + { label: "In 1 hour", offset: 3_600_000 }, +]; + +const meta = preview.meta({ + title: "Utilities/Date", + parameters: { layout: "centered" }, +}); + +export default meta; + +export const TimeAgo = meta.story({ + name: "Relative time string", + parameters: { + docs: { + description: { + story: + "`createTimeAgo` formats a date as a human-readable relative string (\"5 minutes ago\", \"last year\") and keeps it current via auto-updates. Works for future dates too (\"in 1 hour\").", + }, + }, + }, + render: () => { + const [offset, setOffset] = createSignal(-5 * 60_000); + const target = () => new Date(Date.now() + offset()); + const [timeAgo, { now, difference }] = createTimeAgo(target, { interval: 1000 }); + + return ( +
+

createTimeAgo

+ +
+ + {p => ( + + )} + +
+ + + +
+ {timeAgo()} +
+ +
+ {now().toLocaleTimeString()} + {target().toLocaleString()} + {difference()} +
+
+ ); + }, +}); diff --git a/packages/date/stories/createTimeDifference.stories.tsx b/packages/date/stories/createTimeDifference.stories.tsx new file mode 100644 index 000000000..fc04878a7 --- /dev/null +++ b/packages/date/stories/createTimeDifference.stories.tsx @@ -0,0 +1,99 @@ +import preview from "../../../.storybook/preview.js"; +import { createDate, createTimeDifference, createTimeDifferenceFromNow } from "@solid-primitives/date"; +import { Stat, container, formatMs, toDatetimeLocal } from "./_helpers.js"; + +const meta = preview.meta({ + title: "Utilities/Date", + parameters: { layout: "centered" }, +}); + +export default meta; + +export const TimeDifference = meta.story({ + name: "Date difference", + parameters: { + docs: { + description: { + story: + "`createTimeDifference` returns the difference in milliseconds between two reactive dates. Both inputs can be signals — the result updates whenever either changes.", + }, + }, + }, + render: () => { + const [from, setFrom] = createDate(new Date(Date.now() - 7 * 86_400_000)); + const [to, setTo] = createDate(new Date()); + const [diff] = createTimeDifference(from, to); + + return ( +
+

createTimeDifference

+ +
+ + +
+ +
+ {diff()} + {formatMs(diff())} + {(diff() / 86_400_000).toFixed(2)} +
+
+ ); + }, +}); + +export const TimeDifferenceFromNow = meta.story({ + name: "Live difference from now", + parameters: { + docs: { + description: { + story: + "`createTimeDifferenceFromNow` auto-updates the \"now\" side of the difference on a configurable interval, so the result stays current without manual wiring.", + }, + }, + }, + render: () => { + const [target, setTarget] = createDate(new Date(Date.now() + 3_600_000)); + const [diff, { now, target: targetDate, update }] = createTimeDifferenceFromNow(target, 1000); + + return ( +
+

createTimeDifferenceFromNow

+ + + +
+ {now().toLocaleTimeString()} + {targetDate().toLocaleString()} + {formatMs(diff())} +
+ + +
+ ); + }, +}); diff --git a/packages/date/stories/tsconfig.json b/packages/date/stories/tsconfig.json new file mode 100644 index 000000000..0cd588e9e --- /dev/null +++ b/packages/date/stories/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../../.storybook/tsconfig.json", + "include": ["./**/*"] +} diff --git a/packages/timer/stories/_helpers.tsx b/packages/timer/stories/_helpers.tsx new file mode 100644 index 000000000..6b3d07398 --- /dev/null +++ b/packages/timer/stories/_helpers.tsx @@ -0,0 +1,17 @@ +export const Stat = (props: { label: string; children: string | number }) => ( +
+ {props.label} + + {props.children} + +
+); + +export const container = { + "font-family": "system-ui", + padding: "1.5rem", + "min-width": "320px", + display: "flex", + "flex-direction": "column", + gap: "1rem", +} as const; diff --git a/packages/timer/stories/createPolled.stories.tsx b/packages/timer/stories/createPolled.stories.tsx new file mode 100644 index 000000000..5409b1990 --- /dev/null +++ b/packages/timer/stories/createPolled.stories.tsx @@ -0,0 +1,117 @@ +import { createSignal } from "solid-js"; +import preview from "../../../.storybook/preview.js"; +import { createPolled, createIntervalCounter } from "@solid-primitives/timer"; +import { Stat, container } from "./_helpers.js"; + +const meta = preview.meta({ + title: "Browser APIs/Timer", + parameters: { layout: "centered" }, +}); + +export default meta; + +export const CreatePolled = meta.story({ + name: "Polling accessor", + parameters: { + docs: { + description: { + story: + "`createPolled` executes a function on every tick and returns a reactive accessor to the latest value. The polling function receives its previous return value as `prev`, enabling accumulation patterns.", + }, + }, + }, + render: () => { + const [interval, setInterval] = createSignal(1000); + + const timestamp = createPolled(() => Date.now(), interval); + const history = createPolled( + (prev: string[]) => { + const t = new Date().toLocaleTimeString(); + return prev.length >= 5 ? [...prev.slice(1), t] : [...prev, t]; + }, + interval, + [] as string[], + ); + + return ( +
+

createPolled

+ + {timestamp()} + +
+
+ Last 5 ticks +
+
+ {history().map((t, i) => ( + {t} + ))} +
+
+ +
+ Interval: + {([250, 500, 1000, 2000] as const).map(ms => ( + + ))} + +
+
+ ); + }, +}); + +export const CreateIntervalCounter = meta.story({ + name: "Interval counter", + parameters: { + docs: { + description: { + story: + "`createIntervalCounter` returns an accessor that increments on every tick. Pass a reactive accessor as the interval to change the speed at runtime.", + }, + }, + }, + render: () => { + const [interval, setInterval] = createSignal(1000); + const count = createIntervalCounter(interval); + + return ( +
+

createIntervalCounter

+ +
+ {count()} +
+ +
+ Interval: + {([100, 250, 500, 1000] as const).map(ms => ( + + ))} + +
+
+ ); + }, +}); diff --git a/packages/timer/stories/createTimer.stories.tsx b/packages/timer/stories/createTimer.stories.tsx new file mode 100644 index 000000000..9655d8718 --- /dev/null +++ b/packages/timer/stories/createTimer.stories.tsx @@ -0,0 +1,165 @@ +import { createSignal, onCleanup } from "solid-js"; +import preview from "../../../.storybook/preview.js"; +import { makeTimer, createTimer, createTimeoutLoop } from "@solid-primitives/timer"; +import readme from "../README.md?raw"; +import { Stat, container } from "./_helpers.js"; + +const meta = preview.meta({ + title: "Browser APIs/Timer", + tags: ["autodocs"], + parameters: { + layout: "centered", + docs: { + description: { + component: readme, + }, + }, + }, +}); + +export default meta; + +export const MakeTimer = meta.story({ + name: "Manual timer", + parameters: { + docs: { + description: { + story: + "`makeTimer` creates a `setTimeout` or `setInterval` and returns a function to clear it. No reactive lifecycle — the caller is responsible for cleanup (e.g. pass to `onCleanup`).", + }, + }, + }, + render: () => { + const [count, setCount] = createSignal(0); + const [running, setRunning] = createSignal(false); + let clear: VoidFunction | undefined; + + const start = () => { + if (running()) return; + clear = makeTimer(() => setCount(c => c + 1), 500, setInterval); + setRunning(true); + }; + + const stop = () => { + clear?.(); + clear = undefined; + setRunning(false); + }; + + onCleanup(() => clear?.()); + + return ( +
+

makeTimer

+ + {count()} + +
+ + + +
+ +

+ Cleanup is manual — onCleanup(makeTimer(...)) ties it to the component lifecycle. +

+
+ ); + }, +}); + +export const CreateTimerStory = meta.story({ + name: "Reactive interval", + parameters: { + docs: { + description: { + story: + "`createTimer` wraps `makeTimer` in the reactive lifecycle. Pass a reactive accessor as the delay to change the interval on the fly — elapsed fraction carries forward so ticks stay smooth.", + }, + }, + }, + render: () => { + const [delay, setDelay] = createSignal(1000); + const [count, setCount] = createSignal(0); + + createTimer(() => setCount(c => c + 1), delay, setInterval); + + return ( +
+

createTimer

+ + {count()} + {delay() === false ? "paused" : `${delay()}ms`} + +
+ {([250, 500, 1000, 2000] as const).map(ms => ( + + ))} + +
+
+ ); + }, +}); + +export const CreateTimeoutLoop = meta.story({ + name: "Between-tick loop", + parameters: { + docs: { + description: { + story: + "`createTimeoutLoop` is like `createTimer` with `setInterval`, but the new delay only takes effect between executions — mid-tick delay changes don't affect the current interval.", + }, + }, + }, + render: () => { + const [delay, setDelay] = createSignal(1000); + const [count, setCount] = createSignal(0); + + createTimeoutLoop(() => setCount(c => c + 1), delay); + + return ( +
+

createTimeoutLoop

+ + {count()} + {delay() === false ? "paused" : `${delay()}ms`} + +
+ {([250, 500, 1000, 2000] as const).map(ms => ( + + ))} + +
+ +

+ Change the delay mid-tick — it takes effect on the next execution, not the current one. +

+
+ ); + }, +}); diff --git a/packages/timer/stories/tsconfig.json b/packages/timer/stories/tsconfig.json new file mode 100644 index 000000000..0cd588e9e --- /dev/null +++ b/packages/timer/stories/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../../.storybook/tsconfig.json", + "include": ["./**/*"] +} From f4b3a13008744d46ae1945817f1db7777606f50d Mon Sep 17 00:00:00 2001 From: David Di Biase <1168397+davedbase@users.noreply.github.com> Date: Mon, 25 May 2026 12:15:20 -0400 Subject: [PATCH 09/24] Added examples for autofocus and bounds --- packages/autofocus/stories/_helpers.tsx | 8 + .../autofocus/stories/autofocus.stories.tsx | 190 ++++++++++++ packages/bounds/stories/_helpers.tsx | 31 ++ .../stories/createElementBounds.stories.tsx | 292 ++++++++++++++++++ 4 files changed, 521 insertions(+) create mode 100644 packages/autofocus/stories/_helpers.tsx create mode 100644 packages/autofocus/stories/autofocus.stories.tsx create mode 100644 packages/bounds/stories/_helpers.tsx create mode 100644 packages/bounds/stories/createElementBounds.stories.tsx diff --git a/packages/autofocus/stories/_helpers.tsx b/packages/autofocus/stories/_helpers.tsx new file mode 100644 index 000000000..5a25c358b --- /dev/null +++ b/packages/autofocus/stories/_helpers.tsx @@ -0,0 +1,8 @@ +export const container = { + "font-family": "system-ui", + padding: "1.5rem", + width: "320px", + display: "flex", + "flex-direction": "column", + gap: "1rem", +} as const; diff --git a/packages/autofocus/stories/autofocus.stories.tsx b/packages/autofocus/stories/autofocus.stories.tsx new file mode 100644 index 000000000..00423433f --- /dev/null +++ b/packages/autofocus/stories/autofocus.stories.tsx @@ -0,0 +1,190 @@ +import { createSignal, Show } from "solid-js"; +import preview from "../../../.storybook/preview.js"; +import { autofocus, createAutofocus } from "@solid-primitives/autofocus"; +import readme from "../README.md?raw"; +import { container } from "./_helpers.js"; + +const meta = preview.meta({ + title: "DOM/Autofocus", + tags: ["autodocs"], + parameters: { + layout: "centered", + docs: { + description: { + component: readme, + }, + }, + }, +}); + +export default meta; + +export const AutofocusRefCallback = meta.story({ + name: "autofocus() ref callback", + parameters: { + docs: { + description: { + story: + "`autofocus()` is a ref callback factory. Attach it via `ref={autofocus()}` and include the native `autofocus` attribute — the primitive checks for that attribute before focusing, so removing it is all you need to opt out. Unmount and remount the input below to see it re-focus each time.", + }, + }, + }, + render: () => { + const [mounted, setMounted] = createSignal(true); + + return ( +
+

autofocus()

+ + + + + + + +

+ The native autofocus attribute alone only fires on page load. This + primitive re-applies it on every render. +

+
+ ); + }, +}); + +export const ConditionalAutofocus = meta.story({ + name: "Conditional autofocus", + parameters: { + docs: { + description: { + story: + "Toggle the `autofocus` attribute to enable or disable focusing — no extra API needed. `autofocus()` only calls `.focus()` when the attribute is present on the element at settle time.", + }, + }, + }, + render: () => { + const [enabled, setEnabled] = createSignal(true); + const [mounted, setMounted] = createSignal(true); + + return ( +
+

Conditional autofocus

+ + + + + + + + +
+ ); + }, +}); + +export const CreateAutofocusLetRef = meta.story({ + name: "createAutofocus — let ref", + parameters: { + docs: { + description: { + story: + "`createAutofocus(() => ref)` integrates with the reactive lifecycle using a plain `let` ref variable. The element receives focus after the component settles — no `autofocus` attribute required.", + }, + }, + }, + render: () => { + const [mounted, setMounted] = createSignal(true); + + const FocusedInput = () => { + let ref!: HTMLInputElement; + createAutofocus(() => ref); + return ( + + ); + }; + + return ( +
+

createAutofocus — let ref

+ + + + + + +
+ ); + }, +}); + +export const CreateAutofocusSignalRef = meta.story({ + name: "createAutofocus — signal ref", + parameters: { + docs: { + description: { + story: + "`createAutofocus(ref)` also accepts a signal accessor — pass `ref={setRef}` on the element. Focus re-fires whenever the signal changes to a new element, making it easy to shift focus as the DOM updates.", + }, + }, + }, + render: () => { + const [mounted, setMounted] = createSignal(true); + + const FocusedInput = () => { + const [ref, setRef] = createSignal(); + createAutofocus(ref); + return ( + + ); + }; + + return ( +
+

createAutofocus — signal ref

+ + + + + + + +

+ The signal approach is useful when you need to store the ref elsewhere — e.g.{" "} + const [ref, setRef] = createSignal() at an outer scope. +

+
+ ); + }, +}); diff --git a/packages/bounds/stories/_helpers.tsx b/packages/bounds/stories/_helpers.tsx new file mode 100644 index 000000000..95652b8e5 --- /dev/null +++ b/packages/bounds/stories/_helpers.tsx @@ -0,0 +1,31 @@ +import type { NullableBounds } from "@solid-primitives/bounds"; + +export const container = { + "font-family": "system-ui", + padding: "1.5rem", + "min-width": "360px", + display: "flex", + "flex-direction": "column", + gap: "1rem", +} as const; + +export const BoundsGrid = (props: { bounds: NullableBounds }) => ( +
+ {(["top", "left", "bottom", "right", "width", "height"] as const).map(key => ( +
+ {key} + + {props.bounds[key] !== null ? `${Math.round(props.bounds[key]!)}px` : "—"} + +
+ ))} +
+); diff --git a/packages/bounds/stories/createElementBounds.stories.tsx b/packages/bounds/stories/createElementBounds.stories.tsx new file mode 100644 index 000000000..b9ea0fd48 --- /dev/null +++ b/packages/bounds/stories/createElementBounds.stories.tsx @@ -0,0 +1,292 @@ +import { createSignal } from "solid-js"; +import preview from "../../../.storybook/preview.js"; +import { createElementBounds, type UpdateGuard } from "@solid-primitives/bounds"; +import readme from "../README.md?raw"; +import { container, BoundsGrid } from "./_helpers.js"; + +const meta = preview.meta({ + title: "DOM/Bounds", + tags: ["autodocs"], + parameters: { + layout: "centered", + docs: { + description: { + component: readme, + }, + }, + }, +}); + +export default meta; + +export const LiveBounds = meta.story({ + name: "Live element bounds", + parameters: { + docs: { + description: { + story: + "`createElementBounds` returns a reactive store-like object that tracks an element's `getBoundingClientRect()` — updating on resize, scroll, and DOM mutation. Drag the sliders to resize the box and watch all six values update in real time.", + }, + }, + }, + render: () => { + const [width, setWidth] = createSignal(160); + const [height, setHeight] = createSignal(100); + + let ref!: HTMLDivElement; + const bounds = createElementBounds(() => ref); + + return ( +
+

createElementBounds

+ +
+ {width()} × {height()} +
+ +
+ + +
+ + +
+ ); + }, +}); + +export const ReactiveTarget = meta.story({ + name: "Reactive target", + parameters: { + docs: { + description: { + story: + "The `target` argument can be a signal accessor. Set it to a falsy value to pause tracking — bounds values return `null`. Toggle the target below to see the difference.", + }, + }, + }, + render: () => { + const [active, setActive] = createSignal(true); + const [ref, setRef] = createSignal(); + + const bounds = createElementBounds(() => (active() ? ref() : null)); + + return ( +
+

Reactive target

+ +
+ {active() ? "Tracked" : "Not tracked"} +
+ + + + +
+ ); + }, +}); + +export const ScrollTracking = meta.story({ + name: "Scroll tracking", + parameters: { + docs: { + description: { + story: + "`trackScroll` (enabled by default) listens for scroll events on any ancestor and updates `top`, `left`, `right`, and `bottom` as the element moves relative to the viewport. Scroll the container below to see the position values change.", + }, + }, + }, + render: () => { + let ref!: HTMLDivElement; + const bounds = createElementBounds(() => ref); + + return ( +
+

Scroll tracking

+ +
+
+
+ Scroll me +
+
+
+ + + +

+ Scroll the container — top, left, bottom, and{" "} + right reflect the element's position in the viewport. +

+
+ ); + }, +}); + +export const ThrottledTracking = meta.story({ + name: "Throttled updates (UpdateGuard)", + parameters: { + docs: { + description: { + story: + "Each tracking option accepts an `UpdateGuard` in place of `true` — a higher-order function `(update) => throttledUpdate` that wraps the internal trigger. Use it to rate-limit expensive recalculations. The counter below only increments at most once every 400ms of scrolling, no matter how many scroll events fire.", + }, + }, + }, + render: () => { + const [updateCount, setUpdateCount] = createSignal(0); + + const throttleGuard = + (ms: number): UpdateGuard => + fn => { + let last = 0; + return (...args) => { + const now = Date.now(); + if (now - last < ms) return; + last = now; + setUpdateCount(c => c + 1); + fn(...args); + }; + }; + + let ref!: HTMLDivElement; + const bounds = createElementBounds(() => ref, { + trackScroll: throttleGuard(400), + trackResize: throttleGuard(400), + }); + + return ( +
+

UpdateGuard — throttled tracking

+ +
+
+
+ Scroll me +
+
+
+ +
+ Bounds updates fired + {updateCount()} +
+ + + +

+ Pass an UpdateGuard to wrap the internal trigger — throttle, debounce, or + batch updates any way you like. +

+
+ ); + }, +}); + From ab19abc423b5f1e77a9942740a51cb4295266d54 Mon Sep 17 00:00:00 2001 From: David Di Biase <1168397+davedbase@users.noreply.github.com> Date: Mon, 25 May 2026 12:35:39 -0400 Subject: [PATCH 10/24] ADded masonry, geolocation and clipboard --- packages/clipboard/stories/_helpers.tsx | 25 ++ .../clipboard/stories/clipboard.stories.tsx | 280 ++++++++++++++++++ packages/geolocation/stories/_helpers.tsx | 15 + .../stories/geolocation.stories.tsx | 237 +++++++++++++++ packages/masonry/stories/masonry.stories.tsx | 224 ++++++++++++++ 5 files changed, 781 insertions(+) create mode 100644 packages/clipboard/stories/_helpers.tsx create mode 100644 packages/clipboard/stories/clipboard.stories.tsx create mode 100644 packages/geolocation/stories/_helpers.tsx create mode 100644 packages/geolocation/stories/geolocation.stories.tsx create mode 100644 packages/masonry/stories/masonry.stories.tsx diff --git a/packages/clipboard/stories/_helpers.tsx b/packages/clipboard/stories/_helpers.tsx new file mode 100644 index 000000000..19e29fc2e --- /dev/null +++ b/packages/clipboard/stories/_helpers.tsx @@ -0,0 +1,25 @@ +export const Stat = (props: { label: string; children: string | number }) => ( +
+ {props.label} + {props.children} +
+); + +export const container = { + "font-family": "system-ui", + padding: "1.5rem", + width: "360px", + display: "flex", + "flex-direction": "column", + gap: "1rem", +} as const; + +export const inputStyle = { + padding: "0.4rem 0.75rem", + "font-size": "0.9rem", + width: "100%", + border: "1px solid #e2e8f0", + "border-radius": "6px", + "box-sizing": "border-box", + "font-family": "system-ui", +} as const; diff --git a/packages/clipboard/stories/clipboard.stories.tsx b/packages/clipboard/stories/clipboard.stories.tsx new file mode 100644 index 000000000..b98e92136 --- /dev/null +++ b/packages/clipboard/stories/clipboard.stories.tsx @@ -0,0 +1,280 @@ +import { createSignal, For, Show } from "solid-js"; +import preview from "../../../.storybook/preview.js"; +import { + writeClipboard, + readClipboard, + createClipboard, + copyToClipboard, + input as inputHighlight, + type ClipboardSetter, +} from "@solid-primitives/clipboard"; +import readme from "../README.md?raw"; +import { container, inputStyle } from "./_helpers.js"; + +const meta = preview.meta({ + title: "Browser APIs/Clipboard", + tags: ["autodocs"], + parameters: { + layout: "centered", + docs: { + description: { + component: readme, + }, + }, + }, +}); + +export default meta; + +export const CopyDirective = meta.story({ + name: "copyToClipboard ref directive", + parameters: { + docs: { + description: { + story: + "`copyToClipboard()` returns a ref callback that writes an element's value to the clipboard on click. On ``/`