@botiverse/raft-ui 0.64.0 → 0.66.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.
Files changed (90) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/components/activity-inbox/activity-inbox-sidebar.recipe.mjs +1 -1
  3. package/dist/components/activity-inbox/activity-inbox-toolbar.recipe.mjs +6 -1
  4. package/dist/components/alert-dialog/alert-dialog.mjs +3 -3
  5. package/dist/components/announcement-dialog/announcement-dialog.mjs +2 -2
  6. package/dist/components/app-link-card/app-link-card.mjs +1 -1
  7. package/dist/components/app-rail/app-rail.recipe.mjs +12 -7
  8. package/dist/components/app-shell/app-shell.mjs +1 -1
  9. package/dist/components/avatar/avatar.mjs +1 -0
  10. package/dist/components/badge/badge.mjs +6 -1
  11. package/dist/components/banner/banner.mjs +1 -1
  12. package/dist/components/button/button-split.mjs +10 -3
  13. package/dist/components/button/button.mjs +13 -8
  14. package/dist/components/code-block/code-block.recipe.mjs +1 -1
  15. package/dist/components/combobox/combobox.mjs +4 -4
  16. package/dist/components/combobox-select/combobox-select.css +6 -3
  17. package/dist/components/composer/composer-suggestion-list.mjs +1 -1
  18. package/dist/components/composer/composer-toolbar-label.mjs +1 -1
  19. package/dist/components/composer/composer.mjs +1 -1
  20. package/dist/components/composer/composer.recipe.mjs +38 -26
  21. package/dist/components/conversation-panel/conversation-panel-empty-state.mjs +1 -1
  22. package/dist/components/conversation-panel/conversation-panel.recipe.mjs +3 -2
  23. package/dist/components/dialog/dialog-sheet-context.mjs +1 -1
  24. package/dist/components/dialog/dialog.mjs +7 -7
  25. package/dist/components/drawer/drawer.mjs +3 -2
  26. package/dist/components/drawer/drawer.recipe.mjs +5 -3
  27. package/dist/components/empty-state/empty-state.mjs +1 -1
  28. package/dist/components/field/field.mjs +1 -1
  29. package/dist/components/files/files.recipe.mjs +1 -1
  30. package/dist/components/filter-chip/filter-chip.mjs +1 -1
  31. package/dist/components/form-section/form-section.mjs +1 -1
  32. package/dist/components/icon-tile/icon-tile.mjs +3 -3
  33. package/dist/components/inbox-item/inbox-item.recipe.mjs +4 -2
  34. package/dist/components/input/input.recipe.mjs +1 -1
  35. package/dist/components/input-group/input-group.mjs +1 -1
  36. package/dist/components/lightbox/lightbox.mjs +1 -1
  37. package/dist/components/list-row/list-row.recipe.mjs +2 -2
  38. package/dist/components/message-action-card/message-action-card-content.recipe.mjs +1 -1
  39. package/dist/components/message-action-card/message-action-card.recipe.mjs +1 -1
  40. package/dist/components/message-item/index.d.mts +2 -2
  41. package/dist/components/message-item/message-item-content.d.mts +14 -0
  42. package/dist/components/message-item/message-item-content.mjs +146 -1
  43. package/dist/components/message-item/message-item.recipe.d.mts +3 -0
  44. package/dist/components/message-item/message-item.recipe.mjs +3 -2
  45. package/dist/components/message-item/message-reaction.recipe.mjs +4 -3
  46. package/dist/components/message-list/message-list.recipe.mjs +3 -1
  47. package/dist/components/mode-bar/mode-bar.mjs +1 -1
  48. package/dist/components/notification-center/notification-center.mjs +1 -1
  49. package/dist/components/panel/panel-action.recipe.mjs +5 -5
  50. package/dist/components/panel/panel-header.recipe.mjs +10 -9
  51. package/dist/components/panel/panel.recipe.mjs +2 -2
  52. package/dist/components/picker-trigger-button/picker-trigger-button.mjs +1 -1
  53. package/dist/components/profile-panel/profile-panel.recipe.mjs +1 -1
  54. package/dist/components/scroll-area/scroll-area.css +74 -33
  55. package/dist/components/search/search-entity.recipe.mjs +3 -2
  56. package/dist/components/search/search-message.recipe.mjs +1 -0
  57. package/dist/components/search/search-thread.recipe.mjs +1 -1
  58. package/dist/components/search/search-trigger.mjs +1 -1
  59. package/dist/components/search/search.recipe.mjs +7 -3
  60. package/dist/components/segmented-control/segmented-control.mjs +9 -8
  61. package/dist/components/select/select.mjs +2 -2
  62. package/dist/components/sidebar/index.d.mts +2 -2
  63. package/dist/components/sidebar/sidebar-item.recipe.mjs +5 -4
  64. package/dist/components/sidebar/sidebar-section.d.mts +11 -2
  65. package/dist/components/sidebar/sidebar-section.mjs +29 -3
  66. package/dist/components/sidebar/sidebar-section.recipe.mjs +7 -2
  67. package/dist/components/sidebar/sidebar.recipe.mjs +3 -3
  68. package/dist/components/switch/switch.mjs +3 -3
  69. package/dist/components/tabs/tabs.mjs +1 -1
  70. package/dist/components/task-board/task-board-column.recipe.mjs +1 -1
  71. package/dist/components/task-list/task-list-section.recipe.mjs +1 -1
  72. package/dist/components/tasks/tasks-panel.recipe.mjs +4 -3
  73. package/dist/components/text-selection-toolbar/text-selection-toolbar.recipe.mjs +1 -1
  74. package/dist/components/textarea/textarea.mjs +1 -1
  75. package/dist/components/thread-panel/thread-panel.recipe.mjs +3 -3
  76. package/dist/components/toggle-group/toggle-group.mjs +1 -1
  77. package/dist/components/web-top-bar/index.d.mts +2 -0
  78. package/dist/components/web-top-bar/web-top-bar.d.mts +20 -0
  79. package/dist/components/web-top-bar/web-top-bar.mjs +63 -0
  80. package/dist/components/web-top-bar/web-top-bar.recipe.mjs +23 -0
  81. package/dist/foundation.css +100 -5
  82. package/dist/index.d.mts +2 -2
  83. package/dist/index.mjs +2 -2
  84. package/dist/lib/head-edges.mjs +38 -8
  85. package/dist/lib/list-cell.mjs +1 -0
  86. package/dist/styles.css +54 -7
  87. package/dist/tokens.json +260 -4
  88. package/dist/wip.d.mts +4 -1
  89. package/dist/wip.mjs +3 -1
  90. package/package.json +1 -1
@@ -587,10 +587,7 @@
587
587
  block-size var(--r-scroll-area-duration) var(--r-scroll-area-easing);
588
588
  }
589
589
 
590
- /* Shown while hovered (trigger="hover"), always (trigger="none"), and while scrolling or dragging (every trigger). */
591
- .r-scroll-area.r-scroll-area--hover-trigger:hover
592
- > .r-scroll-area__gutters
593
- > .r-scroll-area__gutter,
590
+ /* Shown always (trigger="none"), and while scrolling or dragging (every trigger). */
594
591
  .r-scroll-area.r-scroll-area--none-trigger > .r-scroll-area__gutters > .r-scroll-area__gutter,
