@botiverse/raft-ui 0.10.4 → 0.10.6

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 CHANGED
@@ -1,3 +1,20 @@
1
+ ## [0.10.6](https://github.com/botiverse/raft-design/compare/v0.10.5...v0.10.6) (2026-10-21)
2
+
3
+ ### Added
4
+
5
+ - Comments beside a document, as in Google Docs, through `@botiverse/raft-ui/wip`: `CommentMargin`, `CommentCard` (with `CommentCardTrigger`, `CommentCardMeta`, `CommentCardQuote`), `CommentEntry` and `CommentMarker`. Cards sit level with their passages and keep the document's order; on a narrow viewer a `CommentMarker` beside each passage opens the discussion in a bottom sheet instead. `useCommentMarginFits(viewer, { minWidth })` picks between the two, `setCommentHighlights` with `COMMENT_HIGHLIGHT` / `COMMENT_HIGHLIGHT_ACTIVE` highlights the passages, and `resolveCommentMarginLayout` is the layout for callers that place cards themselves. New pattern: Comments. ([#614](https://github.com/botiverse/raft-design/pull/614))
6
+ - `AvatarGroup` reads `--avatar-group-surface` (default `layer-canvas`) for the ring between overlapping avatars, so a stack on another surface can match it. ([#614](https://github.com/botiverse/raft-design/pull/614))
7
+
8
+ ## [0.10.5](https://github.com/botiverse/raft-design/compare/v0.10.4...v0.10.5) (2026-10-20)
9
+
10
+ ### Added
11
+
12
+ - `ComboboxSelect` takes `sheetThreshold` (default 10) and `sheetTitle`, and its `messages` take `search`, `done` and `close` for the phone's bottom sheet. ([#618](https://github.com/botiverse/raft-design/pull/618))
13
+
14
+ ### Fixed
15
+
16
+ - `ComboboxSelect` on a phone (a touch screen under 48rem) no longer focuses a text input and raises the keyboard when people only pick a value. Up to `sheetThreshold` options open as an anchored list that picks its side once and doesn't flip while the keyboard or the address bar moves; more options, `create` and remote search open a bottom sheet with the search input at its top. Desktop and touch tablets are unchanged. ([#618](https://github.com/botiverse/raft-design/pull/618))
17
+
1
18
  ## [0.10.4](https://github.com/botiverse/raft-design/compare/v0.10.3...v0.10.4) (2026-10-20)
2
19
 
3
20
  ### Fixed
@@ -270,6 +270,121 @@
270
270
  background: var(--fill-muted);
271
271
  color: var(--foreground-disabled);
272
272
  }
273
+ /* On a phone the field is a trigger, not a text input: a select-like button
274
+ that shows the value. Its hit area covers the whole field; the clear button
275
+ sits above it. */
276
+ .r-combobox-select__trigger {
277
+ box-sizing: border-box;
278
+ min-width: 0;
279
+ min-height: inherit;
280
+ flex: 1;
281
+ display: flex;
282
+ align-items: center;
283
+ padding: 0;
284
+ border: 0;
285
+ outline: 0;
286
+ background: transparent;
287
+ color: inherit;
288
+ font: inherit;
289
+ text-align: start;
290
+ cursor: default;
291
+ -webkit-tap-highlight-color: transparent;
292
+ }
293
+ .r-combobox-select__trigger::after {
294
+ content: "";
295
+ position: absolute;
296
+ inset: 0;
297
+ border-radius: inherit;
298
+ }
299
+ .r-combobox-select__trigger:disabled {
300
+ color: inherit;
301
+ }
302
+ .r-combobox-select__value {
303
+ min-width: 0;
304
+ overflow: hidden;
305
+ text-overflow: ellipsis;
306
+ white-space: nowrap;
307
+ }
308
+ .r-combobox-select__placeholder {
309
+ min-width: 0;
310
+ overflow: hidden;
311
+ text-overflow: ellipsis;
312
+ white-space: nowrap;
313
+ color: var(--foreground-hint);
314
+ }
315
+ .r-combobox-select__trigger .r-combobox-select__chips {
316
+ margin-inline-start: -6px;
317
+ }
318
+ .r-combobox-select__trigger .r-combobox-select__chip {
319
+ padding-inline-end: 8px;
320
+ }
321
+ .r-combobox-select__clear {
322
+ position: relative;
323
+ z-index: 1;
324
+ }
325
+ .r-combobox-select__arrow {
326
+ pointer-events: none;
327
+ }
328
+ .r-combobox-select__control--trigger[data-popup-open] .r-combobox-select__arrow > svg {
329
+ transform: rotate(180deg);
330
+ }
331
+ /* The phone's anchored list fits the room on its side instead of flipping. */
332
+ .r-combobox-select__popup--anchored .r-combobox-select__list {
333
+ box-sizing: border-box;
334
+ max-height: min(calc(16rem + 12px), var(--available-height, 100vh));
335
+ }
336
+ /* The phone's bottom sheet: the field's label as its title, the search input
337
+ at its top, then the whole list, scrolling in the rest of the sheet. */
338
+ .r-combobox-select__sheet-popup {
339
+ height: 82dvh;
340
+ }
341
+ .r-combobox-select__sheet {
342
+ display: flex;
343
+ flex: 1;
344
+ flex-direction: column;
345
+ min-height: 0;
346
+ }
347
+ .r-combobox-select__sheet-header {
348
+ flex-direction: row;
349
+ align-items: center;
350
+ justify-content: space-between;
351
+ gap: 8px;
352
+ padding-inline-end: 8px;
353
+ }
354
+ .r-combobox-select__sheet-title {
355
+ min-width: 0;
356
+ flex: 1;
357
+ }
358
+ .r-combobox-select__sheet-search {
359
+ flex: 0 0 auto;
360
+ padding: 4px 16px 8px;
361
+ }
362
+ .r-combobox-select__search-icon {
363
+ width: 16px;
364
+ height: 16px;
365
+ flex: 0 0 auto;
366
+ color: var(--foreground-hint);
367
+ }
368
+ .r-combobox-select__sheet-body {
369
+ min-height: 0;
370
+ overflow-y: auto;
371
+ overscroll-behavior: contain;
372
+ padding: 0 8px calc(16px + env(safe-area-inset-bottom, 0px));
373
+ }
374
+ .r-combobox-select__sheet .r-combobox-select__list {
375
+ max-height: none;
376
+ overflow: visible;
377
+ padding: 0;
378
+ }
379
+ .r-combobox-select__sheet .r-combobox-select__option {
380
+ min-height: 52px;
381
+ padding: 0 12px;
382
+ font-size: var(--text-body);
383
+ line-height: var(--text-body--line-height);
384
+ }
385
+ .r-combobox-select__sheet .r-combobox-select__group-label {
386
+ padding: 12px 12px 4px;
387
+ }
273
388
  @keyframes r-combobox-select-spin {
274
389
  to {
275
390
  transform: rotate(360deg);
@@ -7,6 +7,7 @@ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
7
  import { Button } from "@base-ui/react/button";
8
8
  import { mergeProps } from "@base-ui/react/merge-props";
9
9
  import { useRender } from "@base-ui/react/use-render";
10
+ import { Drawer } from "@base-ui/react/drawer";
10
11
  //#region src/lib/tv.ts
11
12
  const tv$1 = ((options) => {
12
13
  const recipe = tv(options);
@@ -544,4 +545,444 @@ function DialogNav({ className, render, ...props }) {
544
545
  });
545
546
  }
546
547
  //#endregion
547
- export { ThemeStateContext as C, useTheme as S, defaultNativeButton as _, DialogDescription as a, resolveThemeScopeProps as b, DialogNav as c, DialogSurface as d, DialogTitle as f, Spinner as g, buttonVariants as h, DialogContent as i, DialogOverlay as l, Button$1 as m, DialogBody as n, DialogFooter as o, DialogTrigger as p, DialogClose as r, DialogHeader as s, Dialog$1 as t, DialogPortal as u, useParentOverlayKind as v, tv$1 as w, useThemeScopeProps as x, withOverlayLayer as y };
548
+ //#region src/components/panel/panel-header.recipe.ts
549
+ /**
550
+ * Where a head's edge controls sit, shared by every head (panel, section,
551
+ * drawer, thread). Phone: a filled thing (a sticker, a pill) puts its shape
552
+ * on 16. A ghost button has no shape, so its empty 44px box overhangs, and
553
+ * the two edge buttons mirror each other: the last action (6px padding,
554
+ * `panelHeadActions`' -3px) and a leading Back (16px padding, -13px) both sit
555
+ * 3px from their edge. Their 22px icon frames are then 14px in and every
556
+ * glyph's centre 25px in, whatever the glyph (an arrow, a gear, a narrow ⋮);
557
+ * aligning ink instead would move each button by its glyph's own side
558
+ * bearing. A Button straight in the head (ghost ones are PanelActions) is a
559
+ * filled control, so its shape ends on the content edge: 20 / 16.
560
+ */
561
+ const panelHeadEdges = [
562
+ "pr-3 pl-5 max-md:pr-1.5 max-md:pl-4",
563
+ "max-md:[&>[data-slot=panel-action]:first-child]:-ml-[13px]",
564
+ "[&>[data-slot=button]:last-child]:mr-2 max-md:[&>[data-slot=button]:last-child]:mr-2.5"
565
+ ];
566
+ /**
567
+ * A head's trailing actions. The last glyph ends on the head's edge: 20px on
568
+ * desktop (12px of padding, 1px here, the 32px button's 7px glyph inset); on
569
+ * a phone 14px in (44px buttons, 11px inset), mirroring a leading Back. The
570
+ * margin and gap follow the button's size, not the layout: a touch screen
571
+ * from 768px has the desktop head with 44px buttons, so -3px puts its last
572
+ * glyph on 20px too.
573
+ */
574
+ const panelHeadActions = "flex shrink-0 items-center gap-0.5 mr-[-3px] md:pointer-fine:mr-px md:pointer-fine:gap-1";
575
+ /**
576
+ * `header` and `sectionHeader` share one bar, expressed through
577
+ * `compoundSlots`: a 56px row (the shell header height) with a seam under it.
578
+ * On a phone the section head sits on the frame.
579
+ */
580
+ const panelHeader = tv$1({
581
+ slots: {
582
+ header: [],
583
+ sectionHeader: [],
584
+ headerIcon: [
585
+ "flex size-[27px] shrink-0 items-center justify-center",
586
+ "rounded-sticker border-[1.5px] border-sticker-ink bg-brand text-sticker-ink ring-[1.5px] ring-sticker-edge",
587
+ "not-data-[icon-kind=avatar]:[&_svg]:size-3.5 not-data-[icon-kind=avatar]:[&_svg]:stroke-2",
588
+ "data-[icon-kind=avatar]:size-auto data-[icon-kind=avatar]:border-transparent data-[icon-kind=avatar]:bg-transparent"
589
+ ],
590
+ headerContent: "flex min-w-0 flex-1 flex-col justify-center",
591
+ heading: "flex min-w-0 items-center gap-2",
592
+ title: "truncate font-sans text-headline font-bold text-foreground",
593
+ meta: "min-w-0 truncate font-sans text-caption text-foreground-hint",
594
+ status: [
595
+ "inline-flex shrink-0 items-center gap-1 border-0 bg-transparent p-0",
596
+ "font-sans text-caption font-medium normal-case text-foreground-hint",
597
+ "[&_svg]:size-3.5 [&_svg]:shrink-0"
598
+ ],
599
+ activity: [
600
+ "inline-flex shrink-0 items-center gap-1.5",
601
+ "font-sans text-caption text-foreground-hint",
602
+ "[&_svg]:size-3.5 [&_svg]:shrink-0"
603
+ ],
604
+ actions: panelHeadActions
605
+ },
606
+ variants: { size: {
607
+ sm: {},
608
+ md: { meta: ["text-footnote"] }
609
+ } },
610
+ compoundSlots: [{
611
+ slots: ["header", "sectionHeader"],
612
+ class: [
613
+ "flex h-(--shell-header-height,56px) shrink-0 items-center gap-3 max-md:gap-2",
614
+ panelHeadEdges,
615
+ "border-b border-line-seam bg-layer-canvas text-foreground",
616
+ "max-md:sticky max-md:top-0 max-md:z-30"
617
+ ]
618
+ }, {
619
+ slots: ["sectionHeader"],
620
+ class: [
621
+ "max-md:bg-layer-frame max-md:text-foreground-on-frame",
622
+ "max-md:[&>[data-slot=panel-header-icon]]:hidden",
623
+ "max-md:**:data-[slot=panel-title]:text-foreground-on-frame",
624
+ "max-md:**:data-[slot=panel-meta]:text-foreground-on-frame-muted",
625
+ "max-md:**:data-[slot=panel-action]:text-foreground-on-frame",
626
+ "max-md:**:data-[slot=panel-action]:hover:bg-fill-frame-pressed max-md:**:data-[slot=panel-action]:active:bg-fill-frame-pressed"
627
+ ]
628
+ }]
629
+ });
630
+ const drawer = tv$1({
631
+ extend: tv$1({
632
+ slots: {
633
+ overlay: [
634
+ "opacity-[max(var(--drawer-overlay-min-opacity,0),calc(1-var(--drawer-swipe-progress)))]",
635
+ "transition-opacity duration-200 ease-slide",
636
+ "data-starting-style:opacity-0 data-ending-style:pointer-events-none data-ending-style:opacity-0 data-ending-style:duration-150",
637
+ "motion-reduce:transition-none"
638
+ ],
639
+ popup: [
640
+ "[--drawer-blur:2px] [--drawer-ease:var(--ease-slide)]",
641
+ "[--closed-transform:translate3d(var(--drawer-exit-x,0px),var(--drawer-exit-y,0px),0)]",
642
+ "[--drawer-stack-peek:16px] [--drawer-stack-step:0.05]",
643
+ "[--drawer-stack-progress:clamp(0,var(--drawer-swipe-progress),1)]",
644
+ "[--drawer-stack-offset:max(0px,calc((var(--nested-drawers)-var(--drawer-stack-progress))*var(--drawer-stack-peek)))]",
645
+ "[--drawer-stack-scale-base:calc(max(0,1-(var(--nested-drawers)*var(--drawer-stack-step))))]",
646
+ "[--drawer-stack-scale:clamp(0,calc(var(--drawer-stack-scale-base)+(var(--drawer-stack-step)*var(--drawer-stack-progress))),1)]",
647
+ "[--drawer-stack-shrink:calc(1-var(--drawer-stack-scale))]",
648
+ "[--drawer-stack-shrink-offset:calc(var(--drawer-stack-shrink)*var(--drawer-stack-size))]",
649
+ "origin-(--drawer-transform-origin)",
650
+ "transform-[translate3d(calc(var(--drawer-swipe-x,0px)+var(--drawer-stack-x,0px)),calc(var(--drawer-swipe-y,0px)+var(--drawer-stack-y,0px)),0)_scale(var(--drawer-stack-scale))]",
651
+ "opacity-100 blur-0",
652
+ "transition-[transform,height,opacity,filter] duration-240 ease-(--drawer-ease) will-change-transform",
653
+ "data-ending-style:duration-[calc(var(--drawer-swipe-strength,1)*180ms)]",
654
+ "data-starting-style:transform-(--closed-transform) data-starting-style:opacity-0 data-starting-style:blur-(--drawer-blur)",
655
+ "data-ending-style:transform-(--closed-transform) data-ending-style:opacity-0 data-ending-style:blur-(--drawer-blur)",
656
+ "data-swiping:duration-0 data-nested-drawer-swiping:duration-0 motion-reduce:transition-none"
657
+ ],
658
+ content: ["transition-opacity duration-150 ease-slide motion-reduce:transition-none", "group-data-nested-drawer-open/drawer-popup:opacity-0 group-data-nested-drawer-swiping/drawer-popup:opacity-100"],
659
+ swipeHandle: ["transition-opacity duration-150 motion-reduce:transition-none", "group-data-nested-drawer-open/drawer-popup:opacity-0 group-data-nested-drawer-swiping/drawer-popup:opacity-100"]
660
+ },
661
+ variants: {
662
+ side: {
663
+ down: { popup: [
664
+ "[--drawer-exit-y:calc(100%+var(--drawer-inset)+2px)]",
665
+ "[--drawer-stack-y:calc(0px-var(--drawer-stack-offset)-var(--drawer-stack-shrink-offset))]",
666
+ "[--drawer-transform-origin:50%_100%]"
667
+ ] },
668
+ up: { popup: [
669
+ "[--drawer-exit-y:calc(-100%-var(--drawer-inset)-2px)]",
670
+ "[--drawer-stack-y:calc(var(--drawer-stack-offset)+var(--drawer-stack-shrink-offset))]",
671
+ "[--drawer-transform-origin:50%_0%]"
672
+ ] },
673
+ left: { popup: [
674
+ "[--drawer-exit-x:calc(-100%-var(--drawer-inset)-2px)]",
675
+ "[--drawer-stack-x:calc(var(--drawer-stack-offset)+var(--drawer-stack-shrink-offset))]",
676
+ "[--drawer-transform-origin:0%_50%]"
677
+ ] },
678
+ right: { popup: [
679
+ "[--drawer-exit-x:calc(100%+var(--drawer-inset)+2px)]",
680
+ "[--drawer-stack-x:calc(0px-var(--drawer-stack-offset)-var(--drawer-stack-shrink-offset))]",
681
+ "[--drawer-transform-origin:100%_50%]"
682
+ ] }
683
+ },
684
+ axis: {
685
+ x: { popup: ["[--drawer-stack-size:100%]", "[--drawer-swipe-x:var(--drawer-swipe-movement-x)]"] },
686
+ y: { popup: ["[--drawer-stack-size:max(0px,var(--drawer-frontmost-height,var(--drawer-height)))]", "[--drawer-swipe-y:calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-movement-y))]"] }
687
+ },
688
+ snapPoints: { true: { overlay: ["[--drawer-overlay-min-opacity:0.5]"] } }
689
+ }
690
+ }),
691
+ slots: {
692
+ overlay: [
693
+ "fixed inset-0 z-50 min-h-dvh select-none",
694
+ "supports-[-webkit-touch-callout:none]:absolute",
695
+ "bg-layer-backdrop"
696
+ ],
697
+ viewport: ["pointer-events-none fixed inset-0 z-50 select-none"],
698
+ popup: [
699
+ "group/drawer-popup pointer-events-auto fixed z-50 flex h-(--drawer-content-height) flex-col outline-none",
700
+ "[--drawer-inset:12px] [--drawer-content-height:var(--drawer-height,auto)]",
701
+ "data-nested-drawer-open:overflow-hidden",
702
+ "bg-layer-popover text-foreground",
703
+ "shadow-float ring-1 ring-line-seam"
704
+ ],
705
+ content: ["flex min-h-0 flex-1 flex-col rounded-[inherit] select-text", "group-data-swiping/drawer-popup:select-none"],
706
+ swipeHandle: [
707
+ "relative z-10 shrink-0 cursor-grab select-none active:cursor-grabbing",
708
+ "before:absolute before:content-['']",
709
+ "before:rounded-[1px] before:bg-line-seam"
710
+ ],
711
+ close: ["shrink-0"],
712
+ closeIcon: ["size-5.5"],
713
+ header: ["flex flex-col", "items-stretch gap-1 px-4 pt-4 pb-2 text-left"],
714
+ body: ["flex flex-1 flex-col", "items-stretch px-4 pt-2 pb-4 text-left"],
715
+ footer: ["mt-auto py-5", "px-4 pt-3 pb-4"],
716
+ actions: [
717
+ "flex w-full flex-col items-stretch",
718
+ "**:data-[slot=button]:w-full",
719
+ "gap-2"
720
+ ],
721
+ title: ["text-pretty text-foreground", "max-w-none text-left font-sans text-headline font-bold"],
722
+ description: ["text-pretty", "max-w-none text-left font-sans text-callout text-foreground-muted"]
723
+ },
724
+ variants: {
725
+ nested: {
726
+ false: {},
727
+ true: { overlay: ["bg-layer-backdrop-nested"] }
728
+ },
729
+ side: {
730
+ down: {
731
+ popup: [
732
+ "bottom-(--drawer-inset) min-h-64 max-h-[82vh]",
733
+ "rounded-t-dialog [--drawer-inset:0px]",
734
+ "pb-[env(safe-area-inset-bottom,0px)]"
735
+ ],
736
+ swipeHandle: ["before:top-3"]
737
+ },
738
+ up: {
739
+ popup: [
740
+ "top-(--drawer-inset) max-h-[80vh]",
741
+ "rounded-b-dialog [--drawer-inset:0px]",
742
+ "pt-[env(safe-area-inset-top,0px)]"
743
+ ],
744
+ swipeHandle: ["order-last", "before:bottom-3"]
745
+ },
746
+ left: {
747
+ popup: ["left-(--drawer-inset)"],
748
+ swipeHandle: ["order-last", "before:right-3"]
749
+ },
750
+ right: {
751
+ popup: ["right-(--drawer-inset)"],
752
+ swipeHandle: ["before:left-3"]
753
+ }
754
+ },
755
+ axis: {
756
+ x: {
757
+ popup: ["flex-row", "inset-y-0 w-full max-w-[420px] [--drawer-inset:0px]"],
758
+ swipeHandle: [
759
+ "my-auto h-16 w-11",
760
+ "before:top-1/2 before:-translate-y-1/2",
761
+ "before:w-1 before:h-9"
762
+ ],
763
+ header: [
764
+ "min-h-14 shrink-0 flex-row items-center justify-between gap-2 py-0 text-left",
765
+ "border-b border-line-seam",
766
+ panelHeadEdges
767
+ ],
768
+ body: ["items-stretch text-left", "min-h-0 overflow-y-auto px-5 py-4"],
769
+ footer: ["border-t border-line-seam px-5 py-3"],
770
+ title: ["min-w-0 max-w-none flex-1 text-left"],
771
+ description: ["max-w-none text-left"],
772
+ actions: ["flex-row flex-wrap justify-end", "**:data-[slot=button]:w-auto"]
773
+ },
774
+ y: {
775
+ popup: [
776
+ "data-nested-drawer-open:h-(--drawer-frontmost-height)",
777
+ "mx-auto md:max-w-md",
778
+ "inset-x-0"
779
+ ],
780
+ swipeHandle: [
781
+ "mx-auto w-16",
782
+ "before:left-1/2 before:-translate-x-1/2",
783
+ "h-4",
784
+ "before:top-1.5 before:h-1 before:w-9"
785
+ ]
786
+ }
787
+ }
788
+ },
789
+ compoundVariants: [{
790
+ side: "down",
791
+ snapPoints: true,
792
+ class: { header: ["pt-2"] }
793
+ }, {
794
+ axis: "y",
795
+ snapPoints: true,
796
+ class: { popup: ["[--drawer-content-height:100dvh]"] }
797
+ }]
798
+ });
799
+ //#endregion
800
+ //#region src/components/drawer/drawer.tsx
801
+ const DrawerConfigContext = createContext(null);
802
+ function useDrawerConfig() {
803
+ const context = useContext(DrawerConfigContext);
804
+ if (!context) throw new Error("Drawer parts must be used within Drawer.");
805
+ return context;
806
+ }
807
+ function Drawer$1({ modal = true, snapPoints, swipeDirection = "down", children, ...props }) {
808
+ const hasSnapPoints = snapPoints != null && snapPoints.length > 0;
809
+ const swipeAxis = swipeDirection === "down" || swipeDirection === "up" ? "y" : "x";
810
+ const contextValue = useMemo(() => ({
811
+ hasSnapPoints,
812
+ modal,
813
+ swipeAxis,
814
+ swipeDirection
815
+ }), [
816
+ hasSnapPoints,
817
+ modal,
818
+ swipeAxis,
819
+ swipeDirection
820
+ ]);
821
+ return /* @__PURE__ */ jsx(DrawerConfigContext.Provider, {
822
+ value: contextValue,
823
+ children: /* @__PURE__ */ jsx(Drawer.Root, {
824
+ modal,
825
+ snapPoints,
826
+ swipeDirection,
827
+ ...props,
828
+ children: withOverlayLayer("drawer", modal === true, children)
829
+ })
830
+ });
831
+ }
832
+ function DrawerTrigger(props) {
833
+ return /* @__PURE__ */ jsx(Drawer.Trigger, {
834
+ "data-slot": "drawer-trigger",
835
+ ...props
836
+ });
837
+ }
838
+ function DrawerPortal(props) {
839
+ return /* @__PURE__ */ jsx(Drawer.Portal, {
840
+ "data-slot": "drawer-portal",
841
+ ...useThemeScopeProps(props)
842
+ });
843
+ }
844
+ function DrawerOverlay({ className, ...props }) {
845
+ const { hasSnapPoints } = useDrawerConfig();
846
+ const nested = useParentOverlayKind() === "dialog";
847
+ const { overlay } = drawer({
848
+ snapPoints: hasSnapPoints,
849
+ nested
850
+ });
851
+ return /* @__PURE__ */ jsx(Drawer.Backdrop, {
852
+ "data-slot": "drawer-overlay",
853
+ "data-nested": nested ? "" : void 0,
854
+ forceRender: nested,
855
+ className: overlay({ className }),
856
+ ...props
857
+ });
858
+ }
859
+ function DrawerSwipeHandle() {
860
+ const { swipeAxis, swipeDirection } = useDrawerConfig();
861
+ const { swipeHandle } = drawer({
862
+ side: swipeDirection,
863
+ axis: swipeAxis
864
+ });
865
+ return /* @__PURE__ */ jsx("div", {
866
+ "data-slot": "drawer-swipe-handle",
867
+ "aria-hidden": "true",
868
+ className: swipeHandle()
869
+ });
870
+ }
871
+ function DrawerContent({ className, children, portalProps, ...props }) {
872
+ const { hasSnapPoints, modal, swipeAxis, swipeDirection } = useDrawerConfig();
873
+ const { content, popup, viewport } = drawer({
874
+ side: swipeDirection,
875
+ axis: swipeAxis,
876
+ snapPoints: hasSnapPoints
877
+ });
878
+ return /* @__PURE__ */ jsxs(DrawerPortal, {
879
+ ...portalProps,
880
+ children: [modal === true ? /* @__PURE__ */ jsx(DrawerOverlay, {}) : null, /* @__PURE__ */ jsx(Drawer.Viewport, {
881
+ "data-slot": "drawer-viewport",
882
+ className: cn(viewport(), modal === true && "pointer-events-auto"),
883
+ children: /* @__PURE__ */ jsxs(Drawer.Popup, {
884
+ "data-slot": "drawer-popup",
885
+ className: popup({ className }),
886
+ ...props,
887
+ children: [hasSnapPoints ? /* @__PURE__ */ jsx(DrawerSwipeHandle, {}) : null, /* @__PURE__ */ jsx(Drawer.Content, {
888
+ "data-slot": "drawer-content",
889
+ className: content(),
890
+ children
891
+ })]
892
+ })
893
+ })]
894
+ });
895
+ }
896
+ function DrawerClose({ className, variant, size, children, render, "aria-label": ariaLabel, ...props }) {
897
+ const { close, closeIcon } = drawer();
898
+ if (render) return /* @__PURE__ */ jsx(Drawer.Close, {
899
+ "data-slot": "drawer-close",
900
+ className,
901
+ render,
902
+ "aria-label": ariaLabel,
903
+ ...props,
904
+ children
905
+ });
906
+ return /* @__PURE__ */ jsx(Drawer.Close, {
907
+ "data-slot": "drawer-close",
908
+ render: /* @__PURE__ */ jsx(Button$1, {
909
+ variant: variant ?? "ghost",
910
+ size: size ?? "icon-lg",
911
+ "aria-label": ariaLabel ?? "Close"
912
+ }),
913
+ className: close({ className }),
914
+ ...props,
915
+ children: children ?? /* @__PURE__ */ jsx(X, { className: closeIcon() })
916
+ });
917
+ }
918
+ function DrawerHeader({ className, render, ...props }) {
919
+ const { hasSnapPoints, swipeAxis, swipeDirection } = useDrawerConfig();
920
+ const { header } = drawer({
921
+ side: swipeDirection,
922
+ axis: swipeAxis,
923
+ snapPoints: hasSnapPoints
924
+ });
925
+ const defaultProps = { className: header({ className }) };
926
+ return useRender({
927
+ defaultTagName: "div",
928
+ render,
929
+ props: mergeProps(defaultProps, props),
930
+ state: { slot: "drawer-header" }
931
+ });
932
+ }
933
+ function DrawerFooter({ className, render, ...props }) {
934
+ const { swipeAxis } = useDrawerConfig();
935
+ const { footer } = drawer({ axis: swipeAxis });
936
+ const defaultProps = { className: footer({ className }) };
937
+ return useRender({
938
+ defaultTagName: "div",
939
+ render,
940
+ props: mergeProps(defaultProps, props),
941
+ state: { slot: "drawer-footer" }
942
+ });
943
+ }
944
+ function DrawerBody({ className, render, ...props }) {
945
+ const { swipeAxis } = useDrawerConfig();
946
+ const { body } = drawer({ axis: swipeAxis });
947
+ const defaultProps = { className: body({ className }) };
948
+ return useRender({
949
+ defaultTagName: "div",
950
+ render,
951
+ props: mergeProps(defaultProps, props),
952
+ state: { slot: "drawer-body" }
953
+ });
954
+ }
955
+ function DrawerActions({ className, render, children, ...props }) {
956
+ const swipeAxis = useContext(DrawerConfigContext)?.swipeAxis;
957
+ const { actions } = drawer({ axis: swipeAxis });
958
+ const defaultProps = {
959
+ className: actions({ className }),
960
+ children
961
+ };
962
+ return useRender({
963
+ defaultTagName: "div",
964
+ render,
965
+ props: mergeProps(defaultProps, props),
966
+ state: { slot: "drawer-actions" }
967
+ });
968
+ }
969
+ function DrawerTitle({ className, ...props }) {
970
+ const { swipeAxis } = useDrawerConfig();
971
+ const { title } = drawer({ axis: swipeAxis });
972
+ return /* @__PURE__ */ jsx(Drawer.Title, {
973
+ "data-slot": "drawer-title",
974
+ className: title({ className }),
975
+ ...props
976
+ });
977
+ }
978
+ function DrawerDescription({ className, ...props }) {
979
+ const { swipeAxis } = useDrawerConfig();
980
+ const { description } = drawer({ axis: swipeAxis });
981
+ return /* @__PURE__ */ jsx(Drawer.Description, {
982
+ "data-slot": "drawer-description",
983
+ className: description({ className }),
984
+ ...props
985
+ });
986
+ }
987
+ //#endregion
988
+ export { buttonVariants as A, DialogNav as C, DialogTitle as D, DialogSurface as E, resolveThemeScopeProps as F, useThemeScopeProps as I, useTheme as L, defaultNativeButton as M, useParentOverlayKind as N, DialogTrigger as O, withOverlayLayer as P, ThemeStateContext as R, DialogHeader as S, DialogPortal as T, DialogBody as _, DrawerContent as a, DialogDescription as b, DrawerHeader as c, DrawerTitle as d, DrawerTrigger as f, Dialog$1 as g, panelHeader as h, DrawerClose as i, Spinner as j, Button$1 as k, DrawerOverlay as l, panelHeadEdges as m, DrawerActions as n, DrawerDescription as o, panelHeadActions as p, DrawerBody as r, DrawerFooter as s, Drawer$1 as t, DrawerPortal as u, DialogClose as v, DialogOverlay as w, DialogFooter as x, DialogContent as y, tv$1 as z };
package/dist/index.d.mts CHANGED
@@ -4992,7 +4992,7 @@ export declare const TaskStatusBadge: typeof TaskStatusBadgeRoot;
4992
4992
  //#endregion
4993
4993
  //#region src/components/legacy-task-panel/legacy-task-panel.d.ts
4994
4994
  type LegacyTaskPanelRootProps = useRender.ComponentProps<"div"> & {
4995
- /** Docs preview chrome. Shell hosts (Playground) leave this off. */
4995
+ /** Docs preview chrome. A host shell that draws its own frame leaves this off. */
4996
4996
  framed?: boolean;
4997
4997
  };
4998
4998
  /** @deprecated No consumer uses it; compose read-only task details from Dialog and DescriptionList. Removed in raft-ui 1.0. */