Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
eb91386
Add primitive components
IzumiSy Mar 9, 2026
daa37da
Format
IzumiSy Mar 9, 2026
0b3098d
Update docs
IzumiSy Mar 9, 2026
c7bde48
fix: remove unused VariantProps from ToggleGroup type signature
IzumiSy Mar 9, 2026
29891cc
fix: make Slider.Root composable by using children when provided
IzumiSy Mar 9, 2026
14857fd
fix: remove unused Skeleton component
IzumiSy Mar 9, 2026
6d3b44d
fix: restructure Radio, Checkbox, Toggle to namespace object pattern
IzumiSy Mar 9, 2026
957f406
Format docs
IzumiSy Mar 9, 2026
acf5603
Add error state to useAsyncItems hook
IzumiSy Mar 9, 2026
64249b0
Rename query to value in Autocomplete.useAsync return type
IzumiSy Mar 9, 2026
e02858d
Add ButtonProps type export
IzumiSy Mar 9, 2026
0e719ad
refactor: convert Switch to namespace pattern (Switch.Root)
IzumiSy Mar 10, 2026
185691e
refactor: remove standalone Label export, use Field.Label instead
IzumiSy Mar 10, 2026
917f45a
refactor: convert Meter and Progress to composable namespace API
IzumiSy Mar 10, 2026
436ec7e
docs: update Switch, Meter, Progress, Label docs for namespace API ch…
IzumiSy Mar 10, 2026
7aba51f
fix: wrap AlertDialog.Action with BaseAlertDialog.Close for auto-clos…
IzumiSy Mar 12, 2026
d5af396
fix: replace unsafe Function cast with typed overload dispatch in com…
IzumiSy Mar 12, 2026
aaff5d9
fix: add ToggleProps type export for consistency with Badge and Button
IzumiSy Mar 12, 2026
5a1bce5
Format files
IzumiSy Mar 12, 2026
ba544cb
Split component docs
IzumiSy Mar 13, 2026
9038adb
Fix components
IzumiSy Mar 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ This project has comprehensive documentation organized in the `docs/` directory:
### Core Documentation

- **[Quick Start](./docs/quickstart.md)** - Installation, setup, and first steps
- **[API Reference](./docs/api.md)** - Complete API documentation for all components, hooks, and functions
- **[API Reference](./docs/api.md)** - Complete API documentation for hooks, providers, and functions
- **[Components](./docs/components/)** - UI component reference (Badge, Button, Dialog, Select, etc.)
- **[Module & Resource Definition](./docs/module-resource-definition.md)** - How to structure your application using modules and resources
- **[File-Based Routing](./docs/file-based-routing.md)** - Defining pages via directory structure with vite plugin
- **[Routing & Navigation](./docs/routing-and-navigation.md)** - Client-side navigation hooks and Command Palette
Expand Down
29 changes: 29 additions & 0 deletions docs/components/accordion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Accordion

Collapsible content sections.

## Parts

| Part | Description |
| ------------------- | ------------------------------------------------------- |
| `Accordion.Root` | Container for all accordion items |
| `Accordion.Item` | Individual collapsible section |
| `Accordion.Trigger` | Button that toggles the section (includes chevron icon) |
| `Accordion.Content` | Collapsible panel content |

## Example

```tsx
import { Accordion } from "@tailor-platform/app-shell";

<Accordion.Root>
<Accordion.Item value="item-1">
<Accordion.Trigger>Section 1</Accordion.Trigger>
<Accordion.Content>Content for section 1</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="item-2">
<Accordion.Trigger>Section 2</Accordion.Trigger>
<Accordion.Content>Content for section 2</Accordion.Content>
</Accordion.Item>
</Accordion.Root>;
```
37 changes: 37 additions & 0 deletions docs/components/alert-dialog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# AlertDialog

Modal dialog requiring user confirmation.

## Parts

| Part | Description |
| ------------------------- | -------------------------------------------- |
| `AlertDialog.Root` | Root provider |
| `AlertDialog.Trigger` | Button that opens the dialog |
| `AlertDialog.Content` | Dialog content (includes overlay and portal) |
| `AlertDialog.Header` | Header container |
| `AlertDialog.Footer` | Footer container (action buttons) |
| `AlertDialog.Title` | Dialog title |
| `AlertDialog.Description` | Dialog description text |
| `AlertDialog.Action` | Confirm action button |
| `AlertDialog.Cancel` | Cancel button (closes dialog) |