595
592
  .r-scroll-area
596
593
  > .r-scroll-area__gutters.r-scroll-area__gutters--scrolling
@@ -602,31 +599,7 @@
602
599
  transition-duration: var(--r-scroll-area-duration-fade-in);
603
600
  }
604
601
 
605
- /*
606
- * trigger="scroll": a hidden gutter doesn't catch presses meant for the
607
- * content under it. A gutter the pointer is already on (it was shown by
608
- * scrolling) stays visible and usable after `hideDelay`, until the pointer
609
- * leaves it; a hidden gutter can't become hovered, so it never shows on hover.
610
- */
611
- .r-scroll-area.r-scroll-area--scroll-trigger
612
- > .r-scroll-area__gutters
613
- > .r-scroll-area__gutter:hover {
614
- opacity: 1;
615
- transition-duration: var(--r-scroll-area-duration-fade-in);
616
- }
617
- .r-scroll-area.r-scroll-area--scroll-trigger
618
- > .r-scroll-area__gutters:not(.r-scroll-area__gutters--scrolling):not(
619
- .r-scroll-area__gutters--dragging
620
- )
621
- > .r-scroll-area__gutter:not(:hover) {
622
- pointer-events: none;
623
- }
624
-
625
- /* Pointed at, or while dragged: the thumb thickens and darkens. */
626
- .r-scroll-area
627
- > .r-scroll-area__gutters
628
- > .r-scroll-area__gutter--vertical:hover
629
- > .r-scroll-area__thumb,
602
+ /* While dragged: the thumb thickens and darkens. */
630
603
  .r-scroll-area
631
604
  > .r-scroll-area__gutters
632
605
  > .r-scroll-area__gutter--vertical.r-scroll-area__gutter--dragging
@@ -634,10 +607,6 @@
634
607
  background: var(--r-scroll-area-thumb-color-hover);
635
608
  inline-size: var(--r-scroll-area-thumb-size-hover);
636
609
  }
637
- .r-scroll-area
638
- > .r-scroll-area__gutters
639
- > .r-scroll-area__gutter--horizontal:hover
640
- > .r-scroll-area__thumb,
641
610
  .r-scroll-area
642
611
  > .r-scroll-area__gutters
643
612
  > .r-scroll-area__gutter--horizontal.r-scroll-area__gutter--dragging
@@ -646,6 +615,78 @@
646
615
  block-size: var(--r-scroll-area-thumb-size-hover);
647
616
  }
648
617
 
