@shadow-js/ui 0.0.0-stage → 1.0.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/CHANGELOG.md +24 -0
- package/LICENSE +21 -0
- package/README.md +598 -2
- package/dist/cli.mjs +2293 -0
- package/dist/dev/cli/schema.d.ts +73 -0
- package/dist/dev/index.d.ts +6 -0
- package/dist/dev/index.js +5 -0
- package/dist/dev/locales/ar.d.ts +141 -0
- package/dist/dev/locales/ar.js +128 -0
- package/dist/dev/locales/ar.js.map +1 -0
- package/dist/dev/locales/en.d.ts +141 -0
- package/dist/dev/locales/en.js +128 -0
- package/dist/dev/locales/en.js.map +1 -0
- package/dist/dev/registry/utils/utils.d.ts +29 -0
- package/dist/dev/registry/utils/utils.js +27 -0
- package/dist/dev/registry/utils/utils.js.map +1 -0
- package/dist/dev/theme/theme-logic.d.ts +187 -0
- package/dist/dev/theme/theme-logic.js +184 -0
- package/dist/dev/theme/theme-logic.js.map +1 -0
- package/dist/dev/theme/theme-provider.d.ts +90 -0
- package/dist/dev/theme/theme-provider.js +150 -0
- package/dist/dev/theme/theme-provider.js.map +1 -0
- package/dist/prod/index.js +1 -0
- package/dist/prod/locales/ar.js +2 -0
- package/dist/prod/locales/ar.js.map +1 -0
- package/dist/prod/locales/en.js +2 -0
- package/dist/prod/locales/en.js.map +1 -0
- package/dist/prod/registry/utils/utils.js +2 -0
- package/dist/prod/registry/utils/utils.js.map +1 -0
- package/dist/prod/theme/theme-logic.js +2 -0
- package/dist/prod/theme/theme-logic.js.map +1 -0
- package/dist/prod/theme/theme-provider.js +2 -0
- package/dist/prod/theme/theme-provider.js.map +1 -0
- package/package.json +102 -4
- package/registry/accordion/accordion.tsx +210 -0
- package/registry/accordion/item.json +4 -0
- package/registry/alert/alert.tsx +200 -0
- package/registry/alert/item.json +4 -0
- package/registry/alert-dialog/alert-dialog.tsx +530 -0
- package/registry/alert-dialog/item.json +4 -0
- package/registry/aspect-ratio/aspect-ratio.tsx +71 -0
- package/registry/aspect-ratio/item.json +4 -0
- package/registry/attachment/attachment.tsx +459 -0
- package/registry/attachment/item.json +4 -0
- package/registry/avatar/avatar.tsx +385 -0
- package/registry/avatar/item.json +4 -0
- package/registry/badge/badge.tsx +108 -0
- package/registry/badge/item.json +4 -0
- package/registry/breadcrumb/breadcrumb.tsx +354 -0
- package/registry/breadcrumb/item.json +4 -0
- package/registry/bubble/bubble.tsx +260 -0
- package/registry/bubble/item.json +4 -0
- package/registry/button/button.tsx +125 -0
- package/registry/button/item.json +4 -0
- package/registry/button-group/button-group.tsx +189 -0
- package/registry/button-group/item.json +4 -0
- package/registry/calendar/calendar.tsx +348 -0
- package/registry/calendar/item.json +4 -0
- package/registry/card/card.tsx +311 -0
- package/registry/card/item.json +4 -0
- package/registry/carousel/carousel.tsx +851 -0
- package/registry/carousel/item.json +4 -0
- package/registry/chart/chart.tsx +1956 -0
- package/registry/chart/item.json +4 -0
- package/registry/chart-scale/chart-scale.ts +670 -0
- package/registry/chart-scale/item.json +5 -0
- package/registry/checkbox/checkbox.tsx +79 -0
- package/registry/checkbox/item.json +4 -0
- package/registry/code-block/code-block.tsx +470 -0
- package/registry/code-block/item.json +4 -0
- package/registry/collapsible/collapsible.tsx +117 -0
- package/registry/collapsible/item.json +4 -0
- package/registry/combobox/combobox.tsx +977 -0
- package/registry/combobox/item.json +4 -0
- package/registry/command/command.tsx +757 -0
- package/registry/command/item.json +4 -0
- package/registry/context-menu/context-menu.tsx +697 -0
- package/registry/context-menu/item.json +4 -0
- package/registry/data-table/data-table.tsx +437 -0
- package/registry/data-table/item.json +4 -0
- package/registry/date-picker/date-picker.tsx +349 -0
- package/registry/date-picker/item.json +4 -0
- package/registry/dialog/dialog.tsx +412 -0
- package/registry/dialog/item.json +4 -0
- package/registry/direction/direction.tsx +88 -0
- package/registry/direction/item.json +4 -0
- package/registry/drawer/drawer.tsx +787 -0
- package/registry/drawer/item.json +4 -0
- package/registry/dropdown-menu/dropdown-menu.tsx +692 -0
- package/registry/dropdown-menu/item.json +4 -0
- package/registry/empty/empty.tsx +240 -0
- package/registry/empty/item.json +4 -0
- package/registry/field/field.tsx +624 -0
- package/registry/field/item.json +4 -0
- package/registry/form/form.tsx +1112 -0
- package/registry/form/item.json +4 -0
- package/registry/hover-card/hover-card.tsx +144 -0
- package/registry/hover-card/item.json +4 -0
- package/registry/icons/icons.tsx +1691 -0
- package/registry/icons/item.json +4 -0
- package/registry/input/input.tsx +43 -0
- package/registry/input/item.json +4 -0
- package/registry/input-group/input-group.tsx +315 -0
- package/registry/input-group/item.json +4 -0
- package/registry/input-otp/input-otp.tsx +329 -0
- package/registry/input-otp/item.json +4 -0
- package/registry/item/item.json +4 -0
- package/registry/item/item.tsx +439 -0
- package/registry/kbd/item.json +4 -0
- package/registry/kbd/kbd.tsx +65 -0
- package/registry/label/item.json +4 -0
- package/registry/label/label.tsx +60 -0
- package/registry/marker/item.json +4 -0
- package/registry/marker/marker.tsx +175 -0
- package/registry/menubar/item.json +4 -0
- package/registry/menubar/menubar.tsx +694 -0
- package/registry/message/item.json +4 -0
- package/registry/message/message.tsx +280 -0
- package/registry/message-scroller/item.json +4 -0
- package/registry/message-scroller/message-scroller.tsx +262 -0
- package/registry/native-select/item.json +4 -0
- package/registry/native-select/native-select.tsx +113 -0
- package/registry/navigation-menu/item.json +4 -0
- package/registry/navigation-menu/navigation-menu.tsx +362 -0
- package/registry/pagination/item.json +4 -0
- package/registry/pagination/pagination.tsx +460 -0
- package/registry/password-input/item.json +5 -0
- package/registry/password-input/password-input.tsx +494 -0
- package/registry/popover/item.json +4 -0
- package/registry/popover/popover.tsx +284 -0
- package/registry/progress/item.json +4 -0
- package/registry/progress/progress.tsx +190 -0
- package/registry/questionnaire/item.json +4 -0
- package/registry/questionnaire/questionnaire.tsx +569 -0
- package/registry/radio-group/item.json +4 -0
- package/registry/radio-group/radio-group.tsx +101 -0
- package/registry/resizable/item.json +4 -0
- package/registry/resizable/resizable.tsx +455 -0
- package/registry/scroll-area/item.json +4 -0
- package/registry/scroll-area/scroll-area.tsx +149 -0
- package/registry/select/item.json +4 -0
- package/registry/select/select.tsx +571 -0
- package/registry/separator/item.json +4 -0
- package/registry/separator/separator.tsx +52 -0
- package/registry/sheet/item.json +4 -0
- package/registry/sheet/sheet.tsx +476 -0
- package/registry/sidebar/item.json +4 -0
- package/registry/sidebar/sidebar.tsx +1870 -0
- package/registry/skeleton/item.json +4 -0
- package/registry/skeleton/skeleton.tsx +47 -0
- package/registry/slider/item.json +4 -0
- package/registry/slider/slider.tsx +149 -0
- package/registry/spinner/item.json +4 -0
- package/registry/spinner/spinner.tsx +51 -0
- package/registry/switch/item.json +4 -0
- package/registry/switch/switch.tsx +93 -0
- package/registry/table/item.json +4 -0
- package/registry/table/table.tsx +373 -0
- package/registry/tabs/item.json +4 -0
- package/registry/tabs/tabs.tsx +209 -0
- package/registry/textarea/item.json +4 -0
- package/registry/textarea/textarea.tsx +51 -0
- package/registry/toast/item.json +4 -0
- package/registry/toast/toast.tsx +949 -0
- package/registry/toggle/item.json +4 -0
- package/registry/toggle/toggle.tsx +110 -0
- package/registry/toggle-group/item.json +4 -0
- package/registry/toggle-group/toggle-group.tsx +189 -0
- package/registry/tooltip/item.json +4 -0
- package/registry/tooltip/tooltip.tsx +169 -0
- package/registry/trace/item.json +4 -0
- package/registry/trace/trace.tsx +356 -0
- package/registry/ui-strings/item.json +5 -0
- package/registry/ui-strings/ui-strings.tsx +454 -0
- package/registry/use-highlighted-code/item.json +5 -0
- package/registry/use-highlighted-code/use-highlighted-code.tsx +145 -0
- package/registry/use-mobile/item.json +5 -0
- package/registry/use-mobile/use-mobile.ts +46 -0
- package/registry/utils/item.json +5 -0
- package/registry/utils/utils.ts +38 -0
- package/registry.json +3274 -0
- package/styles/animations.css +321 -0
- package/styles/theme-core.css +55 -0
- package/styles/theme.css +12 -0
- package/styles/themes/gray.css +69 -0
- package/styles/themes/neutral.css +69 -0
- package/styles/themes/slate.css +69 -0
- package/styles/themes/stone.css +69 -0
- package/styles/themes/zinc.css +69 -0
- package/styles/typeset.css +251 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { splitProps } from "@shadow-js/core";
|
|
2
|
+
import type {
|
|
3
|
+
CollapsibleContentProps,
|
|
4
|
+
CollapsibleProps,
|
|
5
|
+
CollapsibleTriggerProps,
|
|
6
|
+
PolymorphicTarget,
|
|
7
|
+
} from "@shadow-js/primitives";
|
|
8
|
+
import type { ComponentProps, JSX } from "@shadow-js/web";
|
|
9
|
+
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
|
|
10
|
+
import { ChevronRightIcon } from "@/components/ui/icons";
|
|
11
|
+
import { cn } from "@/lib/utils";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A list of the steps an agent takes: each is a line with an icon, a title and an optional description
|
|
15
|
+
* and status. A line can expand with {@link TraceCollapsible}, or be wrapped in a link or the trigger of a
|
|
16
|
+
* dialog, sheet, drawer or popover. Use `Trace` for the steps, `Message` for the reply and `Marker` for notes
|
|
17
|
+
* between turns.
|
|
18
|
+
*
|
|
19
|
+
* Keyboard and ARIA: the container is a plain `div` with no role. A {@link TraceLine} on its own is text and is
|
|
20
|
+
* not focusable. The line becomes a button when wrapped in {@link TraceCollapsibleTrigger}, or takes the keys of a link or
|
|
21
|
+
* dialog trigger it is wrapped in. Status is shown with color and motion, so say it in the title too ("Running tests",
|
|
22
|
+
* "Failed to run lint"). Inside a message scroller each added line is announced once.
|
|
23
|
+
*
|
|
24
|
+
* Compared with shadcn/ui: `as` replaces `render`, `class` replaces `className`, and every part has a `data-slot`.
|
|
25
|
+
*
|
|
26
|
+
* @param props - The `div` attributes and `class`.
|
|
27
|
+
* @returns The trace container.
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* import { SearchIcon } from "@/components/ui/icons";
|
|
31
|
+
* import { Trace, TraceIcon, TraceLine, TraceTitle } from "@/components/ui/trace";
|
|
32
|
+
*
|
|
33
|
+
* export function Step() {
|
|
34
|
+
* return (
|
|
35
|
+
* <Trace>
|
|
36
|
+
* <TraceLine>
|
|
37
|
+
* <TraceIcon>
|
|
38
|
+
* <SearchIcon />
|
|
39
|
+
* </TraceIcon>
|
|
40
|
+
* <TraceTitle>Searched for minimumReleaseAge</TraceTitle>
|
|
41
|
+
* </TraceLine>
|
|
42
|
+
* </Trace>
|
|
43
|
+
* );
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
* @since 1.0.0
|
|
47
|
+
* @see {@link TraceLine}
|
|
48
|
+
* @see {@link TraceCollapsible}
|
|
49
|
+
*/
|
|
50
|
+
function Trace(props: ComponentProps<"div">): JSX.Element {
|
|
51
|
+
const [local, rest] = splitProps(props, ["class"]);
|
|
52
|
+
return (
|
|
53
|
+
<div data-slot="trace" class={cn("flex min-w-0 flex-col gap-1.5", local.class)} {...rest} />
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The state of the work a {@link TraceLine} reports. A line with no status is finished work.
|
|
59
|
+
* @since 1.0.0
|
|
60
|
+
* @see {@link TraceLine}
|
|
61
|
+
*/
|
|
62
|
+
export type TraceStatus = "running" | "error" | "pending";
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Props of {@link TraceLine}: the attributes of a `span` plus `status` (`"running"`, `"error"` or `"pending"`).
|
|
66
|
+
* Leave `status` out for work that finished.
|
|
67
|
+
* @since 1.0.0
|
|
68
|
+
* @see {@link TraceLine}
|
|
69
|
+
*/
|
|
70
|
+
export type TraceLineProps = ComponentProps<"span"> & { readonly status?: TraceStatus | undefined };
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* One step: an icon, a title, an optional description. `status` says how the work is going: `running` shimmers the
|
|
74
|
+
* title, `error` colors the line, `pending` italicizes the title and dims the icon. The line is a `span` and not a tab stop on its own: wrap it
|
|
75
|
+
* in a trigger or a link to make it interactive.
|
|
76
|
+
*
|
|
77
|
+
* Keyboard and ARIA: no role and no keys. The title is the accessible name, so write it as a sentence, with the state in it.
|
|
78
|
+
*
|
|
79
|
+
* @param props - The line props: `status` and the `span` attributes.
|
|
80
|
+
* @returns The line.
|
|
81
|
+
* @example
|
|
82
|
+
* ```tsx
|
|
83
|
+
* import { Spinner } from "@/components/ui/spinner";
|
|
84
|
+
* import { TraceIcon, TraceLine, TraceTitle } from "@/components/ui/trace";
|
|
85
|
+
*
|
|
86
|
+
* export const Running = (
|
|
87
|
+
* <TraceLine status="running">
|
|
88
|
+
* <TraceIcon>
|
|
89
|
+
* <Spinner aria-hidden="true" />
|
|
90
|
+
* </TraceIcon>
|
|
91
|
+
* <TraceTitle>Running pnpm build</TraceTitle>
|
|
92
|
+
* </TraceLine>
|
|
93
|
+
* );
|
|
94
|
+
* ```
|
|
95
|
+
* @since 1.0.0
|
|
96
|
+
* @see {@link Trace}
|
|
97
|
+
*/
|
|
98
|
+
function TraceLine(props: TraceLineProps): JSX.Element {
|
|
99
|
+
const [local, rest] = splitProps(props, ["class", "status"]);
|
|
100
|
+
return (
|
|
101
|
+
<span
|
|
102
|
+
data-slot="trace-line"
|
|
103
|
+
data-status={local.status}
|
|
104
|
+
class={cn(
|
|
105
|
+
"group/trace-line flex min-w-0 items-center gap-2 text-sm text-muted-foreground data-[status=error]:text-destructive data-[status=pending]:italic data-[status=pending]:[&_[data-slot=trace-icon]]:opacity-60",
|
|
106
|
+
local.class,
|
|
107
|
+
)}
|
|
108
|
+
{...rest}
|
|
109
|
+
/>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* The icon of a line. It is decorative and hidden from assistive technology. Before the title it names the
|
|
115
|
+
* action; after the title it acts as an indicator.
|
|
116
|
+
*
|
|
117
|
+
* Keyboard and ARIA: `aria-hidden="true"`, no role and no keys.
|
|
118
|
+
*
|
|
119
|
+
* @param props - The `span` attributes and `class`.
|
|
120
|
+
* @returns The icon slot.
|
|
121
|
+
* @example
|
|
122
|
+
* ```tsx
|
|
123
|
+
* import { TerminalIcon } from "@/components/ui/icons";
|
|
124
|
+
* import { TraceIcon } from "@/components/ui/trace";
|
|
125
|
+
*
|
|
126
|
+
* export const Icon = (
|
|
127
|
+
* <TraceIcon>
|
|
128
|
+
* <TerminalIcon />
|
|
129
|
+
* </TraceIcon>
|
|
130
|
+
* );
|
|
131
|
+
* ```
|
|
132
|
+
* @since 1.0.0
|
|
133
|
+
* @see {@link TraceLine}
|
|
134
|
+
*/
|
|
135
|
+
function TraceIcon(props: ComponentProps<"span">): JSX.Element {
|
|
136
|
+
const [local, rest] = splitProps(props, ["class"]);
|
|
137
|
+
return (
|
|
138
|
+
<span
|
|
139
|
+
data-slot="trace-icon"
|
|
140
|
+
aria-hidden="true"
|
|
141
|
+
class={cn(
|
|
142
|
+
"inline-flex shrink-0 items-center [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
|
|
143
|
+
local.class,
|
|
144
|
+
)}
|
|
145
|
+
{...rest}
|
|
146
|
+
/>
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* The text of a line: one line that truncates, and shimmers while the line is `running`.
|
|
152
|
+
*
|
|
153
|
+
* Keyboard and ARIA: no role and no keys. The text is the accessible name of the line (and of the trigger around it).
|
|
154
|
+
*
|
|
155
|
+
* @param props - The `span` attributes and `class`.
|
|
156
|
+
* @returns The title.
|
|
157
|
+
* @example
|
|
158
|
+
* ```tsx
|
|
159
|
+
* import { TraceTitle } from "@/components/ui/trace";
|
|
160
|
+
*
|
|
161
|
+
* export const Title = <TraceTitle>Read the build log</TraceTitle>;
|
|
162
|
+
* ```
|
|
163
|
+
* @since 1.0.0
|
|
164
|
+
* @see {@link TraceLine}
|
|
165
|
+
*/
|
|
166
|
+
function TraceTitle(props: ComponentProps<"span">): JSX.Element {
|
|
167
|
+
const [local, rest] = splitProps(props, ["class"]);
|
|
168
|
+
return (
|
|
169
|
+
<span
|
|
170
|
+
data-slot="trace-title"
|
|
171
|
+
class={cn("min-w-0 truncate group-data-[status=running]/trace-line:shimmer", local.class)}
|
|
172
|
+
{...rest}
|
|
173
|
+
/>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Secondary text after the title: a diff stat, a duration, a count. It does not truncate.
|
|
179
|
+
*
|
|
180
|
+
* Keyboard and ARIA: no role and no keys.
|
|
181
|
+
*
|
|
182
|
+
* @param props - The `span` attributes and `class`.
|
|
183
|
+
* @returns The description.
|
|
184
|
+
* @example
|
|
185
|
+
* ```tsx
|
|
186
|
+
* import { TraceDescription } from "@/components/ui/trace";
|
|
187
|
+
*
|
|
188
|
+
* export const Count = <TraceDescription>2 of 5 done</TraceDescription>;
|
|
189
|
+
* ```
|
|
190
|
+
* @since 1.0.0
|
|
191
|
+
* @see {@link TraceLine}
|
|
192
|
+
*/
|
|
193
|
+
function TraceDescription(props: ComponentProps<"span">): JSX.Element {
|
|
194
|
+
const [local, rest] = splitProps(props, ["class"]);
|
|
195
|
+
return (
|
|
196
|
+
<span
|
|
197
|
+
data-slot="trace-description"
|
|
198
|
+
class={cn("shrink-0 text-xs text-muted-foreground", local.class)}
|
|
199
|
+
{...rest}
|
|
200
|
+
/>
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* An expandable row: put a {@link TraceLine} in a {@link TraceCollapsibleTrigger} and the detail in a
|
|
206
|
+
* {@link TraceCollapsibleContent}. It takes the props of Collapsible: `open` with `onOpenChange` to control it,
|
|
207
|
+
* `defaultOpen` to start open. To open a row while it streams and still respect the reader's click, pass
|
|
208
|
+
* `open={open ?? running}` with the reader's choice in `open`.
|
|
209
|
+
*
|
|
210
|
+
* Keyboard and ARIA: see {@link TraceCollapsibleTrigger}.
|
|
211
|
+
*
|
|
212
|
+
* @param props - The collapsible props.
|
|
213
|
+
* @returns The row.
|
|
214
|
+
* @example
|
|
215
|
+
* ```tsx
|
|
216
|
+
* import { TerminalIcon } from "@/components/ui/icons";
|
|
217
|
+
* import {
|
|
218
|
+
* Trace,
|
|
219
|
+
* TraceCollapsible,
|
|
220
|
+
* TraceCollapsibleContent,
|
|
221
|
+
* TraceCollapsibleTrigger,
|
|
222
|
+
* TraceIcon,
|
|
223
|
+
* TraceLine,
|
|
224
|
+
* TraceTitle,
|
|
225
|
+
* } from "@/components/ui/trace";
|
|
226
|
+
*
|
|
227
|
+
* export function Command() {
|
|
228
|
+
* return (
|
|
229
|
+
* <Trace>
|
|
230
|
+
* <TraceCollapsible>
|
|
231
|
+
* <TraceCollapsibleTrigger>
|
|
232
|
+
* <TraceLine>
|
|
233
|
+
* <TraceIcon>
|
|
234
|
+
* <TerminalIcon />
|
|
235
|
+
* </TraceIcon>
|
|
236
|
+
* <TraceTitle>Ran node --version</TraceTitle>
|
|
237
|
+
* </TraceLine>
|
|
238
|
+
* </TraceCollapsibleTrigger>
|
|
239
|
+
* <TraceCollapsibleContent>v24.18.0</TraceCollapsibleContent>
|
|
240
|
+
* </TraceCollapsible>
|
|
241
|
+
* </Trace>
|
|
242
|
+
* );
|
|
243
|
+
* }
|
|
244
|
+
* ```
|
|
245
|
+
* @since 1.0.0
|
|
246
|
+
* @see {@link Trace}
|
|
247
|
+
*/
|
|
248
|
+
function TraceCollapsible(props: CollapsibleProps): JSX.Element {
|
|
249
|
+
const [local, rest] = splitProps(props, ["class"]);
|
|
250
|
+
return (
|
|
251
|
+
<Collapsible
|
|
252
|
+
data-slot="trace-collapsible"
|
|
253
|
+
class={cn("group/trace-collapsible flex min-w-0 flex-col gap-1.5", local.class)}
|
|
254
|
+
{...rest}
|
|
255
|
+
/>
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* The button that toggles a row. Put a {@link TraceLine} inside it; it adds a chevron at the end. Buttons cannot be
|
|
261
|
+
* nested in it, so put row actions beside it, not inside.
|
|
262
|
+
*
|
|
263
|
+
* Keyboard and ARIA: a native button (Enter and Space) with `aria-expanded` and, while the panel is mounted,
|
|
264
|
+
* `aria-controls`. The accessible name is the title of the line inside.
|
|
265
|
+
*
|
|
266
|
+
* @param props - The trigger props.
|
|
267
|
+
* @returns The trigger button.
|
|
268
|
+
* @example
|
|
269
|
+
* ```tsx
|
|
270
|
+
* import { TraceCollapsibleTrigger, TraceLine, TraceTitle } from "@/components/ui/trace";
|
|
271
|
+
*
|
|
272
|
+
* export const Row = (
|
|
273
|
+
* <TraceCollapsibleTrigger>
|
|
274
|
+
* <TraceLine>
|
|
275
|
+
* <TraceTitle>Researched in 3 steps</TraceTitle>
|
|
276
|
+
* </TraceLine>
|
|
277
|
+
* </TraceCollapsibleTrigger>
|
|
278
|
+
* );
|
|
279
|
+
* ```
|
|
280
|
+
* @since 1.0.0
|
|
281
|
+
* @see {@link TraceCollapsible}
|
|
282
|
+
*/
|
|
283
|
+
function TraceCollapsibleTrigger<T extends PolymorphicTarget = "button">(
|
|
284
|
+
props: CollapsibleTriggerProps<T>,
|
|
285
|
+
): JSX.Element {
|
|
286
|
+
const [local, rest] = splitProps(
|
|
287
|
+
props as unknown as { readonly class?: string; readonly children?: JSX.Element },
|
|
288
|
+
["class", "children"],
|
|
289
|
+
);
|
|
290
|
+
return (
|
|
291
|
+
<CollapsibleTrigger
|
|
292
|
+
data-slot="trace-collapsible-trigger"
|
|
293
|
+
class={cn(
|
|
294
|
+
"flex w-full min-w-0 items-center gap-2 rounded-md text-start outline-none transition-colors hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 motion-reduce:transition-none focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-transparent",
|
|
295
|
+
local.class,
|
|
296
|
+
)}
|
|
297
|
+
{...(rest as object)}
|
|
298
|
+
>
|
|
299
|
+
<span class="flex min-w-0 flex-1 items-center">{local.children}</span>
|
|
300
|
+
<ChevronRightIcon
|
|
301
|
+
aria-hidden="true"
|
|
302
|
+
class="size-4 shrink-0 text-muted-foreground transition-transform group-data-[state=open]/trace-collapsible:rotate-90 rtl:rotate-180 rtl:group-data-[state=open]/trace-collapsible:rotate-90 motion-reduce:transition-none"
|
|
303
|
+
/>
|
|
304
|
+
</CollapsibleTrigger>
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Props of {@link TraceCollapsibleContent}: the props of Collapsible's content plus `keepMounted`.
|
|
310
|
+
* @since 1.0.0
|
|
311
|
+
* @see {@link TraceCollapsibleContent}
|
|
312
|
+
*/
|
|
313
|
+
export type TraceCollapsibleContentProps = CollapsibleContentProps & {
|
|
314
|
+
/** Keeps the detail mounted while the row is closed, so nested rows keep their open state. @default false */
|
|
315
|
+
readonly keepMounted?: boolean | undefined;
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* The expandable detail of a row: text, a code block, or a nested {@link Trace}. It is muted, so add `text-foreground` to a
|
|
320
|
+
* block with its own background inside it. `keepMounted` keeps nested rows alive while this one is closed.
|
|
321
|
+
*
|
|
322
|
+
* Keyboard and ARIA: no role and no keys; it is the target of the trigger's `aria-controls`.
|
|
323
|
+
*
|
|
324
|
+
* @param props - The content props.
|
|
325
|
+
* @returns The content.
|
|
326
|
+
* @example
|
|
327
|
+
* ```tsx
|
|
328
|
+
* import { TraceCollapsibleContent } from "@/components/ui/trace";
|
|
329
|
+
*
|
|
330
|
+
* export const Detail = <TraceCollapsibleContent keepMounted>v24.18.0</TraceCollapsibleContent>;
|
|
331
|
+
* ```
|
|
332
|
+
* @since 1.0.0
|
|
333
|
+
* @see {@link TraceCollapsible}
|
|
334
|
+
*/
|
|
335
|
+
function TraceCollapsibleContent(props: TraceCollapsibleContentProps): JSX.Element {
|
|
336
|
+
const [local, rest] = splitProps(props, ["class", "keepMounted"]);
|
|
337
|
+
return (
|
|
338
|
+
<CollapsibleContent
|
|
339
|
+
data-slot="trace-collapsible-content"
|
|
340
|
+
forceMount={local.keepMounted === true ? true : undefined}
|
|
341
|
+
class={cn("ms-2 border-s ps-4 text-sm text-muted-foreground", local.class)}
|
|
342
|
+
{...rest}
|
|
343
|
+
/>
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export {
|
|
348
|
+
Trace,
|
|
349
|
+
TraceCollapsible,
|
|
350
|
+
TraceCollapsibleContent,
|
|
351
|
+
TraceCollapsibleTrigger,
|
|
352
|
+
TraceDescription,
|
|
353
|
+
TraceIcon,
|
|
354
|
+
TraceLine,
|
|
355
|
+
TraceTitle,
|
|
356
|
+
};
|