Changelog
what shipped in @wrkspace/shell.
00aa386: Lock AppShell to the viewport so the sidebar stays put and page content scrolls in the main pane.
10000e8: Export StepUpPanel so step-up can replace an open confirm instead of stacking a second modal.
fa26445: Fix Copyable's icon-pop animation playing on mount instead of only when the copy button is actually clicked.
a663cf2: Add @wrkspace/shell/activity - a shared Bus event activity timeline (day-grouped list, event detail sheet, formatter registry, group-by-day/format-time helpers) for any app rendering GET /v1/events/me results. Extracted from apps/bus/web so it can be reused (e.g. by apps/id's own Activity tab) without duplicating the UI.
41f2499: - Export TagTone from the package root (the Tag component already accepted it, but consumers couldn't import the type).
- Fix
KeyValueandCopyableoverflowing their container instead of wrapping/truncating long values, which broke layouts (e.g. sheets) on narrow viewports.
f080610: Add BootScreen - a full-region gate for a server-side check (session, permissions, feature flags) that must resolve before any UI can render at all, as opposed to Skeleton, which placeholders a region that stays otherwise usable while its own data loads. Presentational only, so it drops straight in as a Suspense fallback from a Server Component: <Suspense fallback={<BootScreen logo={<DitherLogo size={32} />} label="verifying session" />}>. Optional logo, label (default "loading"), description, and fullscreen (covers the viewport instead of filling the parent). Documented in the loading-model table in README and docs/interactions.md.
103d1de: Every raw ASCII (>, <, v) or Unicode glyph (▶, ▼, ▾, ▸) standing in for an arrow/chevron now renders as a real pixelarticons icon, matching the pixel-art aesthetic:
- Disclosure/navigation:
Selecttrigger (togglesChevronRight/ChevronDownon open),Sidebar's collapsible group toggle,DropdownMenu/ContextMenu/Menubarsubmenu triggers (ChevronRight, previously inconsistent between>and▶across the three),NavigationMenutrigger (ChevronDown, keeps its rotate-on-open animation),AccordionandTreeexpand/collapse indicators,Calendar's previous/next month buttons, andPagination's prev/next controls. - Selected/highlighted-item marker:
Marker,Menuitem,Selectitem indicator,Sidebaritem and sub-item,CommandPalettehighlighted row, andPrompt's prefix all now use aChevronRighticon instead of a literal>character - same documented meaning (docs/interactions.md's "selected: accent marker"), just rendered as a pixel icon like everything else instead of a font glyph.
First stable release. The component API is now considered stable - breaking changes will follow semver major bumps going forward. This release closes out the pre-1.0.0 audit: WCAG AA contrast fixes, focus-visible coverage, Table/DitherSurface/Combobox/CommandPalette performance work, and documentation/test-coverage gaps (see 0.13.1).
cf1f75c: Fixes from the pre-1.0.0 audit: --shell-warning text now meets WCAG AA contrast (4.71:1, was 2.98:1) and --shell-border contrast is raised (light 1.56:1 → 2.38:1, dark 1.53:1 → 2.29:1). Added missing focus-visible rings on Accordion trigger, Tree trigger, TagsInput chip remove, and Copyable's copy button. Table sort/row-key derivation is now memoized and column-resize drag is throttled via requestAnimationFrame instead of updating state on every pointermove, fixing jank when resizing columns on large datasets. DitherSurface's animate loop is capped at 30fps. Combobox and CommandPalette memoize their filtered/grouped results instead of recomputing on every render. Field is documented as presentational-only (not wired to children via htmlFor/aria - use FormField for actual form controls). Steps is now documented in README and docs/recipes.md. Added component tests for TagsInput, Table, CommandPalette, Calendar, and DatePicker.
41425c2: Slider range thumbs, marks, and showValue; Steps orientation, descriptions, and clickable completed steps; ConfirmPhrase / ConfirmSubmit for typed destroy confirms. Single-thumb Slider now sits on the track (no gap-2 beside it).
95d5bb4: Adds cyan and magenta accent presets alongside phosphor and amber (SHELL_ACCENTS, data-shell-accent="cyan" | "magenta"), for TUI palettes that need more than green/amber.
95d5bb4: data-shell-density="compact" now also affects Table (row/header cell padding), ListItem, and Sidebar (header height, sub-item height, collapsible group toggle padding) via new --shell-row-py/--shell-row-py-header tokens, instead of only form controls and buttons.
95d5bb4: Skeleton now respects prefers-reduced-motion (previously always animated). Avatar, DitherSurface, and Spinner now use the shared usePrefersReducedMotion hook instead of a one-shot inline matchMedia check, so they react live if the OS setting changes while mounted, matching Copyable/Sensitive.
16ea282: Combobox gains an opt-in async mode: onSearch(query, signal) fetches options as the user types (debounced via debounceMs, default 300ms), gated to only run while the popup is open, with a race-guard (AbortController + request-id check) so stale responses never overwrite newer ones. Shows a Spinner while loading. onSearchError reports rejected searches. Sync items-based filtering is unchanged when onSearch is not passed. Also fixes a dead-space gap below the results list caused by the empty-state slot rendering even when there are matches.
bad0d52: useShortcuts now supports two-key chord bindings (e.g. "g u")
7204f71: Add formatBinding/isMacPlatform helpers to keys-format for rendering platform-correct shortcut hints (e.g. "mod+k" -> ⌘K / Ctrl+K)
0b9c779: LogViewer now virtualizes its row list (@tanstack/react-virtual) and raises the default maxLines from 1000 to 10000
770a203: Table now renders on CSS grid internally and gains opt-in column resize (resizable, columnWidths/defaultColumnWidths/onColumnWidthsChange/autoSaveId), column pin (pin: "left" | "right"), and row virtualization (virtualize, height, estimateRowHeight) via @tanstack/react-virtual. Default rendering (no virtualize/resizable/pin) is unchanged for existing consumers. Also fixes the sort indicator to use consistently-sized chevron icons instead of mismatched ^/v characters.
6f5009b: Reduce React Doctor complexity in DiffViewer/JsonViewer/ObjectTree; mark CodeBlock highlighter markup explicitly
ddef20e: Open ContextMenu on long-press, Tooltip and PreviewCard on tap, and hide keyboard shortcuts on touch.
Add RSC-safe Table actions and Pagination prevHref/nextHref props so Server Components can render list pages without passing functions to Client Components.
0b17066: Keep iOS Safari from covering the topbar and zooming into form fields.
Menu grammar:
<ContextMenu />now matches DropdownMenu and Menubar: checkbox, radio, group, sub, shortcut.
Density contract:
- Compact remaps
--shell-control-h*on Select, Textarea, NumberInput, TagsInput, and Otp/Pin as well as Button, Input, Combobox, and Autocomplete. - PasswordInput and the date pickers inherit the tokens from Input and Button.
Forms:
FormNumberInput,FormSlider,FormFileUpload,FormOtpInput,FormPinInput, andFormAutocomplete.
FileUpload:
maxSize,maxFiles,acceptrejection reasons, controlledvalue, per-fileprogress, andonReject.
Code:
<CodeBlock html={...} />plusCODE_HIGHLIGHT_STYLEso RSC can pass Shiki markup without pulling Shiki into the main barrel.
Toast:
useToast().toast({ action: { label, onClick } })for undo / retry.
Showroom: ThemeSwitch and ScrollArea catalog pages.
Raise amber light-theme button contrast with light on-accent text.
bcf0b63: Export IconComponent so apps can type pixelart icons without clashing React type copies.
Token contract:
data-shell-accent: omit for inverse, orphosphor/amber.data-shell-density="compact"remaps--shell-control-h*on Button, Input, Combobox, and Autocomplete.applyShellThemeon<html>,shellThemePropson a wrapper.
Docs: README recipes for pickers, forms, and list pages. Token table in docs/tokens.md.
List pages:
<Table />: real HTML table with sort, select, empty, loading, sticky header, and footer.<DropdownMenu />: same grammar as Menubar (sub, checkbox, radio, group, shortcut).<CommandPalette />: grouped fuzzy search with keyboard shortcuts.<Pagination />: App RouterhrefandrenderLink.
Forms and pickers:
<PasswordInput />: show/hide toggle with the icon on the trailing edge.<DateRangePicker />and Calendarmode="range".FormInput,FormPassword,FormDatePicker,FormDateRangePicker,FormCombobox,FormTagsInput, andFormTextarea.- Combobox uses the same fuzzy filter as Autocomplete.
Data lists:
<DataList />and<SearchField />for GET search pages.hiddenSearchFieldsdropsqandpagefrom filter chips.
100% Base UI Coverage:
<Menubar />: Complete horizontal desktop/TUI menu bar suite with submenus (MenubarSub,MenubarSubTrigger,MenubarSubContent), checkable items (MenubarCheckboxItem), radio groups (MenubarRadioGroup,MenubarRadioItem), shortcuts (MenubarShortcut), and seamless arrow-key navigation across menus.<PreviewCard />: Accessible hover card preview popup (PreviewCard,PreviewCardTrigger,PreviewCardContent,PreviewCardArrow) with geometric terminal arrows, configurable delays, and portal positioning.<NavigationMenu />: Accessible top navigation menu with viewport panels (NavigationMenu,NavigationMenuList,NavigationMenuItem,NavigationMenuTrigger,NavigationMenuContent,NavigationMenuLink,NavigationMenuViewport).<Autocomplete />: Free-text search input with dynamic filtered completions, 1:1Inputstyling, prefix/suffix support, scrollable list ([scrollbar-width:thin]), and integratedfuzzyFilterpowered by DPfuzzyMatch.
Skeleton Modernization: Redesigned <Skeleton /> to lightweight, clean CSS pulse (bg-shell-muted/15 animate-pulse), eliminating canvas requestAnimationFrame redraw loops and low-resolution pixel distortion.
Accessibility & ARIA Status: Provided default sr-only class on ARIA live region status elements (<AutocompleteStatus />) to prevent layout shifts while maintaining complete WCAG accessibility.
Mobile Navigation & Sidebar Polish: Added <SidebarClose /> and resolved mobile sheet drawer backdrop dismiss issues and z-index contexts.
DitherLogo Standardization: Standardized logo pixel dimensions to 24px across SiteShell and demo headers.
Tabs & Meters Alignment: Fixed TabsList baseline borders and horizontal scrolling; resolved Meter and ObjectTree container overflow on mobile viewports.
Showroom Upgrades: Added Open Graph image generation (/api/og/[slug]) and interactive component showcases across apps/shell.
bf8cf9c: Add <DiffViewer /> component powered by @pierre/diffs with split/unified layouts, custom TUI hunk expansion separators, and Shiki code syntax highlighting. @pierre/diffs is configured as an optional peer dependency.
e07b88c: Add <ObjectTree /> and <JsonViewer /> components for interactive TUI data inspection, Tree vs Raw view modes, instant filtering, expand/collapse depth controls, and copy/export actions.
0c23bdd: Add 3D mechanical <Kbd /> and <KeyCap /> components with tactile active press depression, modifier symbol formatting, and multi-key sequence support.
528672e: Add <LogViewer /> component for terminal log streaming with instant search filtering, level badges, follow autoscroll, line actions, copy, and export capabilities.
ce8030f: Add <ResizablePanelGroup />, <ResizablePanel />, <ResizableHandle />, and <SplitPane /> components for mechanical tmux/vim split panes with horizontal and vertical resizing, drag limits, and optional persistence.
f7f8742: Add <SidebarCollapsibleGroup />, <SidebarGroup />, <SidebarGroupLabel />, <SidebarMenuSub />, <SidebarMenuSubItem />, <SidebarBadge />, and <SidebarSeparator /> for rich, collapsible, multi-tier sidebar navigation.
Optimize DP fuzzy search with Int32Array Levenshtein distance and strictly normalized scores, fix AppShell viewport overflow, resolve DiffViewer SSR hydration, and align ObjectTree chevron guide lines.
DiffViewer Light/Dark Theming: Support automatic real-time DOM theme syncing (.dark / [data-theme="dark"] mutation observer) in <DiffViewer />, switching between pierre-light and pierre-dark immediately when the app theme toggles.
DiffViewer: Full-featured terminal diff and review component powered by @pierre/diffs, supporting split/unified view modes, custom TUI arrows and line info styling, and Shiki code highlighting.
ResizablePanels & SplitPane: Mechanical tmux/vim splits (<ResizablePanelGroup />, <ResizablePanel />, <ResizableHandle />, <SplitPane />) with retro monospace grips and layout persistence.
Kbd & KeyCap: 3D mechanical keycaps with zero-layout-shift active:translate-y-[2px] tactile depression, automatic modifier symbol normalization, and multi-key sequences.
JsonViewer & ObjectTree: Interactive JSON inspector with collapsible object trees, type filtering, raw code view, and clipboard export.
LogViewer: Monospace log stream console with log level color tagging, follow autoscroll, and real-time filtering.
Sidebar Architecture: Expanded sidebar suite with <SidebarCollapsibleGroup />, <SidebarGroup />, <SidebarGroupLabel />, <SidebarMenuSub />, <SidebarMenuSubItem />, <SidebarBadge />, and <SidebarSeparator />.
Render Stability: Fixed React render loops and maximum update depth issues across ResizablePanels, Duration, and Progress.
Docs & Site Shell: Modularized demo system and upgraded shell app with sticky fixed sidebar navigation, live search, and dedicated /components/[slug] subpages for all components.
4f5dd63: Add <Duration /> component with live client-side ticking, tabular-nums monospace typography, and multiple TUI formatting modes (hms, digital, compact, long, short).
Mathematically align AreaChart X-axis labels and ticks with corresponding data points and crosshairs.
Enable dynamic cell-based pixel density (cell = 2) with ResizeObserver across AreaChart, Sparkline, BarChart, and DonutChart for crisp fine-grained dithering.
bfde6ad: Add dithered chart components (Sparkline, AreaChart, BarChart, DonutChart) with ordered dithering, crosshairs, tooltips, and theme support
Keep Sensitive values and their toggle controls together without wrapping.
Mask Sensitive with a fixed-length asterisk string so length is not leaked.
985da5b: Replace Sensitive's fake shade dither with a TUI asterisk mask.