From 4f41877fa9620c1b37622363e539f0a994c2dba0 Mon Sep 17 00:00:00 2001 From: Aaron Reisman Date: Wed, 17 Jun 2026 16:37:07 +0700 Subject: [PATCH] Add Propel Oxlint rule for Tailwind shorthand --- packages/propel/package.json | 1 + .../accordion/accordion.stories.tsx | 2 +- .../propel/src/components/accordion/index.tsx | 6 +- .../breadcrumb/breadcrumb.stories.tsx | 19 +- .../src/components/breadcrumb/index.tsx | 8 +- .../propel/src/components/button/index.tsx | 2 +- .../components/checkbox/checkbox.stories.tsx | 2 +- .../propel/src/components/checkbox/index.tsx | 10 +- .../src/components/icon-button/index.tsx | 2 +- .../propel/src/components/nav-item/index.tsx | 8 +- .../pagination/pagination.stories.tsx | 8 +- packages/propel/src/components/pill/index.tsx | 4 +- .../propel/src/components/radio/index.tsx | 4 +- .../propel/src/components/search/index.tsx | 6 +- .../propel/src/components/switch/index.tsx | 10 +- .../propel/src/components/table/index.tsx | 2 +- packages/propel/src/components/tabs/index.tsx | 6 +- .../propel/src/components/toast/index.tsx | 2 +- .../src/components/toast/toast.stories.tsx | 16 +- .../propel/src/components/toolbar/index.tsx | 4 +- packages/propel/src/internal/node-slot.ts | 2 +- packages/propel/src/internal/scrollbar.ts | 2 +- pnpm-lock.yaml | 538 +++++++++++++++--- tools/oxlint-plugin-propel/.gitignore | 4 + tools/oxlint-plugin-propel/README.md | 60 ++ tools/oxlint-plugin-propel/package.json | 43 ++ tools/oxlint-plugin-propel/src/index.ts | 73 +++ .../oxlint-plugin-propel/tests/index.test.ts | 77 +++ tools/oxlint-plugin-propel/tsconfig.json | 20 + tools/oxlint-plugin-propel/vite.config.ts | 17 + vite.config.ts | 6 +- 31 files changed, 834 insertions(+), 130 deletions(-) create mode 100644 tools/oxlint-plugin-propel/.gitignore create mode 100644 tools/oxlint-plugin-propel/README.md create mode 100644 tools/oxlint-plugin-propel/package.json create mode 100644 tools/oxlint-plugin-propel/src/index.ts create mode 100644 tools/oxlint-plugin-propel/tests/index.test.ts create mode 100644 tools/oxlint-plugin-propel/tsconfig.json create mode 100644 tools/oxlint-plugin-propel/vite.config.ts diff --git a/packages/propel/package.json b/packages/propel/package.json index 7efc4f08..39fc172c 100644 --- a/packages/propel/package.json +++ b/packages/propel/package.json @@ -75,6 +75,7 @@ "@types/react-dom": "^19.2.3", "@typescript/native-preview": "7.0.0-dev.20260509.2", "@vitest/browser-playwright": "4.1.9", + "@vitest/coverage-v8": "4.1.8", "playwright": "^1.61.0", "react": "^19.2.7", "react-dom": "^19.2.7", diff --git a/packages/propel/src/components/accordion/accordion.stories.tsx b/packages/propel/src/components/accordion/accordion.stories.tsx index 00a6411a..66860d7b 100644 --- a/packages/propel/src/components/accordion/accordion.stories.tsx +++ b/packages/propel/src/components/accordion/accordion.stories.tsx @@ -13,7 +13,7 @@ import { Accordion, AccordionItem, AccordionPanel, AccordionTrigger } from "./in // column plus their prop-driven states (checked / disabled / error). // * Static components with no interaction-state styling (badge / banner / avatar / // tooltip-popup) get NO pseudo-states story. -// * Base UI `data-[checked]` / `data-[disabled]` states are NOT forced by the +// * Base UI `data-checked` / `data-disabled` states are NOT forced by the // pseudo addon — those are attribute selectors, not pseudo-classes — so they must // be shown via real props, not the `pseudo` parameter. const meta = { diff --git a/packages/propel/src/components/accordion/index.tsx b/packages/propel/src/components/accordion/index.tsx index e3dcfced..e6ceebf8 100644 --- a/packages/propel/src/components/accordion/index.tsx +++ b/packages/propel/src/components/accordion/index.tsx @@ -72,7 +72,7 @@ export function AccordionTrigger({ leadingIcon, children, ...props }: AccordionT {children} @@ -92,10 +92,10 @@ export function AccordionPanel({ children, ...props }: AccordionPanelProps) { return ( diff --git a/packages/propel/src/components/breadcrumb/breadcrumb.stories.tsx b/packages/propel/src/components/breadcrumb/breadcrumb.stories.tsx index b72f627f..e86fbec2 100644 --- a/packages/propel/src/components/breadcrumb/breadcrumb.stories.tsx +++ b/packages/propel/src/components/breadcrumb/breadcrumb.stories.tsx @@ -141,8 +141,7 @@ export const DropdownInteraction: Story = { await userEvent.click(trigger); // Once open, the collapsed crumbs are real menu items (Base UI portals the // menu to , so query the page document, not just the story canvas). - const menu = await within(document.body).findByRole("menu"); - const items = within(menu).getAllByRole("menuitem"); + const items = await within(document.body).findAllByRole("menuitem"); await expect(items).toHaveLength(2); await expect(items[0]).toHaveTextContent("Projects"); await expect(items[1]).toHaveTextContent("Design"); @@ -265,11 +264,13 @@ export const KeyboardNavigation: Story = { trigger.focus(); await expect(trigger).toHaveFocus(); await userEvent.keyboard("{ArrowDown}"); - await waitFor(() => expect(body.getByRole("menu")).toBeInTheDocument()); + await expect(await body.findByRole("menuitem", { name: "Plane Web" })).toBeInTheDocument(); }); await step("arrow-nav + Enter selects a sibling", async () => { - const menu = body.getByRole("menu"); + const firstItem = await body.findByRole("menuitem", { name: "Plane Web" }); + const menu = firstItem.closest('[role="menu"]'); + if (!(menu instanceof HTMLElement)) throw new Error("breadcrumb menu not found"); const items = within(menu).getAllByRole("menuitem"); await expect(items).toHaveLength(2); // Opening with ArrowDown highlights the first item; one more ArrowDown moves to @@ -278,15 +279,19 @@ export const KeyboardNavigation: Story = { await waitFor(() => expect(items[1]).toHaveAttribute("data-highlighted")); await userEvent.keyboard("{Enter}"); // Selecting closes the menu. - await waitFor(() => expect(body.queryByRole("menu")).toBeNull()); + await waitFor(() => + expect(body.queryByRole("menuitem", { name: "Plane Web" })).not.toBeInTheDocument(), + ); }); await step("Escape closes the menu and returns focus to the trigger", async () => { trigger.focus(); await userEvent.keyboard("{Enter}"); - await waitFor(() => expect(body.getByRole("menu")).toBeInTheDocument()); + await expect(await body.findByRole("menuitem", { name: "Plane Web" })).toBeInTheDocument(); await userEvent.keyboard("{Escape}"); - await waitFor(() => expect(body.queryByRole("menu")).toBeNull()); + await waitFor(() => + expect(body.queryByRole("menuitem", { name: "Plane Web" })).not.toBeInTheDocument(), + ); await expect(trigger).toHaveFocus(); }); }, diff --git a/packages/propel/src/components/breadcrumb/index.tsx b/packages/propel/src/components/breadcrumb/index.tsx index 8a908076..b50aa306 100644 --- a/packages/propel/src/components/breadcrumb/index.tsx +++ b/packages/propel/src/components/breadcrumb/index.tsx @@ -125,7 +125,7 @@ export function BreadcrumbDropdown({ aria-label={label} className={cx( crumbVariants({ interactive: true }), - "cursor-default data-[popup-open]:bg-layer-transparent-hover data-[popup-open]:text-primary", + "cursor-default data-popup-open:bg-layer-transparent-hover data-popup-open:text-primary", )} {...props} > @@ -155,7 +155,7 @@ export type BreadcrumbDropdownItemProps = Omit< export function BreadcrumbDropdownItem(props: BreadcrumbDropdownItemProps) { return ( ); @@ -208,7 +208,7 @@ export function BreadcrumbMenuTrigger({ icon, children, ...props }: BreadcrumbMe @@ -223,7 +223,7 @@ export function BreadcrumbMenuTrigger({ icon, children, ...props }: BreadcrumbMe *closed* chevron so it points left along the mirrored trail — the open (rotated-down) chevron must not be mirrored, or it would point up. */} diff --git a/packages/propel/src/components/button/index.tsx b/packages/propel/src/components/button/index.tsx index bc899754..f64ca019 100644 --- a/packages/propel/src/components/button/index.tsx +++ b/packages/propel/src/components/button/index.tsx @@ -221,7 +221,7 @@ export function Button({ {...props} > {loading ? ( - + ) : inlineStartNode ? ( {inlineStartNode} diff --git a/packages/propel/src/components/checkbox/checkbox.stories.tsx b/packages/propel/src/components/checkbox/checkbox.stories.tsx index f23abd35..c14d5fed 100644 --- a/packages/propel/src/components/checkbox/checkbox.stories.tsx +++ b/packages/propel/src/components/checkbox/checkbox.stories.tsx @@ -118,7 +118,7 @@ export const Error: Story = { await expect(unchecked).toHaveClass("border-danger-strong"); // Checked danger box: accent-blue fill, like every other tone. await expect(checked).toHaveAttribute("aria-checked", "true"); - await expect(checked).toHaveClass("data-[checked]:bg-accent-primary"); + await expect(checked).toHaveClass("data-checked:bg-accent-primary"); }, }; diff --git a/packages/propel/src/components/checkbox/index.tsx b/packages/propel/src/components/checkbox/index.tsx index d0dda1d9..235a12d6 100644 --- a/packages/propel/src/components/checkbox/index.tsx +++ b/packages/propel/src/components/checkbox/index.tsx @@ -21,12 +21,12 @@ const checkboxVariants = cva( // tone, so it lives here in the base rather than the tone variants. This // keeps a tone-less `CheckboxVisual` from rendering a white check on no fill. // A white icon sits on top. Base UI exposes these via `data-*` attributes. - "data-[checked]:border-transparent data-[checked]:bg-accent-primary data-[checked]:text-icon-on-color", - "data-[indeterminate]:border-transparent data-[indeterminate]:bg-accent-primary data-[indeterminate]:text-icon-on-color", + "data-checked:border-transparent data-checked:bg-accent-primary data-checked:text-icon-on-color", + "data-indeterminate:border-transparent data-indeterminate:bg-accent-primary data-indeterminate:text-icon-on-color", // Disabled: muted border/fill and no pointer; overrides the checked fill. - "data-[disabled]:cursor-not-allowed data-[disabled]:border-disabled data-[disabled]:bg-transparent", - "data-[disabled]:data-[checked]:border-transparent data-[disabled]:data-[checked]:bg-layer-disabled data-[disabled]:data-[checked]:text-icon-disabled", - "data-[disabled]:data-[indeterminate]:border-transparent data-[disabled]:data-[indeterminate]:bg-layer-disabled data-[disabled]:data-[indeterminate]:text-icon-disabled", + "data-disabled:cursor-not-allowed data-disabled:border-disabled data-disabled:bg-transparent", + "data-disabled:data-checked:border-transparent data-disabled:data-checked:bg-layer-disabled data-disabled:data-checked:text-icon-disabled", + "data-disabled:data-indeterminate:border-transparent data-disabled:data-indeterminate:bg-layer-disabled data-disabled:data-indeterminate:text-icon-disabled", ), { variants: { diff --git a/packages/propel/src/components/icon-button/index.tsx b/packages/propel/src/components/icon-button/index.tsx index feb9d30e..c8a96a1d 100644 --- a/packages/propel/src/components/icon-button/index.tsx +++ b/packages/propel/src/components/icon-button/index.tsx @@ -102,7 +102,7 @@ export function IconButton({ {...props} > {loading ? ( - + ) : ( {children} diff --git a/packages/propel/src/components/nav-item/index.tsx b/packages/propel/src/components/nav-item/index.tsx index a18b0ff6..ea24811e 100644 --- a/packages/propel/src/components/nav-item/index.tsx +++ b/packages/propel/src/components/nav-item/index.tsx @@ -34,7 +34,7 @@ const navItemVariants = cva( "hover:bg-layer-transparent-hover active:bg-layer-transparent-active active:text-primary", "focus-visible:ring-2 focus-visible:ring-accent-strong", // Selected (Figma "Selected" state): filled surface + primary text. - "data-[active]:bg-layer-transparent-selected data-[active]:text-primary", + "data-active:bg-layer-transparent-selected data-active:text-primary", // Disabled: dimmed and non-interactive. "disabled:pointer-events-none disabled:text-disabled aria-disabled:pointer-events-none aria-disabled:text-disabled", ), @@ -120,7 +120,7 @@ export function NavItem({ className={cx( "flex size-4 shrink-0 items-center justify-center text-icon-placeholder [&>svg]:size-full", // Selected/pressed pull the leading icon up to the primary tone. - "group-active/nav-item:text-icon-primary group-data-[active]/nav-item:text-icon-primary", + "group-active/nav-item:text-icon-primary group-data-active/nav-item:text-icon-primary", // Disabled dims the icon to match the dimmed label. "group-disabled/nav-item:text-icon-disabled group-aria-disabled/nav-item:text-icon-disabled", )} @@ -294,7 +294,7 @@ export function NavItemHeader({ "flex size-4 shrink-0 items-center justify-center text-icon-secondary [&>svg]:size-full", // The Figma glyph is a filled caret-down. Collapsed rotates it a quarter turn // so it points at the inline-start; RTL mirrors so it still points inward. - "rotate-90 transition-transform data-[expanded]:rotate-0 rtl:-rotate-90 rtl:data-[expanded]:rotate-0", + "rotate-90 transition-transform data-expanded:rotate-0 rtl:-rotate-90 rtl:data-expanded:rotate-0", )} > {chevron} @@ -327,7 +327,7 @@ export function NavItemChevron({ data-open={open ? "" : undefined} className={cx( "flex size-4 shrink-0 items-center justify-center text-icon-placeholder [&>svg]:size-full", - "transition-transform data-[open]:rotate-180 rtl:-scale-x-100", + "transition-transform data-open:rotate-180 rtl:-scale-x-100", )} > {icon} diff --git a/packages/propel/src/components/pagination/pagination.stories.tsx b/packages/propel/src/components/pagination/pagination.stories.tsx index 59cf701f..bc7308a0 100644 --- a/packages/propel/src/components/pagination/pagination.stories.tsx +++ b/packages/propel/src/components/pagination/pagination.stories.tsx @@ -87,7 +87,7 @@ export const PageSizeSelector: Story = { await step("clicking the trigger opens the page-size menu", async () => { await userEvent.click(canvas.getByRole("button", { name: /50 per page/i })); - await waitFor(() => expect(body.getByRole("menu")).toBeInTheDocument()); + await expect(await body.findByRole("menuitem", { name: "25" })).toBeInTheDocument(); // All sizes are listed as menu items. for (const n of [25, 50, 100]) { await expect(body.getByRole("menuitem", { name: String(n) })).toBeInTheDocument(); @@ -108,10 +108,8 @@ export const PageSizeSelector: Story = { await expect(trigger).toHaveFocus(); // ArrowDown opens the menu and highlights the first item (25). await userEvent.keyboard("{ArrowDown}"); - await waitFor(() => expect(body.getByRole("menu")).toBeInTheDocument()); - await waitFor(() => - expect(body.getByRole("menuitem", { name: "25" })).toHaveAttribute("data-highlighted"), - ); + const firstItem = await body.findByRole("menuitem", { name: "25" }); + await waitFor(() => expect(firstItem).toHaveAttribute("data-highlighted")); // ArrowDown moves the highlight to the second item (50); Enter selects it. await userEvent.keyboard("{ArrowDown}"); await waitFor(() => diff --git a/packages/propel/src/components/pill/index.tsx b/packages/propel/src/components/pill/index.tsx index 6b68eda8..4017e7b2 100644 --- a/packages/propel/src/components/pill/index.tsx +++ b/packages/propel/src/components/pill/index.tsx @@ -58,7 +58,7 @@ function PillNode({ children }: { children: React.ReactNode }) { } function PillSpinner() { - return ; + return ; } // The truncating label. `min-w-0` lets it shrink so the 120px cap can ellipsize it. @@ -128,7 +128,7 @@ const pillSwitchColors = cx( "hover:border-strong hover:bg-layer-2-hover", // Selected (the toggle's pressed state) is the darker `-selected` fill + strong // border + primary label. - "data-[pressed]:border-strong data-[pressed]:bg-layer-2-selected data-[pressed]:text-primary", + "data-pressed:border-strong data-pressed:bg-layer-2-selected data-pressed:text-primary", "disabled:cursor-not-allowed disabled:border-subtle-1 disabled:bg-layer-transparent disabled:text-disabled", ); diff --git a/packages/propel/src/components/radio/index.tsx b/packages/propel/src/components/radio/index.tsx index 84ee3da7..5f186e31 100644 --- a/packages/propel/src/components/radio/index.tsx +++ b/packages/propel/src/components/radio/index.tsx @@ -23,11 +23,11 @@ const radioVariants = cva( "flex size-4 shrink-0 items-center justify-center rounded-full border-sm border-current bg-layer-1", "text-icon-tertiary transition-colors outline-none", // Selected uses the accent color for both the ring and the dot. - "data-[checked]:text-icon-accent-primary", + "data-checked:text-icon-accent-primary", // Keyboard focus ring, drawn outside the control so it never clips the dot. "focus-visible:ring-2 focus-visible:ring-accent-strong focus-visible:ring-offset-2", // Disabled is dimmed and non-interactive. - "data-[disabled]:cursor-not-allowed data-[disabled]:text-icon-disabled data-[disabled]:opacity-60", + "data-disabled:cursor-not-allowed data-disabled:text-icon-disabled data-disabled:opacity-60", ), ); diff --git a/packages/propel/src/components/search/index.tsx b/packages/propel/src/components/search/index.tsx index ac232051..60ee0d4a 100644 --- a/packages/propel/src/components/search/index.tsx +++ b/packages/propel/src/components/search/index.tsx @@ -148,11 +148,11 @@ const expandableBoxClass = cx( "transition-[width,border-color,background-color] duration-200 ease-out motion-reduce:transition-none", // Collapsed it reads as an icon button (hover fill). It never rests focused — focusing // the field expands it — so the focus ring lives on the expanded chrome below. - "not-data-[expanded]:hover:bg-layer-transparent-hover", + "not-data-expanded:hover:bg-layer-transparent-hover", // Expanded: widen to the full field and show the search-box chrome (subtle border + // layer-2 fill at rest, accent border + 1px accent ring on focus). - "data-[expanded]:w-[204px] data-[expanded]:border-subtle-1 data-[expanded]:bg-layer-2", - "data-[expanded]:focus-within:border-accent-strong data-[expanded]:focus-within:ring-1 data-[expanded]:focus-within:ring-accent-strong/35", + "data-expanded:w-[204px] data-expanded:border-subtle-1 data-expanded:bg-layer-2", + "data-expanded:focus-within:border-accent-strong data-expanded:focus-within:ring-1 data-expanded:focus-within:ring-accent-strong/35", ); export type ExpandableSearchProps = SearchProps; diff --git a/packages/propel/src/components/switch/index.tsx b/packages/propel/src/components/switch/index.tsx index 5bdd3e0f..11fbbcec 100644 --- a/packages/propel/src/components/switch/index.tsx +++ b/packages/propel/src/components/switch/index.tsx @@ -10,10 +10,10 @@ const trackVariants = cva( cx( "relative inline-flex shrink-0 items-center rounded-full p-px transition-colors", // Off track = Figma icon/placeholder; on track = accent/primary. - "bg-icon-placeholder data-[checked]:bg-accent-primary", + "bg-icon-placeholder data-checked:bg-accent-primary", // Unchangeable (disabled or readonly) dims the whole control to 40%, // matching Figma's "Unchangeable" states. Disabled also blocks the cursor. - "data-[disabled]:cursor-not-allowed data-[disabled]:opacity-40 data-[readonly]:opacity-40", + "data-disabled:cursor-not-allowed data-disabled:opacity-40 data-readonly:opacity-40", "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent-strong", ), { @@ -35,9 +35,9 @@ const trackVariants = cva( const thumbVariants = cva("rounded-full bg-on-color shadow-raised-100 transition-transform", { variants: { magnitude: { - lg: "size-4 data-[checked]:translate-x-[12px]", - md: "size-3.5 data-[checked]:translate-x-[11px]", - sm: "size-3 data-[checked]:translate-x-[9px]", + lg: "size-4 data-checked:translate-x-[12px]", + md: "size-3.5 data-checked:translate-x-[11px]", + sm: "size-3 data-checked:translate-x-[9px]", }, }, }); diff --git a/packages/propel/src/components/table/index.tsx b/packages/propel/src/components/table/index.tsx index 5857eff6..cd186ecc 100644 --- a/packages/propel/src/components/table/index.tsx +++ b/packages/propel/src/components/table/index.tsx @@ -306,7 +306,7 @@ export function TableCell({ const actionableTriggerClass = cx( "flex h-11 w-full items-center outline-none", "bg-layer-transparent hover:bg-layer-transparent-hover focus-visible:bg-layer-transparent-hover", - "data-[popup-open]:bg-layer-transparent-active", + "data-popup-open:bg-layer-transparent-active", "disabled:pointer-events-none disabled:text-disabled", ); diff --git a/packages/propel/src/components/tabs/index.tsx b/packages/propel/src/components/tabs/index.tsx index baebd5ae..66ba1d52 100644 --- a/packages/propel/src/components/tabs/index.tsx +++ b/packages/propel/src/components/tabs/index.tsx @@ -131,7 +131,7 @@ const tabVariants = cva( variants: { variant: { contained: - "inline-flex h-6 items-center justify-center gap-1 rounded-md border-sm border-transparent px-1.5 text-13 text-secondary hover:text-primary data-[active]:border-subtle-1 data-[active]:bg-layer-2 data-[active]:text-primary data-[active]:shadow-raised-200", + "inline-flex h-6 items-center justify-center gap-1 rounded-md border-sm border-transparent px-1.5 text-13 text-secondary hover:text-primary data-active:border-subtle-1 data-active:bg-layer-2 data-active:text-primary data-active:shadow-raised-200", underline: "group/tab inline-flex flex-col items-stretch gap-2 text-14", }, }, @@ -143,7 +143,7 @@ const tabVariants = cva( // layout and the bar track. `contained` renders its label inline, so this is // only used for `underline`. const underlineLabelVariants = cva( - "flex h-7 items-center justify-center gap-1.5 rounded-md px-2 py-0.5 text-tertiary transition-colors group-hover/tab:bg-layer-transparent-hover group-hover/tab:text-secondary group-data-[active]/tab:bg-layer-transparent-selected group-data-[active]/tab:text-primary", + "flex h-7 items-center justify-center gap-1.5 rounded-md px-2 py-0.5 text-tertiary transition-colors group-hover/tab:bg-layer-transparent-hover group-hover/tab:text-secondary group-data-active/tab:bg-layer-transparent-selected group-data-active/tab:text-primary", ); // The 3px bar track under an `underline` tab. The track is inset `px-2` (8px) @@ -154,7 +154,7 @@ const underlineLabelVariants = cva( // (primary), so the active tab's own bar stays transparent to avoid doubling. const underlineBarTrackVariants = cva("flex px-2"); const underlineBarVariants = cva( - "h-[3px] w-full rounded-full bg-current text-transparent transition-colors group-hover/tab:text-icon-placeholder group-data-[active]/tab:text-transparent", + "h-[3px] w-full rounded-full bg-current text-transparent transition-colors group-hover/tab:text-icon-placeholder group-data-active/tab:text-transparent", ); // The leading-icon box. Sized to 16px (`Icon`) and tinted via `currentColor`, diff --git a/packages/propel/src/components/toast/index.tsx b/packages/propel/src/components/toast/index.tsx index 98dab2ac..3c531167 100644 --- a/packages/propel/src/components/toast/index.tsx +++ b/packages/propel/src/components/toast/index.tsx @@ -229,7 +229,7 @@ export function Toast({ toast, ...props }: ToastProps) { className={cx( surfaceVariants({ elevation: "raised", radius: "lg" }), "relative flex w-full items-start gap-2 px-4 py-3", - "transition-opacity data-[ending]:opacity-0", + "transition-opacity data-ending:opacity-0", )} {...props} > diff --git a/packages/propel/src/components/toast/toast.stories.tsx b/packages/propel/src/components/toast/toast.stories.tsx index c073c495..7f3e876e 100644 --- a/packages/propel/src/components/toast/toast.stories.tsx +++ b/packages/propel/src/components/toast/toast.stories.tsx @@ -130,12 +130,11 @@ export const ProgressInteraction: Story = { /> ), play: async ({ canvas, userEvent }) => { - const body = within(document.body); - await userEvent.click(canvas.getByRole("button", { name: /show toast with progress/i })); - // The toast appears asynchronously in a portal; assert on the document body. - const toast = await waitFor(() => body.getByRole("dialog")); + // The toast appears asynchronously in a portal; assert its dialog role and + // accessible name before making scoped assertions. + const toast = await within(document.body).findByRole("dialog", { name: "Toast title" }); await expect(toast).toBeVisible(); // Base UI's Progress owns the `progressbar` role + `aria-valuenow`; the bar @@ -202,8 +201,9 @@ export const QueueAndDismiss: Story = { await userEvent.click(canvas.getByRole("button", { name: /show success toast/i })); - // The toast appears asynchronously in a portal; assert on the document body. - const toast = await waitFor(() => body.getByRole("dialog")); + // The toast appears asynchronously in a portal; assert its dialog role and + // accessible name before hover/focus assertions. + const toast = await body.findByRole("dialog", { name: "Toast title" }); await expect(toast).toBeVisible(); await expect(body.getByText("Toast title")).toBeVisible(); await expect(body.getByText("Description of the toast alert")).toBeVisible(); @@ -244,7 +244,7 @@ export const ActionsInteraction: Story = { onLeft.mockClear(); await userEvent.click(canvas.getByRole("button", { name: /show toast with actions/i })); - await waitFor(() => body.getByRole("dialog")); + await body.findByRole("dialog", { name: "Toast title" }); // The right-aligned primary action fires its handler on click. const view = await waitFor(() => body.getByRole("button", { name: "View" })); @@ -285,7 +285,7 @@ export const KeyboardDismiss: Story = { const body = within(document.body); await userEvent.click(canvas.getByRole("button", { name: /show success toast/i })); - const toast = await waitFor(() => body.getByRole("dialog")); + const toast = await body.findByRole("dialog", { name: "Toast title" }); await expect(toast).toBeVisible(); // F6 is Base UI's keyboard entry point: it moves focus into the viewport region diff --git a/packages/propel/src/components/toolbar/index.tsx b/packages/propel/src/components/toolbar/index.tsx index f6162cd5..7bce382d 100644 --- a/packages/propel/src/components/toolbar/index.tsx +++ b/packages/propel/src/components/toolbar/index.tsx @@ -106,7 +106,7 @@ const itemVariants = cva( "bg-layer-transparent text-icon-secondary outline-none", "hover:bg-layer-transparent-hover active:bg-layer-transparent-active", "focus-visible:ring-2 focus-visible:ring-accent-strong", - "data-[pressed]:bg-layer-transparent-selected data-[pressed]:text-icon-accent-primary", + "data-pressed:bg-layer-transparent-selected data-pressed:text-icon-accent-primary", "disabled:pointer-events-none disabled:text-icon-disabled", "[&_svg]:shrink-0", ), @@ -206,7 +206,7 @@ const dropdownTriggerVariants = cva( "bg-layer-transparent text-13 text-secondary outline-none", "hover:bg-layer-transparent-hover active:bg-layer-transparent-active", "focus-visible:ring-2 focus-visible:ring-accent-strong", - "data-[popup-open]:bg-layer-transparent-selected", + "data-popup-open:bg-layer-transparent-selected", "disabled:pointer-events-none disabled:text-disabled", ), { diff --git a/packages/propel/src/internal/node-slot.ts b/packages/propel/src/internal/node-slot.ts index 61732d6e..91c9001f 100644 --- a/packages/propel/src/internal/node-slot.ts +++ b/packages/propel/src/internal/node-slot.ts @@ -11,5 +11,5 @@ import { cx } from "class-variance-authority"; // otherwise. This is the single channel a parent uses to size whatever node it holds. export const nodeSlotClass = cx( "inline-flex shrink-0 items-center justify-center", - "[&>img]:size-[var(--node-size)] [&>svg]:size-[var(--node-size)]", + "[&>img]:size-(--node-size) [&>svg]:size-(--node-size)", ); diff --git a/packages/propel/src/internal/scrollbar.ts b/packages/propel/src/internal/scrollbar.ts index 07ab7e82..103f5bb6 100644 --- a/packages/propel/src/internal/scrollbar.ts +++ b/packages/propel/src/internal/scrollbar.ts @@ -8,7 +8,7 @@ import { cx } from "class-variance-authority"; // that compose Base UI ScrollArea directly (e.g. Tabs, whose list is the viewport). export const scrollbarClass = cx( "flex touch-none p-[3px] opacity-0 transition-opacity duration-150 ease-out select-none", - "data-[hovering]:opacity-100 data-[scrolling]:opacity-100", + "data-hovering:opacity-100 data-scrolling:opacity-100", "data-[orientation=vertical]:w-3", "data-[orientation=horizontal]:h-3 data-[orientation=horizontal]:flex-col", ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eba2e69a..6888b886 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,7 +23,7 @@ importers: version: 2.31.0(@types/node@25.9.3) vite-plus: specifier: 'catalog:' - version: 0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0) + version: 0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0) packages/propel: dependencies: @@ -42,25 +42,25 @@ importers: devDependencies: '@storybook/addon-a11y': specifier: ^10.4.5 - version: 10.4.5(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))) + version: 10.4.5(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))) '@storybook/addon-designs': specifier: ^11.1.3 - version: 11.1.3(@storybook/addon-docs@10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))) + version: 11.1.3(18d5313c2038f010e24ea42f33de5044) '@storybook/addon-docs': specifier: ^10.4.5 - version: 10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) + version: 10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) '@storybook/addon-mcp': specifier: ^0.6.0 - version: 0.6.0(@storybook/addon-vitest@10.4.5(d8d8c6145d5df30d7d9880a51e5b5061))(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(typescript@6.0.3) + version: 0.6.0(eb106c8d249302fb7f5800fd41bb642d) '@storybook/addon-themes': specifier: ^10.4.5 - version: 10.4.5(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))) + version: 10.4.5(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))) '@storybook/addon-vitest': specifier: ^10.4.5 - version: 10.4.5(d8d8c6145d5df30d7d9880a51e5b5061) + version: 10.4.5(@vitest/browser-playwright@4.1.9(@voidzero-dev/vite-plus-test@0.1.24)(playwright@1.61.0)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)))(@vitest/runner@4.1.9)(@voidzero-dev/vite-plus-test@0.1.24)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))) '@storybook/react-vite': specifier: ^10.4.5 - version: 10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.27.7)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) + version: 10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.27.7)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) '@tailwindcss/vite': specifier: ^4.3.1 version: 4.3.1(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) @@ -78,7 +78,10 @@ importers: version: 7.0.0-dev.20260509.2 '@vitest/browser-playwright': specifier: 4.1.9 - version: 4.1.9(@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))(playwright@1.61.0)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) + version: 4.1.9(@voidzero-dev/vite-plus-test@0.1.24)(playwright@1.61.0)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) + '@vitest/coverage-v8': + specifier: 4.1.8 + version: 4.1.8(@voidzero-dev/vite-plus-test@0.1.24) playwright: specifier: ^1.61.0 version: 1.61.0 @@ -90,10 +93,10 @@ importers: version: 19.2.7(react@19.2.7) storybook: specifier: ^10.4.5 - version: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + version: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) storybook-addon-pseudo-states: specifier: ^10.4.5 - version: 10.4.5(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))) + version: 10.4.5(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))) tailwindcss: specifier: ^4.3.1 version: 4.3.1 @@ -102,14 +105,39 @@ importers: version: 6.0.3 vite-plus: specifier: 'catalog:' - version: 0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0) + version: 0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0) vitest: specifier: npm:@voidzero-dev/vite-plus-test@latest - version: '@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)' + version: '@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)' wrangler: specifier: 4.100.0 version: 4.100.0 + tools/oxlint-plugin-propel: + dependencies: + '@oxlint/plugins': + specifier: 1.61.0 + version: 1.61.0 + devDependencies: + '@types/node': + specifier: ^25.6.2 + version: 25.9.3 + '@typescript/native-preview': + specifier: 7.0.0-dev.20260509.2 + version: 7.0.0-dev.20260509.2 + bumpp: + specifier: ^11.1.0 + version: 11.1.0 + oxlint: + specifier: 1.67.0 + version: 1.67.0(oxlint-tsgolint@0.23.0)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + typescript: + specifier: ^6.0.3 + version: 6.0.3 + vite-plus: + specifier: 'catalog:' + version: 0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0) + packages: '@adobe/css-tools@4.5.0': @@ -220,6 +248,10 @@ packages: '@types/react': optional: true + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + '@blazediff/core@1.9.1': resolution: {integrity: sha512-ehg3jIkYKulZh+8om/O25vkvSsXXwC+skXmyA87FFx6A/45eqOkZsBltMw/TVteb0mloiGT8oGRTcjRAz66zaA==} @@ -1449,6 +1481,9 @@ packages: resolution: {integrity: sha512-HDVTWq3H0uTXiU0eeSQntcVUTPP3GamzeXI41+x7uU9J65JgWQh3qWZHblR1i0npXfFtF+mxBiU2nJH8znxWnQ==} engines: {node: '>=18'} + '@quansync/fs@1.0.0': + resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} + '@rolldown/binding-android-arm64@1.0.3': resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1943,9 +1978,32 @@ packages: peerDependencies: vitest: 4.1.9 + '@vitest/coverage-v8@4.1.8': + resolution: {integrity: sha512-lt3kovsyHwYe00wq4D1ti0Z974fWj4NLp6siqiyEufUpyFwK9Yhi7rBhac9JL5aA0zoMrJqc4vYPZRUnI7l7nw==} + peerDependencies: + '@vitest/browser': 4.1.8 + vitest: 4.1.8 + peerDependenciesMeta: + '@vitest/browser': + optional: true + '@vitest/expect@3.2.4': resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + '@vitest/expect@4.1.8': + resolution: {integrity: sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==} + + '@vitest/mocker@4.1.8': + resolution: {integrity: sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + '@vitest/mocker@4.1.9': resolution: {integrity: sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==} peerDependencies: @@ -1960,21 +2018,36 @@ packages: '@vitest/pretty-format@3.2.4': resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + '@vitest/pretty-format@4.1.8': + resolution: {integrity: sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==} + '@vitest/pretty-format@4.1.9': resolution: {integrity: sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==} + '@vitest/runner@4.1.8': + resolution: {integrity: sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==} + '@vitest/runner@4.1.9': resolution: {integrity: sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==} + '@vitest/snapshot@4.1.8': + resolution: {integrity: sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==} + '@vitest/spy@3.2.4': resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + '@vitest/spy@4.1.8': + resolution: {integrity: sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==} + '@vitest/spy@4.1.9': resolution: {integrity: sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==} '@vitest/utils@3.2.4': resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + '@vitest/utils@4.1.8': + resolution: {integrity: sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==} + '@vitest/utils@4.1.9': resolution: {integrity: sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==} @@ -2150,6 +2223,9 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + args-tokenizer@0.3.0: + resolution: {integrity: sha512-xXAd7G2Mll5W8uo37GETpQ2VrE84M181Z7ugHFGQnJZ50M2mbOv0osSZ9VsSgPfJQ+LVG0prSi0th+ELMsno7Q==} + aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} @@ -2169,6 +2245,9 @@ packages: resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} engines: {node: '>=4'} + ast-v8-to-istanbul@1.0.4: + resolution: {integrity: sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==} + axe-core@4.12.1: resolution: {integrity: sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==} engines: {node: '>=4'} @@ -2202,10 +2281,19 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + bumpp@11.1.0: + resolution: {integrity: sha512-jdwOGMyX8JIqpQ0N2RMRR87DHZaoJnUtui5lU9LqFfFK5JC0H8qY9uWqXoa+dEWt/K7rOmmsoyiZB8RBM7RPBQ==} + engines: {node: '>=20.19.0'} + hasBin: true + bundle-name@4.1.0: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} + cac@7.0.0: + resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} + engines: {node: '>=20.19.0'} + caniuse-lite@1.0.30001799: resolution: {integrity: sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==} @@ -2213,6 +2301,10 @@ packages: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + chardet@2.1.1: resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} @@ -2275,6 +2367,9 @@ packages: resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} engines: {node: '>=12'} + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -2326,6 +2421,9 @@ packages: es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} + esbuild@0.27.3: resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} engines: {node: '>=18'} @@ -2358,6 +2456,10 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} @@ -2428,10 +2530,17 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + hasown@2.0.4: resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} engines: {node: '>= 0.4'} + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + human-id@4.2.0: resolution: {integrity: sha512-K3GbkIWqyvvlpfhBPlbEvD97TtqBpAYA4kt+cn2lD2x2HuohzZCibcA2nOlnJT6exqvJLggoB5nv2dNf192nEA==} hasBin: true @@ -2489,10 +2598,25 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + jiti@2.7.0: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2517,6 +2641,9 @@ packages: engines: {node: '>=6'} hasBin: true + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -2627,6 +2754,13 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + magicast@0.5.3: + resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -2835,6 +2969,9 @@ packages: quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + quansync@1.0.0: + resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -2940,6 +3077,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} @@ -2969,6 +3109,9 @@ packages: sqids@0.3.0: resolution: {integrity: sha512-lOQK1ucVg+W6n3FhRwwSeUijxe93b51Bfz5PMRMihVf1iVkl82ePQG7V5vwrhzB11v0NtsR25PSZRGiSomJaJw==} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + std-env@4.1.0: resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} @@ -3012,6 +3155,10 @@ packages: resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} engines: {node: '>=18'} + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -3089,6 +3236,12 @@ packages: engines: {node: '>=14.17'} hasBin: true + unconfig-core@7.5.0: + resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} + + unconfig@7.5.0: + resolution: {integrity: sha512-oi8Qy2JV4D3UQ0PsopR28CzdQ3S/5A1zwsUwp/rosSbfhJ5z7b90bIyTwi/F7hCLD4SGcZVjDzd4XoUQcEanvA==} + undici-types@7.24.6: resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} @@ -3181,6 +3334,47 @@ packages: yaml: optional: true + vitest@4.1.8: + resolution: {integrity: sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.1.8 + '@vitest/browser-preview': 4.1.8 + '@vitest/browser-webdriverio': 4.1.8 + '@vitest/coverage-istanbul': 4.1.8 + '@vitest/coverage-v8': 4.1.8 + '@vitest/ui': 4.1.8 + happy-dom: '*' + jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} @@ -3189,6 +3383,11 @@ packages: engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + workerd@1.20260611.1: resolution: {integrity: sha512-CS/640T7pIJ2HYX6x2DwKFGbcSckAWN3tgcdq+ptB6SaqjWUhlzIgA/YhPuwIU+/NnMnGpqOFX/hC18Oyge63w==} engines: {node: '>=16'} @@ -3392,6 +3591,8 @@ snapshots: optionalDependencies: '@types/react': 19.2.17 + '@bcoe/v8-coverage@1.0.2': {} + '@blazediff/core@1.9.1': {} '@braidai/lang@1.1.2': @@ -4264,6 +4465,10 @@ snapshots: '@publint/pack@0.1.4': optional: true + '@quansync/fs@1.0.0': + dependencies: + quansync: 1.0.0 + '@rolldown/binding-android-arm64@1.0.3': optional: true @@ -4327,32 +4532,32 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@storybook/addon-a11y@10.4.5(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))': + '@storybook/addon-a11y@10.4.5(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))': dependencies: '@storybook/global': 5.0.0 axe-core: 4.12.1 - storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) - '@storybook/addon-designs@11.1.3(@storybook/addon-docs@10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))': + '@storybook/addon-designs@11.1.3(18d5313c2038f010e24ea42f33de5044)': dependencies: '@figspec/react': 2.0.1(@types/react@19.2.17)(react@19.2.7) - storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) optionalDependencies: - '@storybook/addon-docs': 10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) + '@storybook/addon-docs': 10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) react: 19.2.7 react-dom: 19.2.7(react@19.2.7) transitivePeerDependencies: - '@types/react' - '@storybook/addon-docs@10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))': + '@storybook/addon-docs@10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))': dependencies: '@mdx-js/react': 3.1.1(@types/react@19.2.17)(react@19.2.7) - '@storybook/csf-plugin': 10.4.5(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) + '@storybook/csf-plugin': 10.4.5(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) '@storybook/icons': 2.0.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - '@storybook/react-dom-shim': 10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))) + '@storybook/react-dom-shim': 10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))) react: 19.2.7 react-dom: 19.2.7(react@19.2.7) - storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) ts-dedent: 2.3.0 optionalDependencies: '@types/react': 19.2.17 @@ -4363,44 +4568,43 @@ snapshots: - vite - webpack - '@storybook/addon-mcp@0.6.0(@storybook/addon-vitest@10.4.5(d8d8c6145d5df30d7d9880a51e5b5061))(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(typescript@6.0.3)': + '@storybook/addon-mcp@0.6.0(eb106c8d249302fb7f5800fd41bb642d)': dependencies: '@storybook/mcp': 0.7.0(typescript@6.0.3) '@tmcp/adapter-valibot': 0.1.6(tmcp@1.19.4(typescript@6.0.3))(valibot@1.2.0(typescript@6.0.3)) '@tmcp/transport-http': 0.8.6(tmcp@1.19.4(typescript@6.0.3)) picoquery: 2.5.0 - storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) tmcp: 1.19.4(typescript@6.0.3) valibot: 1.2.0(typescript@6.0.3) optionalDependencies: - '@storybook/addon-vitest': 10.4.5(d8d8c6145d5df30d7d9880a51e5b5061) + '@storybook/addon-vitest': 10.4.5(@vitest/browser-playwright@4.1.9(@voidzero-dev/vite-plus-test@0.1.24)(playwright@1.61.0)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)))(@vitest/runner@4.1.9)(@voidzero-dev/vite-plus-test@0.1.24)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))) transitivePeerDependencies: - '@tmcp/auth' - typescript - '@storybook/addon-themes@10.4.5(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))': + '@storybook/addon-themes@10.4.5(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))': dependencies: - storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) ts-dedent: 2.3.0 - '@storybook/addon-vitest@10.4.5(d8d8c6145d5df30d7d9880a51e5b5061)': + '@storybook/addon-vitest@10.4.5(@vitest/browser-playwright@4.1.9(@voidzero-dev/vite-plus-test@0.1.24)(playwright@1.61.0)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)))(@vitest/runner@4.1.9)(@voidzero-dev/vite-plus-test@0.1.24)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))': dependencies: '@storybook/global': 5.0.0 '@storybook/icons': 2.0.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) optionalDependencies: - '@vitest/browser': 4.1.9(@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) - '@vitest/browser-playwright': 4.1.9(@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))(playwright@1.61.0)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) + '@vitest/browser-playwright': 4.1.9(@voidzero-dev/vite-plus-test@0.1.24)(playwright@1.61.0)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) '@vitest/runner': 4.1.9 - vitest: '@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)' + vitest: '@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)' transitivePeerDependencies: - react - react-dom - '@storybook/builder-vite@10.4.5(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))': + '@storybook/builder-vite@10.4.5(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))': dependencies: - '@storybook/csf-plugin': 10.4.5(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) - storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + '@storybook/csf-plugin': 10.4.5(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) + storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) ts-dedent: 2.3.0 vite: 8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0) transitivePeerDependencies: @@ -4408,9 +4612,9 @@ snapshots: - rollup - webpack - '@storybook/csf-plugin@10.4.5(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))': + '@storybook/csf-plugin@10.4.5(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))': dependencies: - storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) unplugin: 2.3.11 optionalDependencies: esbuild: 0.27.7 @@ -4433,28 +4637,28 @@ snapshots: - '@tmcp/auth' - typescript - '@storybook/react-dom-shim@10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))': + '@storybook/react-dom-shim@10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))': dependencies: react: 19.2.7 react-dom: 19.2.7(react@19.2.7) - storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) optionalDependencies: '@types/react': 19.2.17 '@types/react-dom': 19.2.3(@types/react@19.2.17) - '@storybook/react-vite@10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.27.7)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))': + '@storybook/react-vite@10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.27.7)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))': dependencies: '@joshwooding/vite-plugin-react-docgen-typescript': 0.7.0(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) '@rollup/pluginutils': 5.4.0 - '@storybook/builder-vite': 10.4.5(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) - '@storybook/react': 10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(typescript@6.0.3) + '@storybook/builder-vite': 10.4.5(esbuild@0.27.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) + '@storybook/react': 10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(typescript@6.0.3) empathic: 2.0.1 magic-string: 0.30.21 react: 19.2.7 react-docgen: 8.0.3 react-dom: 19.2.7(react@19.2.7) resolve: 1.22.12 - storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) tsconfig-paths: 4.2.0 vite: 8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0) transitivePeerDependencies: @@ -4466,15 +4670,15 @@ snapshots: - typescript - webpack - '@storybook/react@10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(typescript@6.0.3)': + '@storybook/react@10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)))(typescript@6.0.3)': dependencies: '@storybook/global': 5.0.0 - '@storybook/react-dom-shim': 10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))) + '@storybook/react-dom-shim': 10.4.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))) react: 19.2.7 react-docgen: 8.0.3 react-docgen-typescript: 2.4.0(typescript@6.0.3) react-dom: 19.2.7(react@19.2.7) - storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) optionalDependencies: '@types/react': 19.2.17 '@types/react-dom': 19.2.3(@types/react@19.2.17) @@ -4683,20 +4887,20 @@ snapshots: dependencies: valibot: 1.2.0(typescript@6.0.3) - '@vitest/browser-playwright@4.1.9(@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))(playwright@1.61.0)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))': + '@vitest/browser-playwright@4.1.9(@voidzero-dev/vite-plus-test@0.1.24)(playwright@1.61.0)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))': dependencies: - '@vitest/browser': 4.1.9(@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) + '@vitest/browser': 4.1.9(@voidzero-dev/vite-plus-test@0.1.24)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) '@vitest/mocker': 4.1.9(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) playwright: 1.61.0 tinyrainbow: 3.1.0 - vitest: '@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)' + vitest: '@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)' transitivePeerDependencies: - bufferutil - msw - utf-8-validate - vite - '@vitest/browser@4.1.9(@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))': + '@vitest/browser@4.1.9(@voidzero-dev/vite-plus-test@0.1.24)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))': dependencies: '@blazediff/core': 1.9.1 '@vitest/mocker': 4.1.9(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) @@ -4705,7 +4909,7 @@ snapshots: pngjs: 7.0.0 sirv: 3.0.2 tinyrainbow: 3.1.0 - vitest: '@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)' + vitest: '@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)' ws: 8.21.0 transitivePeerDependencies: - bufferutil @@ -4713,6 +4917,35 @@ snapshots: - utf-8-validate - vite + '@vitest/coverage-v8@4.1.8(@voidzero-dev/vite-plus-test@0.1.24)': + dependencies: + '@bcoe/v8-coverage': 1.0.2 + '@vitest/utils': 4.1.8 + ast-v8-to-istanbul: 1.0.4 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.2.0 + magicast: 0.5.3 + obug: 2.1.3 + std-env: 4.1.0 + tinyrainbow: 3.1.0 + vitest: '@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)' + + '@vitest/coverage-v8@4.1.8(vitest@4.1.8)': + dependencies: + '@bcoe/v8-coverage': 1.0.2 + '@vitest/utils': 4.1.8 + ast-v8-to-istanbul: 1.0.4 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.2.0 + magicast: 0.5.3 + obug: 2.1.3 + std-env: 4.1.0 + tinyrainbow: 3.1.0 + vitest: 4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) + optional: true + '@vitest/expect@3.2.4': dependencies: '@types/chai': 5.2.3 @@ -4721,6 +4954,25 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 + '@vitest/expect@4.1.8': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 + chai: 6.2.2 + tinyrainbow: 3.1.0 + optional: true + + '@vitest/mocker@4.1.8(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))': + dependencies: + '@vitest/spy': 4.1.8 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0) + optional: true + '@vitest/mocker@4.1.9(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.9 @@ -4733,20 +4985,41 @@ snapshots: dependencies: tinyrainbow: 2.0.0 + '@vitest/pretty-format@4.1.8': + dependencies: + tinyrainbow: 3.1.0 + '@vitest/pretty-format@4.1.9': dependencies: tinyrainbow: 3.1.0 + '@vitest/runner@4.1.8': + dependencies: + '@vitest/utils': 4.1.8 + pathe: 2.0.3 + optional: true + '@vitest/runner@4.1.9': dependencies: '@vitest/utils': 4.1.9 pathe: 2.0.3 optional: true + '@vitest/snapshot@4.1.8': + dependencies: + '@vitest/pretty-format': 4.1.8 + '@vitest/utils': 4.1.8 + magic-string: 0.30.21 + pathe: 2.0.3 + optional: true + '@vitest/spy@3.2.4': dependencies: tinyspy: 4.0.4 + '@vitest/spy@4.1.8': + optional: true + '@vitest/spy@4.1.9': {} '@vitest/utils@3.2.4': @@ -4755,6 +5028,12 @@ snapshots: loupe: 3.2.1 tinyrainbow: 2.0.0 + '@vitest/utils@4.1.8': + dependencies: + '@vitest/pretty-format': 4.1.8 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 + '@vitest/utils@4.1.9': dependencies: '@vitest/pretty-format': 4.1.9 @@ -4795,7 +5074,7 @@ snapshots: '@voidzero-dev/vite-plus-linux-x64-musl@0.1.24': optional: true - '@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)': + '@voidzero-dev/vite-plus-test@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 @@ -4813,6 +5092,7 @@ snapshots: ws: 8.21.0 optionalDependencies: '@types/node': 25.9.3 + '@vitest/coverage-v8': 4.1.8(vitest@4.1.8) transitivePeerDependencies: - '@arethetypeswrong/core' - '@tsdown/css' @@ -4857,6 +5137,8 @@ snapshots: argparse@2.0.1: {} + args-tokenizer@0.3.0: {} + aria-query@5.3.0: dependencies: dequal: 2.0.3 @@ -4871,6 +5153,12 @@ snapshots: dependencies: tslib: 2.8.1 + ast-v8-to-istanbul@1.0.4: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 10.0.0 + axe-core@4.12.1: {} balanced-match@4.0.4: {} @@ -4899,10 +5187,24 @@ snapshots: node-releases: 2.0.47 update-browserslist-db: 1.2.3(browserslist@4.28.2) + bumpp@11.1.0: + dependencies: + args-tokenizer: 0.3.0 + cac: 7.0.0 + jsonc-parser: 3.3.1 + package-manager-detector: 1.6.0 + semver: 7.8.4 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + unconfig: 7.5.0 + yaml: 2.9.0 + bundle-name@4.1.0: dependencies: run-applescript: 7.1.0 + cac@7.0.0: {} + caniuse-lite@1.0.30001799: {} chai@5.3.3: @@ -4913,6 +5215,9 @@ snapshots: loupe: 3.2.1 pathval: 2.0.1 + chai@6.2.2: + optional: true + chardet@2.1.1: {} check-error@2.1.3: {} @@ -4957,6 +5262,8 @@ snapshots: define-lazy-prop@3.0.0: {} + defu@6.1.7: {} + dequal@2.0.3: {} detect-indent@6.1.0: {} @@ -4995,6 +5302,9 @@ snapshots: es-module-lexer@1.7.0: {} + es-module-lexer@2.1.0: + optional: true + esbuild@0.27.3: optionalDependencies: '@esbuild/aix-ppc64': 0.27.3 @@ -5067,6 +5377,9 @@ snapshots: esutils@2.0.3: {} + expect-type@1.3.0: + optional: true + extendable-error@0.1.7: {} fast-glob@3.3.3: @@ -5140,10 +5453,14 @@ snapshots: graceful-fs@4.2.11: {} + has-flag@4.0.0: {} + hasown@2.0.4: dependencies: function-bind: 1.1.2 + html-escaper@2.0.2: {} + human-id@4.2.0: {} iconv-lite@0.7.2: @@ -5184,8 +5501,23 @@ snapshots: isexe@2.0.0: {} + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + jiti@2.7.0: {} + js-tokens@10.0.0: {} + js-tokens@4.0.0: {} js-yaml@3.14.2: @@ -5203,6 +5535,8 @@ snapshots: json5@2.2.3: {} + jsonc-parser@3.3.1: {} + jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 @@ -5282,6 +5616,16 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + magicast@0.5.3: + dependencies: + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + source-map-js: 1.2.1 + + make-dir@4.0.0: + dependencies: + semver: 7.8.4 + merge2@1.4.1: {} micromatch@4.0.8: @@ -5379,7 +5723,7 @@ snapshots: '@oxc-resolver/binding-win32-arm64-msvc': 11.20.0 '@oxc-resolver/binding-win32-x64-msvc': 11.20.0 - oxfmt@0.52.0(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)): + oxfmt@0.52.0(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)): dependencies: tinypool: 2.1.0 optionalDependencies: @@ -5402,7 +5746,7 @@ snapshots: '@oxfmt/binding-win32-arm64-msvc': 0.52.0 '@oxfmt/binding-win32-ia32-msvc': 0.52.0 '@oxfmt/binding-win32-x64-msvc': 0.52.0 - vite-plus: 0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0) + vite-plus: 0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0) oxlint-tsgolint@0.23.0: optionalDependencies: @@ -5413,7 +5757,7 @@ snapshots: '@oxlint-tsgolint/win32-arm64': 0.23.0 '@oxlint-tsgolint/win32-x64': 0.23.0 - oxlint@1.67.0(oxlint-tsgolint@0.23.0)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)): + oxlint@1.67.0(oxlint-tsgolint@0.23.0)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)): optionalDependencies: '@oxlint/binding-android-arm-eabi': 1.67.0 '@oxlint/binding-android-arm64': 1.67.0 @@ -5435,7 +5779,7 @@ snapshots: '@oxlint/binding-win32-ia32-msvc': 1.67.0 '@oxlint/binding-win32-x64-msvc': 1.67.0 oxlint-tsgolint: 0.23.0 - vite-plus: 0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0) + vite-plus: 0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0) p-filter@2.1.0: dependencies: @@ -5457,8 +5801,7 @@ snapshots: dependencies: quansync: 0.2.11 - package-manager-detector@1.6.0: - optional: true + package-manager-detector@1.6.0: {} path-exists@4.0.0: {} @@ -5527,6 +5870,8 @@ snapshots: quansync@0.2.11: {} + quansync@1.0.0: {} + queue-microtask@1.2.3: {} react-day-picker@10.0.1(@types/react@19.2.17)(react@19.2.7): @@ -5675,6 +6020,9 @@ snapshots: shebang-regex@3.0.0: {} + siginfo@2.0.0: + optional: true + signal-exit@4.1.0: {} sirv@3.0.2: @@ -5698,13 +6046,16 @@ snapshots: sqids@0.3.0: {} + stackback@0.0.2: + optional: true + std-env@4.1.0: {} - storybook-addon-pseudo-states@10.4.5(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))): + storybook-addon-pseudo-states@10.4.5(storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0))): dependencies: - storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + storybook: 10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) - storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)): + storybook@10.4.5(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@2.8.8)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)): dependencies: '@storybook/global': 5.0.0 '@storybook/icons': 2.0.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) @@ -5724,7 +6075,7 @@ snapshots: optionalDependencies: '@types/react': 19.2.17 prettier: 2.8.8 - vite-plus: 0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0) + vite-plus: 0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0) transitivePeerDependencies: - '@testing-library/dom' - bufferutil @@ -5746,6 +6097,10 @@ snapshots: supports-color@10.2.2: {} + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + supports-preserve-symlinks-flag@1.0.0: {} tailwindcss@4.3.1: {} @@ -5804,6 +6159,19 @@ snapshots: typescript@6.0.3: {} + unconfig-core@7.5.0: + dependencies: + '@quansync/fs': 1.0.0 + quansync: 1.0.0 + + unconfig@7.5.0: + dependencies: + '@quansync/fs': 1.0.0 + defu: 6.1.7 + jiti: 2.7.0 + quansync: 1.0.0 + unconfig-core: 7.5.0 + undici-types@7.24.6: {} undici@7.24.8: {} @@ -5840,14 +6208,14 @@ snapshots: validate-npm-package-name@5.0.1: optional: true - vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0): + vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0): dependencies: '@oxc-project/types': 0.133.0 '@oxlint/plugins': 1.61.0 '@voidzero-dev/vite-plus-core': 0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(yaml@2.9.0) - '@voidzero-dev/vite-plus-test': 0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0) - oxfmt: 0.52.0(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) - oxlint: 1.67.0(oxlint-tsgolint@0.23.0)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + '@voidzero-dev/vite-plus-test': 0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0) + oxfmt: 0.52.0(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) + oxlint: 1.67.0(oxlint-tsgolint@0.23.0)(vite-plus@0.1.24(@arethetypeswrong/core@0.18.3)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(esbuild@0.27.7)(jiti@2.7.0)(publint@0.3.21)(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0))(yaml@2.9.0)) oxlint-tsgolint: 0.23.0 optionalDependencies: '@voidzero-dev/vite-plus-darwin-arm64': 0.1.24 @@ -5904,12 +6272,47 @@ snapshots: jiti: 2.7.0 yaml: 2.9.0 + vitest@4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)): + dependencies: + '@vitest/expect': 4.1.8 + '@vitest/mocker': 4.1.8(vite@8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.8 + '@vitest/runner': 4.1.8 + '@vitest/snapshot': 4.1.8 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 + es-module-lexer: 2.1.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.3 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.1.0 + tinybench: 2.9.0 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.0 + vite: 8.0.16(@types/node@25.9.3)(esbuild@0.27.7)(jiti@2.7.0)(yaml@2.9.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 25.9.3 + '@vitest/coverage-v8': 4.1.8(vitest@4.1.8) + transitivePeerDependencies: + - msw + optional: true + webpack-virtual-modules@0.6.2: {} which@2.0.2: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + optional: true + workerd@1.20260611.1: optionalDependencies: '@cloudflare/workerd-darwin-64': 1.20260611.1 @@ -5944,8 +6347,7 @@ snapshots: yallist@3.1.1: {} - yaml@2.9.0: - optional: true + yaml@2.9.0: {} youch-core@0.3.3: dependencies: diff --git a/tools/oxlint-plugin-propel/.gitignore b/tools/oxlint-plugin-propel/.gitignore new file mode 100644 index 00000000..75352116 --- /dev/null +++ b/tools/oxlint-plugin-propel/.gitignore @@ -0,0 +1,4 @@ +node_modules +dist +*.log +.DS_Store diff --git a/tools/oxlint-plugin-propel/README.md b/tools/oxlint-plugin-propel/README.md new file mode 100644 index 00000000..ab6b895d --- /dev/null +++ b/tools/oxlint-plugin-propel/README.md @@ -0,0 +1,60 @@ +# oxlint-plugin-propel + +Project-specific Oxlint rules for Propel. + +This package is private to the workspace and is loaded by the root `vite.config.ts` through Oxlint's local `jsPlugins` support. + +## Rules + +### `propel/prefer-tailwind-v4-shorthand` + +Enforces the Tailwind CSS v4 shorthand forms we use in component class strings. + +Fixes exact CSS custom property arbitrary values: + +```tsx +"h-[var(--accordion-panel-height)]"; +"h-(--accordion-panel-height)"; +``` + +Fixes presence-only data variants: + +```tsx +"data-[highlighted]:text-primary"; +"data-highlighted:text-primary"; +``` + +It also handles grouped, peer, named, and negated presence data variants: + +```tsx +"group-data-[popup-open]/trigger:text-primary"; +"group-data-popup-open/trigger:text-primary"; +``` + +The rule intentionally does not rewrite valued arbitrary data selectors such as `data-[state=open]:...` or arbitrary values with fallbacks such as `h-[var(--height,auto)]`. + +## Development + +Run the package tests: + +```bash +vp run --filter oxlint-plugin-propel test +``` + +Run workspace validation: + +```bash +vp check +vp test +``` + +The root config enables the rule as an error: + +```ts +lint: { + jsPlugins: ["./tools/oxlint-plugin-propel/src/index.ts"], + rules: { + "propel/prefer-tailwind-v4-shorthand": "error", + }, +} +``` diff --git a/tools/oxlint-plugin-propel/package.json b/tools/oxlint-plugin-propel/package.json new file mode 100644 index 00000000..20bd0383 --- /dev/null +++ b/tools/oxlint-plugin-propel/package.json @@ -0,0 +1,43 @@ +{ + "name": "oxlint-plugin-propel", + "version": "0.0.0", + "private": true, + "description": "Oxlint rules for Propel project conventions.", + "homepage": "https://github.com/makeplane/propel#readme", + "bugs": { + "url": "https://github.com/makeplane/propel/issues" + }, + "license": "AGPL-3.0-only", + "author": "Plane (https://plane.so)", + "repository": { + "type": "git", + "url": "git+https://github.com/makeplane/propel.git", + "directory": "tools/oxlint-plugin-propel" + }, + "files": [ + "dist" + ], + "type": "module", + "exports": { + ".": "./dist/index.mjs", + "./package.json": "./package.json" + }, + "scripts": { + "build": "vp pack", + "dev": "vp pack --watch", + "test": "vp test", + "check": "vp check", + "prepublishOnly": "vp run build" + }, + "dependencies": { + "@oxlint/plugins": "1.61.0" + }, + "devDependencies": { + "@types/node": "^25.6.2", + "@typescript/native-preview": "7.0.0-dev.20260509.2", + "bumpp": "^11.1.0", + "oxlint": "1.67.0", + "typescript": "^6.0.3", + "vite-plus": "catalog:" + } +} diff --git a/tools/oxlint-plugin-propel/src/index.ts b/tools/oxlint-plugin-propel/src/index.ts new file mode 100644 index 00000000..950fc9f6 --- /dev/null +++ b/tools/oxlint-plugin-propel/src/index.ts @@ -0,0 +1,73 @@ +import type { Context, ESTree, Plugin, Rule } from "@oxlint/plugins"; + +export const RULE_NAME = "prefer-tailwind-v4-shorthand"; + +const cssVariableArbitraryValue = /\[var\((--[A-Za-z0-9_-]+)\)\]/g; +const presenceDataVariant = + /(^|[\s:])(not-)?((?:group-|peer-|in-)?data-)\[([A-Za-z][A-Za-z0-9_-]*)\]((?:\/[A-Za-z][A-Za-z0-9_-]*)?):/g; + +export function normalizeTailwindV4Shorthand(value: string): string { + return value + .replace(cssVariableArbitraryValue, "($1)") + .replace(presenceDataVariant, "$1$2$3$4$5:"); +} + +function quoteStringLiteral(raw: string, value: string): string { + const quote = raw.startsWith("'") ? "'" : '"'; + const escaped = value + .replaceAll("\\", "\\\\") + .replaceAll(quote, `\\${quote}`) + .replaceAll("\r", "\\r") + .replaceAll("\n", "\\n"); + + return `${quote}${escaped}${quote}`; +} + +function maybeReportStringLiteral(context: Context, node: ESTree.StringLiteral): void { + const replacement = normalizeTailwindV4Shorthand(node.value); + if (replacement === node.value) return; + + const raw = context.sourceCode.getText(node); + if (!/^(['"])/.test(raw)) return; + + context.report({ + node, + messageId: "preferTailwindV4Shorthand", + fix(fixer) { + return fixer.replaceText(node, quoteStringLiteral(raw, replacement)); + }, + }); +} + +export const preferTailwindV4ShorthandRule = { + meta: { + type: "suggestion", + docs: { + description: + "Prefer Tailwind CSS v4 shorthand syntax for simple arbitrary values and data variants.", + recommended: true, + }, + fixable: "code", + messages: { + preferTailwindV4Shorthand: "Use Tailwind CSS v4 shorthand syntax for this class string.", + }, + }, + createOnce(context) { + return { + Literal(node) { + if (typeof node.value === "string") maybeReportStringLiteral(context, node); + }, + }; + }, +} satisfies Rule; + +const plugin = { + meta: { + name: "propel", + }, + rules: { + [RULE_NAME]: preferTailwindV4ShorthandRule, + }, +} satisfies Plugin; + +export default plugin; diff --git a/tools/oxlint-plugin-propel/tests/index.test.ts b/tools/oxlint-plugin-propel/tests/index.test.ts new file mode 100644 index 00000000..aec40293 --- /dev/null +++ b/tools/oxlint-plugin-propel/tests/index.test.ts @@ -0,0 +1,77 @@ +import { RuleTester } from "oxlint/plugins-dev"; +import { describe, it } from "vite-plus/test"; + +import { preferTailwindV4ShorthandRule, RULE_NAME } from "../src/index.ts"; + +RuleTester.describe = describe; +RuleTester.it = it; + +const tester = new RuleTester({ + languageOptions: { + parserOptions: { + lang: "tsx", + }, + }, +}); + +function code(value: string): string { + return value; +} + +tester.run(RULE_NAME, preferTailwindV4ShorthandRule, { + valid: [ + { + name: "keeps valued data selectors", + code: 'const className = "data-[state=open]:bg-primary data-[orientation=vertical]:w-3";', + }, + { + name: "keeps arbitrary values with fallbacks", + code: 'const className = "h-[var(--accordion-panel-height,auto)] w-[theme(--spacing-4)]";', + }, + { + name: "keeps arbitrary selectors", + code: 'const className = "[&[data-highlighted]]:bg-primary";', + }, + ], + invalid: [ + { + name: "fixes css variable arbitrary values", + code: code( + 'const className = "h-[' + "var(--accordion-panel-height)] size-[" + 'var(--node-size)]";', + ), + output: 'const className = "h-(--accordion-panel-height) size-(--node-size)";', + errors: [{ messageId: "preferTailwindV4Shorthand" }], + }, + { + name: "fixes presence data variants", + code: code( + 'const className = "data-[' + "ending-style]:h-0 data-[" + 'highlighted]:text-primary";', + ), + output: 'const className = "data-ending-style:h-0 data-highlighted:text-primary";', + errors: [{ messageId: "preferTailwindV4Shorthand" }], + }, + { + name: "fixes grouped and negated presence data variants", + code: code( + 'const className = "group-data-[' + + "popup-open]/trigger:text-primary not-data-[" + + "expanded]:hover:bg-layer-transparent-hover peer-data-[" + + 'active]:opacity-100";', + ), + output: + 'const className = "group-data-popup-open/trigger:text-primary not-data-expanded:hover:bg-layer-transparent-hover peer-data-active:opacity-100";', + errors: [{ messageId: "preferTailwindV4Shorthand" }], + }, + { + name: "fixes jsx attribute strings", + code: code( + 'const element =
;', + ), + output: + 'const element =
;', + errors: [{ messageId: "preferTailwindV4Shorthand" }], + }, + ], +}); diff --git a/tools/oxlint-plugin-propel/tsconfig.json b/tools/oxlint-plugin-propel/tsconfig.json new file mode 100644 index 00000000..ff4adab5 --- /dev/null +++ b/tools/oxlint-plugin-propel/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "esnext", + "lib": ["es2023"], + "moduleDetection": "force", + "module": "nodenext", + "moduleResolution": "nodenext", + "resolveJsonModule": true, + "types": ["node"], + "strict": true, + "noUnusedLocals": true, + "declaration": true, + "noEmit": true, + "allowImportingTsExtensions": true, + "esModuleInterop": true, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "skipLibCheck": true + } +} diff --git a/tools/oxlint-plugin-propel/vite.config.ts b/tools/oxlint-plugin-propel/vite.config.ts new file mode 100644 index 00000000..bffbbc1e --- /dev/null +++ b/tools/oxlint-plugin-propel/vite.config.ts @@ -0,0 +1,17 @@ +import { defineConfig } from "vite-plus"; + +export default defineConfig({ + pack: { + dts: { + tsgo: true, + }, + exports: true, + }, + lint: { + options: { + typeAware: true, + typeCheck: true, + }, + }, + fmt: {}, +}); diff --git a/vite.config.ts b/vite.config.ts index ef83f007..54d9c9ce 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -24,6 +24,7 @@ export default defineConfig({ jsdoc: true, }, lint: { + jsPlugins: ["./tools/oxlint-plugin-propel/src/index.ts"], // Tooling/config files are validated by actually building and testing, not by // the library's type-aware lint: // - .storybook/* — Storybook compiles & type-checks these itself; they use @@ -38,7 +39,10 @@ export default defineConfig({ ], options: { typeAware: true, typeCheck: true }, // Project convention: always use `type`, never `interface`. - rules: { "typescript/consistent-type-definitions": ["error", "type"] }, + rules: { + "propel/prefer-tailwind-v4-shorthand": "error", + "typescript/consistent-type-definitions": ["error", "type"], + }, }, run: { cache: true,