panelui-web 0.7.0 → 0.8.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/dist/components/alert/index.d.ts +138 -0
- package/dist/components/alert/index.js +279 -0
- package/dist/components/alert-dialog/index.d.ts +128 -0
- package/dist/components/alert-dialog/index.js +327 -0
- package/dist/components/canvas/index.d.ts +114 -0
- package/dist/components/canvas/index.js +210 -0
- package/dist/components/dialog/index.d.ts +162 -0
- package/dist/components/dialog/index.js +299 -0
- package/dist/components/prompt/index.d.ts +34 -8
- package/dist/components/prompt/index.js +43 -13
- package/dist/components/sheet/index.d.ts +47 -1
- package/dist/components/sheet/index.js +251 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +5 -1
- package/package.json +1 -1
|
@@ -32,6 +32,14 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
32
32
|
* and closes with its `open` prop, folding under the card, so a band can come
|
|
33
33
|
* and go without the page jumping by more than its own height.
|
|
34
34
|
*
|
|
35
|
+
* ## Modes
|
|
36
|
+
*
|
|
37
|
+
* A prompt that changes with what the app is doing names its states with
|
|
38
|
+
* `mode`, and each band says which of them it belongs to with its own
|
|
39
|
+
* `mode`. The bands that match open and the others fold, in one movement,
|
|
40
|
+
* so the card moves once, by the difference between them. A band's own
|
|
41
|
+
* `open` still wins over its mode.
|
|
42
|
+
*
|
|
35
43
|
* ## Sending
|
|
36
44
|
*
|
|
37
45
|
* Enter sends and Shift+Enter starts a new line; Enter while a character is
|
|
@@ -120,8 +128,10 @@ const promptVariants = tv({
|
|
|
120
128
|
submitRing: 'pointer-events-none absolute -inset-[3px] size-[calc(100%+6px)] text-primary transition-opacity duration-200',
|
|
121
129
|
statusText: 'min-w-0 truncate bg-[linear-gradient(90deg,var(--muted-foreground)_35%,var(--foreground)_50%,var(--muted-foreground)_65%)] bg-[length:250%_100%] bg-clip-text text-transparent',
|
|
122
130
|
statusSpinner: 'ms-auto size-4 animate-spin text-muted-foreground motion-reduce:animate-none',
|
|
131
|
+
// The strip folds like a band: its tuck under the card moves with it.
|
|
132
|
+
contextFold: 'mx-4 grid transition-[grid-template-rows,margin,opacity] duration-300 ease-[cubic-bezier(0.2,0,0,1)] motion-reduce:transition-none',
|
|
123
133
|
context: [
|
|
124
|
-
'relative
|
|
134
|
+
'relative flex items-center gap-x-4 gap-y-1 rounded-b-[1rem] border bg-muted px-3.5 pb-2 pt-6.5 text-xs text-muted-foreground',
|
|
125
135
|
'flex-wrap [&_svg]:shrink-0 [&_svg:not([class*=size-])]:size-3.5',
|
|
126
136
|
],
|
|
127
137
|
contextItem: 'inline-flex min-w-0 items-center gap-1.5 whitespace-nowrap',
|
|
@@ -209,7 +219,7 @@ function attach(file) {
|
|
|
209
219
|
preview: file.type.startsWith('image/') ? URL.createObjectURL(file) : undefined,
|
|
210
220
|
};
|
|
211
221
|
}
|
|
212
|
-
function PromptRoot({ value: controlledValue, defaultValue = '', onValueChange, onSubmit, status = 'idle', onStop, disabled = false, defaultFiles, accept, maxFiles, onReject, className, children, ...props }) {
|
|
222
|
+
function PromptRoot({ value: controlledValue, defaultValue = '', onValueChange, onSubmit, status = 'idle', onStop, disabled = false, defaultFiles, accept, maxFiles, onReject, mode, className, children, ...props }) {
|
|
213
223
|
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
214
224
|
const value = controlledValue ?? internalValue;
|
|
215
225
|
const [attachments, setAttachments] = useState(() => (defaultFiles ?? []).map(attach));
|
|
@@ -274,6 +284,7 @@ function PromptRoot({ value: controlledValue, defaultValue = '', onValueChange,
|
|
|
274
284
|
removeAttachment,
|
|
275
285
|
openFileDialog,
|
|
276
286
|
status,
|
|
287
|
+
mode,
|
|
277
288
|
busy,
|
|
278
289
|
disabled,
|
|
279
290
|
empty,
|
|
@@ -287,12 +298,12 @@ function PromptRoot({ value: controlledValue, defaultValue = '', onValueChange,
|
|
|
287
298
|
keyHandler,
|
|
288
299
|
listbox,
|
|
289
300
|
setListbox,
|
|
290
|
-
}), [value, setValue, attachments, addFiles, removeAttachment, openFileDialog, status, busy, disabled, empty, submit, stop, onStop, dragging, fieldId, listbox]);
|
|
301
|
+
}), [value, setValue, attachments, addFiles, removeAttachment, openFileDialog, status, mode, busy, disabled, empty, submit, stop, onStop, dragging, fieldId, listbox]);
|
|
291
302
|
const send = (event) => {
|
|
292
303
|
event.preventDefault();
|
|
293
304
|
submit();
|
|
294
305
|
};
|
|
295
|
-
return (_jsx(PromptStore.Provider, { value: context, children: _jsxs("form", { "data-slot": "prompt", "data-status": status, "aria-busy": busy || undefined, className: promptVariants().root({ className }), onSubmit: send, ...props, children: [children, _jsx("input", { ref: fileInput, type: "file", multiple: maxFiles !== 1, accept: accept, tabIndex: -1, "aria-hidden": "true", className: "hidden", onChange: (event) => {
|
|
306
|
+
return (_jsx(PromptStore.Provider, { value: context, children: _jsxs("form", { "data-slot": "prompt", "data-status": status, "data-mode": mode, "aria-busy": busy || undefined, className: promptVariants().root({ className }), onSubmit: send, ...props, children: [children, _jsx("input", { ref: fileInput, type: "file", multiple: maxFiles !== 1, accept: accept, tabIndex: -1, "aria-hidden": "true", className: "hidden", onChange: (event) => {
|
|
296
307
|
if (event.target.files)
|
|
297
308
|
addFiles(event.target.files);
|
|
298
309
|
// Cleared, so choosing the same file again still counts as a change.
|
|
@@ -311,9 +322,22 @@ function Band({ edge, open, slot, className, children, ...props }) {
|
|
|
311
322
|
}, [open]);
|
|
312
323
|
return (_jsx("div", { "data-slot": slot, "data-open": open ? '' : undefined, className: slots.band(), children: _jsx("div", { ref: clip, className: slots.bandClip(), children: _jsx("div", { className: slots.bandInner({ className }), ...props, children: children }) }) }));
|
|
313
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* Whether a band is open: its own `open` if given, else whether the
|
|
327
|
+
* prompt's mode is one of the band's, else what the band does by default.
|
|
328
|
+
*/
|
|
329
|
+
function useBandOpen(part, open, mode, fallback) {
|
|
330
|
+
const prompt = usePrompt(part);
|
|
331
|
+
if (open !== undefined)
|
|
332
|
+
return open;
|
|
333
|
+
if (mode !== undefined)
|
|
334
|
+
return prompt.mode !== undefined && (Array.isArray(mode) ? mode : [mode]).includes(prompt.mode);
|
|
335
|
+
return fallback(prompt);
|
|
336
|
+
}
|
|
314
337
|
/** A band above the field, for something to do before or while writing: connect an account, pick a project. */
|
|
315
|
-
function PromptBanner({ open
|
|
316
|
-
|
|
338
|
+
function PromptBanner({ open, mode, ...props }) {
|
|
339
|
+
const shown = useBandOpen('Prompt.Banner', open, mode, () => true);
|
|
340
|
+
return _jsx(Band, { edge: "top", open: shown, slot: "prompt-banner", ...props });
|
|
317
341
|
}
|
|
318
342
|
PromptBanner.displayName = 'Prompt.Banner';
|
|
319
343
|
/** The banner's button, at its end. */
|
|
@@ -340,17 +364,22 @@ function useShimmer(active) {
|
|
|
340
364
|
return ref;
|
|
341
365
|
}
|
|
342
366
|
/** A band under the field saying what the answer is doing, with the words lit by a moving sweep. */
|
|
343
|
-
function PromptStatus({ open, icon, spinner = true, children, ...props }) {
|
|
344
|
-
const
|
|
345
|
-
const shown = open ?? prompt.busy;
|
|
367
|
+
function PromptStatus({ open, mode, icon, spinner = true, children, ...props }) {
|
|
368
|
+
const shown = useBandOpen('Prompt.Status', open, mode, (prompt) => prompt.busy);
|
|
346
369
|
const slots = promptVariants();
|
|
347
370
|
const text = useShimmer(shown);
|
|
348
371
|
return (_jsxs(Band, { edge: "bottom", open: shown, slot: "prompt-status", role: "status", ...props, children: [icon, _jsx("span", { ref: text, className: slots.statusText(), children: children }), spinner ? (_jsx("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", className: slots.statusSpinner(), children: _jsx("path", { d: "M21 12a9 9 0 1 1-6.22-8.56" }) })) : null] }));
|
|
349
372
|
}
|
|
350
373
|
PromptStatus.displayName = 'Prompt.Status';
|
|
351
374
|
/** A strip under the field, inset from its edges, for where the message is going: a branch, a folder, a ticket. */
|
|
352
|
-
function PromptContext({ className, ...props }) {
|
|
353
|
-
|
|
375
|
+
function PromptContext({ open, mode, className, ...props }) {
|
|
376
|
+
const shown = useBandOpen('Prompt.Context', open, mode, () => true);
|
|
377
|
+
const slots = promptVariants();
|
|
378
|
+
const clip = useRef(null);
|
|
379
|
+
useEffect(() => {
|
|
380
|
+
clip.current?.toggleAttribute('inert', !shown);
|
|
381
|
+
}, [shown]);
|
|
382
|
+
return (_jsx("div", { "data-slot": "prompt-context", "data-open": shown ? '' : undefined, className: slots.contextFold({ className: shown ? '-mt-5 grid-rows-[1fr] opacity-100' : 'mt-0 grid-rows-[0fr] opacity-0' }), children: _jsx("div", { ref: clip, className: "min-h-0 overflow-hidden", children: _jsx("div", { className: slots.context({ className }), ...props }) }) }));
|
|
354
383
|
}
|
|
355
384
|
PromptContext.displayName = 'Prompt.Context';
|
|
356
385
|
/** One fact in the context strip, with an icon before it. */
|
|
@@ -567,7 +596,8 @@ function ProgressRing({ done, total }) {
|
|
|
567
596
|
* fills as they are done, opening into the list. The list scrolls past
|
|
568
597
|
* `maxHeight`, and keeps the task in progress in view.
|
|
569
598
|
*/
|
|
570
|
-
function PromptTasks({ open
|
|
599
|
+
function PromptTasks({ open, mode, title, expanded, defaultExpanded = false, onExpandedChange, maxHeight = '10rem', className, children, ...props }) {
|
|
600
|
+
const shown = useBandOpen('Prompt.Tasks', open, mode, () => true);
|
|
571
601
|
const slots = promptVariants();
|
|
572
602
|
const [inner, setInner] = useState(defaultExpanded);
|
|
573
603
|
const isExpanded = expanded ?? inner;
|
|
@@ -593,7 +623,7 @@ function PromptTasks({ open = true, title, expanded, defaultExpanded = false, on
|
|
|
593
623
|
setInner(!isExpanded);
|
|
594
624
|
onExpandedChange?.(!isExpanded);
|
|
595
625
|
};
|
|
596
|
-
return (_jsxs(Band, { edge: "top", open:
|
|
626
|
+
return (_jsxs(Band, { edge: "top", open: shown, slot: "prompt-tasks", className: ['flex-col items-stretch gap-0 px-0 pt-0.5', className].filter(Boolean).join(' '), ...props, children: [_jsxs("button", { type: "button", "aria-expanded": isExpanded, "aria-controls": listId, onClick: toggle, className: slots.tasksHeader(), children: [_jsx(ProgressRing, { done: done, total: tasks.length }), _jsx("span", { className: slots.tasksTitle(), children: title }), _jsxs("span", { className: slots.tasksCount(), children: [done, "/", tasks.length] }), _jsx("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: slots.tasksChevron({ className: isExpanded ? 'rotate-180' : undefined }), children: _jsx("path", { d: "m6 9 6 6 6-6" }) })] }), _jsx("div", { className: slots.tasksBody({ className: isExpanded ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]' }), children: _jsx("div", { className: "min-h-0 overflow-hidden", children: _jsx("ol", { ref: list, id: listId, "aria-label": "Tasks", className: slots.tasksList(), style: { maxHeight }, children: children }) }) })] }));
|
|
597
627
|
}
|
|
598
628
|
PromptTasks.displayName = 'Prompt.Tasks';
|
|
599
629
|
/** One task in `Prompt.Tasks`. */
|
|
@@ -161,6 +161,50 @@ declare function SheetClose({ render, icon, children, ...props }: SheetCloseProp
|
|
|
161
161
|
declare namespace SheetClose {
|
|
162
162
|
var displayName: string;
|
|
163
163
|
}
|
|
164
|
+
export interface SheetSlidesProps extends Omit<ComponentProps<'div'>, 'onChange'> {
|
|
165
|
+
/**
|
|
166
|
+
* `true` makes it a deck: each slide fills the height, and a scroll
|
|
167
|
+
* glides to the next one. `false` makes it a numbered column of smaller
|
|
168
|
+
* slides that scrolls freely. Default `true`.
|
|
169
|
+
*/
|
|
170
|
+
snap?: boolean;
|
|
171
|
+
/** The current slide, counted from 0, when the caller holds it. Setting it scrolls that slide into view. */
|
|
172
|
+
index?: number;
|
|
173
|
+
/** The slide to start on, when the caller does not hold it. Default `0`. */
|
|
174
|
+
defaultIndex?: number;
|
|
175
|
+
/**
|
|
176
|
+
* Called with the new index when the current slide changes: scrolled to
|
|
177
|
+
* in a deck, pressed in a column. In a column, passing it makes each
|
|
178
|
+
* slide a button.
|
|
179
|
+
*/
|
|
180
|
+
onIndexChange?: (index: number) => void;
|
|
181
|
+
/** Show "3 / 8" under the current slide. Default: on in a deck. */
|
|
182
|
+
counter?: boolean;
|
|
183
|
+
/** The shape of a slide in a column, as a CSS aspect ratio. Default `16 / 9`. */
|
|
184
|
+
aspect?: string;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* A column of rounded slides in place of `Sheet.Body`: a deck that moves one
|
|
188
|
+
* slide at a time, or with `snap={false}`, a numbered column to choose from.
|
|
189
|
+
*/
|
|
190
|
+
declare function SheetSlides({ snap, index, defaultIndex, onIndexChange, counter, aspect, className, style, children, 'aria-label': label, ...props }: SheetSlidesProps): import("react").JSX.Element;
|
|
191
|
+
declare namespace SheetSlides {
|
|
192
|
+
var displayName: string;
|
|
193
|
+
}
|
|
194
|
+
export interface SheetSlideProps extends ComponentProps<'div'> {
|
|
195
|
+
/**
|
|
196
|
+
* What a screen reader calls it, after its place: "3 of 8, Harbour at
|
|
197
|
+
* dawn". An image's `alt` usually says it already.
|
|
198
|
+
*/
|
|
199
|
+
label?: string;
|
|
200
|
+
/** Its shape in a column, overriding `Sheet.Slides`' `aspect`. */
|
|
201
|
+
aspect?: string;
|
|
202
|
+
}
|
|
203
|
+
/** One slide: a rounded frame that fills with an image, a video or anything drawn. */
|
|
204
|
+
declare function SheetSlide({ label, aspect, className, style, children, ...props }: SheetSlideProps): import("react").JSX.Element;
|
|
205
|
+
declare namespace SheetSlide {
|
|
206
|
+
var displayName: string;
|
|
207
|
+
}
|
|
164
208
|
export interface SheetStageProps extends ComponentProps<'div'> {
|
|
165
209
|
}
|
|
166
210
|
/**
|
|
@@ -183,5 +227,7 @@ export declare const Sheet: typeof SheetRoot & {
|
|
|
183
227
|
Footer: typeof SheetFooter;
|
|
184
228
|
Close: typeof SheetClose;
|
|
185
229
|
Stage: typeof SheetStage;
|
|
230
|
+
Slides: typeof SheetSlides;
|
|
231
|
+
Slide: typeof SheetSlide;
|
|
186
232
|
};
|
|
187
|
-
export { SheetTrigger, SheetNext, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetBody, SheetFooter, SheetClose, SheetStage, };
|
|
233
|
+
export { SheetTrigger, SheetNext, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetBody, SheetFooter, SheetClose, SheetStage, SheetSlides, SheetSlide, };
|
|
@@ -45,10 +45,20 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
45
45
|
*
|
|
46
46
|
* Every sheet follows a drag and leaves on a flick toward its own edge. The
|
|
47
47
|
* grabber on a top or bottom sheet says so before anybody tries.
|
|
48
|
+
*
|
|
49
|
+
* ## Slides
|
|
50
|
+
*
|
|
51
|
+
* `Sheet.Slides` takes the place of the body with a column of rounded
|
|
52
|
+
* slides, for photos or a deck. By default it is a deck: each slide fills
|
|
53
|
+
* the sheet's height, a turn of the wheel or a swipe of the trackpad glides
|
|
54
|
+
* to the next slide, an arrow key moves one, and a counter under it says
|
|
55
|
+
* which. Without `snap` it is a numbered column of smaller slides that
|
|
56
|
+
* scrolls freely, the way a presentation's slide panel does, and pressing
|
|
57
|
+
* one chooses it.
|
|
48
58
|
*/
|
|
49
59
|
import { Drawer } from '@base-ui/react/drawer';
|
|
50
60
|
import { ScrollArea } from '@base-ui/react/scroll-area';
|
|
51
|
-
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from 'react';
|
|
61
|
+
import { Children, createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from 'react';
|
|
52
62
|
import { tv } from 'tailwind-variants';
|
|
53
63
|
/*
|
|
54
64
|
* One curve for every movement: the sheet arriving, the one behind it stepping
|
|
@@ -120,6 +130,32 @@ const sheetVariants = tv({
|
|
|
120
130
|
scrollbar: 'my-3 me-1 flex w-1.5 opacity-0 transition-opacity delay-300 data-hovering:opacity-100 data-hovering:delay-0 data-scrolling:opacity-100 data-scrolling:delay-0',
|
|
121
131
|
thumb: 'relative flex-1 rounded-full bg-foreground/20',
|
|
122
132
|
footer: 'flex shrink-0 flex-col gap-2 px-6 pt-3 pb-6',
|
|
133
|
+
/*
|
|
134
|
+
* Slides. As a deck the viewport is a size container, so a slide can be
|
|
135
|
+
* exactly its height less the padding, which is what lets one flick land
|
|
136
|
+
* on one slide. The minimum height is for a sheet that sizes itself to
|
|
137
|
+
* its content, where a deck would otherwise have no height to fill.
|
|
138
|
+
*/
|
|
139
|
+
slides: 'relative flex min-h-0 flex-1 flex-col',
|
|
140
|
+
// Focus is shown on the current slide, not as a square round the scroller.
|
|
141
|
+
slidesViewport: 'group/slides min-h-0 flex-1 overscroll-contain outline-none',
|
|
142
|
+
slidesContent: 'flex flex-col gap-3 px-3',
|
|
143
|
+
// 20px is the sheet's 32 less the 12px it is set in by: one corner, two curves.
|
|
144
|
+
slide: [
|
|
145
|
+
'relative shrink-0 overflow-hidden rounded-[20px] bg-muted',
|
|
146
|
+
'[&>img]:size-full [&>img]:object-cover [&>video]:size-full [&>video]:object-cover',
|
|
147
|
+
// A hairline over the picture, so a photo keeps an edge on a sheet of its own colour.
|
|
148
|
+
"after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:ring-1 after:ring-inset after:ring-foreground/[0.08] after:content-['']",
|
|
149
|
+
'group-focus-visible/slides:data-current:ring-2 group-focus-visible/slides:data-current:ring-ring',
|
|
150
|
+
],
|
|
151
|
+
slideRow: 'grid grid-cols-[1.25rem_minmax(0,1fr)] items-start gap-2.5',
|
|
152
|
+
slideNumber: 'pt-1 text-end text-xs font-medium tabular-nums text-muted-foreground',
|
|
153
|
+
slideButton: [
|
|
154
|
+
'group/slide block w-full cursor-pointer rounded-[14px] text-start outline-none transition-shadow duration-150',
|
|
155
|
+
'focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-popover',
|
|
156
|
+
],
|
|
157
|
+
// No blur behind it: a filter over a scrolling picture repaints on every frame.
|
|
158
|
+
counter: 'pointer-events-none absolute inset-x-0 bottom-5 mx-auto w-fit rounded-full bg-black/60 px-2.5 py-1 text-xs font-medium tabular-nums text-white',
|
|
123
159
|
/*
|
|
124
160
|
* The page behind steps back by 3%, not more: enough to read as a layer
|
|
125
161
|
* underneath, not so much that the page looks like it shrank. It keeps its
|
|
@@ -414,6 +450,217 @@ function SheetClose({ render, icon = false, children, ...props }) {
|
|
|
414
450
|
return (_jsx(Drawer.Close, { render: render, ...props, children: content }));
|
|
415
451
|
}
|
|
416
452
|
SheetClose.displayName = 'Sheet.Close';
|
|
453
|
+
const SlidesContext = createContext(null);
|
|
454
|
+
/** The rounded frame of a slide: the slide itself in a deck, inside its row in a column. */
|
|
455
|
+
const frameOf = (slide) => slide.querySelector('[data-slide-frame]') ?? slide;
|
|
456
|
+
const SlideIndexContext = createContext(0);
|
|
457
|
+
function reduceMotion() {
|
|
458
|
+
return typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* A column of rounded slides in place of `Sheet.Body`: a deck that moves one
|
|
462
|
+
* slide at a time, or with `snap={false}`, a numbered column to choose from.
|
|
463
|
+
*/
|
|
464
|
+
function SheetSlides({ snap = true, index, defaultIndex = 0, onIndexChange, counter, aspect = '16 / 9', className, style, children, 'aria-label': label = 'Slides', ...props }) {
|
|
465
|
+
const slots = sheetVariants();
|
|
466
|
+
const viewport = useRef(null);
|
|
467
|
+
const slides = Children.toArray(children);
|
|
468
|
+
const count = slides.length;
|
|
469
|
+
const [internal, setInternal] = useState(defaultIndex);
|
|
470
|
+
const current = Math.min(Math.max(index ?? internal, 0), Math.max(count - 1, 0));
|
|
471
|
+
const live = useRef({ current, onIndexChange, controlled: index !== undefined });
|
|
472
|
+
live.current = { current, onIndexChange, controlled: index !== undefined };
|
|
473
|
+
const slideAt = (at) => viewport.current?.querySelectorAll('[data-slot=sheet-slide]')[at] ?? null;
|
|
474
|
+
// Scrolls the slides alone. `scrollIntoView` would move every scroller
|
|
475
|
+
// above them too, the page included when a sheet is drawn inline.
|
|
476
|
+
const reveal = useCallback((at, smooth) => {
|
|
477
|
+
const root = viewport.current;
|
|
478
|
+
const slide = slideAt(at);
|
|
479
|
+
if (!root || !slide)
|
|
480
|
+
return;
|
|
481
|
+
const box = root.getBoundingClientRect();
|
|
482
|
+
const frame = frameOf(slide).getBoundingClientRect();
|
|
483
|
+
const above = frame.top - box.top;
|
|
484
|
+
const below = frame.bottom - box.bottom;
|
|
485
|
+
const by = snap ? above - (box.height - frame.height) / 2 : above < 0 ? above - 8 : below > 0 ? below + 8 : 0;
|
|
486
|
+
if (by === 0)
|
|
487
|
+
return;
|
|
488
|
+
const behavior = smooth && !reduceMotion() ? 'smooth' : 'auto';
|
|
489
|
+
if (!snap) {
|
|
490
|
+
root.scrollBy({ top: by, behavior });
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
// A deck stops at every slide on the way, which is right for a hand
|
|
494
|
+
// and wrong for Home or End. Snapping is off for the length of a jump.
|
|
495
|
+
root.style.scrollSnapType = 'none';
|
|
496
|
+
root.scrollBy({ top: by, behavior });
|
|
497
|
+
let restored = false;
|
|
498
|
+
const restore = () => {
|
|
499
|
+
if (restored)
|
|
500
|
+
return;
|
|
501
|
+
restored = true;
|
|
502
|
+
root.style.scrollSnapType = '';
|
|
503
|
+
};
|
|
504
|
+
if (behavior === 'smooth' && 'onscrollend' in window) {
|
|
505
|
+
root.addEventListener('scrollend', restore, { once: true });
|
|
506
|
+
window.setTimeout(restore, 1200);
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
requestAnimationFrame(restore);
|
|
510
|
+
}
|
|
511
|
+
}, [snap]);
|
|
512
|
+
// The slide last brought into view. One that became current by being
|
|
513
|
+
// scrolled to is already in view, and must not be scrolled to again: that
|
|
514
|
+
// would pull a deck back to it in the middle of a longer scroll.
|
|
515
|
+
const shown = useRef(null);
|
|
516
|
+
const settle = useCallback((next) => {
|
|
517
|
+
shown.current = next;
|
|
518
|
+
if (next === live.current.current)
|
|
519
|
+
return;
|
|
520
|
+
if (!live.current.controlled)
|
|
521
|
+
setInternal(next);
|
|
522
|
+
live.current.onIndexChange?.(next);
|
|
523
|
+
}, []);
|
|
524
|
+
// A deck's current slide is the one most in view.
|
|
525
|
+
useEffect(() => {
|
|
526
|
+
const root = viewport.current;
|
|
527
|
+
if (!snap || !root || typeof IntersectionObserver === 'undefined')
|
|
528
|
+
return;
|
|
529
|
+
const observer = new IntersectionObserver((entries) => {
|
|
530
|
+
for (const entry of entries) {
|
|
531
|
+
if (entry.isIntersecting)
|
|
532
|
+
settle(Number(entry.target.dataset.index));
|
|
533
|
+
}
|
|
534
|
+
}, { root, threshold: 0.6 });
|
|
535
|
+
root.querySelectorAll('[data-slot=sheet-slide]').forEach((slide) => observer.observe(slide));
|
|
536
|
+
return () => observer.disconnect();
|
|
537
|
+
}, [snap, count, settle]);
|
|
538
|
+
// Opens on the current slide, and follows `index` when it is set from outside.
|
|
539
|
+
useEffect(() => {
|
|
540
|
+
const first = shown.current === null;
|
|
541
|
+
if (!first && shown.current === current)
|
|
542
|
+
return;
|
|
543
|
+
shown.current = current;
|
|
544
|
+
if (first && current === 0)
|
|
545
|
+
return;
|
|
546
|
+
const box = viewport.current?.getBoundingClientRect();
|
|
547
|
+
const slide = slideAt(current);
|
|
548
|
+
const frame = slide ? frameOf(slide).getBoundingClientRect() : undefined;
|
|
549
|
+
const visible = box && frame && frame.top >= box.top - 1 && frame.bottom <= box.bottom + 1;
|
|
550
|
+
// A deck that scrolled there by itself is already on it.
|
|
551
|
+
if (!visible || (first && snap))
|
|
552
|
+
reveal(current, !first);
|
|
553
|
+
}, [current, reveal, snap]);
|
|
554
|
+
const go = (next) => {
|
|
555
|
+
const at = Math.min(Math.max(next, 0), count - 1);
|
|
556
|
+
if (snap)
|
|
557
|
+
reveal(at, true);
|
|
558
|
+
else {
|
|
559
|
+
settle(at);
|
|
560
|
+
reveal(at, true);
|
|
561
|
+
slideAt(at)?.querySelector('button')?.focus();
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
const goNow = useRef(go);
|
|
565
|
+
goNow.current = go;
|
|
566
|
+
/*
|
|
567
|
+
* A wheel or a trackpad turns a deck one slide per gesture. Left to the
|
|
568
|
+
* browser, a slow scroll drifts part of the way, eases off and springs
|
|
569
|
+
* back, and a fast one runs past several slides. Here a deliberate scroll
|
|
570
|
+
* glides to the next slide, and the rest of the same gesture, the
|
|
571
|
+
* trackpad's momentum included, is absorbed rather than fought. A touch
|
|
572
|
+
* screen keeps the browser's own snapping, which follows the finger.
|
|
573
|
+
*/
|
|
574
|
+
useEffect(() => {
|
|
575
|
+
const root = viewport.current;
|
|
576
|
+
if (!snap || !root)
|
|
577
|
+
return;
|
|
578
|
+
let pending = 0;
|
|
579
|
+
let lastWheel = 0;
|
|
580
|
+
let lockedUntil = 0;
|
|
581
|
+
const onWheel = (event) => {
|
|
582
|
+
// Sideways scrolling and pinch-zoom are not turns.
|
|
583
|
+
if (event.ctrlKey || Math.abs(event.deltaX) > Math.abs(event.deltaY))
|
|
584
|
+
return;
|
|
585
|
+
event.preventDefault();
|
|
586
|
+
const now = performance.now();
|
|
587
|
+
const gap = now - lastWheel;
|
|
588
|
+
lastWheel = now;
|
|
589
|
+
if (now < lockedUntil) {
|
|
590
|
+
// Still the same gesture: keep it from turning a second slide.
|
|
591
|
+
lockedUntil = Math.max(lockedUntil, now + 140);
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
if (gap > 200)
|
|
595
|
+
pending = 0;
|
|
596
|
+
pending += event.deltaMode === 1 ? event.deltaY * 16 : event.deltaY;
|
|
597
|
+
if (Math.abs(pending) < 24)
|
|
598
|
+
return;
|
|
599
|
+
const step = Math.sign(pending);
|
|
600
|
+
pending = 0;
|
|
601
|
+
lockedUntil = now + 500;
|
|
602
|
+
goNow.current(live.current.current + step);
|
|
603
|
+
};
|
|
604
|
+
root.addEventListener('wheel', onWheel, { passive: false });
|
|
605
|
+
return () => root.removeEventListener('wheel', onWheel);
|
|
606
|
+
}, [snap]);
|
|
607
|
+
const keys = (event) => {
|
|
608
|
+
const step = event.key === 'ArrowDown' || event.key === 'PageDown' || (event.key === ' ' && !event.shiftKey)
|
|
609
|
+
? 1
|
|
610
|
+
: event.key === 'ArrowUp' || event.key === 'PageUp' || (event.key === ' ' && event.shiftKey)
|
|
611
|
+
? -1
|
|
612
|
+
: 0;
|
|
613
|
+
if (step !== 0) {
|
|
614
|
+
event.preventDefault();
|
|
615
|
+
go(current + step);
|
|
616
|
+
}
|
|
617
|
+
else if (event.key === 'Home' || event.key === 'End') {
|
|
618
|
+
event.preventDefault();
|
|
619
|
+
go(event.key === 'Home' ? 0 : count - 1);
|
|
620
|
+
}
|
|
621
|
+
};
|
|
622
|
+
const context = useMemo(() => ({ snap, count, current, choose: settle, pressable: !snap && onIndexChange !== undefined }), [snap, count, current, settle, onIndexChange]);
|
|
623
|
+
return (_jsx(SlidesContext.Provider, { value: context, children: _jsxs(ScrollArea.Root, { "data-slot": "sheet-slides", "data-snap": snap ? '' : undefined, className: slots.slides({ className }), style: { ...style, ['--slide-aspect']: aspect }, ...props, children: [_jsx(ScrollArea.Viewport, { ref: viewport, tabIndex: 0, "aria-roledescription": "carousel", "aria-label": label, onKeyDown: keys, className: slots.slidesViewport({
|
|
624
|
+
className: snap
|
|
625
|
+
? 'min-h-[min(60dvh,32rem)] snap-y snap-mandatory [container-type:size]'
|
|
626
|
+
: undefined,
|
|
627
|
+
}), children: _jsx(ScrollArea.Content, { className: slots.slidesContent({ className: snap ? 'py-1.5' : 'gap-2 pb-3 pt-1' }), children: slides.map((slide, at) => (_jsx(SlideIndexContext.Provider, { value: at, children: slide }, at))) }) }), _jsx(ScrollArea.Scrollbar, { orientation: "vertical", className: slots.scrollbar(), children: _jsx(ScrollArea.Thumb, { className: slots.thumb() }) }), (counter ?? snap) && count > 1 ? (_jsxs("div", { "data-slot": "sheet-slides-counter", "aria-hidden": "true", className: slots.counter(), children: [current + 1, " / ", count] })) : null] }) }));
|
|
628
|
+
}
|
|
629
|
+
SheetSlides.displayName = 'Sheet.Slides';
|
|
630
|
+
/** One slide: a rounded frame that fills with an image, a video or anything drawn. */
|
|
631
|
+
function SheetSlide({ label, aspect, className, style, children, ...props }) {
|
|
632
|
+
const slides = useContext(SlidesContext);
|
|
633
|
+
if (!slides)
|
|
634
|
+
throw new Error('Sheet.Slide must be used inside <Sheet.Slides>.');
|
|
635
|
+
const at = useContext(SlideIndexContext);
|
|
636
|
+
const slots = sheetVariants();
|
|
637
|
+
const place = `${at + 1} of ${slides.count}`;
|
|
638
|
+
const selected = at === slides.current;
|
|
639
|
+
const name = label ? `${place}, ${label}` : place;
|
|
640
|
+
const frameClass = slots.slide({
|
|
641
|
+
className: [
|
|
642
|
+
slides.snap
|
|
643
|
+
? 'h-[calc(100cqh-0.75rem)] snap-center'
|
|
644
|
+
: // In a column a slide sits on the sheet's own colour, so it takes the
|
|
645
|
+
// theme's border as a real edge, and a shadow to stand off the sheet.
|
|
646
|
+
'aspect-(--slide-aspect) rounded-[14px] shadow-xs ring-1 ring-border transition-shadow duration-150 after:hidden',
|
|
647
|
+
!slides.snap && !selected && slides.pressable && 'group-hover/slide:ring-foreground/25',
|
|
648
|
+
// Chosen in a column: a ring in the info colour, the theme's colour for
|
|
649
|
+
// something switched on, clear of the slide's edge.
|
|
650
|
+
!slides.snap && selected && 'shadow-none ring-2 ring-[var(--info)] ring-offset-2 ring-offset-popover',
|
|
651
|
+
className,
|
|
652
|
+
],
|
|
653
|
+
});
|
|
654
|
+
const frameStyle = aspect ? { ...style, aspectRatio: aspect } : style;
|
|
655
|
+
// In a deck the slide is the frame, so the observer that finds the current
|
|
656
|
+
// one has a box to watch.
|
|
657
|
+
if (slides.snap) {
|
|
658
|
+
return (_jsx("div", { "data-slot": "sheet-slide", "data-slide-frame": "", "data-index": at, "data-current": selected ? '' : undefined, role: "group", "aria-roledescription": "slide", "aria-label": name, className: frameClass, style: frameStyle, ...props, children: children }));
|
|
659
|
+
}
|
|
660
|
+
const frame = (_jsx("div", { "data-slide-frame": "", "data-current": selected ? '' : undefined, className: frameClass, style: frameStyle, children: children }));
|
|
661
|
+
return (_jsxs("div", { "data-slot": "sheet-slide", "data-index": at, "data-selected": selected ? '' : undefined, className: slots.slideRow(), ...props, children: [_jsx("span", { "aria-hidden": "true", className: slots.slideNumber({ className: selected ? 'text-[var(--info)]' : undefined }), children: at + 1 }), slides.pressable ? (_jsx("button", { type: "button", "aria-label": label ? name : `Slide ${place}`, "aria-current": selected ? 'true' : undefined, className: slots.slideButton(), onClick: () => slides.choose(at), children: frame })) : (_jsx("div", { role: "group", "aria-roledescription": "slide", "aria-label": name, children: frame }))] }));
|
|
662
|
+
}
|
|
663
|
+
SheetSlide.displayName = 'Sheet.Slide';
|
|
417
664
|
/**
|
|
418
665
|
* Wrap the app — or the part of the page a sheet belongs to — in this, and
|
|
419
666
|
* the page steps back slightly while a sheet is open. Sheets opened anywhere
|
|
@@ -435,5 +682,7 @@ export const Sheet = Object.assign(SheetRoot, {
|
|
|
435
682
|
Footer: SheetFooter,
|
|
436
683
|
Close: SheetClose,
|
|
437
684
|
Stage: SheetStage,
|
|
685
|
+
Slides: SheetSlides,
|
|
686
|
+
Slide: SheetSlide,
|
|
438
687
|
});
|
|
439
|
-
export { SheetTrigger, SheetNext, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetBody, SheetFooter, SheetClose, SheetStage, };
|
|
688
|
+
export { SheetTrigger, SheetNext, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetBody, SheetFooter, SheetClose, SheetStage, SheetSlides, SheetSlide, };
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { Planet, PlanetGlobe, PlanetMarker, PlanetControls, PlanetList, PlanetLi
|
|
|
4
4
|
export { Feedback, FeedbackTrigger, FeedbackContent, FeedbackPanel, FeedbackTitle, FeedbackClose, FeedbackField, FeedbackDescription, FeedbackMessage, FeedbackRating, FeedbackFooter, FeedbackCancel, FeedbackSubmit, type FeedbackProps, type FeedbackTriggerProps, type FeedbackContentProps, type FeedbackPanelProps, type FeedbackTitleProps, type FeedbackCloseProps, type FeedbackFieldProps, type FeedbackDescriptionProps, type FeedbackMessageProps, type FeedbackRatingProps, type FeedbackFooterProps, type FeedbackActionProps, type FeedbackSubmitProps, } from './components/feedback/index.js';
|
|
5
5
|
export { Card, CardHeader, CardTitle, CardDescription, CardAction, CardContent, CardFooter, type CardProps, type CardHeaderProps, type CardTitleProps, type CardDescriptionProps, type CardActionProps, type CardContentProps, type CardFooterProps, } from './components/card/index.js';
|
|
6
6
|
export { Frame, FrameHeader, FrameTitle, FrameDescription, FrameAction, FramePanel, FrameRow, FrameMedia, FrameContent, FrameActions, FrameSection, FrameFooter, type FrameProps, type FrameVariant, type FrameHeaderProps, type FrameTitleProps, type FrameDescriptionProps, type FrameActionProps, type FramePanelProps, type FrameRowProps, type FrameMediaProps, type FrameContentProps, type FrameActionsProps, type FrameSectionProps, type FrameFooterProps, } from './components/frame/index.js';
|
|
7
|
-
export { Sheet, SheetTrigger, SheetNext, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetBody, SheetFooter, SheetClose, SheetStage, type SheetProps, type SheetSide, type SheetTriggerProps, type SheetNextProps, type SheetContentProps, type SheetHeaderProps, type SheetTitleProps, type SheetDescriptionProps, type SheetBodyProps, type SheetFooterProps, type SheetCloseProps, type SheetStageProps, } from './components/sheet/index.js';
|
|
7
|
+
export { Sheet, SheetTrigger, SheetNext, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetBody, SheetFooter, SheetClose, SheetStage, SheetSlides, SheetSlide, type SheetProps, type SheetSide, type SheetTriggerProps, type SheetNextProps, type SheetContentProps, type SheetHeaderProps, type SheetTitleProps, type SheetDescriptionProps, type SheetBodyProps, type SheetFooterProps, type SheetCloseProps, type SheetStageProps, type SheetSlidesProps, type SheetSlideProps, } from './components/sheet/index.js';
|
|
8
8
|
export { DayGrid, DayGridLegend, DayGridWeekdays, DayGridCaption, DayGridTitle, DayGridDescription, type DayGridProps, type DayGridLegendProps, type DayGridWeekdaysProps, type DayGridCaptionProps, type DayGridTitleProps, type DayGridDescriptionProps, type DayGridColor, type DayCell, type DayLevel, } from './components/day-grid/index.js';
|
|
9
9
|
export { RangeMeter, RangeMeterLabel, RangeMeterScale, type RangeMeterProps, type RangeMeterLabelProps, type RangeMeterScaleProps, type RangeMeterColor, } from './components/range-meter/index.js';
|
|
10
10
|
export { BarPicker, type BarPickerProps, type BarPickerBar, type BarPickerColor, } from './components/bar-picker/index.js';
|
|
@@ -21,9 +21,13 @@ export { Textarea, type TextareaProps } from './components/textarea/index.js';
|
|
|
21
21
|
export { Switch, type SwitchProps, type SwitchSize, type SwitchColor } from './components/switch/index.js';
|
|
22
22
|
export { Label, LabelText, LabelHint, LabelAction, type LabelProps, type LabelTextProps, type LabelHintProps, type LabelActionProps, } from './components/label/index.js';
|
|
23
23
|
export { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SelectGroup, SelectGroupLabel, SelectSeparator, type SelectProps, type SelectTriggerProps, type SelectValueProps, type SelectContentProps, type SelectItemProps, type SelectGroupProps, type SelectGroupLabelProps, type SelectSeparatorProps, } from './components/select/index.js';
|
|
24
|
-
export { Prompt, PromptBanner, PromptBannerAction, PromptField, PromptAttachments, PromptTextarea, PromptFooter, PromptTools, PromptTool, PromptAttach, PromptMenu, PromptAttachItem, PromptModel, PromptSubmit, PromptStatus, PromptTasks, PromptTask, PromptCommands, PromptRecorder, PromptContext, PromptContextItem, PromptHint, type PromptProps, type PromptState, type PromptMessage, type PromptAttachment, type PromptRejectReason, type PromptBannerProps, type PromptBannerActionProps, type PromptFieldProps, type PromptAttachmentsProps, type PromptTextareaProps, type PromptFooterProps, type PromptToolsProps, type PromptToolProps, type PromptAttachProps, type PromptMenuProps, type PromptAttachItemProps, type PromptModelProps, type PromptModelItem, type PromptSubmitProps, type PromptStatusProps, type PromptTasksProps, type PromptTaskProps, type PromptTaskStatus, type PromptCommandsProps, type PromptCommandItem, type PromptRecorderProps, type PromptContextProps, type PromptContextItemProps, type PromptHintProps, } from './components/prompt/index.js';
|
|
24
|
+
export { Prompt, PromptBanner, PromptBannerAction, PromptField, PromptAttachments, PromptTextarea, PromptFooter, PromptTools, PromptTool, PromptAttach, PromptMenu, PromptAttachItem, PromptModel, PromptSubmit, PromptStatus, PromptTasks, PromptTask, PromptCommands, PromptRecorder, PromptContext, PromptContextItem, PromptHint, type PromptProps, type PromptState, type PromptBandMode, type PromptMessage, type PromptAttachment, type PromptRejectReason, type PromptBannerProps, type PromptBannerActionProps, type PromptFieldProps, type PromptAttachmentsProps, type PromptTextareaProps, type PromptFooterProps, type PromptToolsProps, type PromptToolProps, type PromptAttachProps, type PromptMenuProps, type PromptAttachItemProps, type PromptModelProps, type PromptModelItem, type PromptSubmitProps, type PromptStatusProps, type PromptTasksProps, type PromptTaskProps, type PromptTaskStatus, type PromptCommandsProps, type PromptCommandItem, type PromptRecorderProps, type PromptContextProps, type PromptContextItemProps, type PromptHintProps, } from './components/prompt/index.js';
|
|
25
25
|
export { Menu, MenuTrigger, MenuContent, MenuItem, MenuCheckboxItem, MenuRadioGroup, MenuRadioItem, MenuSub, MenuSubTrigger, MenuSubContent, MenuGroup, MenuGroupLabel, MenuSeparator, MenuDescription, MenuShortcut, MenuBadge, type MenuProps, type MenuTriggerProps, type MenuContentProps, type MenuItemProps, type MenuCheckboxItemProps, type MenuRadioGroupProps, type MenuRadioItemProps, type MenuSubProps, type MenuSubTriggerProps, type MenuSubContentProps, type MenuGroupProps, type MenuGroupLabelProps, type MenuSeparatorProps, type MenuDescriptionProps, type MenuShortcutProps, type MenuBadgeProps, } from './components/menu/index.js';
|
|
26
26
|
export { Avatar, AvatarBadge, AvatarGroup, type AvatarProps, type AvatarBadgeProps, type AvatarGroupProps, type AvatarSize, type AvatarShape, type AvatarColor, type AvatarStatus, } from './components/avatar/index.js';
|
|
27
27
|
export { Tabs, TabsList, TabsTrigger, TabsBadge, TabsContent, type TabsProps, type TabsVariant, type TabsListProps, type TabsTriggerProps, type TabsBadgeProps, type TabsContentProps, } from './components/tabs/index.js';
|
|
28
28
|
export { Message, MessageGroup, MessageAvatar, MessageContent, MessageHeader, MessageBubble, MessageBubbleContent, MessageFooter, MessageActions, MessageAction, MessageBranch, MessageStatus, MessageAttachments, MessageAttachment, type MessageFrom, type MessageProps, type MessageGroupProps, type MessageAvatarProps, type MessageContentProps, type MessageHeaderProps, type MessageBubbleProps, type MessageBubbleContentProps, type MessageFooterProps, type MessageActionsProps, type MessageActionProps, type MessageBranchProps, type MessageStatusProps, type MessageAttachmentsProps, type MessageAttachmentProps, } from './components/message/index.js';
|
|
29
29
|
export { Soundwave, SoundwaveCenter, useAudioLevel, useMicrophone, type SoundwaveProps, type SoundwaveCenterProps, type SoundwaveVariant, type SoundwaveState, type SoundwaveColor, type SoundwaveSource, type AudioLevelOptions, type UseMicrophoneOptions, type MicrophoneControls, type MicrophoneStatus, } from './components/soundwave/index.js';
|
|
30
|
+
export { Alert, AlertIcon, AlertTitle, AlertDescription, AlertActions, AlertClose, AlertDetails, AlertItem, type AlertProps, type AlertTone, type AlertVariant, type AlertIconProps, type AlertTitleProps, type AlertDescriptionProps, type AlertActionsProps, type AlertCloseProps, type AlertDetailsProps, type AlertItemProps, } from './components/alert/index.js';
|
|
31
|
+
export { AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogMedia, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, type AlertDialogProps, type AlertDialogTone, type AlertDialogTriggerProps, type AlertDialogContentProps, type AlertDialogMediaProps, type AlertDialogTitleProps, type AlertDialogDescriptionProps, type AlertDialogFooterProps, type AlertDialogCancelProps, type AlertDialogActionProps, } from './components/alert-dialog/index.js';
|
|
32
|
+
export { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogBody, DialogFooter, DialogClose, DialogList, DialogListGroup, DialogListItem, type DialogProps, type DialogTriggerProps, type DialogContentProps, type DialogHeaderProps, type DialogTitleProps, type DialogDescriptionProps, type DialogBodyProps, type DialogFooterProps, type DialogCloseProps, type DialogListProps, type DialogListGroupProps, type DialogListItemProps, } from './components/dialog/index.js';
|
|
33
|
+
export { Canvas, CanvasPattern, CanvasSpotlight, CanvasContent, type CanvasProps, type CanvasViewport, type CanvasPatternVariant, type CanvasFade, type CanvasPatternProps, type CanvasSpotlightProps, type CanvasContentProps, } from './components/canvas/index.js';
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ export { Planet, PlanetGlobe, PlanetMarker, PlanetControls, PlanetList, PlanetLi
|
|
|
4
4
|
export { Feedback, FeedbackTrigger, FeedbackContent, FeedbackPanel, FeedbackTitle, FeedbackClose, FeedbackField, FeedbackDescription, FeedbackMessage, FeedbackRating, FeedbackFooter, FeedbackCancel, FeedbackSubmit, } from './components/feedback/index.js';
|
|
5
5
|
export { Card, CardHeader, CardTitle, CardDescription, CardAction, CardContent, CardFooter, } from './components/card/index.js';
|
|
6
6
|
export { Frame, FrameHeader, FrameTitle, FrameDescription, FrameAction, FramePanel, FrameRow, FrameMedia, FrameContent, FrameActions, FrameSection, FrameFooter, } from './components/frame/index.js';
|
|
7
|
-
export { Sheet, SheetTrigger, SheetNext, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetBody, SheetFooter, SheetClose, SheetStage, } from './components/sheet/index.js';
|
|
7
|
+
export { Sheet, SheetTrigger, SheetNext, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetBody, SheetFooter, SheetClose, SheetStage, SheetSlides, SheetSlide, } from './components/sheet/index.js';
|
|
8
8
|
export { DayGrid, DayGridLegend, DayGridWeekdays, DayGridCaption, DayGridTitle, DayGridDescription, } from './components/day-grid/index.js';
|
|
9
9
|
export { RangeMeter, RangeMeterLabel, RangeMeterScale, } from './components/range-meter/index.js';
|
|
10
10
|
export { BarPicker, } from './components/bar-picker/index.js';
|
|
@@ -27,3 +27,7 @@ export { Avatar, AvatarBadge, AvatarGroup, } from './components/avatar/index.js'
|
|
|
27
27
|
export { Tabs, TabsList, TabsTrigger, TabsBadge, TabsContent, } from './components/tabs/index.js';
|
|
28
28
|
export { Message, MessageGroup, MessageAvatar, MessageContent, MessageHeader, MessageBubble, MessageBubbleContent, MessageFooter, MessageActions, MessageAction, MessageBranch, MessageStatus, MessageAttachments, MessageAttachment, } from './components/message/index.js';
|
|
29
29
|
export { Soundwave, SoundwaveCenter, useAudioLevel, useMicrophone, } from './components/soundwave/index.js';
|
|
30
|
+
export { Alert, AlertIcon, AlertTitle, AlertDescription, AlertActions, AlertClose, AlertDetails, AlertItem, } from './components/alert/index.js';
|
|
31
|
+
export { AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogMedia, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, } from './components/alert-dialog/index.js';
|
|
32
|
+
export { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogBody, DialogFooter, DialogClose, DialogList, DialogListGroup, DialogListItem, } from './components/dialog/index.js';
|
|
33
|
+
export { Canvas, CanvasPattern, CanvasSpotlight, CanvasContent, } from './components/canvas/index.js';
|