From 058a4fdf48fb43e11187e702f5914ea1fdfa466d Mon Sep 17 00:00:00 2001
From: Karn
Date: Wed, 26 Aug 2026 21:58:50 +0530
Subject: [PATCH] feat: add Linear-style collection views
---
.changeset/linear-collection-views.md | 6 +
.gitignore | 1 +
apps/docs/package.json | 3 +
apps/docs/public/components/accordion.md | 9 +
apps/docs/public/components/alert-dialog.md | 9 +
apps/docs/public/components/avatar.md | 9 +
apps/docs/public/components/badge.md | 9 +
apps/docs/public/components/breadcrumbs.md | 9 +
apps/docs/public/components/button.md | 9 +
apps/docs/public/components/calendar.md | 9 +
apps/docs/public/components/callout.md | 9 +
apps/docs/public/components/checkbox.md | 9 +
apps/docs/public/components/collapsible.md | 9 +
.../public/components/collection-controls.md | 9 +
apps/docs/public/components/combobox.md | 9 +
apps/docs/public/components/command-menu.md | 9 +
apps/docs/public/components/composer.md | 9 +
apps/docs/public/components/context-menu.md | 9 +
apps/docs/public/components/data-table.md | 9 +
apps/docs/public/components/dialog.md | 9 +
apps/docs/public/components/drawer.md | 9 +
apps/docs/public/components/empty-state.md | 9 +
apps/docs/public/components/file-upload.md | 9 +
apps/docs/public/components/form.md | 9 +
apps/docs/public/components/icon-button.md | 9 +
apps/docs/public/components/index.md | 50 ++
apps/docs/public/components/input.md | 9 +
apps/docs/public/components/kbd.md | 9 +
apps/docs/public/components/list.md | 9 +
apps/docs/public/components/menu.md | 9 +
apps/docs/public/components/native-select.md | 9 +
apps/docs/public/components/pagination.md | 9 +
apps/docs/public/components/popover.md | 9 +
apps/docs/public/components/progress.md | 9 +
.../docs/public/components/property-picker.md | 9 +
apps/docs/public/components/radio-group.md | 9 +
apps/docs/public/components/search-field.md | 9 +
apps/docs/public/components/select.md | 9 +
apps/docs/public/components/separator.md | 9 +
apps/docs/public/components/sidebar.md | 9 +
apps/docs/public/components/skeleton.md | 9 +
apps/docs/public/components/slider.md | 9 +
apps/docs/public/components/spinner.md | 9 +
apps/docs/public/components/status.md | 9 +
apps/docs/public/components/switch.md | 9 +
apps/docs/public/components/tabs.md | 9 +
apps/docs/public/components/toast.md | 9 +
apps/docs/public/components/toggle-group.md | 9 +
apps/docs/public/components/tooltip.md | 9 +
apps/docs/public/components/tree-view.md | 9 +
apps/docs/public/dependencies.md | 18 +
apps/docs/public/index.md | 8 +
apps/docs/public/llms-full.txt | 570 ++++++++++++++++++
apps/docs/public/llms.txt | 61 ++
apps/docs/scripts/generate-agent-docs.mjs | 189 ++++++
apps/docs/src/docs.css | 89 ++-
apps/docs/src/lib/nav.ts | 16 +-
apps/docs/src/routeTree.gen.ts | 43 ++
apps/docs/src/routes/__root.tsx | 9 +-
.../routes/components/collection-controls.tsx | 194 ++++++
.../docs/src/routes/components/data-table.tsx | 316 ++++++++--
apps/docs/src/routes/components/form.tsx | 122 ++++
apps/docs/src/routes/dependencies.tsx | 7 +-
apps/docs/worker.mjs | 46 ++
apps/docs/wrangler.jsonc | 8 +-
packages/dowel/package.json | 1 +
.../src/components/badge/badge.stylex.ts | 2 +-
.../data-table/data-table.stylex.ts | 110 +++-
.../components/data-table/data-table.test.tsx | 78 +++
.../dowel/src/components/data-table/index.tsx | 549 +++++++++++++++--
.../filter-bar/filter-bar.stylex.ts | 113 ++++
.../components/filter-bar/filter-bar.test.tsx | 36 ++
.../dowel/src/components/filter-bar/index.tsx | 97 +++
.../filter-picker/filter-picker.stylex.ts | 125 ++++
.../filter-picker/filter-picker.test.tsx | 48 ++
.../src/components/filter-picker/index.tsx | 222 +++++++
.../dowel/src/components/form/form.stylex.ts | 22 +
.../dowel/src/components/form/form.test.tsx | 60 ++
packages/dowel/src/components/form/index.tsx | 169 ++++++
.../hover-actions/hover-actions.stylex.ts | 22 +
.../hover-actions/hover-actions.test.tsx | 26 +
.../src/components/hover-actions/index.tsx | 42 ++
packages/dowel/src/components/menu/index.tsx | 3 +-
.../dowel/src/components/menu/menu.stylex.ts | 3 +
.../components/multi-select-toolbar/index.tsx | 52 ++
.../multi-select-toolbar.stylex.ts | 62 ++
.../multi-select-toolbar.test.tsx | 28 +
.../dowel/src/components/popover/index.tsx | 3 +-
.../src/components/popover/popover.stylex.ts | 3 +
.../search-field/search-field.stylex.ts | 4 +
.../src/components/view-options/index.tsx | 267 ++++++++
.../view-options/view-options.stylex.ts | 174 ++++++
.../view-options/view-options.test.tsx | 51 ++
packages/dowel/src/index.ts | 38 ++
packages/dowel/src/theme/themes.stylex.ts | 4 +
packages/dowel/src/theme/tokens.stylex.ts | 2 +
pnpm-lock.yaml | 42 ++
97 files changed, 4506 insertions(+), 122 deletions(-)
create mode 100644 .changeset/linear-collection-views.md
create mode 100644 apps/docs/public/components/accordion.md
create mode 100644 apps/docs/public/components/alert-dialog.md
create mode 100644 apps/docs/public/components/avatar.md
create mode 100644 apps/docs/public/components/badge.md
create mode 100644 apps/docs/public/components/breadcrumbs.md
create mode 100644 apps/docs/public/components/button.md
create mode 100644 apps/docs/public/components/calendar.md
create mode 100644 apps/docs/public/components/callout.md
create mode 100644 apps/docs/public/components/checkbox.md
create mode 100644 apps/docs/public/components/collapsible.md
create mode 100644 apps/docs/public/components/collection-controls.md
create mode 100644 apps/docs/public/components/combobox.md
create mode 100644 apps/docs/public/components/command-menu.md
create mode 100644 apps/docs/public/components/composer.md
create mode 100644 apps/docs/public/components/context-menu.md
create mode 100644 apps/docs/public/components/data-table.md
create mode 100644 apps/docs/public/components/dialog.md
create mode 100644 apps/docs/public/components/drawer.md
create mode 100644 apps/docs/public/components/empty-state.md
create mode 100644 apps/docs/public/components/file-upload.md
create mode 100644 apps/docs/public/components/form.md
create mode 100644 apps/docs/public/components/icon-button.md
create mode 100644 apps/docs/public/components/index.md
create mode 100644 apps/docs/public/components/input.md
create mode 100644 apps/docs/public/components/kbd.md
create mode 100644 apps/docs/public/components/list.md
create mode 100644 apps/docs/public/components/menu.md
create mode 100644 apps/docs/public/components/native-select.md
create mode 100644 apps/docs/public/components/pagination.md
create mode 100644 apps/docs/public/components/popover.md
create mode 100644 apps/docs/public/components/progress.md
create mode 100644 apps/docs/public/components/property-picker.md
create mode 100644 apps/docs/public/components/radio-group.md
create mode 100644 apps/docs/public/components/search-field.md
create mode 100644 apps/docs/public/components/select.md
create mode 100644 apps/docs/public/components/separator.md
create mode 100644 apps/docs/public/components/sidebar.md
create mode 100644 apps/docs/public/components/skeleton.md
create mode 100644 apps/docs/public/components/slider.md
create mode 100644 apps/docs/public/components/spinner.md
create mode 100644 apps/docs/public/components/status.md
create mode 100644 apps/docs/public/components/switch.md
create mode 100644 apps/docs/public/components/tabs.md
create mode 100644 apps/docs/public/components/toast.md
create mode 100644 apps/docs/public/components/toggle-group.md
create mode 100644 apps/docs/public/components/tooltip.md
create mode 100644 apps/docs/public/components/tree-view.md
create mode 100644 apps/docs/public/dependencies.md
create mode 100644 apps/docs/public/index.md
create mode 100644 apps/docs/public/llms-full.txt
create mode 100644 apps/docs/public/llms.txt
create mode 100644 apps/docs/scripts/generate-agent-docs.mjs
create mode 100644 apps/docs/src/routes/components/collection-controls.tsx
create mode 100644 apps/docs/src/routes/components/form.tsx
create mode 100644 apps/docs/worker.mjs
create mode 100644 packages/dowel/src/components/filter-bar/filter-bar.stylex.ts
create mode 100644 packages/dowel/src/components/filter-bar/filter-bar.test.tsx
create mode 100644 packages/dowel/src/components/filter-bar/index.tsx
create mode 100644 packages/dowel/src/components/filter-picker/filter-picker.stylex.ts
create mode 100644 packages/dowel/src/components/filter-picker/filter-picker.test.tsx
create mode 100644 packages/dowel/src/components/filter-picker/index.tsx
create mode 100644 packages/dowel/src/components/form/form.stylex.ts
create mode 100644 packages/dowel/src/components/form/form.test.tsx
create mode 100644 packages/dowel/src/components/form/index.tsx
create mode 100644 packages/dowel/src/components/hover-actions/hover-actions.stylex.ts
create mode 100644 packages/dowel/src/components/hover-actions/hover-actions.test.tsx
create mode 100644 packages/dowel/src/components/hover-actions/index.tsx
create mode 100644 packages/dowel/src/components/multi-select-toolbar/index.tsx
create mode 100644 packages/dowel/src/components/multi-select-toolbar/multi-select-toolbar.stylex.ts
create mode 100644 packages/dowel/src/components/multi-select-toolbar/multi-select-toolbar.test.tsx
create mode 100644 packages/dowel/src/components/view-options/index.tsx
create mode 100644 packages/dowel/src/components/view-options/view-options.stylex.ts
create mode 100644 packages/dowel/src/components/view-options/view-options.test.tsx
diff --git a/.changeset/linear-collection-views.md b/.changeset/linear-collection-views.md
new file mode 100644
index 0000000..4124c04
--- /dev/null
+++ b/.changeset/linear-collection-views.md
@@ -0,0 +1,6 @@
+---
+"@karnstack/dowel": minor
+---
+
+Add collection view controls, advanced DataTable state and interactions, a
+TanStack Form adapter, and a darker dark-mode badge surface.
diff --git a/.gitignore b/.gitignore
index cf06758..8719d87 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@ dist/
# TanStack Start's scratch directory: the SSR bundle it builds only to render
# the prerendered HTML, plus the route generator's temp files.
.tanstack/
+.wrangler/
test-results/
playwright-report/
blob-report/
diff --git a/apps/docs/package.json b/apps/docs/package.json
index 15e1cea..ca99eae 100644
--- a/apps/docs/package.json
+++ b/apps/docs/package.json
@@ -4,7 +4,10 @@
"private": true,
"type": "module",
"scripts": {
+ "agent-docs": "node scripts/generate-agent-docs.mjs",
+ "predev": "pnpm agent-docs",
"dev": "vite dev",
+ "prebuild": "pnpm agent-docs",
"build": "vite build",
"typecheck": "tsc --noEmit",
"test": "echo \"browser accessibility tests run with pnpm test:a11y\" && exit 0",
diff --git a/apps/docs/public/components/accordion.md b/apps/docs/public/components/accordion.md
new file mode 100644
index 0000000..0d406de
--- /dev/null
+++ b/apps/docs/public/components/accordion.md
@@ -0,0 +1,9 @@
+# Accordion
+
+> A keyboard-accessible group of animated disclosure panels.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/accordion)
+- [Markdown documentation](https://dowel.sh/components/accordion.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/alert-dialog.md b/apps/docs/public/components/alert-dialog.md
new file mode 100644
index 0000000..ff286bc
--- /dev/null
+++ b/apps/docs/public/components/alert-dialog.md
@@ -0,0 +1,9 @@
+# Alert Dialog
+
+> A focused confirmation modal for consequential actions.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/alert-dialog)
+- [Markdown documentation](https://dowel.sh/components/alert-dialog.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/avatar.md b/apps/docs/public/components/avatar.md
new file mode 100644
index 0000000..eb6df24
--- /dev/null
+++ b/apps/docs/public/components/avatar.md
@@ -0,0 +1,9 @@
+# Avatar
+
+> An image or initials fallback with shape, size, and presence.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/avatar)
+- [Markdown documentation](https://dowel.sh/components/avatar.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/badge.md b/apps/docs/public/components/badge.md
new file mode 100644
index 0000000..b3828ee
--- /dev/null
+++ b/apps/docs/public/components/badge.md
@@ -0,0 +1,9 @@
+# Badge
+
+> A compact status or metadata pill in five tones.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/badge)
+- [Markdown documentation](https://dowel.sh/components/badge.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/breadcrumbs.md b/apps/docs/public/components/breadcrumbs.md
new file mode 100644
index 0000000..22c42e9
--- /dev/null
+++ b/apps/docs/public/components/breadcrumbs.md
@@ -0,0 +1,9 @@
+# Breadcrumbs
+
+> A compact location trail with automatic middle-item elision.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/breadcrumbs)
+- [Markdown documentation](https://dowel.sh/components/breadcrumbs.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/button.md b/apps/docs/public/components/button.md
new file mode 100644
index 0000000..f1ef950
--- /dev/null
+++ b/apps/docs/public/components/button.md
@@ -0,0 +1,9 @@
+# Button
+
+> The default action control. Five hierarchy levels, two sizes.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/button)
+- [Markdown documentation](https://dowel.sh/components/button.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/calendar.md b/apps/docs/public/components/calendar.md
new file mode 100644
index 0000000..d5fc11a
--- /dev/null
+++ b/apps/docs/public/components/calendar.md
@@ -0,0 +1,9 @@
+# Calendar & Date Picker
+
+> An internationalized month grid and segmented date field.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/calendar)
+- [Markdown documentation](https://dowel.sh/components/calendar.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/callout.md b/apps/docs/public/components/callout.md
new file mode 100644
index 0000000..bb9df69
--- /dev/null
+++ b/apps/docs/public/components/callout.md
@@ -0,0 +1,9 @@
+# Callout
+
+> Persistent contextual guidance with optional actions and tone.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/callout)
+- [Markdown documentation](https://dowel.sh/components/callout.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/checkbox.md b/apps/docs/public/components/checkbox.md
new file mode 100644
index 0000000..a8484a2
--- /dev/null
+++ b/apps/docs/public/components/checkbox.md
@@ -0,0 +1,9 @@
+# Checkbox
+
+> Checked, unchecked, and mixed selection with native form values.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/checkbox)
+- [Markdown documentation](https://dowel.sh/components/checkbox.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/collapsible.md b/apps/docs/public/components/collapsible.md
new file mode 100644
index 0000000..eb28932
--- /dev/null
+++ b/apps/docs/public/components/collapsible.md
@@ -0,0 +1,9 @@
+# Collapsible
+
+> An animated disclosure for one optional content region.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/collapsible)
+- [Markdown documentation](https://dowel.sh/components/collapsible.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/collection-controls.md b/apps/docs/public/components/collection-controls.md
new file mode 100644
index 0000000..b75cca1
--- /dev/null
+++ b/apps/docs/public/components/collection-controls.md
@@ -0,0 +1,9 @@
+# Collection Controls
+
+> Filters, view options, row actions, and bulk selection controls.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/collection-controls)
+- [Markdown documentation](https://dowel.sh/components/collection-controls.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/combobox.md b/apps/docs/public/components/combobox.md
new file mode 100644
index 0000000..41af427
--- /dev/null
+++ b/apps/docs/public/components/combobox.md
@@ -0,0 +1,9 @@
+# Combobox
+
+> A filterable single-choice field for larger collections.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/combobox)
+- [Markdown documentation](https://dowel.sh/components/combobox.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/command-menu.md b/apps/docs/public/components/command-menu.md
new file mode 100644
index 0000000..086b1b1
--- /dev/null
+++ b/apps/docs/public/components/command-menu.md
@@ -0,0 +1,9 @@
+# Command Menu
+
+> A modal search surface for grouped application commands.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/command-menu)
+- [Markdown documentation](https://dowel.sh/components/command-menu.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/composer.md b/apps/docs/public/components/composer.md
new file mode 100644
index 0000000..d7e657d
--- /dev/null
+++ b/apps/docs/public/components/composer.md
@@ -0,0 +1,9 @@
+# Composer
+
+> A borderless creation shell with metadata and action regions.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/composer)
+- [Markdown documentation](https://dowel.sh/components/composer.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/context-menu.md b/apps/docs/public/components/context-menu.md
new file mode 100644
index 0000000..8c70357
--- /dev/null
+++ b/apps/docs/public/components/context-menu.md
@@ -0,0 +1,9 @@
+# Context Menu
+
+> A pointer-positioned menu for actions on a target surface.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/context-menu)
+- [Markdown documentation](https://dowel.sh/components/context-menu.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/data-table.md b/apps/docs/public/components/data-table.md
new file mode 100644
index 0000000..2f23590
--- /dev/null
+++ b/apps/docs/public/components/data-table.md
@@ -0,0 +1,9 @@
+# Data Table
+
+> A borderless, sortable, selectable, and resizable data table.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/data-table)
+- [Markdown documentation](https://dowel.sh/components/data-table.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/dialog.md b/apps/docs/public/components/dialog.md
new file mode 100644
index 0000000..850f3dd
--- /dev/null
+++ b/apps/docs/public/components/dialog.md
@@ -0,0 +1,9 @@
+# Dialog
+
+> A modal on the modal elevation tier, labelled by its title.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/dialog)
+- [Markdown documentation](https://dowel.sh/components/dialog.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/drawer.md b/apps/docs/public/components/drawer.md
new file mode 100644
index 0000000..28aa8d2
--- /dev/null
+++ b/apps/docs/public/components/drawer.md
@@ -0,0 +1,9 @@
+# Drawer
+
+> A swipe-dismissable edge panel for navigation and detail.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/drawer)
+- [Markdown documentation](https://dowel.sh/components/drawer.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/empty-state.md b/apps/docs/public/components/empty-state.md
new file mode 100644
index 0000000..a041176
--- /dev/null
+++ b/apps/docs/public/components/empty-state.md
@@ -0,0 +1,9 @@
+# Empty State
+
+> Structured guidance and actions for a surface without content.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/empty-state)
+- [Markdown documentation](https://dowel.sh/components/empty-state.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/file-upload.md b/apps/docs/public/components/file-upload.md
new file mode 100644
index 0000000..b873239
--- /dev/null
+++ b/apps/docs/public/components/file-upload.md
@@ -0,0 +1,9 @@
+# File Upload
+
+> A native file picker and dropzone with built-in validation.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/file-upload)
+- [Markdown documentation](https://dowel.sh/components/file-upload.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/form.md b/apps/docs/public/components/form.md
new file mode 100644
index 0000000..8d75b05
--- /dev/null
+++ b/apps/docs/public/components/form.md
@@ -0,0 +1,9 @@
+# Form
+
+> TanStack Form with Dowel fields and actions pre-bound.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/form)
+- [Markdown documentation](https://dowel.sh/components/form.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/icon-button.md b/apps/docs/public/components/icon-button.md
new file mode 100644
index 0000000..dd4a333
--- /dev/null
+++ b/apps/docs/public/components/icon-button.md
@@ -0,0 +1,9 @@
+# Icon Button
+
+> A square control for a single icon, with a required label.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/icon-button)
+- [Markdown documentation](https://dowel.sh/components/icon-button.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/index.md b/apps/docs/public/components/index.md
new file mode 100644
index 0000000..d68bbaa
--- /dev/null
+++ b/apps/docs/public/components/index.md
@@ -0,0 +1,50 @@
+# Dowel components
+
+> The complete Dowel component catalog.
+
+- [Accordion](https://dowel.sh/components/accordion.md): A keyboard-accessible group of animated disclosure panels.
+- [Alert Dialog](https://dowel.sh/components/alert-dialog.md): A focused confirmation modal for consequential actions.
+- [Avatar](https://dowel.sh/components/avatar.md): An image or initials fallback with shape, size, and presence.
+- [Badge](https://dowel.sh/components/badge.md): A compact status or metadata pill in five tones.
+- [Breadcrumbs](https://dowel.sh/components/breadcrumbs.md): A compact location trail with automatic middle-item elision.
+- [Button](https://dowel.sh/components/button.md): The default action control. Five hierarchy levels, two sizes.
+- [Calendar & Date Picker](https://dowel.sh/components/calendar.md): An internationalized month grid and segmented date field.
+- [Callout](https://dowel.sh/components/callout.md): Persistent contextual guidance with optional actions and tone.
+- [Checkbox](https://dowel.sh/components/checkbox.md): Checked, unchecked, and mixed selection with native form values.
+- [Collapsible](https://dowel.sh/components/collapsible.md): An animated disclosure for one optional content region.
+- [Combobox](https://dowel.sh/components/combobox.md): A filterable single-choice field for larger collections.
+- [Command Menu](https://dowel.sh/components/command-menu.md): A modal search surface for grouped application commands.
+- [Collection Controls](https://dowel.sh/components/collection-controls.md): Filters, view options, row actions, and bulk selection controls.
+- [Composer](https://dowel.sh/components/composer.md): A borderless creation shell with metadata and action regions.
+- [Context Menu](https://dowel.sh/components/context-menu.md): A pointer-positioned menu for actions on a target surface.
+- [Data Table](https://dowel.sh/components/data-table.md): A borderless, sortable, selectable, and resizable data table.
+- [Dialog](https://dowel.sh/components/dialog.md): A modal on the modal elevation tier, labelled by its title.
+- [Drawer](https://dowel.sh/components/drawer.md): A swipe-dismissable edge panel for navigation and detail.
+- [Empty State](https://dowel.sh/components/empty-state.md): Structured guidance and actions for a surface without content.
+- [File Upload](https://dowel.sh/components/file-upload.md): A native file picker and dropzone with built-in validation.
+- [Form](https://dowel.sh/components/form.md): TanStack Form with Dowel fields and actions pre-bound.
+- [Icon Button](https://dowel.sh/components/icon-button.md): A square control for a single icon, with a required label.
+- [Input](https://dowel.sh/components/input.md): Surface and borderless fields for settings and rich composers.
+- [Kbd](https://dowel.sh/components/kbd.md): A keyboard shortcut rendered one key per cap.
+- [List](https://dowel.sh/components/list.md): Semantic grouped rows with cells, density, and selection.
+- [Menu](https://dowel.sh/components/menu.md): A dropdown with keyboard navigation and typeahead.
+- [Native Select](https://dowel.sh/components/native-select.md): A resilient native choice control with Dowel field styling.
+- [Pagination](https://dowel.sh/components/pagination.md): Controlled page navigation with compact number elision.
+- [Popover](https://dowel.sh/components/popover.md): An anchored surface for interactive controls and rich details.
+- [Property Picker](https://dowel.sh/components/property-picker.md): Searchable grouped metadata selection with a compact pill trigger.
+- [Progress](https://dowel.sh/components/progress.md): Determinate and indeterminate progress for long tasks.
+- [Radio Group](https://dowel.sh/components/radio-group.md): A single-choice group with native forms and arrow-key selection.
+- [Search Field](https://dowel.sh/components/search-field.md): A search input with icon, clear action, and shortcut hint.
+- [Separator](https://dowel.sh/components/separator.md): A quiet horizontal or vertical content divider.
+- [Select](https://dowel.sh/components/select.md): A grouped single-choice popup with native form submission.
+- [Sidebar](https://dowel.sh/components/sidebar.md): A responsive application rail with pointer and keyboard resize.
+- [Slider](https://dowel.sh/components/slider.md): A pointer and keyboard control for a numeric range.
+- [Skeleton](https://dowel.sh/components/skeleton.md): Reduced-motion-aware placeholders for pending content.
+- [Spinner](https://dowel.sh/components/spinner.md): Accessible indeterminate progress in three compact sizes.
+- [Status](https://dowel.sh/components/status.md): A lightweight state icon and label in semantic tones.
+- [Switch](https://dowel.sh/components/switch.md): A compact immediate setting for binary on and off state.
+- [Tabs](https://dowel.sh/components/tabs.md): Compact pill and line view switching with arrow-key activation.
+- [Toast](https://dowel.sh/components/toast.md): A global notification queue with actions and promises.
+- [Toggle Group](https://dowel.sh/components/toggle-group.md): A connected set of independently pressed view controls.
+- [Tooltip](https://dowel.sh/components/tooltip.md): A hover and focus label on the popover elevation tier.
+- [Tree View](https://dowel.sh/components/tree-view.md): A nested hierarchy with selection and keyboard navigation.
diff --git a/apps/docs/public/components/input.md b/apps/docs/public/components/input.md
new file mode 100644
index 0000000..cb4c836
--- /dev/null
+++ b/apps/docs/public/components/input.md
@@ -0,0 +1,9 @@
+# Input
+
+> Surface and borderless fields for settings and rich composers.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/input)
+- [Markdown documentation](https://dowel.sh/components/input.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/kbd.md b/apps/docs/public/components/kbd.md
new file mode 100644
index 0000000..2930898
--- /dev/null
+++ b/apps/docs/public/components/kbd.md
@@ -0,0 +1,9 @@
+# Kbd
+
+> A keyboard shortcut rendered one key per cap.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/kbd)
+- [Markdown documentation](https://dowel.sh/components/kbd.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/list.md b/apps/docs/public/components/list.md
new file mode 100644
index 0000000..f163972
--- /dev/null
+++ b/apps/docs/public/components/list.md
@@ -0,0 +1,9 @@
+# List
+
+> Semantic grouped rows with cells, density, and selection.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/list)
+- [Markdown documentation](https://dowel.sh/components/list.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/menu.md b/apps/docs/public/components/menu.md
new file mode 100644
index 0000000..a163b87
--- /dev/null
+++ b/apps/docs/public/components/menu.md
@@ -0,0 +1,9 @@
+# Menu
+
+> A dropdown with keyboard navigation and typeahead.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/menu)
+- [Markdown documentation](https://dowel.sh/components/menu.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/native-select.md b/apps/docs/public/components/native-select.md
new file mode 100644
index 0000000..e6f1824
--- /dev/null
+++ b/apps/docs/public/components/native-select.md
@@ -0,0 +1,9 @@
+# Native Select
+
+> A resilient native choice control with Dowel field styling.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/native-select)
+- [Markdown documentation](https://dowel.sh/components/native-select.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/pagination.md b/apps/docs/public/components/pagination.md
new file mode 100644
index 0000000..723e01b
--- /dev/null
+++ b/apps/docs/public/components/pagination.md
@@ -0,0 +1,9 @@
+# Pagination
+
+> Controlled page navigation with compact number elision.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/pagination)
+- [Markdown documentation](https://dowel.sh/components/pagination.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/popover.md b/apps/docs/public/components/popover.md
new file mode 100644
index 0000000..0a7d2fc
--- /dev/null
+++ b/apps/docs/public/components/popover.md
@@ -0,0 +1,9 @@
+# Popover
+
+> An anchored surface for interactive controls and rich details.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/popover)
+- [Markdown documentation](https://dowel.sh/components/popover.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/progress.md b/apps/docs/public/components/progress.md
new file mode 100644
index 0000000..7a6c490
--- /dev/null
+++ b/apps/docs/public/components/progress.md
@@ -0,0 +1,9 @@
+# Progress
+
+> Determinate and indeterminate progress for long tasks.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/progress)
+- [Markdown documentation](https://dowel.sh/components/progress.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/property-picker.md b/apps/docs/public/components/property-picker.md
new file mode 100644
index 0000000..d8e8d6c
--- /dev/null
+++ b/apps/docs/public/components/property-picker.md
@@ -0,0 +1,9 @@
+# Property Picker
+
+> Searchable grouped metadata selection with a compact pill trigger.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/property-picker)
+- [Markdown documentation](https://dowel.sh/components/property-picker.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/radio-group.md b/apps/docs/public/components/radio-group.md
new file mode 100644
index 0000000..f203891
--- /dev/null
+++ b/apps/docs/public/components/radio-group.md
@@ -0,0 +1,9 @@
+# Radio Group
+
+> A single-choice group with native forms and arrow-key selection.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/radio-group)
+- [Markdown documentation](https://dowel.sh/components/radio-group.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/search-field.md b/apps/docs/public/components/search-field.md
new file mode 100644
index 0000000..a380ea4
--- /dev/null
+++ b/apps/docs/public/components/search-field.md
@@ -0,0 +1,9 @@
+# Search Field
+
+> A search input with icon, clear action, and shortcut hint.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/search-field)
+- [Markdown documentation](https://dowel.sh/components/search-field.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/select.md b/apps/docs/public/components/select.md
new file mode 100644
index 0000000..f8132fd
--- /dev/null
+++ b/apps/docs/public/components/select.md
@@ -0,0 +1,9 @@
+# Select
+
+> A grouped single-choice popup with native form submission.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/select)
+- [Markdown documentation](https://dowel.sh/components/select.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/separator.md b/apps/docs/public/components/separator.md
new file mode 100644
index 0000000..487fe98
--- /dev/null
+++ b/apps/docs/public/components/separator.md
@@ -0,0 +1,9 @@
+# Separator
+
+> A quiet horizontal or vertical content divider.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/separator)
+- [Markdown documentation](https://dowel.sh/components/separator.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/sidebar.md b/apps/docs/public/components/sidebar.md
new file mode 100644
index 0000000..a9a563b
--- /dev/null
+++ b/apps/docs/public/components/sidebar.md
@@ -0,0 +1,9 @@
+# Sidebar
+
+> A responsive application rail with pointer and keyboard resize.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/sidebar)
+- [Markdown documentation](https://dowel.sh/components/sidebar.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/skeleton.md b/apps/docs/public/components/skeleton.md
new file mode 100644
index 0000000..f5b72c2
--- /dev/null
+++ b/apps/docs/public/components/skeleton.md
@@ -0,0 +1,9 @@
+# Skeleton
+
+> Reduced-motion-aware placeholders for pending content.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/skeleton)
+- [Markdown documentation](https://dowel.sh/components/skeleton.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/slider.md b/apps/docs/public/components/slider.md
new file mode 100644
index 0000000..8f32458
--- /dev/null
+++ b/apps/docs/public/components/slider.md
@@ -0,0 +1,9 @@
+# Slider
+
+> A pointer and keyboard control for a numeric range.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/slider)
+- [Markdown documentation](https://dowel.sh/components/slider.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/spinner.md b/apps/docs/public/components/spinner.md
new file mode 100644
index 0000000..78a0846
--- /dev/null
+++ b/apps/docs/public/components/spinner.md
@@ -0,0 +1,9 @@
+# Spinner
+
+> Accessible indeterminate progress in three compact sizes.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/spinner)
+- [Markdown documentation](https://dowel.sh/components/spinner.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/status.md b/apps/docs/public/components/status.md
new file mode 100644
index 0000000..c2f6832
--- /dev/null
+++ b/apps/docs/public/components/status.md
@@ -0,0 +1,9 @@
+# Status
+
+> A lightweight state icon and label in semantic tones.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/status)
+- [Markdown documentation](https://dowel.sh/components/status.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/switch.md b/apps/docs/public/components/switch.md
new file mode 100644
index 0000000..9f9ccf6
--- /dev/null
+++ b/apps/docs/public/components/switch.md
@@ -0,0 +1,9 @@
+# Switch
+
+> A compact immediate setting for binary on and off state.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/switch)
+- [Markdown documentation](https://dowel.sh/components/switch.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/tabs.md b/apps/docs/public/components/tabs.md
new file mode 100644
index 0000000..8ef0140
--- /dev/null
+++ b/apps/docs/public/components/tabs.md
@@ -0,0 +1,9 @@
+# Tabs
+
+> Compact pill and line view switching with arrow-key activation.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/tabs)
+- [Markdown documentation](https://dowel.sh/components/tabs.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/toast.md b/apps/docs/public/components/toast.md
new file mode 100644
index 0000000..7afe492
--- /dev/null
+++ b/apps/docs/public/components/toast.md
@@ -0,0 +1,9 @@
+# Toast
+
+> A global notification queue with actions and promises.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/toast)
+- [Markdown documentation](https://dowel.sh/components/toast.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/toggle-group.md b/apps/docs/public/components/toggle-group.md
new file mode 100644
index 0000000..626262b
--- /dev/null
+++ b/apps/docs/public/components/toggle-group.md
@@ -0,0 +1,9 @@
+# Toggle Group
+
+> A connected set of independently pressed view controls.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/toggle-group)
+- [Markdown documentation](https://dowel.sh/components/toggle-group.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/tooltip.md b/apps/docs/public/components/tooltip.md
new file mode 100644
index 0000000..036272f
--- /dev/null
+++ b/apps/docs/public/components/tooltip.md
@@ -0,0 +1,9 @@
+# Tooltip
+
+> A hover and focus label on the popover elevation tier.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/tooltip)
+- [Markdown documentation](https://dowel.sh/components/tooltip.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/components/tree-view.md b/apps/docs/public/components/tree-view.md
new file mode 100644
index 0000000..6af75a2
--- /dev/null
+++ b/apps/docs/public/components/tree-view.md
@@ -0,0 +1,9 @@
+# Tree View
+
+> A nested hierarchy with selection and keyboard navigation.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/tree-view)
+- [Markdown documentation](https://dowel.sh/components/tree-view.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/dependencies.md b/apps/docs/public/dependencies.md
new file mode 100644
index 0000000..e68a1fa
--- /dev/null
+++ b/apps/docs/public/dependencies.md
@@ -0,0 +1,18 @@
+# Dowel dependencies
+
+> Runtime packages installed with Dowel and peer runtimes owned by the consuming application.
+
+## Runtime dependencies
+
+- `@base-ui/react`: `^1.7.0`
+- `@heroicons/react`: `2.2.0`
+- `@internationalized/date`: `^3.12.3`
+- `@stylexjs/stylex`: `0.19.0`
+- `@tanstack/react-form`: `^1.33.5`
+- `@tanstack/react-table`: `^9.1.2`
+- `react-aria-components`: `^1.20.0`
+
+## Peer dependencies
+
+- `react`: `^19.0.0`
+- `react-dom`: `^19.0.0`
diff --git a/apps/docs/public/index.md b/apps/docs/public/index.md
new file mode 100644
index 0000000..a92514b
--- /dev/null
+++ b/apps/docs/public/index.md
@@ -0,0 +1,8 @@
+# Dowel
+
+> Compact, accessible React components for product interfaces.
+
+- [Agent documentation index](https://dowel.sh/llms.txt)
+- [Complete agent documentation](https://dowel.sh/llms-full.txt)
+- [Component catalog](https://dowel.sh/components/index.md)
+- [HTML documentation](https://dowel.sh/components)
diff --git a/apps/docs/public/llms-full.txt b/apps/docs/public/llms-full.txt
new file mode 100644
index 0000000..0181d31
--- /dev/null
+++ b/apps/docs/public/llms-full.txt
@@ -0,0 +1,570 @@
+# Dowel complete documentation
+
+> Dowel 0.2.0 is an opinionated React component library for compact, accessible product interfaces.
+
+## Installation
+
+```sh
+pnpm add @karnstack/dowel
+```
+
+```tsx
+import "@karnstack/dowel/dowel.css";
+```
+
+## Conventions
+
+- Import public components and types from `@karnstack/dowel`.
+- Wrap the application in `ThemeProvider` when selecting light, dark, or system themes explicitly.
+- Dowel controls own their appearance. Prefer documented props over consumer class or style overrides.
+- Icon-only controls require an accessible `label`.
+
+## Accordion
+
+> A keyboard-accessible group of animated disclosure panels.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/accordion)
+- [Markdown documentation](https://dowel.sh/components/accordion.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Alert Dialog
+
+> A focused confirmation modal for consequential actions.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/alert-dialog)
+- [Markdown documentation](https://dowel.sh/components/alert-dialog.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Avatar
+
+> An image or initials fallback with shape, size, and presence.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/avatar)
+- [Markdown documentation](https://dowel.sh/components/avatar.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Badge
+
+> A compact status or metadata pill in five tones.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/badge)
+- [Markdown documentation](https://dowel.sh/components/badge.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Breadcrumbs
+
+> A compact location trail with automatic middle-item elision.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/breadcrumbs)
+- [Markdown documentation](https://dowel.sh/components/breadcrumbs.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Button
+
+> The default action control. Five hierarchy levels, two sizes.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/button)
+- [Markdown documentation](https://dowel.sh/components/button.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Calendar & Date Picker
+
+> An internationalized month grid and segmented date field.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/calendar)
+- [Markdown documentation](https://dowel.sh/components/calendar.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Callout
+
+> Persistent contextual guidance with optional actions and tone.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/callout)
+- [Markdown documentation](https://dowel.sh/components/callout.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Checkbox
+
+> Checked, unchecked, and mixed selection with native form values.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/checkbox)
+- [Markdown documentation](https://dowel.sh/components/checkbox.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Collapsible
+
+> An animated disclosure for one optional content region.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/collapsible)
+- [Markdown documentation](https://dowel.sh/components/collapsible.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Combobox
+
+> A filterable single-choice field for larger collections.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/combobox)
+- [Markdown documentation](https://dowel.sh/components/combobox.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Command Menu
+
+> A modal search surface for grouped application commands.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/command-menu)
+- [Markdown documentation](https://dowel.sh/components/command-menu.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Collection Controls
+
+> Filters, view options, row actions, and bulk selection controls.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/collection-controls)
+- [Markdown documentation](https://dowel.sh/components/collection-controls.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Composer
+
+> A borderless creation shell with metadata and action regions.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/composer)
+- [Markdown documentation](https://dowel.sh/components/composer.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Context Menu
+
+> A pointer-positioned menu for actions on a target surface.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/context-menu)
+- [Markdown documentation](https://dowel.sh/components/context-menu.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Data Table
+
+> A borderless, sortable, selectable, and resizable data table.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/data-table)
+- [Markdown documentation](https://dowel.sh/components/data-table.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Dialog
+
+> A modal on the modal elevation tier, labelled by its title.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/dialog)
+- [Markdown documentation](https://dowel.sh/components/dialog.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Drawer
+
+> A swipe-dismissable edge panel for navigation and detail.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/drawer)
+- [Markdown documentation](https://dowel.sh/components/drawer.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Empty State
+
+> Structured guidance and actions for a surface without content.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/empty-state)
+- [Markdown documentation](https://dowel.sh/components/empty-state.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## File Upload
+
+> A native file picker and dropzone with built-in validation.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/file-upload)
+- [Markdown documentation](https://dowel.sh/components/file-upload.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Form
+
+> TanStack Form with Dowel fields and actions pre-bound.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/form)
+- [Markdown documentation](https://dowel.sh/components/form.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Icon Button
+
+> A square control for a single icon, with a required label.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/icon-button)
+- [Markdown documentation](https://dowel.sh/components/icon-button.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Input
+
+> Surface and borderless fields for settings and rich composers.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/input)
+- [Markdown documentation](https://dowel.sh/components/input.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Kbd
+
+> A keyboard shortcut rendered one key per cap.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/kbd)
+- [Markdown documentation](https://dowel.sh/components/kbd.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## List
+
+> Semantic grouped rows with cells, density, and selection.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/list)
+- [Markdown documentation](https://dowel.sh/components/list.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Menu
+
+> A dropdown with keyboard navigation and typeahead.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/menu)
+- [Markdown documentation](https://dowel.sh/components/menu.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Native Select
+
+> A resilient native choice control with Dowel field styling.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/native-select)
+- [Markdown documentation](https://dowel.sh/components/native-select.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Pagination
+
+> Controlled page navigation with compact number elision.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/pagination)
+- [Markdown documentation](https://dowel.sh/components/pagination.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Popover
+
+> An anchored surface for interactive controls and rich details.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/popover)
+- [Markdown documentation](https://dowel.sh/components/popover.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Property Picker
+
+> Searchable grouped metadata selection with a compact pill trigger.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/property-picker)
+- [Markdown documentation](https://dowel.sh/components/property-picker.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Progress
+
+> Determinate and indeterminate progress for long tasks.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/progress)
+- [Markdown documentation](https://dowel.sh/components/progress.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Radio Group
+
+> A single-choice group with native forms and arrow-key selection.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/radio-group)
+- [Markdown documentation](https://dowel.sh/components/radio-group.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Search Field
+
+> A search input with icon, clear action, and shortcut hint.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/search-field)
+- [Markdown documentation](https://dowel.sh/components/search-field.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Separator
+
+> A quiet horizontal or vertical content divider.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/separator)
+- [Markdown documentation](https://dowel.sh/components/separator.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Select
+
+> A grouped single-choice popup with native form submission.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/select)
+- [Markdown documentation](https://dowel.sh/components/select.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Sidebar
+
+> A responsive application rail with pointer and keyboard resize.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/sidebar)
+- [Markdown documentation](https://dowel.sh/components/sidebar.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Slider
+
+> A pointer and keyboard control for a numeric range.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/slider)
+- [Markdown documentation](https://dowel.sh/components/slider.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Skeleton
+
+> Reduced-motion-aware placeholders for pending content.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/skeleton)
+- [Markdown documentation](https://dowel.sh/components/skeleton.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Spinner
+
+> Accessible indeterminate progress in three compact sizes.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/spinner)
+- [Markdown documentation](https://dowel.sh/components/spinner.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Status
+
+> A lightweight state icon and label in semantic tones.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/status)
+- [Markdown documentation](https://dowel.sh/components/status.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Switch
+
+> A compact immediate setting for binary on and off state.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/switch)
+- [Markdown documentation](https://dowel.sh/components/switch.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Tabs
+
+> Compact pill and line view switching with arrow-key activation.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/tabs)
+- [Markdown documentation](https://dowel.sh/components/tabs.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Toast
+
+> A global notification queue with actions and promises.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/toast)
+- [Markdown documentation](https://dowel.sh/components/toast.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Toggle Group
+
+> A connected set of independently pressed view controls.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/toggle-group)
+- [Markdown documentation](https://dowel.sh/components/toggle-group.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Tooltip
+
+> A hover and focus label on the popover elevation tier.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/tooltip)
+- [Markdown documentation](https://dowel.sh/components/tooltip.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
+
+---
+
+## Tree View
+
+> A nested hierarchy with selection and keyboard navigation.
+
+- Package: `@karnstack/dowel`
+- [HTML documentation](https://dowel.sh/components/tree-view)
+- [Markdown documentation](https://dowel.sh/components/tree-view.md)
+
+Import public components and types from the package root. Import `@karnstack/dowel/dowel.css` once at the application root.
diff --git a/apps/docs/public/llms.txt b/apps/docs/public/llms.txt
new file mode 100644
index 0000000..4a76e4c
--- /dev/null
+++ b/apps/docs/public/llms.txt
@@ -0,0 +1,61 @@
+# Dowel
+
+> Dowel is an opinionated React component library for compact, accessible product interfaces.
+
+Install `@karnstack/dowel`, import `@karnstack/dowel/dowel.css` once, and import components from the package root. Dowel targets React 19.
+
+## Components
+
+- [Accordion](https://dowel.sh/components/accordion.md): A keyboard-accessible group of animated disclosure panels.
+- [Alert Dialog](https://dowel.sh/components/alert-dialog.md): A focused confirmation modal for consequential actions.
+- [Avatar](https://dowel.sh/components/avatar.md): An image or initials fallback with shape, size, and presence.
+- [Badge](https://dowel.sh/components/badge.md): A compact status or metadata pill in five tones.
+- [Breadcrumbs](https://dowel.sh/components/breadcrumbs.md): A compact location trail with automatic middle-item elision.
+- [Button](https://dowel.sh/components/button.md): The default action control. Five hierarchy levels, two sizes.
+- [Calendar & Date Picker](https://dowel.sh/components/calendar.md): An internationalized month grid and segmented date field.
+- [Callout](https://dowel.sh/components/callout.md): Persistent contextual guidance with optional actions and tone.
+- [Checkbox](https://dowel.sh/components/checkbox.md): Checked, unchecked, and mixed selection with native form values.
+- [Collapsible](https://dowel.sh/components/collapsible.md): An animated disclosure for one optional content region.
+- [Combobox](https://dowel.sh/components/combobox.md): A filterable single-choice field for larger collections.
+- [Command Menu](https://dowel.sh/components/command-menu.md): A modal search surface for grouped application commands.
+- [Collection Controls](https://dowel.sh/components/collection-controls.md): Filters, view options, row actions, and bulk selection controls.
+- [Composer](https://dowel.sh/components/composer.md): A borderless creation shell with metadata and action regions.
+- [Context Menu](https://dowel.sh/components/context-menu.md): A pointer-positioned menu for actions on a target surface.
+- [Data Table](https://dowel.sh/components/data-table.md): A borderless, sortable, selectable, and resizable data table.
+- [Dialog](https://dowel.sh/components/dialog.md): A modal on the modal elevation tier, labelled by its title.
+- [Drawer](https://dowel.sh/components/drawer.md): A swipe-dismissable edge panel for navigation and detail.
+- [Empty State](https://dowel.sh/components/empty-state.md): Structured guidance and actions for a surface without content.
+- [File Upload](https://dowel.sh/components/file-upload.md): A native file picker and dropzone with built-in validation.
+- [Form](https://dowel.sh/components/form.md): TanStack Form with Dowel fields and actions pre-bound.
+- [Icon Button](https://dowel.sh/components/icon-button.md): A square control for a single icon, with a required label.
+- [Input](https://dowel.sh/components/input.md): Surface and borderless fields for settings and rich composers.
+- [Kbd](https://dowel.sh/components/kbd.md): A keyboard shortcut rendered one key per cap.
+- [List](https://dowel.sh/components/list.md): Semantic grouped rows with cells, density, and selection.
+- [Menu](https://dowel.sh/components/menu.md): A dropdown with keyboard navigation and typeahead.
+- [Native Select](https://dowel.sh/components/native-select.md): A resilient native choice control with Dowel field styling.
+- [Pagination](https://dowel.sh/components/pagination.md): Controlled page navigation with compact number elision.
+- [Popover](https://dowel.sh/components/popover.md): An anchored surface for interactive controls and rich details.
+- [Property Picker](https://dowel.sh/components/property-picker.md): Searchable grouped metadata selection with a compact pill trigger.
+- [Progress](https://dowel.sh/components/progress.md): Determinate and indeterminate progress for long tasks.
+- [Radio Group](https://dowel.sh/components/radio-group.md): A single-choice group with native forms and arrow-key selection.
+- [Search Field](https://dowel.sh/components/search-field.md): A search input with icon, clear action, and shortcut hint.
+- [Separator](https://dowel.sh/components/separator.md): A quiet horizontal or vertical content divider.
+- [Select](https://dowel.sh/components/select.md): A grouped single-choice popup with native form submission.
+- [Sidebar](https://dowel.sh/components/sidebar.md): A responsive application rail with pointer and keyboard resize.
+- [Slider](https://dowel.sh/components/slider.md): A pointer and keyboard control for a numeric range.
+- [Skeleton](https://dowel.sh/components/skeleton.md): Reduced-motion-aware placeholders for pending content.
+- [Spinner](https://dowel.sh/components/spinner.md): Accessible indeterminate progress in three compact sizes.
+- [Status](https://dowel.sh/components/status.md): A lightweight state icon and label in semantic tones.
+- [Switch](https://dowel.sh/components/switch.md): A compact immediate setting for binary on and off state.
+- [Tabs](https://dowel.sh/components/tabs.md): Compact pill and line view switching with arrow-key activation.
+- [Toast](https://dowel.sh/components/toast.md): A global notification queue with actions and promises.
+- [Toggle Group](https://dowel.sh/components/toggle-group.md): A connected set of independently pressed view controls.
+- [Tooltip](https://dowel.sh/components/tooltip.md): A hover and focus label on the popover elevation tier.
+- [Tree View](https://dowel.sh/components/tree-view.md): A nested hierarchy with selection and keyboard navigation.
+
+## Library
+
+- [Complete documentation](https://dowel.sh/llms-full.txt): All component summaries in one Markdown document.
+- [Component index](https://dowel.sh/components/index.md): Compact component catalog.
+- [Dependencies](https://dowel.sh/dependencies.md): Runtime and peer dependency overview.
+- [GitHub](https://github.com/karnstack/dowel): Source, issues, and releases.
diff --git a/apps/docs/scripts/generate-agent-docs.mjs b/apps/docs/scripts/generate-agent-docs.mjs
new file mode 100644
index 0000000..0a8d204
--- /dev/null
+++ b/apps/docs/scripts/generate-agent-docs.mjs
@@ -0,0 +1,189 @@
+import { mkdir, readFile, writeFile } from "node:fs/promises";
+
+import { componentNav } from "../src/lib/nav.ts";
+
+const docsOrigin = "https://dowel.sh";
+const publicRoot = new URL("../public/", import.meta.url);
+const packageRoot = new URL("../../../packages/dowel/", import.meta.url);
+const tick = String.fromCharCode(96);
+
+function absolute(path) {
+ return new URL(path, docsOrigin).href;
+}
+
+function componentSlug(item) {
+ return String(item.to).replace("/components/", "");
+}
+
+function componentMarkdown(item, heading = "#") {
+ const docsUrl = absolute(String(item.to));
+ const markdownUrl = absolute(String(item.to) + ".md");
+ return [
+ heading + " " + item.title,
+ "",
+ "> " + item.summary,
+ "",
+ "- Package: " + tick + "@karnstack/dowel" + tick,
+ "- [HTML documentation](" + docsUrl + ")",
+ "- [Markdown documentation](" + markdownUrl + ")",
+ "",
+ "Import public components and types from the package root. Import " +
+ tick +
+ "@karnstack/dowel/dowel.css" +
+ tick +
+ " once at the application root.",
+ ].join("\n");
+}
+
+await mkdir(new URL("components/", publicRoot), { recursive: true });
+
+for (const item of componentNav) {
+ await writeFile(
+ new URL("components/" + componentSlug(item) + ".md", publicRoot),
+ componentMarkdown(item) + "\n",
+ );
+}
+
+const packageMetadata = JSON.parse(
+ await readFile(new URL("package.json", packageRoot), "utf8"),
+);
+const componentLinks = componentNav
+ .map(
+ (item) =>
+ "- [" +
+ item.title +
+ "](" +
+ absolute(String(item.to) + ".md") +
+ "): " +
+ item.summary,
+ )
+ .join("\n");
+
+const llms = [
+ "# Dowel",
+ "",
+ "> Dowel is an opinionated React component library for compact, accessible product interfaces.",
+ "",
+ "Install " +
+ tick +
+ "@karnstack/dowel" +
+ tick +
+ ", import " +
+ tick +
+ "@karnstack/dowel/dowel.css" +
+ tick +
+ " once, and import components from the package root. Dowel targets React 19.",
+ "",
+ "## Components",
+ "",
+ componentLinks,
+ "",
+ "## Library",
+ "",
+ "- [Complete documentation](" +
+ absolute("/llms-full.txt") +
+ "): All component summaries in one Markdown document.",
+ "- [Component index](" +
+ absolute("/components/index.md") +
+ "): Compact component catalog.",
+ "- [Dependencies](" +
+ absolute("/dependencies.md") +
+ "): Runtime and peer dependency overview.",
+ "- [GitHub](https://github.com/karnstack/dowel): Source, issues, and releases.",
+ "",
+].join("\n");
+
+const componentDocs = componentNav
+ .map((item) => componentMarkdown(item, "##"))
+ .join("\n\n---\n\n");
+const llmsFull = [
+ "# Dowel complete documentation",
+ "",
+ "> Dowel " +
+ packageMetadata.version +
+ " is an opinionated React component library for compact, accessible product interfaces.",
+ "",
+ "## Installation",
+ "",
+ tick.repeat(3) + "sh",
+ "pnpm add @karnstack/dowel",
+ tick.repeat(3),
+ "",
+ tick.repeat(3) + "tsx",
+ 'import "@karnstack/dowel/dowel.css";',
+ tick.repeat(3),
+ "",
+ "## Conventions",
+ "",
+ "- Import public components and types from " +
+ tick +
+ "@karnstack/dowel" +
+ tick +
+ ".",
+ "- Wrap the application in " +
+ tick +
+ "ThemeProvider" +
+ tick +
+ " when selecting light, dark, or system themes explicitly.",
+ "- Dowel controls own their appearance. Prefer documented props over consumer class or style overrides.",
+ "- Icon-only controls require an accessible " + tick + "label" + tick + ".",
+ "",
+ componentDocs,
+ "",
+].join("\n");
+
+const componentIndex = [
+ "# Dowel components",
+ "",
+ "> The complete Dowel component catalog.",
+ "",
+ componentLinks,
+ "",
+].join("\n");
+
+const dependencyLines = Object.entries(packageMetadata.dependencies)
+ .map(
+ ([name, version]) =>
+ "- " + tick + name + tick + ": " + tick + version + tick,
+ )
+ .join("\n");
+const peerLines = Object.entries(packageMetadata.peerDependencies)
+ .map(
+ ([name, version]) =>
+ "- " + tick + name + tick + ": " + tick + version + tick,
+ )
+ .join("\n");
+const dependencies = [
+ "# Dowel dependencies",
+ "",
+ "> Runtime packages installed with Dowel and peer runtimes owned by the consuming application.",
+ "",
+ "## Runtime dependencies",
+ "",
+ dependencyLines,
+ "",
+ "## Peer dependencies",
+ "",
+ peerLines,
+ "",
+].join("\n");
+
+const index = [
+ "# Dowel",
+ "",
+ "> Compact, accessible React components for product interfaces.",
+ "",
+ "- [Agent documentation index](" + absolute("/llms.txt") + ")",
+ "- [Complete agent documentation](" + absolute("/llms-full.txt") + ")",
+ "- [Component catalog](" + absolute("/components/index.md") + ")",
+ "- [HTML documentation](" + absolute("/components") + ")",
+ "",
+].join("\n");
+
+await Promise.all([
+ writeFile(new URL("llms.txt", publicRoot), llms),
+ writeFile(new URL("llms-full.txt", publicRoot), llmsFull),
+ writeFile(new URL("components/index.md", publicRoot), componentIndex),
+ writeFile(new URL("dependencies.md", publicRoot), dependencies),
+ writeFile(new URL("index.md", publicRoot), index),
+]);
diff --git a/apps/docs/src/docs.css b/apps/docs/src/docs.css
index 8040ac1..6664ccf 100644
--- a/apps/docs/src/docs.css
+++ b/apps/docs/src/docs.css
@@ -1709,24 +1709,103 @@ body {
border: 0;
}
-.docs-data-table-header-demo {
- margin-block-start: var(--dowel-space-8);
+.docs-collection-view {
+ position: relative;
+ inline-size: 100%;
+ min-inline-size: 0;
+}
+
+.docs-collection-controls {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: var(--dowel-space-3);
+ inline-size: 100%;
+ min-inline-size: 0;
+ padding-block-end: var(--dowel-space-3);
+}
+
+.docs-collection-controls [data-dowel-component="filter-bar"] {
+ flex: 1;
+ min-inline-size: 0;
+}
+
+.docs-collection-actions {
+ display: flex;
+ flex: none;
+ align-items: center;
+ gap: var(--dowel-space-2);
+}
+
+.docs-selection-demo {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: var(--dowel-space-8);
+ inline-size: 100%;
+ min-block-size: 5rem;
+}
+
+.docs-form-demo {
+ inline-size: min(100%, 30rem);
+}
+
+.docs-form-result {
+ margin: var(--dowel-space-4) 0 0;
+ color: var(--dowel-text-2);
+ font-size: var(--dowel-font-size-sm);
}
.docs-data-table-states {
display: grid;
grid-template-columns: minmax(0, 1fr);
- gap: var(--dowel-space-6);
+ gap: var(--dowel-space-4);
margin-block-start: var(--dowel-space-8);
}
-.docs-data-table-states > [data-dowel-component="data-table"] {
- padding: var(--dowel-space-3);
+.docs-data-table-state,
+.docs-data-table-mode {
+ overflow: hidden;
border: 1px solid var(--dowel-border-1);
border-radius: var(--dowel-radius-lg);
background-color: var(--dowel-bg-1);
}
+.docs-data-table-state {
+ margin: 0;
+}
+
+.docs-data-table-state figcaption,
+.docs-data-table-mode-heading {
+ display: flex;
+ align-items: center;
+ min-block-size: 2.25rem;
+ padding-inline: var(--dowel-space-5);
+ border-block-end: 1px solid var(--dowel-border-1);
+ color: var(--dowel-text-2);
+ font-size: var(--dowel-fs-mini);
+ font-weight: 550;
+}
+
+.docs-data-table-state > [data-dowel-component="data-table"],
+.docs-data-table-mode > [data-dowel-component="data-table"] {
+ padding: var(--dowel-space-2);
+}
+
+.docs-data-table-mode {
+ margin-block-start: var(--dowel-space-8);
+}
+
+.docs-data-table-mode-heading {
+ justify-content: space-between;
+ gap: var(--dowel-space-4);
+}
+
+.docs-data-table-mode-heading > :last-child {
+ color: var(--dowel-text-4);
+ font-weight: 450;
+}
+
.docs-issue-title {
display: flex;
align-items: center;
diff --git a/apps/docs/src/lib/nav.ts b/apps/docs/src/lib/nav.ts
index 374b325..9ad698a 100644
--- a/apps/docs/src/lib/nav.ts
+++ b/apps/docs/src/lib/nav.ts
@@ -80,6 +80,11 @@ export const componentNav: NavItem[] = [
to: "/components/command-menu",
summary: "A modal search surface for grouped application commands.",
},
+ {
+ title: "Collection Controls",
+ to: "/components/collection-controls",
+ summary: "Filters, view options, row actions, and bulk selection controls.",
+ },
{
title: "Composer",
to: "/components/composer",
@@ -115,6 +120,11 @@ export const componentNav: NavItem[] = [
to: "/components/file-upload",
summary: "A native file picker and dropzone with built-in validation.",
},
+ {
+ title: "Form",
+ to: "/components/form",
+ summary: "TanStack Form with Dowel fields and actions pre-bound.",
+ },
{
title: "Icon Button",
to: "/components/icon-button",
@@ -267,6 +277,7 @@ export const componentSections: NavSection[] = [
"/components/calendar",
"/components/combobox",
"/components/file-upload",
+ "/components/form",
"/components/input",
"/components/native-select",
"/components/property-picker",
@@ -327,7 +338,10 @@ export const componentSections: NavSection[] = [
},
{
title: "Composites",
- items: components("/components/composer"),
+ items: components(
+ "/components/collection-controls",
+ "/components/composer",
+ ),
},
];
diff --git a/apps/docs/src/routeTree.gen.ts b/apps/docs/src/routeTree.gen.ts
index a68130f..a357c82 100644
--- a/apps/docs/src/routeTree.gen.ts
+++ b/apps/docs/src/routeTree.gen.ts
@@ -23,6 +23,7 @@ import { Route as ComponentsCalendarRouteImport } from './routes/components/cale
import { Route as ComponentsCalloutRouteImport } from './routes/components/callout'
import { Route as ComponentsCheckboxRouteImport } from './routes/components/checkbox'
import { Route as ComponentsCollapsibleRouteImport } from './routes/components/collapsible'
+import { Route as ComponentsCollectionControlsRouteImport } from './routes/components/collection-controls'
import { Route as ComponentsComboboxRouteImport } from './routes/components/combobox'
import { Route as ComponentsCommandMenuRouteImport } from './routes/components/command-menu'
import { Route as ComponentsComposerRouteImport } from './routes/components/composer'
@@ -32,6 +33,7 @@ import { Route as ComponentsDialogRouteImport } from './routes/components/dialog
import { Route as ComponentsDrawerRouteImport } from './routes/components/drawer'
import { Route as ComponentsEmptyStateRouteImport } from './routes/components/empty-state'
import { Route as ComponentsFileUploadRouteImport } from './routes/components/file-upload'
+import { Route as ComponentsFormRouteImport } from './routes/components/form'
import { Route as ComponentsIconButtonRouteImport } from './routes/components/icon-button'
import { Route as ComponentsInputRouteImport } from './routes/components/input'
import { Route as ComponentsKbdRouteImport } from './routes/components/kbd'
@@ -128,6 +130,12 @@ const ComponentsCollapsibleRoute = ComponentsCollapsibleRouteImport.update({
path: '/collapsible',
getParentRoute: () => ComponentsRouteRoute,
} as any)
+const ComponentsCollectionControlsRoute =
+ ComponentsCollectionControlsRouteImport.update({
+ id: '/collection-controls',
+ path: '/collection-controls',
+ getParentRoute: () => ComponentsRouteRoute,
+ } as any)
const ComponentsComboboxRoute = ComponentsComboboxRouteImport.update({
id: '/combobox',
path: '/combobox',
@@ -173,6 +181,11 @@ const ComponentsFileUploadRoute = ComponentsFileUploadRouteImport.update({
path: '/file-upload',
getParentRoute: () => ComponentsRouteRoute,
} as any)
+const ComponentsFormRoute = ComponentsFormRouteImport.update({
+ id: '/form',
+ path: '/form',
+ getParentRoute: () => ComponentsRouteRoute,
+} as any)
const ComponentsIconButtonRoute = ComponentsIconButtonRouteImport.update({
id: '/icon-button',
path: '/icon-button',
@@ -314,6 +327,7 @@ export interface FileRoutesByFullPath {
'/components/callout': typeof ComponentsCalloutRoute
'/components/checkbox': typeof ComponentsCheckboxRoute
'/components/collapsible': typeof ComponentsCollapsibleRoute
+ '/components/collection-controls': typeof ComponentsCollectionControlsRoute
'/components/combobox': typeof ComponentsComboboxRoute
'/components/command-menu': typeof ComponentsCommandMenuRoute
'/components/composer': typeof ComponentsComposerRoute
@@ -323,6 +337,7 @@ export interface FileRoutesByFullPath {
'/components/drawer': typeof ComponentsDrawerRoute
'/components/empty-state': typeof ComponentsEmptyStateRoute
'/components/file-upload': typeof ComponentsFileUploadRoute
+ '/components/form': typeof ComponentsFormRoute
'/components/icon-button': typeof ComponentsIconButtonRoute
'/components/input': typeof ComponentsInputRoute
'/components/kbd': typeof ComponentsKbdRoute
@@ -363,6 +378,7 @@ export interface FileRoutesByTo {
'/components/callout': typeof ComponentsCalloutRoute
'/components/checkbox': typeof ComponentsCheckboxRoute
'/components/collapsible': typeof ComponentsCollapsibleRoute
+ '/components/collection-controls': typeof ComponentsCollectionControlsRoute
'/components/combobox': typeof ComponentsComboboxRoute
'/components/command-menu': typeof ComponentsCommandMenuRoute
'/components/composer': typeof ComponentsComposerRoute
@@ -372,6 +388,7 @@ export interface FileRoutesByTo {
'/components/drawer': typeof ComponentsDrawerRoute
'/components/empty-state': typeof ComponentsEmptyStateRoute
'/components/file-upload': typeof ComponentsFileUploadRoute
+ '/components/form': typeof ComponentsFormRoute
'/components/icon-button': typeof ComponentsIconButtonRoute
'/components/input': typeof ComponentsInputRoute
'/components/kbd': typeof ComponentsKbdRoute
@@ -414,6 +431,7 @@ export interface FileRoutesById {
'/components/callout': typeof ComponentsCalloutRoute
'/components/checkbox': typeof ComponentsCheckboxRoute
'/components/collapsible': typeof ComponentsCollapsibleRoute
+ '/components/collection-controls': typeof ComponentsCollectionControlsRoute
'/components/combobox': typeof ComponentsComboboxRoute
'/components/command-menu': typeof ComponentsCommandMenuRoute
'/components/composer': typeof ComponentsComposerRoute
@@ -423,6 +441,7 @@ export interface FileRoutesById {
'/components/drawer': typeof ComponentsDrawerRoute
'/components/empty-state': typeof ComponentsEmptyStateRoute
'/components/file-upload': typeof ComponentsFileUploadRoute
+ '/components/form': typeof ComponentsFormRoute
'/components/icon-button': typeof ComponentsIconButtonRoute
'/components/input': typeof ComponentsInputRoute
'/components/kbd': typeof ComponentsKbdRoute
@@ -466,6 +485,7 @@ export interface FileRouteTypes {
| '/components/callout'
| '/components/checkbox'
| '/components/collapsible'
+ | '/components/collection-controls'
| '/components/combobox'
| '/components/command-menu'
| '/components/composer'
@@ -475,6 +495,7 @@ export interface FileRouteTypes {
| '/components/drawer'
| '/components/empty-state'
| '/components/file-upload'
+ | '/components/form'
| '/components/icon-button'
| '/components/input'
| '/components/kbd'
@@ -515,6 +536,7 @@ export interface FileRouteTypes {
| '/components/callout'
| '/components/checkbox'
| '/components/collapsible'
+ | '/components/collection-controls'
| '/components/combobox'
| '/components/command-menu'
| '/components/composer'
@@ -524,6 +546,7 @@ export interface FileRouteTypes {
| '/components/drawer'
| '/components/empty-state'
| '/components/file-upload'
+ | '/components/form'
| '/components/icon-button'
| '/components/input'
| '/components/kbd'
@@ -565,6 +588,7 @@ export interface FileRouteTypes {
| '/components/callout'
| '/components/checkbox'
| '/components/collapsible'
+ | '/components/collection-controls'
| '/components/combobox'
| '/components/command-menu'
| '/components/composer'
@@ -574,6 +598,7 @@ export interface FileRouteTypes {
| '/components/drawer'
| '/components/empty-state'
| '/components/file-upload'
+ | '/components/form'
| '/components/icon-button'
| '/components/input'
| '/components/kbd'
@@ -708,6 +733,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof ComponentsCollapsibleRouteImport
parentRoute: typeof ComponentsRouteRoute
}
+ '/components/collection-controls': {
+ id: '/components/collection-controls'
+ path: '/collection-controls'
+ fullPath: '/components/collection-controls'
+ preLoaderRoute: typeof ComponentsCollectionControlsRouteImport
+ parentRoute: typeof ComponentsRouteRoute
+ }
'/components/combobox': {
id: '/components/combobox'
path: '/combobox'
@@ -771,6 +803,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof ComponentsFileUploadRouteImport
parentRoute: typeof ComponentsRouteRoute
}
+ '/components/form': {
+ id: '/components/form'
+ path: '/form'
+ fullPath: '/components/form'
+ preLoaderRoute: typeof ComponentsFormRouteImport
+ parentRoute: typeof ComponentsRouteRoute
+ }
'/components/icon-button': {
id: '/components/icon-button'
path: '/icon-button'
@@ -960,6 +999,7 @@ interface ComponentsRouteRouteChildren {
ComponentsCalloutRoute: typeof ComponentsCalloutRoute
ComponentsCheckboxRoute: typeof ComponentsCheckboxRoute
ComponentsCollapsibleRoute: typeof ComponentsCollapsibleRoute
+ ComponentsCollectionControlsRoute: typeof ComponentsCollectionControlsRoute
ComponentsComboboxRoute: typeof ComponentsComboboxRoute
ComponentsCommandMenuRoute: typeof ComponentsCommandMenuRoute
ComponentsComposerRoute: typeof ComponentsComposerRoute
@@ -969,6 +1009,7 @@ interface ComponentsRouteRouteChildren {
ComponentsDrawerRoute: typeof ComponentsDrawerRoute
ComponentsEmptyStateRoute: typeof ComponentsEmptyStateRoute
ComponentsFileUploadRoute: typeof ComponentsFileUploadRoute
+ ComponentsFormRoute: typeof ComponentsFormRoute
ComponentsIconButtonRoute: typeof ComponentsIconButtonRoute
ComponentsInputRoute: typeof ComponentsInputRoute
ComponentsKbdRoute: typeof ComponentsKbdRoute
@@ -1008,6 +1049,7 @@ const ComponentsRouteRouteChildren: ComponentsRouteRouteChildren = {
ComponentsCalloutRoute: ComponentsCalloutRoute,
ComponentsCheckboxRoute: ComponentsCheckboxRoute,
ComponentsCollapsibleRoute: ComponentsCollapsibleRoute,
+ ComponentsCollectionControlsRoute: ComponentsCollectionControlsRoute,
ComponentsComboboxRoute: ComponentsComboboxRoute,
ComponentsCommandMenuRoute: ComponentsCommandMenuRoute,
ComponentsComposerRoute: ComponentsComposerRoute,
@@ -1017,6 +1059,7 @@ const ComponentsRouteRouteChildren: ComponentsRouteRouteChildren = {
ComponentsDrawerRoute: ComponentsDrawerRoute,
ComponentsEmptyStateRoute: ComponentsEmptyStateRoute,
ComponentsFileUploadRoute: ComponentsFileUploadRoute,
+ ComponentsFormRoute: ComponentsFormRoute,
ComponentsIconButtonRoute: ComponentsIconButtonRoute,
ComponentsInputRoute: ComponentsInputRoute,
ComponentsKbdRoute: ComponentsKbdRoute,
diff --git a/apps/docs/src/routes/__root.tsx b/apps/docs/src/routes/__root.tsx
index f7b664e..fb6aab8 100644
--- a/apps/docs/src/routes/__root.tsx
+++ b/apps/docs/src/routes/__root.tsx
@@ -43,7 +43,14 @@ export const Route = createRootRoute({
content: "Compact, accessible React components for product interfaces.",
},
],
- links: faviconLinks,
+ links: [
+ ...faviconLinks,
+ {
+ rel: "describedby",
+ href: "/llms.txt",
+ type: "text/markdown",
+ },
+ ],
}),
component: RootDocument,
});
diff --git a/apps/docs/src/routes/components/collection-controls.tsx b/apps/docs/src/routes/components/collection-controls.tsx
new file mode 100644
index 0000000..a7afe03
--- /dev/null
+++ b/apps/docs/src/routes/components/collection-controls.tsx
@@ -0,0 +1,194 @@
+import {
+ ArchiveBoxIcon,
+ EllipsisHorizontalIcon,
+} from "@heroicons/react/16/solid";
+import { createFileRoute } from "@tanstack/react-router";
+import {
+ Button,
+ FilterBar,
+ FilterPicker,
+ HoverActions,
+ IconButton,
+ MultiSelectToolbar,
+ ViewOptions,
+} from "@karnstack/dowel";
+import type {
+ DataTableDensity,
+ FilterBarFilter,
+ FilterPickerProperty,
+} from "@karnstack/dowel";
+import { useState } from "react";
+
+import { Demo } from "../../components/demo";
+import { DocsPage, Section } from "../../components/docs-page";
+
+export const Route = createFileRoute("/components/collection-controls")({
+ component: CollectionControlsDocs,
+});
+
+const toc = [
+ { id: "filters", title: "Filters and views" },
+ { id: "selection", title: "Bulk selection" },
+ { id: "row-actions", title: "Row actions" },
+];
+
+const initialFilters: FilterBarFilter[] = [
+ { id: "status", label: "Status", value: "Active" },
+ { id: "assignee", label: "Assignee", value: "Me" },
+];
+
+const filterProperties: FilterPickerProperty[] = [
+ {
+ id: "status",
+ label: "Status",
+ values: [
+ { value: "active", label: "Active" },
+ { value: "done", label: "Completed" },
+ ],
+ },
+ {
+ id: "assignee",
+ label: "Assignee",
+ values: [
+ { value: "me", label: "Me" },
+ { value: "unassigned", label: "Unassigned" },
+ ],
+ },
+];
+
+function CollectionControlsDocs() {
+ const [filters, setFilters] = useState(initialFilters);
+ const [density, setDensity] = useState("compact");
+ const [selectedCount, setSelectedCount] = useState(3);
+
+ function addFilter(propertyId: string, value: string) {
+ const property = filterProperties.find((item) => item.id === propertyId);
+ const option = property?.values.find((item) => item.value === value);
+ if (!property || !option) return;
+ setFilters((current) => [
+ ...current.filter((filter) => filter.id !== propertyId),
+ { id: propertyId, label: property.label, value: option.label },
+ ]);
+ }
+
+ return (
+
+
+
+ Keep active constraints visible and place display preferences at the
+ collection edge. Both components are controlled, so saved views can
+ own the same state.
+
+ The toolbar appears only while items are selected. Keep its actions
+ specific to the selected set and always provide a way back to the
+ unselected state.
+
+
+
+`}
+ >
+
+
+ setSelectedCount(0)}
+ >
+
+
+
+
+
+
+
+
+ Hover actions reserve no visual attention until the row is hovered or
+ focus moves inside it. Pass visible when a parent row
+ tracks pointer state.
+
- Show the header to expose sorting and column resizing. Sort controls,
- selection boxes, rows, and resize handles all carry visible keyboard
- focus. Resize with the pointer or Left and Right Arrow, then double
- click the handle to restore its original width.
+ Show the header to expose sorting and column resizing. Rows support
+ Arrow, Home, End, Space, Enter, and Shift-range selection. Resize with
+ the pointer or Arrow keys, then double click the handle to restore its
+ original width.
+ The adapter currently includes TextField and{" "}
+ TextareaField. Both bind value, blur, name, touched
+ validation, descriptions, and accessible error output. Use{" "}
+ withDowelForm and withDowelFieldGroup to
+ compose reusable forms without losing inferred value types.
+
+
+
+ );
+}
diff --git a/apps/docs/src/routes/dependencies.tsx b/apps/docs/src/routes/dependencies.tsx
index df7c4f8..8f4cf19 100644
--- a/apps/docs/src/routes/dependencies.tsx
+++ b/apps/docs/src/routes/dependencies.tsx
@@ -35,6 +35,11 @@ const runtimeDependencies = [
version: packageMetadata.dependencies["@tanstack/react-table"],
role: "Its headless, application-controlled state model handles advanced table behavior without coupling Dowel to a table layout or data-fetching opinion.",
},
+ {
+ name: "@tanstack/react-form",
+ version: packageMetadata.dependencies["@tanstack/react-form"],
+ role: "Its typed, headless state and validation model powers Dowel's pre-bound form hook while leaving schema choice and submission behavior application-owned.",
+ },
{
name: "@internationalized/date",
version: packageMetadata.dependencies["@internationalized/date"],
@@ -132,7 +137,7 @@ function DependenciesDocs() {