@tailor-platform/app-shell 1.15.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dist/app-shell-core.css +1 -1
  2. package/dist/app-shell.d.ts +811 -131
  3. package/dist/app-shell.js +7155 -5797
  4. package/dist/{appshell-DLVBFo5J.js → appshell-CahhZy7v.js} +656 -524
  5. package/dist/semantic-contrast.test.ts +154 -0
  6. package/dist/style-entry.d.ts +147 -92
  7. package/dist/testing.d.ts +152 -95
  8. package/dist/testing.js +1 -1
  9. package/dist/theme-bridge.test.ts +101 -1
  10. package/dist/theme.bridge.css +91 -0
  11. package/dist/theme.css +6 -1
  12. package/dist/themes/_template.css +7 -1
  13. package/dist/themes/bloom.css +0 -6
  14. package/dist/themes/cream.css +0 -6
  15. package/dist/themes/default.css +389 -69
  16. package/dist/vite-plugin.d.ts +147 -92
  17. package/package.json +8 -8
  18. package/skills/app-shell-patterns/SKILL.md +108 -19
  19. package/skills/app-shell-patterns/references/api/create-ai-gateway-client.md +115 -0
  20. package/skills/app-shell-patterns/references/api/create-typed-paths.md +117 -0
  21. package/skills/app-shell-patterns/references/api/define-i18n-labels.md +143 -0
  22. package/skills/app-shell-patterns/references/api/define-module.md +247 -0
  23. package/skills/app-shell-patterns/references/api/define-resource.md +307 -0
  24. package/skills/app-shell-patterns/references/api/guards/hidden.md +202 -0
  25. package/skills/app-shell-patterns/references/api/guards/overview.md +354 -0
  26. package/skills/app-shell-patterns/references/api/guards/pass.md +129 -0
  27. package/skills/app-shell-patterns/references/api/guards/redirect-to.md +307 -0
  28. package/skills/app-shell-patterns/references/api/router/use-location.md +240 -0
  29. package/skills/app-shell-patterns/references/api/router/use-navigate.md +138 -0
  30. package/skills/app-shell-patterns/references/api/router/use-params.md +218 -0
  31. package/skills/app-shell-patterns/references/api/use-ai-chat.md +110 -0
  32. package/skills/app-shell-patterns/references/api/use-app-shell-config.md +132 -0
  33. package/skills/app-shell-patterns/references/api/use-app-shell-data.md +150 -0
  34. package/skills/app-shell-patterns/references/api/use-app-shell.md +150 -0
  35. package/skills/app-shell-patterns/references/api/use-auth.md +145 -0
  36. package/skills/app-shell-patterns/references/api/use-override-breadcrumb.md +74 -0
  37. package/skills/app-shell-patterns/references/api/use-page-meta.md +96 -0
  38. package/skills/app-shell-patterns/references/api/use-register-command-palette-actions.md +90 -0
  39. package/skills/app-shell-patterns/references/api/use-resolved-locale.md +67 -0
  40. package/skills/app-shell-patterns/references/api/use-route-error.md +214 -0
  41. package/skills/app-shell-patterns/references/api/use-theme.md +108 -0
  42. package/skills/app-shell-patterns/references/api/use-time-zone.md +80 -0
  43. package/skills/app-shell-patterns/references/api/use-toast.md +104 -0
  44. package/skills/app-shell-patterns/references/components/action-panel.md +168 -0
  45. package/skills/app-shell-patterns/references/components/activity-card.md +142 -0
  46. package/skills/app-shell-patterns/references/components/ai-chat.md +315 -0
  47. package/skills/app-shell-patterns/references/components/alert.md +202 -0
  48. package/skills/app-shell-patterns/references/components/app-shell.md +530 -0
  49. package/skills/app-shell-patterns/references/components/appearance-switcher.md +87 -0
  50. package/skills/app-shell-patterns/references/components/attachment.md +138 -0
  51. package/skills/app-shell-patterns/references/components/autocomplete.md +278 -0
  52. package/skills/app-shell-patterns/references/components/avatar.md +80 -0
  53. package/skills/app-shell-patterns/references/components/badge.md +309 -0
  54. package/skills/app-shell-patterns/references/components/button.md +164 -0
  55. package/skills/app-shell-patterns/references/components/card.md +181 -0
  56. package/skills/app-shell-patterns/references/components/checkbox.md +169 -0
  57. package/skills/app-shell-patterns/references/components/combobox.md +318 -0
  58. package/skills/app-shell-patterns/references/components/command-palette.md +413 -0
  59. package/skills/app-shell-patterns/references/components/csv-importer.md +214 -0
  60. package/skills/app-shell-patterns/references/components/data-table.md +1168 -0
  61. package/skills/app-shell-patterns/references/components/date-picker.md +259 -0
  62. package/skills/app-shell-patterns/references/components/default-header.md +75 -0
  63. package/skills/app-shell-patterns/references/components/default-sidebar.md +136 -0
  64. package/skills/app-shell-patterns/references/components/description-card.md +569 -0
  65. package/skills/app-shell-patterns/references/components/dialog.md +164 -0
  66. package/skills/app-shell-patterns/references/components/document-progress-card.md +154 -0
  67. package/skills/app-shell-patterns/references/components/filter-rail.md +165 -0
  68. package/skills/app-shell-patterns/references/components/form.md +378 -0
  69. package/skills/app-shell-patterns/references/components/global-header-layout.md +132 -0
  70. package/skills/app-shell-patterns/references/components/grid.md +184 -0
  71. package/skills/app-shell-patterns/references/components/input.md +83 -0
  72. package/skills/app-shell-patterns/references/components/layout.md +539 -0
  73. package/skills/app-shell-patterns/references/components/menu.md +218 -0
  74. package/skills/app-shell-patterns/references/components/metric-card.md +94 -0
  75. package/skills/app-shell-patterns/references/components/select.md +283 -0
  76. package/skills/app-shell-patterns/references/components/sheet.md +237 -0
  77. package/skills/app-shell-patterns/references/components/sidebar-group.md +472 -0
  78. package/skills/app-shell-patterns/references/components/sidebar-item.md +458 -0
  79. package/skills/app-shell-patterns/references/components/sidebar-layout.md +258 -0
  80. package/skills/app-shell-patterns/references/components/sidebar-section.md +114 -0
  81. package/skills/app-shell-patterns/references/components/spinner.md +81 -0
  82. package/skills/app-shell-patterns/references/components/table.md +188 -0
  83. package/skills/app-shell-patterns/references/components/tabs.md +158 -0
  84. package/skills/app-shell-patterns/references/components/textarea.md +122 -0
  85. package/skills/app-shell-patterns/references/components/timeline.md +317 -0
  86. package/skills/app-shell-patterns/references/components/toolbar.md +138 -0
  87. package/skills/app-shell-patterns/references/components/tooltip.md +144 -0
  88. package/skills/app-shell-patterns/references/components/with-guard.md +445 -0
  89. package/skills/app-shell-patterns/references/concepts/authentication.md +301 -0
  90. package/skills/app-shell-patterns/references/concepts/custom-components.md +59 -0
  91. package/skills/app-shell-patterns/references/concepts/file-based-routing.md +356 -0
  92. package/skills/app-shell-patterns/references/{fundamental → concepts}/graphql.md +31 -18
  93. package/skills/app-shell-patterns/references/concepts/modules-and-resources.md +229 -0
  94. package/skills/app-shell-patterns/references/concepts/routing-navigation.md +425 -0
  95. package/skills/app-shell-patterns/references/concepts/sidebar-navigation.md +420 -0
  96. package/skills/app-shell-patterns/references/concepts/styling-theming.md +785 -0
  97. package/skills/app-shell-patterns/references/migrations.md +55 -0
  98. package/skills/app-shell-patterns/references/pages/{detail.md → document-detail.md} +10 -33
  99. package/skills/app-shell-patterns/references/patterns/form-composer.md +43 -45
  100. package/skills/app-shell-patterns/references/patterns/form-modal.md +37 -92
  101. package/skills/app-shell-patterns/references/patterns/form-sectioned.md +12 -38
  102. package/skills/app-shell-patterns/references/patterns/form-single-page.md +11 -32
  103. package/skills/app-shell-patterns/references/patterns/form-wizard.md +12 -53
  104. package/skills/app-shell-patterns/references/patterns/interaction-confirm.md +11 -27
  105. package/skills/app-shell-patterns/references/patterns/interaction-multi-select.md +136 -139
  106. package/skills/app-shell-patterns/references/patterns/interaction-toast.md +10 -34
  107. package/skills/app-shell-patterns/references/patterns/list-dense-scan.md +13 -88
  108. package/skills/app-shell-patterns/references/fundamental/components.md +0 -1009
  109. package/skills/app-shell-patterns/references/fundamental/design-system.md +0 -440
