panelui-web 0.7.0 → 0.9.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.
@@ -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';
@@ -16,14 +16,19 @@ export { Stat, StatContent, StatLabel, StatDescription, StatValue, StatUnit, Sta
16
16
  export { CommandDock, CommandDockTrigger, CommandDockPanel, CommandDockInput, CommandDockResults, CommandDockRow, CommandDockRowTitle, CommandDockRowMeta, CommandDockStatus, type CommandDockProps, type CommandDockTriggerProps, type CommandDockPanelProps, type CommandDockInputProps, type CommandDockResultsProps, type CommandDockRowProps, type CommandDockRowTitleProps, type CommandDockRowMetaProps, type CommandDockStatusProps, } from './components/command-dock/index.js';
17
17
  export { NotFound, NotFoundCode, NotFoundTitle, NotFoundDescription, NotFoundActions, type NotFoundProps, type NotFoundCodeProps, type NotFoundTitleProps, type NotFoundDescriptionProps, type NotFoundActionsProps, type NotFoundEffect, type NotFoundColor, } from './components/not-found/index.js';
18
18
  export { Button, buttonVariants, type ButtonProps, type ButtonVariant, type ButtonSize } from './components/button/index.js';
19
+ export { ButtonGroup, ButtonGroupSeparator, ButtonGroupText, buttonGroupVariants, type ButtonGroupProps, type ButtonGroupOrientation, type ButtonGroupSeparatorProps, type ButtonGroupTextProps, type ButtonGroupTextSize, } from './components/button-group/index.js';
19
20
  export { Input, InputGroup, InputAddon, type InputProps, type InputGroupProps, type InputAddonProps, type InputSize } from './components/input/index.js';
20
21
  export { Textarea, type TextareaProps } from './components/textarea/index.js';
21
22
  export { Switch, type SwitchProps, type SwitchSize, type SwitchColor } from './components/switch/index.js';
22
23
  export { Label, LabelText, LabelHint, LabelAction, type LabelProps, type LabelTextProps, type LabelHintProps, type LabelActionProps, } from './components/label/index.js';
23
24
  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';
25
+ 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
26
  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
27
  export { Avatar, AvatarBadge, AvatarGroup, type AvatarProps, type AvatarBadgeProps, type AvatarGroupProps, type AvatarSize, type AvatarShape, type AvatarColor, type AvatarStatus, } from './components/avatar/index.js';
27
28
  export { Tabs, TabsList, TabsTrigger, TabsBadge, TabsContent, type TabsProps, type TabsVariant, type TabsListProps, type TabsTriggerProps, type TabsBadgeProps, type TabsContentProps, } from './components/tabs/index.js';
28
29
  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
30
  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';
31
+ 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';
32
+ 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';
33
+ 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';
34
+ 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';
@@ -16,6 +16,7 @@ export { Stat, StatContent, StatLabel, StatDescription, StatValue, StatUnit, Sta
16
16
  export { CommandDock, CommandDockTrigger, CommandDockPanel, CommandDockInput, CommandDockResults, CommandDockRow, CommandDockRowTitle, CommandDockRowMeta, CommandDockStatus, } from './components/command-dock/index.js';
17
17
  export { NotFound, NotFoundCode, NotFoundTitle, NotFoundDescription, NotFoundActions, } from './components/not-found/index.js';
18
18
  export { Button, buttonVariants } from './components/button/index.js';
19
+ export { ButtonGroup, ButtonGroupSeparator, ButtonGroupText, buttonGroupVariants, } from './components/button-group/index.js';
19
20
  export { Input, InputGroup, InputAddon } from './components/input/index.js';
20
21
  export { Textarea } from './components/textarea/index.js';
21
22
  export { Switch } from './components/switch/index.js';
@@ -27,3 +28,7 @@ export { Avatar, AvatarBadge, AvatarGroup, } from './components/avatar/index.js'
27
28
  export { Tabs, TabsList, TabsTrigger, TabsBadge, TabsContent, } from './components/tabs/index.js';
28
29
  export { Message, MessageGroup, MessageAvatar, MessageContent, MessageHeader, MessageBubble, MessageBubbleContent, MessageFooter, MessageActions, MessageAction, MessageBranch, MessageStatus, MessageAttachments, MessageAttachment, } from './components/message/index.js';
29
30
  export { Soundwave, SoundwaveCenter, useAudioLevel, useMicrophone, } from './components/soundwave/index.js';
31
+ export { Alert, AlertIcon, AlertTitle, AlertDescription, AlertActions, AlertClose, AlertDetails, AlertItem, } from './components/alert/index.js';
32
+ export { AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogMedia, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, } from './components/alert-dialog/index.js';
33
+ export { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogBody, DialogFooter, DialogClose, DialogList, DialogListGroup, DialogListItem, } from './components/dialog/index.js';
34
+ export { Canvas, CanvasPattern, CanvasSpotlight, CanvasContent, } from './components/canvas/index.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "panelui-web",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "PanelUI for the web: animated, data-rich React components styled with Tailwind CSS on shadcn tokens.",
5
5
  "type": "module",
6
6
  "sideEffects": false,