## Example

```tsx
import { AlertDialog } from "@tailor-platform/app-shell";

<AlertDialog.Root>
<AlertDialog.Trigger>Delete Item</AlertDialog.Trigger>
<AlertDialog.Content>
<AlertDialog.Header>
<AlertDialog.Title>Are you sure?</AlertDialog.Title>
<AlertDialog.Description>This action cannot be undone.</AlertDialog.Description>
</AlertDialog.Header>
<AlertDialog.Footer>
<AlertDialog.Cancel>Cancel</AlertDialog.Cancel>
<AlertDialog.Action onClick={handleDelete}>Delete</AlertDialog.Action>
</AlertDialog.Footer>
</AlertDialog.Content>
</AlertDialog.Root>;
```
87 changes: 87 additions & 0 deletions docs/components/autocomplete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Autocomplete

Text input with suggestion dropdown.

## Parts

| Part | Description |
| ------------------------- | ----------------------------------------------------------------------- |
| `Autocomplete.Root` | Root provider (accepts `items`, `value`, `onValueChange`, `filter`) |
| `Autocomplete.InputGroup` | Container for input + trigger + clear (renders defaults if no children) |
| `Autocomplete.Input` | Text input |
| `Autocomplete.Trigger` | Dropdown toggle button |
| `Autocomplete.Clear` | Clear button |
| `Autocomplete.Content` | Dropdown popup (includes portal and positioner) |
| `Autocomplete.List` | Scrollable item list |
| `Autocomplete.Item` | Individual option |
| `Autocomplete.Empty` | Shown when no items match |
| `Autocomplete.Group` | Groups related items |
| `Autocomplete.GroupLabel` | Label for a group |
| `Autocomplete.Value` | Renders the selected value |
| `Autocomplete.Collection` | Server-side collection renderer |
| `Autocomplete.Status` | Screen-reader status (sr-only) |

## Root Props

| Prop | Type | Default | Description |
| ------------------- | ---------------------------------------- | -------- | ------------------------------------------------------------------- |
| `items` | `Value[]` | — | Items to display in the list |
| `value` | `string` | — | Controlled input value |
| `defaultValue` | `string` | — | Initial uncontrolled input value |
| `onValueChange` | `(value: string, details) => void` | — | Called when input value changes |
| `filter` | `FilterFunction \| null` | built-in | Client-side filter. Pass `null` to disable (e.g. for async sources) |
| `mode` | `"list" \| "both" \| "inline" \| "none"` | `"list"` | Controls filtering and inline autocompletion behavior |
| `autoHighlight` | `boolean \| "always"` | `false` | Auto-highlight first matching item |
| `openOnInputClick` | `boolean` | `false` | Open popup when clicking the input |
| `itemToStringValue` | `(value: Value) => string` | — | Convert object values to string for display and form submission |

## Hooks

| Hook | Description |
| ------------------------ | ---------------------------------------------- |
| `Autocomplete.useFilter` | Client-side filtering hook (from Base UI) |
| `Autocomplete.useAsync` | Async fetching with debounce and abort support |

## Example

```tsx
import { Autocomplete } from "@tailor-platform/app-shell";

const fruits = ["Apple", "Banana", "Cherry", "Date"];

<Autocomplete.Root items={fruits}>
<Autocomplete.InputGroup />
<Autocomplete.Content>
<Autocomplete.List>{(item) => <Autocomplete.Item>{item}</Autocomplete.Item>}</Autocomplete.List>
<Autocomplete.Empty>No results found.</Autocomplete.Empty>
</Autocomplete.Content>
</Autocomplete.Root>;
```

## Async Example

```tsx
const movies = Autocomplete.useAsync({
fetcher: async (query, { signal }) => {
const res = await fetch(`/api/movies?q=${query}`, { signal });
if (!res.ok) return [];
return res.json();
},
debounceMs: 300,
});

<Autocomplete.Root
items={movies.items}
value={movies.value}
onValueChange={movies.onValueChange}
filter={null}
>
<Autocomplete.InputGroup />
<Autocomplete.Content>
<Autocomplete.List>
{(item) => <Autocomplete.Item>{item.title}</Autocomplete.Item>}
</Autocomplete.List>
<Autocomplete.Empty>{movies.loading ? "Loading..." : "No results."}</Autocomplete.Empty>
</Autocomplete.Content>
</Autocomplete.Root>;
```
22 changes: 22 additions & 0 deletions docs/components/avatar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Avatar