@@ -0,0 +1,259 @@
1
+ ---
2
+ title: DatePicker
3
+ description: Accessible date input components (@internationalized/date + Base UI)
4
+ ---
5
+
6
+ <!-- GENERATED by docs-kit from docs-src/components/date-picker.docs.outline.md — do not edit by hand. -->
7
+
8
+ # DatePicker
9
+
10
+ Three related components for date input — a segmented field, a field with a calendar popover, and a standalone calendar grid. Built on [`@internationalized/date`](https://react-spectrum.adobe.com/internationalized/date/) and Base UI.
11
+
12
+ ## Import
13
+
14
+ ```tsx
15
+ import {
16
+ DateField,
17
+ DatePicker,
18
+ DateRangePicker,
19
+ Calendar,
20
+ RangeCalendar,
21
+ Field,
22
+ // Date value helpers (re-exported from @internationalized/date)
23
+ parseDate,
24
+ getLocalTimeZone,
25
+ today,
26
+ type CalendarDate,
27
+ type DateValue,
28
+ type DateRange,
29
+ } from "@tailor-platform/app-shell";
30
+ ```
31
+
32
+ ## API shape
33
+
34
+ `DateField` and `DatePicker` are standalone composite controls.
35
+
36
+ - They own date entry, keyboard behavior, constraints, locale/timezone handling, and form value serialization.
37
+ - They expose standard labeling hooks: `id`, `aria-label`, `aria-labelledby`, `aria-describedby`, and `isInvalid`.
38
+ - They also auto-wire into `Field.Root`, so `Field.Label`, `Field.Description`, `Field.Error`, and form validation state work the same way as the other AppShell form controls.
39
+
40
+ ## DateField
41
+
42
+ Standalone usage with an accessible name:
43
+
44
+ ```tsx
45
+ <DateField aria-label="Invoice date" />
46
+ ```
47
+
48
+ With a visible label + description:
49
+
50
+ ```tsx
51
+ <label id="invoice-date-label" htmlFor="invoice-date">
52
+ Invoice date
53
+ </label>
54
+ <DateField
55
+ id="invoice-date"
56
+ aria-labelledby="invoice-date-label"
57
+ aria-describedby="invoice-date-help"
58
+ />
59
+ <p id="invoice-date-help">Format follows your locale</p>
60
+ ```
61
+
62
+ Inside `Field.Root`:
63
+
64
+ ```tsx
65
+ <Field.Root name="invoiceDate">
66
+ <Field.Label>Invoice date</Field.Label>
67
+ <DateField />
68
+ <Field.Description>Format follows your locale</Field.Description>
69
+ </Field.Root>
70
+ ```
71
+
72
+ Controlled:
73
+
74
+ ```tsx
75
+ const [date, setDate] = useState<CalendarDate | null>(null);
76
+
77
+ <DateField aria-label="Invoice date" value={date} onChange={setDate} />;
78
+ ```
79
+
80
+ ## DatePicker
81
+
82
+ A `DateField` with a calendar popover.
83
+
84
+ ```tsx
85
+ <DatePicker aria-label="Ship date" />
86
+ ```
87
+
88
+ Constrained + unavailable dates:
89
+
90
+ ```tsx
91
+ <label id="delivery-date-label" htmlFor="delivery-date">
92
+ Delivery date
93
+ </label>
94
+ <DatePicker
95
+ id="delivery-date"
96
+ aria-labelledby="delivery-date-label"
97
+ minValue={today(getLocalTimeZone())}
98
+ isDateUnavailable={(date) => {
99
+ const dow = date.toDate(getLocalTimeZone()).getDay();
100
+ return dow === 0 || dow === 6; // weekends
101
+ }}
102
+ />
103
+ ```
104
+
105
+ Week start:
106
+
107
+ ```tsx
108
+ <DatePicker aria-label="Date" firstDayOfWeek="mon" />
109
+ ```
110
+
111
+ ## Validation and errors
112
+
113
+ Use standard HTML + ARIA when rendering the field standalone:
114
+
115
+ ```tsx
116
+ <label id="delivery-date-label" htmlFor="delivery-date">
117
+ Delivery date
118
+ </label>
119
+ <DatePicker
120
+ id="delivery-date"
121
+ aria-labelledby="delivery-date-label"
122
+ aria-describedby={error ? "delivery-date-error" : undefined}
123
+ isInvalid={!!error}
124
+ value={value}
125
+ onChange={setValue}
126
+ />
127
+ {error && <p id="delivery-date-error">{error}</p>}
128
+ ```
129
+
130
+ Or let `Field.Root` wire the label, description, and error elements:
131
+
132
+ ```tsx
133
+ <Field.Root name="deliveryDate" error={error ? { message: error } : undefined}>
134
+ <Field.Label>Delivery date</Field.Label>
135
+ <DatePicker value={value} onChange={setValue} />
136
+ <Field.Error match={!!error}>{error}</Field.Error>
137
+ </Field.Root>
138
+ ```
139
+
140
+ ## Calendar
141
+
142
+ A standalone calendar grid for custom date-selection UIs.
143
+
144
+ ```tsx
145
+ <Calendar aria-label="Select date" onChange={(date) => console.log(date)} />
146
+ ```
147
+
148
+ ## DateRangePicker
149
+
150
+ Start and end segmented inputs sharing one calendar popover, with a `{ start, end }` value (`DateRange`) — a **separate component** from `DatePicker`, not a mode. Same composition model as the other controls: standalone with `aria-*`, or inside `Field.Root`. Selection follows the react-aria model — the first calendar pick anchors the range and keeps the popover open, the highlight follows the pointer/arrows, and the second pick completes it; picking backwards swaps the endpoints, while a range **typed** in reverse is flagged invalid (`Field.Error match="customError"`) rather than swapped.
151
+
152
+ ```tsx
153
+ const [range, setRange] = useState<DateRange | null>(null);
154
+
155
+ // standalone
156
+ <DateRangePicker aria-label="Billing period" value={range} onChange={setRange} />
157
+
158
+ // composed
159
+ <Field.Root name="period">
160
+ <Field.Label>Billing period</Field.Label>
161
+ <DateRangePicker />
162
+ <Field.Error match="customError" />
163
+ </Field.Root>
164
+ ```
165
+
166
+ A single combined proxy input is registered as the one Field control — its value is empty until **both** ends are complete, so `isRequired` blocks a partial range. Give that combined input a `name` for a single `start/end` native-POST field (a wrapping `Field.Root` name wins), or use `startName` / `endName` to emit two plain hidden inputs for classic form-POST.
167
+
168
+ ## RangeCalendar
169
+
170
+ The standalone inline range calendar (the grid inside `DateRangePicker`), for custom layouts.
171
+
172
+ ```tsx
173
+ <RangeCalendar aria-label="Stay dates" onChange={(range) => console.log(range)} />
174
+ ```
175
+
176
+ ## Localization
177
+
178
+ Locale and timezone come from AppShell automatically. Override per field with `locale` / `timeZone`:
179
+
180
+ ```tsx
181
+ <DatePicker aria-label="Date" locale="ja-JP" />
182
+ ```
183
+
184
+ ### Day of the week
185
+
186
+ `showDayOfWeek` adds the locale's short day of the week where the locale places it — `2025/12/19(金)` for ja-JP, `Fri, 12/19/2025` for en-US. It is read-only and derived from the entered date: it shows a placeholder until the date is complete, and while a date segment is mid-entry it keeps the previous day of the week (muted), so typing `25` into the day never flashes the 2nd's. Screen readers hear the full day name with each date segment's value.
187
+
188
+ ```tsx
189
+ <DatePicker aria-label="Closing date" showDayOfWeek />
190
+ ```
191
+
192
+ ## Keyboard
193
+
194
+ - **Segments:** `↑`/`↓` increment/decrement, digits type-to-fill (auto-advance), `←`/`→` move between segments, `Backspace` clears, `/` commits the current segment and advances.
195
+ - **Whole-date shortcuts:** `t` today · `m`/`h` start/end of the entered month · `y`/`r` start/end of the year · `w`/`k` start/end of the week · `-` previous day · `=`/`+` next day.
196
+ - **Calendar grid:** arrows move by day/week, `Home`/`End` to week start/end, `PageUp`/`PageDown` by month, `Shift`+`PageUp`/`PageDown` by year, `Enter`/`Space` selects. `Alt`+`↓` opens the calendar from the field.
197
+
198
+ ## Props
199
+
200
+ ### DateFieldProps
201
+
202
+ | Prop | Type | Description |
203
+ | -------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------ |
204
+ | `value` / `defaultValue` | `DateValue \| null` | Controlled / uncontrolled value |
205
+ | `onChange` | `(v: DateValue \| null) => void` | Fires when the value changes |
206
+ | `onBlur` | `() => void` | Fires when focus leaves the whole segmented control |
207
+ | `minValue` / `maxValue` | `DateValue` | Inclusive date range bounds |
208
+ | `isDateUnavailable` | `(date: DateValue) => boolean` | Marks specific dates unavailable |
209
+ | `isDisabled` | `boolean` | Disables interaction and form submission |
210
+ | `isReadOnly` | `boolean` | Allows focus/navigation without editing |
211
+ | `isRequired` | `boolean` | Marks the control required |
212
+ | `isInvalid` | `boolean` | Adds invalid styling / `aria-invalid` to the segmented UI |
213
+ | `placeholderValue` | `DateValue` | Seeds unset segments |
214
+ | `granularity` | `"day" \| "hour" \| "minute" \| "second"` | Smallest editable unit; time granularities add time segments |
215
+ | `hourCycle` | `12 \| 24` | Force 12- or 24-hour time; defaults to the locale |
216
+ | `autoFocus` | `boolean` | Focus the first segment on mount |
217
+ | `locale` | `string` | BCP-47 locale override |
218
+ | `showDayOfWeek` | `boolean` | Show the locale's short day of the week next to the date |
219
+ | `name` | `string` | Emits a form value through the proxy input |
220
+ | `id` | `string` | Proxy input id (use with external `<label htmlFor>`). |
221
+ | `firstDayOfWeek` | `"sun" \| "mon" \| "tue" \| "wed" \| "thu" \| "fri" \| "sat"` | Override the locale week start used by `w` / `k` shortcuts |
222
+ | `aria-label` / `aria-labelledby` | `string` | Accessible name |
223
+ | `aria-describedby` | `string` | IDs of description / error elements |
224
+ | `className` | `string` | Root element class |
225
+
226
+ ### DatePickerProps
227
+
228
+ All `DateFieldProps`, plus:
229
+
230
+ | Prop | Type | Description |
231
+ | ---------------- | ----------------------- | ----------------------------------- |
232
+ | `timeZone` | `string` | IANA timezone for resolving "today" |
233
+ | `firstDayOfWeek` | `"sun" \| "mon" \| ...` | Force the calendar's first column |
234
+
235
+ ### CalendarProps
236
+
237
+ See the calendar docs in-code: controlled/uncontrolled value, min/max, unavailable dates, focused date, locale, timezone, accessible naming, and className.
238
+
239
+ ### DateRangePickerProps
240
+
241
+ The `DatePickerProps` surface (labeling, `isInvalid`, `min/maxValue`, `isDateUnavailable`, `granularity`, `hourCycle`, `firstDayOfWeek`, `timeZone`, `locale`, `showDayOfWeek`, `autoFocus`, `isDisabled/ReadOnly/Required`), with the range-specific differences:
242
+
243
+ | Prop | Type | Description |
244
+ | ------------------------ | -------------------------------- | ------------------------------------------------------------------------------- |
245
+ | `value` / `defaultValue` | `DateRange \| null` | Controlled / uncontrolled `{ start, end }` range |
246
+ | `onChange` | `(v: DateRange \| null) => void` | Fires with a complete range, or `null` when cleared/incomplete |
247
+ | `name` | `string` | One combined hidden input (`start/end`) for native POST; `Field.Root` name wins |
248
+ | `startName` / `endName` | `string` | Emit two plain hidden inputs with the ISO start/end (classic POST) |
249
+
250
+ A typed range with `end` before `start` sets the invalid state and reports a built-in `customError` message (`Field.Error match="customError"`); the calendar always commits ordered endpoints.
251
+
252
+ ### RangeCalendarProps
253
+
254
+ Same surface as `CalendarProps`, with `value` / `defaultValue`: `DateRange | null` and `onChange`: `(v: DateRange) => void` (fired once per selection, when the second date completes the range).
255
+
256
+ ## Related
257
+
258
+ - [useTimeZone](../api/use-time-zone.md)
259
+ - [useResolvedLocale](../api/use-resolved-locale.md)
@@ -0,0 +1,75 @@
1
+ ---
2
+ title: DefaultHeader
3
+ description: The built-in SidebarLayout top bar, extensible via an actions slot
4
+ ---
5
+
6
+ <!-- GENERATED by docs-kit from docs-src/components/default-header.docs.outline.md — do not edit by hand. -->
7
+
8
+ # DefaultHeader
9
+
10
+ `DefaultHeader` is the built-in top bar rendered by [`SidebarLayout`](./sidebar-layout.md). It shows the sidebar trigger and breadcrumb trail on the left, and an `actions` cluster (defaulting to the [`AppearanceSwitcher`](./appearance-switcher.md)) on the right.
11
+
12
+ It is exposed as `SidebarLayout.DefaultHeader` (and as a top-level `DefaultHeader` export) so you can slightly extend the built-in header — the common case being adding a notification bell or user menu — without reconstructing the trigger and breadcrumb yourself.
13
+
14
+ ## Import
15
+
16
+ ```tsx
17
+ import { SidebarLayout } from "@tailor-platform/app-shell";
18
+ // SidebarLayout.DefaultHeader
19
+
20
+ // or, equivalently:
21
+ import { DefaultHeader } from "@tailor-platform/app-shell";
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ `DefaultHeader` goes into `SidebarLayout`'s [`header`](./sidebar-layout.md#header) slot:
27
+
28
+ ```tsx
29
+ import { SidebarLayout, AppearanceSwitcher, Button } from "@tailor-platform/app-shell";
30
+ import { BellIcon } from "lucide-react";
31
+
32
+ <SidebarLayout
33
+ header={
34
+ <SidebarLayout.DefaultHeader
35
+ actions={[
36
+ <Button key="bell" variant="outline" size="icon" aria-label="Notifications">
37
+ <BellIcon />
38
+ </Button>,
39
+ <AppearanceSwitcher key="appearance" />,
40
+ ]}
41
+ />
42
+ }
43
+ />;
44
+ ```
45
+
46
+ ## Props
47
+
48
+ ### actions
49
+
50
+ - **Type:** `React.ReactNode | React.ReactNode[]` (optional)
51
+ - **Default:** `[<AppearanceSwitcher />]`
52
+ - **Description:** The entire right-hand cluster of the header. Rendered in a horizontal, vertically-centered row (`flex flex-row items-center gap-2`) with consistent spacing — you don't wrap it yourself. Accepts a single node or an array of nodes.
53
+
54
+ > ⚠️ **`actions` replaces the whole right-hand cluster, including the appearance switcher.**
55
+ >
56
+ > - Omitting `actions` keeps the default (`[<AppearanceSwitcher />]`), so the out-of-the-box header is unchanged.
57
+ > - If you pass your own `actions` and still want the switcher, include `<AppearanceSwitcher />` in the array — it is a public export.
58
+ > - `actions={[]}` renders an empty right side.
59
+
60
+ This "the switcher is just another action" contract keeps the API a single slot rather than accumulating one-off props like `hideAppearanceSwitcher`.
61
+
62
+ ## When to use which level of customization
63
+
64
+ | Goal | Approach |
65
+ | --------------------------------- | ------------------------------------------------------------------------------- |
66
+ | The standard header | Omit `header` on `SidebarLayout` |
67
+ | Add controls next to the switcher | `header={<SidebarLayout.DefaultHeader actions={[...]} />}` |
68
+ | A completely different header | `header={<MyCustomHeader />}` (see [SidebarLayout](./sidebar-layout.md#header)) |
69
+
70
+ ## Related Components
71
+
72
+ - [SidebarLayout](./sidebar-layout.md) - Hosts the header via the `header` slot
73
+ - [DefaultSidebar](./default-sidebar.md) - The sibling built-in region (`SidebarLayout.DefaultSidebar`)
74
+ - [AppearanceSwitcher](./appearance-switcher.md) - Default action; include it in `actions` to keep it
75
+ - [Button](./button.md) - For building icon actions
@@ -0,0 +1,136 @@
1
+ ---
2
+ title: DefaultSidebar
3
+ description: Built-in sidebar component for auto-generated or composed navigation, with optional search suppression and icon-rail mode
4
+ ---
5
+
6
+ <!-- GENERATED by docs-kit from docs-src/components/default-sidebar.docs.outline.md — do not edit by hand. -->
7
+
8
+ # DefaultSidebar
9
+
10
+ `DefaultSidebar` is the built-in sidebar used by [`SidebarLayout`](./sidebar-layout.md). It has two modes:
11
+
12
+ - **Auto-generation mode** — omit `children` and it renders navigation from your AppShell modules and resources.
13
+ - **Composition mode** — pass `children` and build the menu yourself with `SidebarItem`, `SidebarGroup`, `SidebarSeparator`, and the low-level `SidebarMenuItem` / `SidebarMenuButton` primitives.
14
+
15
+ > Also available as **`SidebarLayout.DefaultSidebar`**. The namespaced form is preferred for discoverability; the top-level `DefaultSidebar` export is kept for backwards compatibility.
16
+
17
+ ## Props
18
+
19
+ | Prop | Type | Default | Description |
20
+ | ------------ | ----------------- | -------- | ------------------------------------------------------------------------------------------------------- |
21
+ | `header` | `React.ReactNode` | built-in | Replaces the sidebar header content. |
22
+ | `footer` | `React.ReactNode` | - | Footer content rendered after the navigation area. |
23
+ | `children` | `React.ReactNode` | - | When provided, enables composition mode and disables auto-generation. |
24
+ | `hideHeader` | `boolean` | `false` | Hides the sidebar's own header row. Useful when a full-width top bar already owns the app title/toggle. |
25
+ | `hideSearch` | `boolean` | `false` | Hides the built-in **Search** entry that opens the Command Palette. |
26
+ | `iconRail` | `boolean` | `false` | Collapses to a persistent icon rail instead of sliding fully off-canvas. |
27
+
28
+ ## Basic usage
29
+
30
+ ```tsx
31
+ import { SidebarLayout } from "@tailor-platform/app-shell";
32
+
33
+ function Layout() {
34
+ return <SidebarLayout.DefaultSidebar />;
35
+ }
36
+ ```
37
+
38
+ ## Composition mode
39
+
40
+ ```tsx
41
+ import {
42
+ SidebarGroup,
43
+ SidebarItem,
44
+ SidebarLayout,
45
+ SidebarSeparator,
46
+ } from "@tailor-platform/app-shell";
47
+
48
+ function Layout() {
49
+ return (
50
+ <SidebarLayout.DefaultSidebar>
51
+ <SidebarItem to="/" />
52
+ <SidebarSeparator />
53
+ <SidebarGroup title="Main">
54
+ <SidebarItem to="/dashboard" />
55
+ <SidebarItem to="/orders" />
56
+ </SidebarGroup>
57
+ </SidebarLayout.DefaultSidebar>
58
+ );
59
+ }
60
+ ```
61
+
62
+ ## Search entry
63
+
64
+ The built-in **Search** entry opens AppShell's [`CommandPalette`](./command-palette.md). It is rendered in both auto-generated and composed navigation.
65
+
66
+ Hide it only when search is already exposed elsewhere, such as a dedicated top-bar control:
67
+
68
+ ```tsx
69
+ <SidebarLayout.DefaultSidebar hideSearch />
70
+ ```
71
+
72
+ ## Icon-rail behavior
73
+
74
+ With `iconRail`, collapsing the sidebar keeps icons visible at every width:
75
+
76
+ - on desktop, the sidebar collapses to a narrow persistent rail
77
+ - on mobile, the rail stays visible and its toggle opens the full sidebar as a slide-in drawer
78
+ - grouped items reveal child pages from the collapsed icon via a flyout popover
79
+ - items without children show their label in a tooltip
80
+
81
+ [`GlobalHeaderLayout`](./global-header-layout.md) bakes this mode in through `GlobalHeaderLayout.DefaultSidebar`.
82
+
83
+ ## Working with a global top bar
84
+
85
+ When the app title and primary toggle live in a full-width top bar, hide the sidebar's own header:
86
+
87
+ ```tsx
88
+ <SidebarLayout topBar={<MyGlobalTopBar />} sidebar={<SidebarLayout.DefaultSidebar hideHeader />} />
89
+ ```
90
+
91
+ ## Custom footer
92
+
93
+ ```tsx
94
+ function UserProfile() {
95
+ return (
96
+ <div className="border-t p-4">
97
+ <p className="text-sm font-medium">Ada Lovelace</p>
98
+ <button type="button" className="mt-2 text-sm text-muted-foreground">
99
+ Logout
100
+ </button>
101
+ </div>
102
+ );
103
+ }
104
+
105
+ <SidebarLayout.DefaultSidebar footer={<UserProfile />} />;
106
+ ```
107
+
108
+ ## Low-level custom items
109
+
110
+ When `SidebarItem` is too opinionated, compose a custom row with the exported primitives:
111
+
112
+ ```tsx
113
+ import { SidebarLayout, SidebarMenuButton, SidebarMenuItem } from "@tailor-platform/app-shell";
114
+ import { BellIcon } from "lucide-react";
115
+
116
+ <SidebarLayout.DefaultSidebar>
117
+ <SidebarMenuItem>
118
+ <SidebarMenuButton
119
+ render={<button type="button" />}
120
+ onClick={() => openNotifications()}
121
+ tooltip="Notifications"
122
+ >
123
+ <BellIcon className="size-4" />
124
+ <span>Notifications</span>
125
+ </SidebarMenuButton>
126
+ </SidebarMenuItem>
127
+ </SidebarLayout.DefaultSidebar>;
128
+ ```
129
+
130
+ ## Related
131
+
132
+ - [SidebarLayout](./sidebar-layout.md) - layout wrapper for sidebar + content
133
+ - [GlobalHeaderLayout](./global-header-layout.md) - opinionated app-wide header mode
134
+ - [SidebarItem](./sidebar-item.md) - individual navigation links
135
+ - [SidebarGroup](./sidebar-group.md) - collapsible navigation groups
136
+ - [Sidebar Navigation](../concepts/sidebar-navigation.md) - navigation concepts and composition patterns