618
+ /*
619
+ * Hover only with a pointer that hovers (design/foundations/states.md): on a
620
+ * touch screen the last thing tapped stays `:hover`, which would leave the
621
+ * scrollbars shown, the thumb thick and a hidden gutter catching taps.
622
+ */
623
+ @media (hover: hover) {
624
+ /* trigger="hover": shown while the pointer is over the area. */
625
+ .r-scroll-area.r-scroll-area--hover-trigger:hover
626
+ > .r-scroll-area__gutters
627
+ > .r-scroll-area__gutter {
628
+ opacity: 1;
629
+ transition-duration: var(--r-scroll-area-duration-fade-in);
630
+ }
631
+
632
+ /*
633
+ * trigger="scroll": a hidden gutter doesn't catch presses meant for the
634
+ * content under it. A gutter the pointer is already on (it was shown by
635
+ * scrolling) stays visible and usable after `hideDelay`, until the pointer
636
+ * leaves it; a hidden gutter can't become hovered, so it never shows on hover.
637
+ */
638
+ .r-scroll-area.r-scroll-area--scroll-trigger
639
+ > .r-scroll-area__gutters
640
+ > .r-scroll-area__gutter:hover {
641
+ opacity: 1;
642
+ transition-duration: var(--r-scroll-area-duration-fade-in);
643
+ }
644
+ .r-scroll-area.r-scroll-area--scroll-trigger
645
+ > .r-scroll-area__gutters:not(.r-scroll-area__gutters--scrolling):not(
646
+ .r-scroll-area__gutters--dragging
647
+ )
648
+ > .r-scroll-area__gutter:not(:hover) {
649
+ pointer-events: none;
650
+ }
651
+
652
+ /* Pointed at: the thumb thickens and darkens, as while dragged. */
653
+ .r-scroll-area
654
+ > .r-scroll-area__gutters
655
+ > .r-scroll-area__gutter--vertical:hover
656
+ > .r-scroll-area__thumb {
657
+ background: var(--r-scroll-area-thumb-color-hover);
658
+ inline-size: var(--r-scroll-area-thumb-size-hover);
659
+ }
660
+ .r-scroll-area
661
+ > .r-scroll-area__gutters
662
+ > .r-scroll-area__gutter--horizontal:hover
663
+ > .r-scroll-area__thumb {
664
+ background: var(--r-scroll-area-thumb-color-hover);
665
+ block-size: var(--r-scroll-area-thumb-size-hover);
666
+ }
667
+ }
668
+
669
+ /*
670
+ * Where nothing hovers, trigger="hover" and "scroll" both show the scrollbars
671
+ * only while the area scrolls or a thumb is dragged, and a hidden gutter
672
+ * never catches a tap: it goes to the content under it. A scrollbar shown by
673
+ * scrolling takes the finger, so its thumb can be dragged; the drag keeps it.
674
+ */
675
+ @media (hover: none) {
676
+ .r-scroll-area.r-scroll-area--hover-trigger
677
+ > .r-scroll-area__gutters:not(.r-scroll-area__gutters--scrolling):not(
678
+ .r-scroll-area__gutters--dragging
679
+ )
680
+ > .r-scroll-area__gutter,
681
+ .r-scroll-area.r-scroll-area--scroll-trigger
682
+ > .r-scroll-area__gutters:not(.r-scroll-area__gutters--scrolling):not(
683
+ .r-scroll-area__gutters--dragging
684
+ )
685
+ > .r-scroll-area__gutter {
686
+ pointer-events: none;
687
+ }
688
+ }
689
+
649
690
  /*
650
691
  * Scroll-driven thumbs: the browser moves each thumb from the scroll itself,
651
692
  * on the compositor, with no script per scroll. The container names its
@@ -5,7 +5,8 @@ const searchEntity = tv({ slots: {
5
5
  entity: [
6
6
  "flex min-w-0 w-full items-center gap-3 text-left",
7
7
  "rounded-none border-0 py-3 text-foreground",
8
- "pointer-coarse:min-h-16",
8
+ "md:pointer-fine:py-2",
9
+ "pointer-coarse:min-h-14 pointer-coarse:py-2",
9
10
  listCell,
10
11
  listCellStates,
11
12
  "disabled:cursor-default",
@@ -15,7 +16,7 @@ const searchEntity = tv({ slots: {
15
16
  entityLeading: ["relative flex shrink-0"],
16
17
  entityIcon: [
17
18
  "flex items-center justify-center overflow-hidden",
18
- "size-[27px] rounded-sticker bg-fill-muted text-foreground-muted",
19
+ "size-[27px] rounded-chip bg-fill-muted text-foreground-muted",
19
20
  "[&_svg]:size-3.5"
20
21
  ],
21
22
  entityActivity: [
@@ -6,6 +6,7 @@ const searchMessage = tv({ slots: {
6
6
  message: [
7
7
  "w-full text-left",
8
8
  "block rounded-none border-0 py-3 text-foreground",
9
+ "md:pointer-fine:py-2",
9
10
  listCell,
10
11
  listCellStates,
11
12
  "disabled:cursor-default",
@@ -2,7 +2,7 @@ import { tv } from "../../lib/tv.mjs";
2
2
  //#region src/components/search/search-thread.recipe.ts
3
3
  const searchThread = tv({ slots: {
4
4
  thread: ["overflow-hidden", "relative rounded-none border-0 bg-transparent text-foreground shadow-none"],
5
- threadHeader: ["py-2", "px-5 pt-3 pb-0"],
5
+ threadHeader: ["py-2", "px-(--surface-inset) pt-3 pb-0"],
6
6
  threadMeta: [
7
7
  "flex flex-wrap items-center",
8
8
  "mb-0.5 gap-1.5",
@@ -6,7 +6,7 @@ import { useRender } from "@base-ui/react/use-render";
6
6
  //#region src/components/search/search-trigger.tsx
7
7
  const searchTrigger = tv({ slots: {
8
8
  root: [
9
- "relative inline-flex h-9 w-[clamp(360px,32vw,520px)] max-w-full min-w-0 shrink-0 items-center gap-2 px-3",
9
+ "relative inline-flex h-(--frame-item-height) w-[clamp(360px,32vw,520px)] max-w-full min-w-0 shrink-0 items-center gap-2 px-3",
10
10
  "rounded-control border-[1.5px] border-line-field bg-layer-card",
11
11
  "text-left font-sans text-body font-normal text-foreground-hint",
12
12
  "select-none outline-none transition-colors duration-100",
@@ -7,13 +7,17 @@ const search = tv({ slots: {
7
7
  "bg-layer-canvas text-foreground",
8
8
  listColumnMargin
9
9
  ],
10
- filtersRow: ["shrink-0", "border-b border-line-seam bg-layer-canvas px-(--column-margin) py-3"],
10
+ filtersRow: [
11
+ "shrink-0",
12
+ "border-b border-line-seam bg-layer-canvas px-(--column-margin) py-3",
13
+ "md:pointer-fine:py-[calc((var(--header-height)-1px-var(--control-height))/2)]"
14
+ ],
11
15
  viewport: ["min-h-0 flex-1 overflow-y-auto scrollbar-list p-4", "bg-layer-canvas px-0 pt-0 pb-4"],
12
- summary: ["block", "mb-0 px-5 pt-2 font-sans text-footnote text-foreground-hint"],
16
+ summary: ["block", "mb-0 px-(--surface-inset) pt-2 font-sans text-footnote text-foreground-hint"],
13
17
  section: ["mb-0"],
14
18
  sectionHeading: [
15
19
  "py-2",
16
- "flex items-center gap-2 px-5 pt-3 pb-0",
20
+ "flex items-center gap-2 px-(--surface-inset) pt-3 pb-0",
17
21
  "font-sans text-footnote font-bold text-foreground-hint"
18
22
  ],
19
23
  list: ["flex flex-col", "gap-0.5 py-2"]
@@ -12,13 +12,14 @@ const segmentedControl = tv({
12
12
  root: [
13
13
  "inline-flex min-w-0 items-center",
14
14
  "w-fit max-w-full flex-nowrap gap-[3px] rounded-[11px] bg-fill-muted p-[3px]",
15
+ "[--segment-size:2rem] md:pointer-fine:[--segment-size:var(--control-height)]",
15
16
  "data-overflowing:overflow-x-auto data-overflowing:overscroll-x-contain data-overflowing:scrollbar-none"
16
17
  ],
17
18
  item: [
18
19
  "inline-flex min-w-0 shrink-0 items-center gap-1.5",
19
20
  "outline-none disabled:pointer-events-none",
20
21
  "[&_svg]:pointer-events-none [&_svg]:shrink-0",
21
- "h-8 justify-center rounded-control border-[1.5px] border-transparent bg-transparent px-3",
22
+ "h-(--segment-size) justify-center rounded-control border-[1.5px] border-transparent bg-transparent px-3",
22
23
  "font-sans text-callout font-semibold text-foreground-muted",
23
24
  "[&_svg:not([class*='size-'])]:size-4",
24
25
  "hover:bg-fill-medium active:bg-fill-medium",
@@ -42,14 +43,14 @@ const segmentedControl = tv({
42
43
  ] }
43
44
  },
44
45
  iconsOnlyBelow: {
45
- xs: { root: ["@max-xs:**:data-[slot=segmented-control-item]:relative @max-xs:**:data-[slot=segmented-control-item]:w-8 @max-xs:**:data-[slot=segmented-control-item]:px-0", "@max-xs:**:data-[slot=segmented-control-label]:sr-only @max-xs:**:data-[slot=segmented-control-count]:sr-only"] },
46
- sm: { root: ["@max-sm:**:data-[slot=segmented-control-item]:relative @max-sm:**:data-[slot=segmented-control-item]:w-8 @max-sm:**:data-[slot=segmented-control-item]:px-0", "@max-sm:**:data-[slot=segmented-control-label]:sr-only @max-sm:**:data-[slot=segmented-control-count]:sr-only"] },
47
- md: { root: ["@max-md:**:data-[slot=segmented-control-item]:relative @max-md:**:data-[slot=segmented-control-item]:w-8 @max-md:**:data-[slot=segmented-control-item]:px-0", "@max-md:**:data-[slot=segmented-control-label]:sr-only @max-md:**:data-[slot=segmented-control-count]:sr-only"] },
48
- lg: { root: ["@max-lg:**:data-[slot=segmented-control-item]:relative @max-lg:**:data-[slot=segmented-control-item]:w-8 @max-lg:**:data-[slot=segmented-control-item]:px-0", "@max-lg:**:data-[slot=segmented-control-label]:sr-only @max-lg:**:data-[slot=segmented-control-count]:sr-only"] },
49
- xl: { root: ["@max-xl:**:data-[slot=segmented-control-item]:relative @max-xl:**:data-[slot=segmented-control-item]:w-8 @max-xl:**:data-[slot=segmented-control-item]:px-0", "@max-xl:**:data-[slot=segmented-control-label]:sr-only @max-xl:**:data-[slot=segmented-control-count]:sr-only"] },
50
- "2xl": { root: ["@max-2xl:**:data-[slot=segmented-control-item]:relative @max-2xl:**:data-[slot=segmented-control-item]:w-8 @max-2xl:**:data-[slot=segmented-control-item]:px-0", "@max-2xl:**:data-[slot=segmented-control-label]:sr-only @max-2xl:**:data-[slot=segmented-control-count]:sr-only"] }
46
+ xs: { root: ["@max-xs:**:data-[slot=segmented-control-item]:relative @max-xs:**:data-[slot=segmented-control-item]:w-(--segment-size) @max-xs:**:data-[slot=segmented-control-item]:px-0", "@max-xs:**:data-[slot=segmented-control-label]:sr-only @max-xs:**:data-[slot=segmented-control-count]:sr-only"] },
47
+ sm: { root: ["@max-sm:**:data-[slot=segmented-control-item]:relative @max-sm:**:data-[slot=segmented-control-item]:w-(--segment-size) @max-sm:**:data-[slot=segmented-control-item]:px-0", "@max-sm:**:data-[slot=segmented-control-label]:sr-only @max-sm:**:data-[slot=segmented-control-count]:sr-only"] },
48
+ md: { root: ["@max-md:**:data-[slot=segmented-control-item]:relative @max-md:**:data-[slot=segmented-control-item]:w-(--segment-size) @max-md:**:data-[slot=segmented-control-item]:px-0", "@max-md:**:data-[slot=segmented-control-label]:sr-only @max-md:**:data-[slot=segmented-control-count]:sr-only"] },
49
+ lg: { root: ["@max-lg:**:data-[slot=segmented-control-item]:relative @max-lg:**:data-[slot=segmented-control-item]:w-(--segment-size) @max-lg:**:data-[slot=segmented-control-item]:px-0", "@max-lg:**:data-[slot=segmented-control-label]:sr-only @max-lg:**:data-[slot=segmented-control-count]:sr-only"] },
50
+ xl: { root: ["@max-xl:**:data-[slot=segmented-control-item]:relative @max-xl:**:data-[slot=segmented-control-item]:w-(--segment-size) @max-xl:**:data-[slot=segmented-control-item]:px-0", "@max-xl:**:data-[slot=segmented-control-label]:sr-only @max-xl:**:data-[slot=segmented-control-count]:sr-only"] },
51
+ "2xl": { root: ["@max-2xl:**:data-[slot=segmented-control-item]:relative @max-2xl:**:data-[slot=segmented-control-item]:w-(--segment-size) @max-2xl:**:data-[slot=segmented-control-item]:px-0", "@max-2xl:**:data-[slot=segmented-control-label]:sr-only @max-2xl:**:data-[slot=segmented-control-count]:sr-only"] }
51
52
  },
52
- iconsOnlyMeasured: { true: { root: ["data-icons-only:**:data-[slot=segmented-control-item]:relative data-icons-only:**:data-[slot=segmented-control-item]:w-8 data-icons-only:**:data-[slot=segmented-control-item]:px-0", "data-icons-only:**:data-[slot=segmented-control-label]:sr-only data-icons-only:**:data-[slot=segmented-control-count]:sr-only"] } }
53
+ iconsOnlyMeasured: { true: { root: ["data-icons-only:**:data-[slot=segmented-control-item]:relative data-icons-only:**:data-[slot=segmented-control-item]:w-(--segment-size) data-icons-only:**:data-[slot=segmented-control-item]:px-0", "data-icons-only:**:data-[slot=segmented-control-label]:sr-only data-icons-only:**:data-[slot=segmented-control-count]:sr-only"] } }
53
54
  }
54
55
  });
55
56
  const ICONS_ONLY_PRESETS = /* @__PURE__ */ new Set([
@@ -17,7 +17,7 @@ const select = tv({
17
17
  "**:data-[slot='button-content']:w-full **:data-[slot='button-content']:justify-between",
18
18
  "[&>span[data-slot='select-trigger-content']]:min-w-0 [&>span[data-slot='select-trigger-content']]:flex-1",
19
19
  "[&_[data-slot='select-trigger-content']_svg]:shrink-0",
20
- "h-control w-full gap-2 pr-3 pl-3.5",
20
+ "h-control w-full gap-2 rounded-(--control-radius) pr-3 pl-3.5",
21
21
  "border-[1.5px] border-line-field",
22
22
  "hover:bg-none",
23
23
  "text-subhead font-semibold text-foreground",
@@ -102,7 +102,7 @@ const select = tv({
102
102
  trigger: [
103
103
  "px-3 text-field font-field",
104
104
  "**:data-[slot='button-content']:font-field **:data-[slot='select-value']:font-field",
105
- "h-control py-0",
105
+ "h-control rounded-(--control-radius) py-0",
106
106
  "data-placeholder:font-field"
107
107
  ],
108
108
  item: ["text-field font-field", "**:data-[slot='select-item-text']:font-field"],
@@ -1,5 +1,5 @@
1
1
  import { SidebarBody, SidebarBodyProps, SidebarContent, SidebarContentProps, SidebarGroupLabel, SidebarGroupLabelProps, SidebarHeader, SidebarHeaderProps, SidebarHeaderTitle, SidebarHeaderTitleProps, SidebarRoot, SidebarRootProps } from "./sidebar.mjs";
2
2
  import { SidebarMenu, SidebarMenuAside, SidebarMenuAsideProps, SidebarMenuCount, SidebarMenuCountProps, SidebarMenuIcon, SidebarMenuIconProps, SidebarMenuProps, SidebarMenuTitle, SidebarMenuTitleProps } from "./sidebar-menu.mjs";
3
3
  import { SidebarItem, SidebarItemAside, SidebarItemAsideProps, SidebarItemChannelIcon, SidebarItemChannelIconProps, SidebarItemContent, SidebarItemContentProps, SidebarItemCount, SidebarItemCountProps, SidebarItemCountSeparator, SidebarItemCountSeparatorProps, SidebarItemIcon, SidebarItemIconProps, SidebarItemIndicator, SidebarItemIndicatorProps, SidebarItemMeta, SidebarItemMetaIcon, SidebarItemMetaIconProps, SidebarItemMetaProps, SidebarItemProps, SidebarItemStatus, SidebarItemStatusProps, SidebarItemSubtitle, SidebarItemSubtitleProps, SidebarItemThreadCount, SidebarItemThreadCountProps, SidebarItemTitle, SidebarItemTitleProps } from "./sidebar-item.mjs";
4
- import { SidebarControl, SidebarControlProps, SidebarList, SidebarListProps, SidebarSection, SidebarSectionAttention, SidebarSectionAttentionProps, SidebarSectionChevron, SidebarSectionChevronProps, SidebarSectionControl, SidebarSectionControlProps, SidebarSectionControls, SidebarSectionControlsProps, SidebarSectionCount, SidebarSectionCountProps, SidebarSectionDisclosure, SidebarSectionDisclosureProps, SidebarSectionEmpty, SidebarSectionEmptyProps, SidebarSectionHeader, SidebarSectionHeaderProps, SidebarSectionProps, SidebarSectionTitle, SidebarSectionTitleProps, SidebarSectionTrailing, SidebarSectionTrailingProps } from "./sidebar-section.mjs";
5
- export { SidebarBody, type SidebarBodyProps, SidebarContent, type SidebarContentProps, SidebarControl, type SidebarControlProps, SidebarGroupLabel, type SidebarGroupLabelProps, SidebarHeader, type SidebarHeaderProps, SidebarHeaderTitle, type SidebarHeaderTitleProps, SidebarItem, SidebarItemAside, type SidebarItemAsideProps, SidebarItemChannelIcon, type SidebarItemChannelIconProps, SidebarItemContent, type SidebarItemContentProps, SidebarItemCount, type SidebarItemCountProps, SidebarItemCountSeparator, type SidebarItemCountSeparatorProps, SidebarItemIcon, type SidebarItemIconProps, SidebarItemIndicator, type SidebarItemIndicatorProps, SidebarItemMeta, SidebarItemMetaIcon, type SidebarItemMetaIconProps, type SidebarItemMetaProps, type SidebarItemProps, SidebarItemStatus, type SidebarItemStatusProps, SidebarItemSubtitle, type SidebarItemSubtitleProps, SidebarItemThreadCount, type SidebarItemThreadCountProps, SidebarItemTitle, type SidebarItemTitleProps, SidebarList, type SidebarListProps, SidebarMenu, SidebarMenuAside, type SidebarMenuAsideProps, SidebarMenuCount, type SidebarMenuCountProps, SidebarMenuIcon, type SidebarMenuIconProps, type SidebarMenuProps, SidebarMenuTitle, type SidebarMenuTitleProps, SidebarRoot, type SidebarRootProps, SidebarSection, SidebarSectionAttention, type SidebarSectionAttentionProps, SidebarSectionChevron, type SidebarSectionChevronProps, SidebarSectionControl, type SidebarSectionControlProps, SidebarSectionControls, type SidebarSectionControlsProps, SidebarSectionCount, type SidebarSectionCountProps, SidebarSectionDisclosure, type SidebarSectionDisclosureProps, SidebarSectionEmpty, type SidebarSectionEmptyProps, SidebarSectionHeader, type SidebarSectionHeaderProps, type SidebarSectionProps, SidebarSectionTitle, type SidebarSectionTitleProps, SidebarSectionTrailing, type SidebarSectionTrailingProps };
4
+ import { SidebarControl, SidebarControlProps, SidebarList, SidebarListProps, SidebarSection, SidebarSectionAttention, SidebarSectionAttentionProps, SidebarSectionChevron, SidebarSectionChevronProps, SidebarSectionControl, SidebarSectionControlProps, SidebarSectionControls, SidebarSectionControlsProps, SidebarSectionCount, SidebarSectionCountProps, SidebarSectionDisclosure, SidebarSectionDisclosureProps, SidebarSectionEmpty, SidebarSectionEmptyProps, SidebarSectionEndChevron, SidebarSectionEndChevronProps, SidebarSectionHeader, SidebarSectionHeaderProps, SidebarSectionProps, SidebarSectionTitle, SidebarSectionTitleProps, SidebarSectionTrailing, SidebarSectionTrailingProps } from "./sidebar-section.mjs";
5
+ export { SidebarBody, type SidebarBodyProps, SidebarContent, type SidebarContentProps, SidebarControl, type SidebarControlProps, SidebarGroupLabel, type SidebarGroupLabelProps, SidebarHeader, type SidebarHeaderProps, SidebarHeaderTitle, type SidebarHeaderTitleProps, SidebarItem, SidebarItemAside, type SidebarItemAsideProps, SidebarItemChannelIcon, type SidebarItemChannelIconProps, SidebarItemContent, type SidebarItemContentProps, SidebarItemCount, type SidebarItemCountProps, SidebarItemCountSeparator, type SidebarItemCountSeparatorProps, SidebarItemIcon, type SidebarItemIconProps, SidebarItemIndicator, type SidebarItemIndicatorProps, SidebarItemMeta, SidebarItemMetaIcon, type SidebarItemMetaIconProps, type SidebarItemMetaProps, type SidebarItemProps, SidebarItemStatus, type SidebarItemStatusProps, SidebarItemSubtitle, type SidebarItemSubtitleProps, SidebarItemThreadCount, type SidebarItemThreadCountProps, SidebarItemTitle, type SidebarItemTitleProps, SidebarList, type SidebarListProps, SidebarMenu, SidebarMenuAside, type SidebarMenuAsideProps, SidebarMenuCount, type SidebarMenuCountProps, SidebarMenuIcon, type SidebarMenuIconProps, type SidebarMenuProps, SidebarMenuTitle, type SidebarMenuTitleProps, SidebarRoot, type SidebarRootProps, SidebarSection, SidebarSectionAttention, type SidebarSectionAttentionProps, SidebarSectionChevron, type SidebarSectionChevronProps, SidebarSectionControl, type SidebarSectionControlProps, SidebarSectionControls, type SidebarSectionControlsProps, SidebarSectionCount, type SidebarSectionCountProps, SidebarSectionDisclosure, type SidebarSectionDisclosureProps, SidebarSectionEmpty, type SidebarSectionEmptyProps, SidebarSectionEndChevron, type SidebarSectionEndChevronProps, SidebarSectionHeader, type SidebarSectionHeaderProps, type SidebarSectionProps, SidebarSectionTitle, type SidebarSectionTitleProps, SidebarSectionTrailing, type SidebarSectionTrailingProps };
@@ -6,7 +6,8 @@ const sidebarItemRecipe = tv({
6
6
  sidebarItem: [
7
7
  "group/sidebar-item flex w-full items-center text-left",
8
8
  listCell,
9
- "h-[38px] gap-2 rounded-none border-0 py-0",
9
+ "h-(--row-height) gap-2 rounded-none border-0 py-0",
10
+ "md:pointer-fine:*:data-[slot=avatar]:-mr-[3px]",
10
11
  "md:py-0 md:[@media(max-height:600px)]:py-0",
11
12
  "max-md:h-auto max-md:min-h-11 max-md:py-2.5",
12
13
  "font-sans text-subhead font-medium text-foreground",
@@ -18,13 +19,13 @@ const sidebarItemRecipe = tv({
18
19
  sidebarItemIcon: [
19
20
  "flex shrink-0 items-center justify-center",
20
21
  "[&>svg]:shrink-0",
21
- "size-[19px] text-foreground-hint [&>svg]:size-4 [&>svg]:stroke-2",
22
+ "size-[19px] md:pointer-fine:size-4 text-foreground-hint [&>svg]:size-4 [&>svg]:stroke-2",
22
23
  "group-data-active/sidebar-item:text-sticker-ink"
23
24
  ],
24
25
  sidebarItemChannelIcon: [
25
26
  "flex shrink-0 items-center justify-center",
26
27
  "[&_svg]:shrink-0",
27
- "size-[19px] text-foreground-hint [&_svg]:size-4 [&_svg]:stroke-2",
28
+ "size-[19px] md:pointer-fine:size-4 text-foreground-hint [&_svg]:size-4 [&_svg]:stroke-2",
28
29
  "group-data-active/sidebar-item:text-sticker-ink"
29
30
  ],
30
31
  sidebarItemContent: ["has-[>[data-slot=sidebar-item-meta-icon]]:items-center"],
@@ -79,7 +80,7 @@ const sidebarItemRecipe = tv({
79
80
  false: {},
80
81
  true: { sidebarItem: [
81
82
  "h-auto items-start whitespace-normal",
82
- "min-h-[38px] py-[9px] md:py-[9px] md:[@media(max-height:600px)]:py-[9px]",
83
+ "min-h-(--row-height) py-[calc((var(--row-height)-20px)/2)] md:py-[calc((var(--row-height)-20px)/2)] md:[@media(max-height:600px)]:py-[calc((var(--row-height)-20px)/2)]",
83
84
  "**:data-[slot=sidebar-item-channel-icon]:h-lh **:data-[slot=sidebar-item-icon]:h-lh",
84
85
  "**:data-[slot=sidebar-item-meta-icon]:h-lh",
85
86
  "*:data-[slot=avatar]:mt-[calc((1lh-19px)/2)]"
@@ -18,8 +18,15 @@ export type SidebarSectionEmptyProps = Omit<ComponentProps<typeof Collapsible.Pa
18
18
  className?: string;
19
19
  };
20
20
  export declare function SidebarSectionEmpty({ className, render, ...props }: SidebarSectionEmptyProps): import("react").JSX.Element;
21
- export type SidebarSectionHeaderProps = useRender.ComponentProps<"div">;
22
- export declare function SidebarSectionHeader({ className, render, ...props }: SidebarSectionHeaderProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
21
+ export type SidebarSectionHeaderProps = useRender.ComponentProps<"div"> & {
22
+ /**
23
+ * The header ends with a `SidebarSectionEndChevron`: with a mouse on a
24
+ * desktop the chevron is that last control, so the one before the title
25
+ * hides. On a touch screen the chevron stays before the title.
26
+ */
27
+ chevronAtEnd?: boolean;
28
+ };
29
+ export declare function SidebarSectionHeader({ className, render, chevronAtEnd, ...props }: SidebarSectionHeaderProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
23
30
  export type SidebarSectionDisclosureProps = useRender.ComponentProps<"button">;
24
31
  export declare function SidebarSectionDisclosure({ className, render, ...props }: SidebarSectionDisclosureProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
25
32
  export type SidebarSectionChevronProps = useRender.ComponentProps<"svg">;
@@ -36,6 +43,8 @@ export declare function SidebarSectionTrailing({ className, render, ...props }:
36
43
  export declare function SidebarSectionControls({ className, render, ...props }: SidebarSectionControlsProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
37
44
  export type SidebarSectionControlProps = useRender.ComponentProps<"button"> & Pick<ButtonProps, "size" | "variant" | "loading" | "loadingLabel">;
38
45
  export declare function SidebarSectionControl({ className, render, size, variant, loading, loadingLabel, children, disabled, ...props }: SidebarSectionControlProps): import("react").JSX.Element;
46
+ export type SidebarSectionEndChevronProps = Omit<SidebarSectionControlProps, "children" | "render">;
47
+ export declare function SidebarSectionEndChevron({ className, ...props }: SidebarSectionEndChevronProps): import("react").JSX.Element;
39
48
  export type SidebarControlProps = SidebarSectionControlProps;
40
49
  export declare const SidebarControl: typeof SidebarSectionControl;
41
50
  //#endregion
@@ -42,10 +42,11 @@ function SidebarSectionEmpty({ className, render, ...props }) {
42
42
  ...mergeProps(defaultProps, props)
43
43
  });
44
44
  }
45
- function SidebarSectionHeader({ className, render, ...props }) {
45
+ function SidebarSectionHeader({ className, render, chevronAtEnd = false, ...props }) {
46
46
  const { sidebarSectionHeader } = sidebarSectionRecipe();
47
47
  const defaultProps = {
48
48
  "data-slot": "sidebar-section-header",
49
+ "data-chevron-at-end": chevronAtEnd ? "" : void 0,
49
50
  className: sidebarSectionHeader({ className })
50
51
  };
51
52
  return useRender({
@@ -67,6 +68,7 @@ function SidebarSectionDisclosure({ className, render, ...props }) {
67
68
  });
68
69
  }
69
70
  function SidebarSectionChevron({ className, render, ...props }) {
71
+ const { sidebarSectionChevronSlot } = sidebarSectionRecipe();
70
72
  const defaultProps = {
71
73
  "data-slot": "sidebar-section-chevron",
72
74
  className: cn("size-3", className)
@@ -76,7 +78,7 @@ function SidebarSectionChevron({ className, render, ...props }) {
76
78
  props: mergeProps(defaultProps, props)
77
79
  });
78
80
  return /* @__PURE__ */ jsx("span", {
79
- className: "flex size-4.5 shrink-0 items-center justify-center",
81
+ className: sidebarSectionChevronSlot(),
80
82
  "aria-hidden": "true",
81
83
  children: chevron
82
84
  });
@@ -159,6 +161,30 @@ function SidebarSectionControl({ className, render, size = "icon-md", variant =
159
161
  children
160
162
  });
161
163
  }
164
+ /**
165
+ * The section's chevron as the last of its controls, with a mouse on a
166
+ * desktop (sidebar.md, Section headers): a SidebarSectionControl that is a
167
+ * second trigger of the section, so it toggles it and turns with it. The
168
+ * title stays the section's one toggle for the keyboard and a screen reader,
169
+ * so this one is out of the tab order and the accessibility tree, and a press
170
+ * doesn't move focus onto it (focus on a hidden element would be read as
171
+ * nothing). Put it in a `SidebarSectionHeader` with `chevronAtEnd`.
172
+ */
173
+ function keepFocus(event) {
174
+ event.preventDefault();
175
+ }
176
+ function SidebarSectionEndChevron({ className, ...props }) {
177
+ const { sidebarSectionEndChevron } = sidebarSectionRecipe();
178
+ return /* @__PURE__ */ jsx(SidebarSectionControl, {
179
+ "data-end-chevron": "",
180
+ render: /* @__PURE__ */ jsx(Collapsible.Trigger, {}),
181
+ tabIndex: -1,
182
+ "aria-hidden": true,
183
+ className: sidebarSectionEndChevron({ className }),
184
+ ...mergeProps({ onMouseDown: keepFocus }, props),
185
+ children: /* @__PURE__ */ jsx(ChevronRight, {})
186
+ });
187
+ }
162
188
  const SidebarControl = SidebarSectionControl;
163
189
  //#endregion
164
- export { SidebarControl, SidebarList, SidebarSection, SidebarSectionAttention, SidebarSectionChevron, SidebarSectionControl, SidebarSectionControls, SidebarSectionCount, SidebarSectionDisclosure, SidebarSectionEmpty, SidebarSectionHeader, SidebarSectionTitle, SidebarSectionTrailing };
190
+ export { SidebarControl, SidebarList, SidebarSection, SidebarSectionAttention, SidebarSectionChevron, SidebarSectionControl, SidebarSectionControls, SidebarSectionCount, SidebarSectionDisclosure, SidebarSectionEmpty, SidebarSectionEndChevron, SidebarSectionHeader, SidebarSectionTitle, SidebarSectionTrailing };
@@ -2,9 +2,9 @@ import { tv } from "../../lib/tv.mjs";
2
2
  //#region src/components/sidebar/sidebar-section.recipe.ts
3
3
  const sidebarSectionRecipe = tv({ slots: {
4
4
  sidebarSection: ["group/section", "px-0"],
5
- sidebarList: ["flex flex-col gap-0.5 py-2"],
5
+ sidebarList: ["flex flex-col gap-0.5 py-2 md:pointer-fine:pt-1"],
6
6
  sidebarSectionEmpty: [
7
- "px-5 py-2",
7
+ "px-(--surface-inset) md:pointer-fine:pl-(--sidebar-text-axis) py-2",
8
8
  "font-sans text-footnote",
9
9
  "text-foreground-hint"
10
10
  ],
@@ -13,6 +13,7 @@ const sidebarSectionRecipe = tv({ slots: {
13
13
  "group/section-header",
14
14
  "my-0 h-auto gap-2 pt-4 pb-0 pl-5",
15
15
  "pr-[calc(max(0px,calc(8px-var(--scrollbar-size,0px)))+12px)]",
16
+ "md:pointer-fine:min-h-6 md:pointer-fine:pt-2 md:pointer-fine:pl-(--sidebar-glyph-axis) md:pointer-fine:pr-[calc(max(0px,calc(8px-var(--scrollbar-size,0px)))+10px)]",
16
17
  "not-pointer-fine:pb-1.5"
17
18
  ],
18
19
  sidebarSectionDisclosure: [
@@ -24,6 +25,8 @@ const sidebarSectionRecipe = tv({ slots: {
24
25
  "outline-none focus-visible:shadow-focus",
25
26
  "**:data-[slot=sidebar-section-chevron]:size-3.5 **:data-[slot=sidebar-section-chevron]:stroke-2"
26
27
  ],
28
+ sidebarSectionChevronSlot: ["flex size-4.5 shrink-0 items-center justify-center", "md:pointer-fine:in-data-chevron-at-end:hidden"],
29
+ sidebarSectionEndChevron: ["hidden md:pointer-fine:flex", "[&_svg]:transition-transform data-panel-open:[&_svg]:rotate-90"],
27
30
  sidebarSectionTitle: ["min-w-0 truncate"],
28
31
  sidebarSectionCount: ["font-mono text-mono-meta font-normal tabular-nums text-foreground-hint"],
29
32
  sidebarSectionAttention: ["inline-flex min-w-4.5 shrink-0 items-center justify-center", "group-data-open/section:hidden"],
@@ -31,12 +34,14 @@ const sidebarSectionRecipe = tv({ slots: {
31
34
  sidebarSectionControls: ["flex shrink-0 items-center gap-1", "[&>[data-icon-inset]:nth-last-child(1_of_:not([data-base-ui-focus-guard],[aria-owns]))]:-mr-icon-inset"],
32
35
  sidebarSectionControl: [
33
36
  "relative flex h-6 w-auto min-w-6 shrink-0 items-center justify-center p-0 -my-1",
37
+ "md:pointer-fine:size-auto md:pointer-fine:h-6 md:pointer-fine:min-w-6",
34
38
  "[&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
35
39
  "[--icon-inset:calc((--spacing(6)-14px)/2)]",
36
40
  "text-foreground-hint",
37
41
  "hover:text-foreground active:text-foreground focus-visible:text-foreground",
38
42
  "data-popup-open:bg-fill-medium data-popup-open:text-foreground",
39
43
  "not-pointer-fine:after:absolute not-pointer-fine:after:inset-[-11px] not-pointer-fine:after:content-['']",
44
+ "pointer-fine:after:absolute pointer-fine:after:inset-[-3px] pointer-fine:after:content-['']",
40
45
  "not-pointer-fine:not-first:after:left-[-3px] not-pointer-fine:not-last:after:right-[-3px]"
41
46
  ]
42
47
  } });
@@ -10,16 +10,16 @@ const sidebarRecipe = tv({ slots: {
10
10
  ],
11
11
  sidebarHeader: [
12
12
  "flex items-center",
13
- "h-(--shell-header-height,56px) shrink-0 gap-2 border-b border-line-seam px-(--column-margin)",
13
+ "h-(--shell-header-height,var(--header-height)) shrink-0 gap-2 border-b border-line-seam px-(--column-margin)",
14
14
  "bg-layer-sidebar text-foreground",
15
15
  "max-md:bg-layer-frame max-md:text-foreground-on-frame",
16
16
  headEdgePull,
17
- "[@media(max-height:600px)]:h-12"
17
+ "[@media(max-height:600px)]:h-(--header-height-short)"
18
18
  ],
19
19
  sidebarHeaderMask: ["pointer-events-none absolute inset-x-0 top-0 -z-10 hidden"],
20
20
  sidebarHeaderMaskLayer: ["absolute inset-x-0 top-0"],
21
21
  sidebarHeaderTitle: ["truncate font-bold", "font-sans text-headline text-foreground max-md:text-foreground-on-frame"],
22
- sidebarGroupLabel: ["px-5 pt-4 pb-0", "font-sans text-footnote font-bold normal-case tracking-normal text-foreground-hint"],
22
+ sidebarGroupLabel: ["px-5 pt-4 pb-0 md:pointer-fine:px-(--sidebar-glyph-axis) md:pointer-fine:pt-2", "font-sans text-footnote font-bold normal-case tracking-normal text-foreground-hint"],
23
23
  sidebarBody: ["relative flex min-h-0 flex-1 overflow-hidden", "bg-layer-sidebar max-md:bg-layer-canvas"],
24
24
  sidebarContent: ["relative flex min-h-0 min-w-0 flex-1"],
25
25
  sidebarViewport: ["size-full min-h-0 flex-1 overflow-x-hidden overflow-y-auto"],
@@ -9,9 +9,9 @@ const switchRecipe = tv({ slots: {
9
9
  "motion-reduce:transition-none",
10
10
  "not-data-disabled:cursor-pointer",
11
11
  "data-disabled:cursor-not-allowed",
12
- "after:absolute after:-inset-x-3 after:-inset-y-2 after:content-['']",
12
+ "after:absolute after:-inset-x-3 after:-inset-y-[calc((44px-var(--switch-height))/2+1.5px)] after:content-['']",
13
13
  "focus-visible:ring-line-strong focus-visible:ring-offset-layer-sidebar",
14
- "h-[30px] w-[50px] rounded-full border-[1.5px] border-line-strong bg-fill-muted p-[2.5px]",
14
+ "h-(--switch-height) w-(--switch-width) rounded-full border-[1.5px] border-line-strong bg-fill-muted p-[2.5px]",
15
15
  "duration-150",
16
16
  "data-checked:border-sticker-ink data-checked:bg-selected data-checked:ring-[1.5px] data-checked:ring-sticker-edge",
17
17
  "focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:shadow-focus",
@@ -22,7 +22,7 @@ const switchRecipe = tv({ slots: {
22
22
  "pointer-events-none block",
23
23
  "transition-transform ease-out",
24
24
  "motion-reduce:transition-none",
25
- "size-[22px] rounded-full bg-layer-card shadow-[0_0_0_1.5px_var(--line-strong)] data-[checked]:translate-x-5",
25
+ "size-[calc(var(--switch-height)-8px)] rounded-full bg-layer-card shadow-[0_0_0_1.5px_var(--line-strong)] data-checked:translate-x-[calc(var(--switch-width)-var(--switch-height))]",
26
26
  "duration-220 ease-slide",
27
27
  "data-checked:bg-sticker-paper data-checked:shadow-[0_0_0_1.5px_var(--sticker-ink)]",
28
28
  "data-disabled:bg-fill-muted data-disabled:shadow-[0_0_0_1.5px_var(--foreground-disabled)]",
@@ -41,7 +41,7 @@ const tabs = tv({
41
41
  default: {
42
42
  list: ["gap-0.5"],
43
43
  tab: [
44
- "h-8 justify-center gap-1.5 rounded-control border-[1.5px] border-transparent px-3",
44
+ "h-8 md:pointer-fine:h-control justify-center gap-1.5 rounded-control border-[1.5px] border-transparent px-3",
45
45
  "after:inset-x-0 after:-inset-y-1.5",
46
46
  "hover:bg-fill-medium active:bg-fill-medium",
47
47
  "data-active:border-sticker-ink data-active:bg-selected data-active:font-bold data-active:text-sticker-ink data-active:ring-[1.5px] data-active:ring-sticker-edge",
@@ -8,7 +8,7 @@ const taskBoardColumn = tv({ slots: {
8
8
  ],
9
9
  trigger: [
10
10
  "group flex w-full touch-manipulation items-center justify-between text-left outline-none",
11
- "min-h-8 gap-2 rounded-control",
11
+ "min-h-8 md:pointer-fine:min-h-control gap-2 rounded-control",
12
12
  "font-sans text-footnote font-bold text-foreground-muted",
13
13
  "data-[panel-open]:mb-2",
14
14
  "focus-visible:shadow-focus"
@@ -5,7 +5,7 @@ const taskListSection = tv({ slots: {
5
5
  trigger: [
6
6
  "group flex w-full touch-manipulation items-center text-left outline-none",
7
7
  "disabled:cursor-default",
8
- "min-h-8 justify-start gap-2 rounded-control",
8
+ "min-h-8 md:pointer-fine:min-h-control justify-start gap-2 rounded-control",
9
9
  "font-sans text-footnote font-bold text-foreground-hint",
10
10
  "focus-visible:shadow-focus"
11
11
  ],
@@ -5,7 +5,8 @@ const tasksPanel = tv({ slots: {
5
5
  toolbar: [
6
6
  "grid shrink-0 grid-cols-[minmax(0,1fr)_auto] items-center gap-2",
7
7
  "@min-md/tasks:flex @min-md/tasks:flex-wrap @min-md/tasks:items-center @min-md/tasks:justify-between",
8
- "min-h-14 border-b border-line-seam bg-layer-canvas px-5 py-3",
8
+ "min-h-(--header-height) border-b border-line-seam bg-layer-canvas px-(--surface-inset) py-3",
9
+ "md:pointer-fine:@min-[40rem]/tasks:py-0",
9
10
  "@max-md/tasks:px-4"
10
11
  ],
11
12
  toolbarGroup: ["flex flex-wrap items-center gap-2"],
@@ -20,14 +21,14 @@ const tasksPanel = tv({ slots: {
20
21
  toolbarLabel: [
21
22
  "inline-flex items-center",
22
23
  "[&_svg]:size-3.5 [&_svg]:shrink-0 [&>svg:last-child]:size-3",
23
- "h-8 gap-1.5 rounded-control px-2.5",
24
+ "h-8 md:pointer-fine:h-control gap-1.5 rounded-control px-2.5",
24
25
  "bg-transparent inset-ring inset-ring-line-seam",
25
26
  "font-sans text-footnote font-semibold text-foreground-muted whitespace-nowrap"
26
27
  ],
27
28
  viewport: [
28
29
  "min-h-0 flex-1 overflow-auto overscroll-contain p-4",
29
30
  "pb-[calc(1rem+env(safe-area-inset-bottom,0px))]",
30
- "bg-layer-canvas px-5",
31
+ "bg-layer-canvas px-(--surface-inset)",
31
32
  "@max-md/tasks:px-4"
32
33
  ],
33
34
  empty: ["flex h-full flex-col items-center justify-center"]
@@ -8,7 +8,7 @@ const textSelectionToolbar = tv({ slots: {
8
8
  ],
9
9
  button: [
10
10
  "flex shrink-0 items-center gap-1.5 outline-none transition-colors",
11
- "h-7 rounded-chip px-2.5 whitespace-nowrap text-foreground",
11
+ "h-7 rounded-chip md:pointer-fine:h-control md:pointer-fine:rounded-control px-2.5 whitespace-nowrap text-foreground",
12
12
  "hover:bg-fill-medium active:bg-fill-medium",
13
13
  "focus-visible:shadow-focus",
14
14
  "[&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-foreground-muted"
@@ -6,7 +6,7 @@ const textarea = tv({ slots: { root: [
6
6
  "scroll-pb-(--ta-scroll-pb,0)",
7
7
  "font-heading text-field font-field outline-none",
8
8
  "py-2.5",
9
- "rounded-control border-[1.5px] border-line-field bg-layer-card",
9
+ "rounded-(--control-radius) border-[1.5px] border-line-field bg-layer-card",
10
10
  "text-foreground placeholder:text-foreground-hint",
11
11
  "shadow-none transition-shadow duration-90 ease-out focus-visible:shadow-focus",
12
12
  "data-invalid:border-danger-strong",
@@ -4,7 +4,7 @@ import { panelHeadActions, panelHeadEdges } from "../panel/panel-header.recipe.m
4
4
  const threadPanel = tv({ slots: {
5
5
  root: ["isolate flex size-full min-h-0 flex-col", "relative bg-layer-canvas font-sans text-foreground"],
6
6
  header: [
7
- "flex h-(--shell-header-height,56px) shrink-0 items-center gap-3 max-md:gap-2",
7
+ "flex h-(--shell-header-height,var(--header-height)) shrink-0 items-center gap-3 max-md:gap-2",
8
8
  panelHeadEdges,
9
9
  "border-b border-line-seam bg-layer-canvas"
10
10
  ],
@@ -19,7 +19,7 @@ const threadPanel = tv({ slots: {
19
19
  search: [
20
20
  "relative z-20 flex shrink-0 items-center gap-1.5 py-2",
21
21
  "[&>[data-slot=input-group]]:min-w-0 *:data-[slot=input-group]:flex-1",
22
- "border-b border-line-hairline bg-layer-canvas px-5"
22
+ "border-b border-line-hairline bg-layer-canvas px-(--surface-inset)"
23
23
  ],
24
24
  searchTrailing: ["ml-auto flex shrink-0 items-center gap-1.5"],
25
25
  searchCount: ["shrink-0 whitespace-nowrap font-mono tabular-nums", "text-mono-meta text-foreground-hint"],
@@ -28,7 +28,7 @@ const threadPanel = tv({ slots: {
28
28
  "border-b border-line-hairline bg-transparent pb-timeline-end",
29
29
  "**:data-message-item:bg-transparent"
30
30
  ],
31
- replySummary: ["pt-timeline-start", "px-5"],
31
+ replySummary: ["pt-timeline-start", "px-(--surface-inset)"],
32
32
  replyCount: ["my-timeline-row border-b pb-2 text-center font-mono", "border-line-hairline text-mono-meta text-foreground-hint"],
33
33
  footer: ["pt-0", "text-caption text-foreground-hint"]
34
34
  } });
@@ -14,7 +14,7 @@ const toggleGroup = tv({ slots: {
14
14
  "gap-[3px] rounded-[11px] bg-fill-muted p-[3px]"
15
15
  ],
16
16
  item: [
17
- "inline-flex h-8 min-w-0 shrink-0 items-center justify-center gap-1.5",
17
+ "inline-flex h-8 md:pointer-fine:h-control min-w-0 shrink-0 items-center justify-center gap-1.5",
18
18
  "whitespace-nowrap",
19
19
  "outline-2 outline-offset-2 outline-transparent transition-[background-color,color,box-shadow,transform] duration-100",
20
20
  "disabled:pointer-events-none data-disabled:cursor-not-allowed",
@@ -0,0 +1,2 @@
1
+ import { WebTopBarCenter, WebTopBarCenterProps, WebTopBarEnd, WebTopBarEndProps, WebTopBarRoot, WebTopBarRootProps, WebTopBarStart, WebTopBarStartProps } from "./web-top-bar.mjs";
2
+ export { WebTopBarCenter, type WebTopBarCenterProps, WebTopBarEnd, type WebTopBarEndProps, WebTopBarRoot, type WebTopBarRootProps, WebTopBarStart, type WebTopBarStartProps };