From bbd86e6902f73c1f96be005e0dbe0f189b2a558d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Collonval?= Date: Thu, 9 Apr 2026 10:35:47 +0200 Subject: [PATCH 01/26] docs: add design spec for 16 new components Covers accordion, alert-dialog, button-group, collapsible, field, input-group, popover, resizable, scroll-area, separator, sheet, sidebar, skeleton, slider, toast, and table. Defines dependency-first build order, token additions, component APIs, testing and story strategy. --- .../specs/2026-04-09-new-components-design.md | 359 ++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-09-new-components-design.md diff --git a/docs/superpowers/specs/2026-04-09-new-components-design.md b/docs/superpowers/specs/2026-04-09-new-components-design.md new file mode 100644 index 0000000..8bf42d6 --- /dev/null +++ b/docs/superpowers/specs/2026-04-09-new-components-design.md @@ -0,0 +1,359 @@ +# New Components Design Spec + +**Date:** 2026-04-09 +**Scope:** Add 16 new components to @webscit/toolkit, matching shadcn's general-purpose API. + +## Components + +accordion, alert-dialog, button-group, collapsible, field, input-group, popover, resizable, scroll-area, separator, sheet, sidebar, skeleton, slider, toast (replaces "sonner" from the original list — built on Base UI Toast instead of the sonner library), table + +## Implementation Strategy: Dependency-First + +### Token Additions (first) + +New semantic color tokens: + +| Token | Purpose | +|---|---| +| `sct.color.success` / `sct.color.success-foreground` | Success states (toast, future use) | +| `sct.color.warning` / `sct.color.warning-foreground` | Warning states | +| `sct.color.info` / `sct.color.info-foreground` | Informational states | + +New sidebar dimension tokens: + +| Token | Default | Purpose | +|---|---|---| +| `sct.sidebar.width` | 16rem | Default sidebar width | +| `sct.sidebar.width-collapsed` | 3rem | Collapsed/icon-only width | + +Primitive green/amber values go in `base.tokens.json`. Semantic aliases in `semantic.tokens.json` and `semantic-dark.tokens.json`. + +### Dependency Graph + +``` +Layer 0 — Leaf components (no deps on other new components): +├── separator (native
/
) +├── skeleton (native
+ CSS animation) +├── scroll-area (native HTML + CSS scrollbar styling) +├── table (native elements) +├── popover (Base UI popover) +├── slider (Base UI slider) +├── collapsible (Base UI collapsible) +├── accordion (Base UI accordion) +├── alert-dialog (Base UI alert-dialog) +├── sheet (Base UI dialog, side-sliding variant) +├── button-group (native
) +├── input-group (native
composition) +├── resizable (react-resizable-panels wrapper) +└── toast (Base UI toast) + +Layer 1 — Depends on Layer 0: +└── field (uses separator, label; Base UI field + fieldset) + +Layer 2 — Depends on Layers 0 + 1: +└── sidebar (uses collapsible, sheet, separator, skeleton, + scroll-area, tooltip, button, input) +``` + +**Build order:** Tokens first → all Layer 0 (parallelizable) → field → sidebar. + +## Component API Designs + +All components follow existing conventions: +- `sct-` scope-anchor class on root element +- `@scope (.sct-) { ... }` in CSS +- `data-slot` attributes on every sub-component +- `data-variant` / `data-size` / `data-orientation` for variants +- Base UI `data-*` attributes for states +- No `cn()` / `clsx` — manual class composition: `` `sct-foo${className ? ` ${className}` : ''}` `` + +### Separator + +```tsx +export function Separator({ orientation = "horizontal", decorative = true, className, ...props }) +// Renders
(or role="none" if decorative) +// data-orientation="horizontal" | "vertical" +``` + +### Skeleton + +```tsx +export function Skeleton({ className, ...props }) +// Renders
with pulse/shimmer CSS animation +// CSS-only, no JS state +``` + +### Scroll Area + +```tsx +export function ScrollArea({ className, children, ...props }) +export function ScrollBar({ orientation = "vertical", className, ...props }) +// Native overflow with custom scrollbar styling via CSS +// Uses ::-webkit-scrollbar + scrollbar-width/color for Firefox +``` + +### Table + +```tsx +export function Table({ className, ...props }) //
+export function TableHeader({ className, ...props }) // +export function TableBody({ className, ...props }) // +export function TableFooter({ className, ...props }) // +export function TableRow({ className, ...props }) // +export function TableHead({ className, ...props }) //
+export function TableCell({ className, ...props }) // +export function TableCaption({ className, ...props }) //
+``` + +### Popover + +```tsx +export function Popover(props) // Base UI Popover.Root +export function PopoverTrigger(props) // Base UI Popover.Trigger +export function PopoverContent(props) // Base UI Popover.Popup (inside Portal + Positioner) +export function PopoverClose(props) // Base UI Popover.Close +``` + +### Slider + +```tsx +export function Slider({ className, ...props }) // Base UI Slider.Root +export function SliderTrack(props) // Base UI Slider.Track +export function SliderRange(props) // Base UI Slider.Range (or Indicator) +export function SliderThumb(props) // Base UI Slider.Thumb +``` + +### Collapsible + +```tsx +export function Collapsible(props) // Base UI Collapsible.Root +export function CollapsibleTrigger(props) // Base UI Collapsible.Trigger +export function CollapsibleContent(props) // Base UI Collapsible.Panel (animated) +``` + +### Accordion + +```tsx +export function Accordion(props) // Base UI Accordion.Root +export function AccordionItem(props) // Base UI Accordion.Item +export function AccordionTrigger(props) // Base UI Accordion.Trigger (inside Header) +export function AccordionContent(props) // Base UI Accordion.Panel +``` + +### Alert Dialog + +```tsx +export function AlertDialog(props) // Base UI AlertDialog.Root +export function AlertDialogTrigger(props) // Base UI AlertDialog.Trigger +export function AlertDialogContent(props) // Base UI AlertDialog.Popup (inside Portal) +export function AlertDialogOverlay(props) // Base UI AlertDialog.Backdrop +export function AlertDialogHeader(props) // plain
+export function AlertDialogFooter(props) // plain
+export function AlertDialogTitle(props) // Base UI AlertDialog.Title +export function AlertDialogDescription(props) // Base UI AlertDialog.Description +export function AlertDialogAction(props) //