@tailor-platform/app-shell 1.14.0 → 1.16.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.
- package/LICENSE.md +21 -0
- package/dist/app-shell-core.css +1 -1
- package/dist/app-shell.d.ts +1203 -316
- package/dist/app-shell.js +4562 -3307
- package/dist/{appshell-CtS8Y3LW.js → appshell-B0wh5Lq0.js} +850 -549
- package/dist/style-entry.d.ts +118 -98
- package/dist/testing.d.ts +118 -98
- package/dist/testing.js +1 -1
- package/dist/themes/_template.css +1 -1
- package/dist/vite-plugin.d.ts +118 -98
- package/package.json +13 -13
- package/skills/app-shell-patterns/SKILL.md +108 -24
- package/skills/app-shell-patterns/references/api/create-ai-gateway-client.md +115 -0
- package/skills/app-shell-patterns/references/api/create-typed-paths.md +117 -0
- package/skills/app-shell-patterns/references/api/define-i18n-labels.md +143 -0
- package/skills/app-shell-patterns/references/api/define-module.md +247 -0
- package/skills/app-shell-patterns/references/api/define-resource.md +307 -0
- package/skills/app-shell-patterns/references/api/guards/hidden.md +202 -0
- package/skills/app-shell-patterns/references/api/guards/overview.md +354 -0
- package/skills/app-shell-patterns/references/api/guards/pass.md +129 -0
- package/skills/app-shell-patterns/references/api/guards/redirect-to.md +307 -0
- package/skills/app-shell-patterns/references/api/router/use-location.md +240 -0
- package/skills/app-shell-patterns/references/api/router/use-navigate.md +138 -0
- package/skills/app-shell-patterns/references/api/router/use-params.md +218 -0
- package/skills/app-shell-patterns/references/api/use-ai-chat.md +110 -0
- package/skills/app-shell-patterns/references/api/use-app-shell-config.md +126 -0
- package/skills/app-shell-patterns/references/api/use-app-shell-data.md +146 -0
- package/skills/app-shell-patterns/references/api/use-app-shell.md +143 -0
- package/skills/app-shell-patterns/references/api/use-auth.md +145 -0
- package/skills/app-shell-patterns/references/api/use-override-breadcrumb.md +74 -0
- package/skills/app-shell-patterns/references/api/use-page-meta.md +96 -0
- package/skills/app-shell-patterns/references/api/use-register-command-palette-actions.md +90 -0
- package/skills/app-shell-patterns/references/api/use-resolved-locale.md +67 -0
- package/skills/app-shell-patterns/references/api/use-route-error.md +214 -0
- package/skills/app-shell-patterns/references/api/use-theme.md +108 -0
- package/skills/app-shell-patterns/references/api/use-time-zone.md +80 -0
- package/skills/app-shell-patterns/references/api/use-toast.md +107 -0
- package/skills/app-shell-patterns/references/components/action-panel.md +168 -0
- package/skills/app-shell-patterns/references/components/activity-card.md +142 -0
- package/skills/app-shell-patterns/references/components/ai-chat.md +315 -0
- package/skills/app-shell-patterns/references/components/alert.md +202 -0
- package/skills/app-shell-patterns/references/components/app-shell.md +530 -0
- package/skills/app-shell-patterns/references/components/appearance-switcher.md +87 -0
- package/skills/app-shell-patterns/references/components/attachment.md +138 -0
- package/skills/app-shell-patterns/references/components/autocomplete.md +278 -0
- package/skills/app-shell-patterns/references/components/avatar.md +80 -0
- package/skills/app-shell-patterns/references/components/badge.md +309 -0
- package/skills/app-shell-patterns/references/components/button.md +164 -0
- package/skills/app-shell-patterns/references/components/card.md +109 -0
- package/skills/app-shell-patterns/references/components/checkbox.md +169 -0
- package/skills/app-shell-patterns/references/components/combobox.md +318 -0
- package/skills/app-shell-patterns/references/components/command-palette.md +413 -0
- package/skills/app-shell-patterns/references/components/csv-importer.md +214 -0
- package/skills/app-shell-patterns/references/components/data-table.md +953 -0
- package/skills/app-shell-patterns/references/components/date-picker.md +248 -0
- package/skills/app-shell-patterns/references/components/default-header.md +75 -0
- package/skills/app-shell-patterns/references/components/default-sidebar.md +136 -0
- package/skills/app-shell-patterns/references/components/description-card.md +569 -0
- package/skills/app-shell-patterns/references/components/dialog.md +164 -0
- package/skills/app-shell-patterns/references/components/document-progress-card.md +154 -0
- package/skills/app-shell-patterns/references/components/form.md +378 -0
- package/skills/app-shell-patterns/references/components/global-header-layout.md +132 -0
- package/skills/app-shell-patterns/references/components/grid.md +184 -0
- package/skills/app-shell-patterns/references/components/input.md +83 -0
- package/skills/app-shell-patterns/references/components/layout.md +539 -0
- package/skills/app-shell-patterns/references/components/menu.md +218 -0
- package/skills/app-shell-patterns/references/components/metric-card.md +94 -0
- package/skills/app-shell-patterns/references/components/select.md +283 -0
- package/skills/app-shell-patterns/references/components/sheet.md +237 -0
- package/skills/app-shell-patterns/references/components/sidebar-group.md +466 -0
- package/skills/app-shell-patterns/references/components/sidebar-item.md +458 -0
- package/skills/app-shell-patterns/references/components/sidebar-layout.md +258 -0
- package/skills/app-shell-patterns/references/components/spinner.md +81 -0
- package/skills/app-shell-patterns/references/components/table.md +188 -0
- package/skills/app-shell-patterns/references/components/tabs.md +158 -0
- package/skills/app-shell-patterns/references/components/textarea.md +122 -0
- package/skills/app-shell-patterns/references/components/timeline.md +317 -0
- package/skills/app-shell-patterns/references/components/toolbar.md +138 -0
- package/skills/app-shell-patterns/references/components/tooltip.md +144 -0
- package/skills/app-shell-patterns/references/components/with-guard.md +445 -0
- package/skills/app-shell-patterns/references/concepts/authentication.md +301 -0
- package/skills/app-shell-patterns/references/concepts/custom-components.md +59 -0
- package/skills/app-shell-patterns/references/concepts/file-based-routing.md +350 -0
- package/skills/app-shell-patterns/references/{fundamental → concepts}/graphql.md +11 -4
- package/skills/app-shell-patterns/references/concepts/modules-and-resources.md +229 -0
- package/skills/app-shell-patterns/references/concepts/routing-navigation.md +387 -0
- package/skills/app-shell-patterns/references/concepts/sidebar-navigation.md +388 -0
- package/skills/app-shell-patterns/references/{fundamental/design-system.md → concepts/styling-theming.md} +260 -105
- package/skills/app-shell-patterns/references/migrations.md +34 -0
- package/skills/app-shell-patterns/references/pages/document-detail.md +1125 -0
- package/skills/app-shell-patterns/references/patterns/form-composer.md +44 -46
- package/skills/app-shell-patterns/references/patterns/form-modal.md +39 -100
- package/skills/app-shell-patterns/references/patterns/form-sectioned.md +12 -38
- package/skills/app-shell-patterns/references/patterns/form-single-page.md +11 -32
- package/skills/app-shell-patterns/references/patterns/form-wizard.md +12 -53
- package/skills/app-shell-patterns/references/patterns/interaction-confirm.md +11 -27
- package/skills/app-shell-patterns/references/patterns/interaction-multi-select.md +14 -28
- package/skills/app-shell-patterns/references/patterns/interaction-toast.md +10 -34
- package/skills/app-shell-patterns/references/patterns/list-dense-scan.md +11 -86
- package/skills/app-shell-patterns/references/fundamental/components.md +0 -981
- package/skills/app-shell-patterns/references/patterns/detail-hero-with-actions.md +0 -201
|
@@ -0,0 +1,248 @@
|
|
|
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
|
+
## Keyboard
|
|
185
|
+
|
|
186
|
+
- **Segments:** `↑`/`↓` increment/decrement, digits type-to-fill (auto-advance), `←`/`→` move between segments, `Backspace` clears, `/` commits the current segment and advances.
|
|
187
|
+
- **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.
|
|
188
|
+
- **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.
|
|
189
|
+
|
|
190
|
+
## Props
|
|
191
|
+
|
|
192
|
+
### DateFieldProps
|
|
193
|
+
|
|
194
|
+
| Prop | Type | Description |
|
|
195
|
+
| -------------------------------- | ------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
196
|
+
| `value` / `defaultValue` | `DateValue \| null` | Controlled / uncontrolled value |
|
|
197
|
+
| `onChange` | `(v: DateValue \| null) => void` | Fires when the value changes |
|
|
198
|
+
| `onBlur` | `() => void` | Fires when focus leaves the whole segmented control |
|
|
199
|
+
| `minValue` / `maxValue` | `DateValue` | Inclusive date range bounds |
|
|
200
|
+
| `isDateUnavailable` | `(date: DateValue) => boolean` | Marks specific dates unavailable |
|
|
201
|
+
| `isDisabled` | `boolean` | Disables interaction and form submission |
|
|
202
|
+
| `isReadOnly` | `boolean` | Allows focus/navigation without editing |
|
|
203
|
+
| `isRequired` | `boolean` | Marks the control required |
|
|
204
|
+
| `isInvalid` | `boolean` | Adds invalid styling / `aria-invalid` to the segmented UI |
|
|
205
|
+
| `placeholderValue` | `DateValue` | Seeds unset segments |
|
|
206
|
+
| `autoFocus` | `boolean` | Focus the first segment on mount |
|
|
207
|
+
| `locale` | `string` | BCP-47 locale override |
|
|
208
|
+
| `name` | `string` | Emits a form value through the proxy input |
|
|
209
|
+
| `id` | `string` | Proxy input id (use with external `<label htmlFor>`). |
|
|
210
|
+
| `firstDayOfWeek` | `"sun" \| "mon" \| "tue" \| "wed" \| "thu" \| "fri" \| "sat"` | Override the locale week start used by `w` / `k` shortcuts |
|
|
211
|
+
| `aria-label` / `aria-labelledby` | `string` | Accessible name |
|
|
212
|
+
| `aria-describedby` | `string` | IDs of description / error elements |
|
|
213
|
+
| `className` | `string` | Root element class |
|
|
214
|
+
|
|
215
|
+
### DatePickerProps
|
|
216
|
+
|
|
217
|
+
All `DateFieldProps`, plus:
|
|
218
|
+
|
|
219
|
+
| Prop | Type | Description |
|
|
220
|
+
| ---------------- | ----------------------- | ----------------------------------- |
|
|
221
|
+
| `timeZone` | `string` | IANA timezone for resolving "today" |
|
|
222
|
+
| `firstDayOfWeek` | `"sun" \| "mon" \| ...` | Force the calendar's first column |
|
|
223
|
+
|
|
224
|
+
### CalendarProps
|
|
225
|
+
|
|
226
|
+
See the calendar docs in-code: controlled/uncontrolled value, min/max, unavailable dates, focused date, locale, timezone, accessible naming, and className.
|
|
227
|
+
|
|
228
|
+
### DateRangePickerProps
|
|
229
|
+
|
|
230
|
+
The `DatePickerProps` surface (labeling, `isInvalid`, `min/maxValue`, `isDateUnavailable`, `granularity`, `firstDayOfWeek`, `timeZone`, `locale`, `autoFocus`, `isDisabled/ReadOnly/Required`), with the range-specific differences:
|
|
231
|
+
|
|
232
|
+
| Prop | Type | Description |
|
|
233
|
+
| ------------------------ | -------------------------------- | ------------------------------------------------------------------------------- |
|
|
234
|
+
| `value` / `defaultValue` | `DateRange \| null` | Controlled / uncontrolled `{ start, end }` range |
|
|
235
|
+
| `onChange` | `(v: DateRange \| null) => void` | Fires with a complete range, or `null` when cleared/incomplete |
|
|
236
|
+
| `name` | `string` | One combined hidden input (`start/end`) for native POST; `Field.Root` name wins |
|
|
237
|
+
| `startName` / `endName` | `string` | Emit two plain hidden inputs with the ISO start/end (classic POST) |
|
|
238
|
+
|
|
239
|
+
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.
|
|
240
|
+
|
|
241
|
+
### RangeCalendarProps
|
|
242
|
+
|
|
243
|
+
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).
|
|
244
|
+
|
|
245
|
+
## Related
|
|
246
|
+
|
|
247
|
+
- [useTimeZone](../api/use-time-zone.md)
|
|
248
|
+
- [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
|