User avatar with image and fallback.

## Parts

| Part | Description |
| ----------------- | ------------------------------------- |
| `Avatar.Root` | Circular container (default: 32×32px) |
| `Avatar.Image` | Avatar image |
| `Avatar.Fallback` | Shown when image fails to load |

## Example

```tsx
import { Avatar } from "@tailor-platform/app-shell";

<Avatar.Root>
<Avatar.Image src="/avatar.jpg" alt="User" />
<Avatar.Fallback>JD</Avatar.Fallback>
</Avatar.Root>;
```
37 changes: 37 additions & 0 deletions docs/components/breadcrumb.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Breadcrumb

Navigation breadcrumb trail.

## Parts

| Part | Description |
| ---------------------- | ------------------------------------------ |
| `Breadcrumb.Root` | Nav container (`<nav>`) |
| `Breadcrumb.List` | Ordered list |
| `Breadcrumb.Item` | Individual breadcrumb item |
| `Breadcrumb.Link` | Clickable link (uses react-router `Link`) |
| `Breadcrumb.Page` | Current page (non-clickable) |
| `Breadcrumb.Separator` | Separator between items (default: chevron) |
| `Breadcrumb.Ellipsis` | Ellipsis for collapsed items |

## Example

```tsx
import { Breadcrumb } from "@tailor-platform/app-shell";

<Breadcrumb.Root>
<Breadcrumb.List>
<Breadcrumb.Item>
<Breadcrumb.Link to="/">Home</Breadcrumb.Link>
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item>
<Breadcrumb.Link to="/products">Products</Breadcrumb.Link>
</Breadcrumb.Item>
<Breadcrumb.Separator />
<Breadcrumb.Item>
<Breadcrumb.Page>Current Page</Breadcrumb.Page>
</Breadcrumb.Item>
</Breadcrumb.List>
</Breadcrumb.Root>;
```
23 changes: 23 additions & 0 deletions docs/components/button.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Button

Button component with multiple variants and sizes. Supports polymorphic rendering via `render` prop.

## Props

| Prop | Type | Default | Description |
| --------- | ----------------------------------------------------------------------------- | ----------- | ---------------------------------------------- |
| `variant` | `"default" \| "destructive" \| "outline" \| "secondary" \| "ghost" \| "link"` | `"default"` | Visual style |
| `size` | `"default" \| "sm" \| "lg" \| "icon"` | `"default"` | Button size |
| `render` | `React.ReactElement` | — | Render as a different element (e.g., `<Link>`) |

## Example

```tsx
import { Button } from "@tailor-platform/app-shell";
import { Link } from "react-router";

<Button>Default</Button>
<Button variant="destructive">Delete</Button>
<Button variant="outline" size="sm">Small Outline</Button>
<Button render={<Link to="/page" />}>Navigate</Button>
```
33 changes: 33 additions & 0 deletions docs/components/checkbox.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Checkbox

Checkbox input with indeterminate state support.

## Parts

| Part | Description |
| ---------------- | ------------------------------------------------ |
| `Checkbox.Root` | Single checkbox (includes check/minus indicator) |
| `Checkbox.Group` | Groups related checkboxes |

## Example

```tsx
import { Checkbox } from "@tailor-platform/app-shell";

{
/* Single checkbox */
}
<Checkbox.Root />;

{
/* Group of checkboxes */
}
<Checkbox.Group>
<label>
<Checkbox.Root /> Option A
</label>
<label>
<Checkbox.Root /> Option B
</label>
</Checkbox.Group>;
```
22 changes: 22 additions & 0 deletions docs/components/collapsible.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Collapsible

Expandable/collapsible content section.

## Parts

| Part | Description |
| --------------------- | ----------------- |
| `Collapsible.Root` | Root provider |
| `Collapsible.Trigger` | Toggle button |
| `Collapsible.Content` | Collapsible panel |

## Example

```tsx
import { Collapsible } from "@tailor-platform/app-shell";

<Collapsible.Root>
<Collapsible.Trigger>Toggle</Collapsible.Trigger>
<Collapsible.Content>Collapsible content here.</Collapsible.Content>
</Collapsible.Root>;
```
Loading
Loading