@adecore/ui 0.39.0 → 0.40.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 (207) hide show
  1. package/dist/AccentSwatches.js +2 -3
  2. package/dist/Banner.js +1 -6
  3. package/dist/ChoiceCards.js +0 -5
  4. package/dist/ColorSwatch.js +1 -4
  5. package/dist/ColorWheelPicker.js +3 -6
  6. package/dist/DockShell.js +3 -5
  7. package/dist/EmptyState.js +0 -1
  8. package/dist/ErrorBoundary.js +1 -5
  9. package/dist/Field.js +2 -6
  10. package/dist/FileIcon.js +2 -4
  11. package/dist/Icon.js +1 -2
  12. package/dist/IconButton.js +1 -1
  13. package/dist/IconPicker.js +3 -7
  14. package/dist/Input.js +1 -2
  15. package/dist/Kbd.js +1 -3
  16. package/dist/LazyBoundary.js +2 -3
  17. package/dist/Meter.js +0 -1
  18. package/dist/MiddleTruncate.js +2 -6
  19. package/dist/PanelEmpty.js +0 -1
  20. package/dist/PanelHeader.js +1 -4
  21. package/dist/Pill.js +1 -6
  22. package/dist/ProjectSwitcher.js +1 -1
  23. package/dist/PromptDialog.js +5 -8
  24. package/dist/RelativeTime.js +1 -1
  25. package/dist/SegmentBar.js +1 -2
  26. package/dist/Segmented.js +2 -5
  27. package/dist/Select.js +1 -4
  28. package/dist/ShortcutHints.js +2 -3
  29. package/dist/Slider.js +0 -1
  30. package/dist/SlidingColumn.js +2 -4
  31. package/dist/SplitButton.js +1 -5
  32. package/dist/TextMenu.js +1 -5
  33. package/dist/Tile.js +0 -4
  34. package/dist/Toasts.js +1 -9
  35. package/dist/Tooltip.js +1 -1
  36. package/dist/UIProvider.js +0 -5
  37. package/dist/Waveform.js +4 -2
  38. package/dist/Wipe.js +1 -6
  39. package/dist/ZoomControls.js +0 -1
  40. package/dist/clipboard.js +2 -5
  41. package/dist/combobox/parts.js +3 -9
  42. package/dist/command-palette/parts.js +5 -14
  43. package/dist/dialog/parts.js +5 -10
  44. package/dist/dialog-layer.js +2 -3
  45. package/dist/error-boundary.js +4 -20
  46. package/dist/file-icon.js +4 -9
  47. package/dist/file-tree/empty-lines.js +2 -8
  48. package/dist/file-tree/use-empty-lines.js +1 -5
  49. package/dist/file-tree/use-slots.js +6 -10
  50. package/dist/format/datetime.js +32 -29
  51. package/dist/format/duration.js +2 -10
  52. package/dist/format/locale.js +19 -39
  53. package/dist/format/number.js +9 -22
  54. package/dist/format/regions.js +4 -7
  55. package/dist/icon-picker.js +5 -14
  56. package/dist/key-value-list/parts.js +1 -5
  57. package/dist/lazy.js +4 -19
  58. package/dist/locales.js +2 -6
  59. package/dist/menu/parts.js +61 -133
  60. package/dist/middle-truncate.js +2 -3
  61. package/dist/placement.js +0 -1
  62. package/dist/popover/parts.js +1 -5
  63. package/dist/popup-layer.js +2 -4
  64. package/dist/prefetch.js +2 -5
  65. package/dist/selection.js +1 -5
  66. package/dist/settings/MasterDetail.js +1 -7
  67. package/dist/settings/SettingsDialog.js +1 -2
  68. package/dist/settings/SettingsRow.js +2 -5
  69. package/dist/settings/SettingsSection.js +1 -1
  70. package/dist/shortcut-hints.js +1 -5
  71. package/dist/shortcut.js +1 -2
  72. package/dist/tabs/overflow.js +1 -6
  73. package/dist/tabs/parts.js +69 -95
  74. package/dist/testing/dedupe.js +5 -7
  75. package/dist/tint.js +3 -5
  76. package/dist/toast-store.js +2 -10
  77. package/dist/tree/use-tree-shift.js +2 -6
  78. package/dist/useColumnResize.js +9 -10
  79. package/dist/useNow.js +2 -9
  80. package/dist/workspace/DropPreview.js +1 -5
  81. package/dist/workspace/preview.js +4 -9
  82. package/package.json +9 -9
  83. package/src/AccentSwatches.tsx +9 -3
  84. package/src/Banner.tsx +5 -11
  85. package/src/Button.tsx +4 -0
  86. package/src/Checkbox.tsx +3 -0
  87. package/src/ChoiceCards.tsx +12 -11
  88. package/src/CloseButton.tsx +1 -0
  89. package/src/ColorSwatch.tsx +7 -8
  90. package/src/ColorWheelPicker.tsx +28 -12
  91. package/src/ColumnResizeHandle.tsx +1 -0
  92. package/src/CopyButton.tsx +6 -0
  93. package/src/DisabledReason.tsx +1 -0
  94. package/src/DockShell.tsx +11 -10
  95. package/src/EmptyState.tsx +10 -6
  96. package/src/ErrorBoundary.tsx +13 -10
  97. package/src/Field.tsx +11 -13
  98. package/src/FileIcon.tsx +4 -4
  99. package/src/Icon.tsx +2 -4
  100. package/src/IconButton.tsx +14 -5
  101. package/src/IconPicker.tsx +30 -15
  102. package/src/Input.tsx +11 -9
  103. package/src/Kbd.tsx +8 -7
  104. package/src/LazyBoundary.tsx +3 -3
  105. package/src/Meter.tsx +7 -2
  106. package/src/MiddleTruncate.tsx +15 -6
  107. package/src/PanelEmpty.tsx +9 -7
  108. package/src/PanelHeader.tsx +2 -5
  109. package/src/Pill.tsx +7 -8
  110. package/src/ProjectSwitcher.tsx +16 -6
  111. package/src/PromptDialog.tsx +31 -26
  112. package/src/RelativeTime.tsx +6 -1
  113. package/src/SegmentBar.tsx +22 -11
  114. package/src/Segmented.tsx +16 -11
  115. package/src/Select.tsx +7 -4
  116. package/src/SelectSearch.tsx +3 -0
  117. package/src/ShortcutHints.tsx +24 -3
  118. package/src/Skeleton.tsx +1 -0
  119. package/src/Slider.tsx +4 -1
  120. package/src/SlidingColumn.tsx +18 -14
  121. package/src/Spinner.tsx +1 -0
  122. package/src/SplitButton.tsx +8 -8
  123. package/src/Stepper.tsx +6 -0
  124. package/src/Switch.tsx +2 -0
  125. package/src/TextMenu.tsx +2 -5
  126. package/src/Tile.tsx +2 -6
  127. package/src/Toasts.tsx +8 -12
  128. package/src/Tooltip.tsx +10 -5
  129. package/src/UIProvider.tsx +7 -7
  130. package/src/Waveform.tsx +41 -12
  131. package/src/Wipe.tsx +5 -6
  132. package/src/ZoomControls.tsx +5 -2
  133. package/src/clipboard.ts +4 -5
  134. package/src/combobox/parts.tsx +18 -14
  135. package/src/command-palette/context.ts +2 -0
  136. package/src/command-palette/index.parts.ts +1 -0
  137. package/src/command-palette/parts.tsx +20 -14
  138. package/src/command-palette/virtual.tsx +21 -0
  139. package/src/dialog/parts.tsx +10 -13
  140. package/src/dialog-layer.ts +5 -3
  141. package/src/error-boundary.ts +7 -20
  142. package/src/file-icon.ts +8 -9
  143. package/src/file-tree/empty-lines.ts +24 -8
  144. package/src/file-tree/helpers.ts +34 -0
  145. package/src/file-tree/highlight.ts +19 -0
  146. package/src/file-tree/index.parts.ts +1 -0
  147. package/src/file-tree/parts.tsx +41 -5
  148. package/src/file-tree/use-empty-lines.ts +22 -5
  149. package/src/file-tree/use-file-tree-shift.tsx +10 -0
  150. package/src/file-tree/use-file-tree.ts +2 -0
  151. package/src/file-tree/use-slots.ts +77 -12
  152. package/src/format/datetime.ts +42 -17
  153. package/src/format/duration.ts +28 -10
  154. package/src/format/index.ts +3 -0
  155. package/src/format/locale.ts +33 -42
  156. package/src/format/number.ts +21 -27
  157. package/src/format/regions.ts +4 -7
  158. package/src/icon-picker.ts +23 -16
  159. package/src/index.ts +8 -0
  160. package/src/key-value-list/parts.tsx +1 -5
  161. package/src/lazy-landings.ts +2 -0
  162. package/src/lazy.tsx +23 -19
  163. package/src/locales.ts +2 -6
  164. package/src/match.ts +14 -0
  165. package/src/menu/parts.tsx +30 -55
  166. package/src/middle-truncate.ts +12 -3
  167. package/src/modality.ts +4 -0
  168. package/src/placement.ts +2 -1
  169. package/src/platform.ts +2 -0
  170. package/src/popover/parts.tsx +3 -5
  171. package/src/popup-layer.ts +6 -4
  172. package/src/prefetch.ts +18 -5
  173. package/src/project-switcher-row.tsx +2 -0
  174. package/src/segmented-keys.ts +6 -0
  175. package/src/select-shared.ts +2 -0
  176. package/src/selection.ts +5 -5
  177. package/src/settings/ConfirmDialog.tsx +3 -0
  178. package/src/settings/MasterDetail.tsx +3 -9
  179. package/src/settings/SettingsDialog.tsx +27 -9
  180. package/src/settings/SettingsRow.tsx +16 -10
  181. package/src/settings/SettingsSection.tsx +10 -5
  182. package/src/settings/index.ts +3 -0
  183. package/src/settings/target.ts +1 -0
  184. package/src/shortcut-hints.ts +10 -5
  185. package/src/shortcut.ts +26 -6
  186. package/src/tabs/overflow.ts +8 -6
  187. package/src/tabs/parts.tsx +50 -26
  188. package/src/testing/dedupe.ts +27 -7
  189. package/src/testing/fake-source.ts +1 -0
  190. package/src/tint.ts +3 -5
  191. package/src/toast-store.ts +20 -14
  192. package/src/tree/parts.tsx +8 -0
  193. package/src/tree/shift.ts +6 -0
  194. package/src/tree/use-tree-shift.tsx +23 -7
  195. package/src/useAsyncAction.ts +8 -0
  196. package/src/useColumnResize.ts +24 -15
  197. package/src/useContentSize.ts +5 -0
  198. package/src/useMeasuredWidth.ts +1 -0
  199. package/src/useNow.ts +6 -11
  200. package/src/workspace/DropPreview.tsx +3 -5
  201. package/src/workspace/SplitView.tsx +109 -0
  202. package/src/workspace/TabStrip.tsx +42 -0
  203. package/src/workspace/Workspace.tsx +5 -0
  204. package/src/workspace/context.ts +1 -0
  205. package/src/workspace/geometry.ts +49 -0
  206. package/src/workspace/model.ts +72 -0
  207. package/src/workspace/preview.ts +15 -15
@@ -1,5 +1,5 @@
1
1
  import { c as _c } from "react/compiler-runtime";
2
- import { Children, createContext, isValidElement, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
2
+ import { Children, createContext, isValidElement, useContext, useEffect, useLayoutEffect, useRef, useState } from 'react';
3
3
  import clsx from 'clsx';
4
4
  import { ChevronDown, X } from 'lucide-react';
5
5
  import { useTranslation } from 'react-i18next';
@@ -21,7 +21,6 @@ const SelectionContext = createContext({
21
21
  const InMenuContext = createContext(false);
22
22
  /* The underline sits over the strip's border rather than above it, without a negative margin that would make the strip scroll. */
23
23
  const TAB = 'relative flex h-9 shrink-0 items-center gap-1.5 whitespace-nowrap text-xs font-medium text-text-muted hover:text-text data-[active]:text-text data-[disabled]:opacity-50 after:absolute after:inset-x-0 after:-bottom-px after:h-0.5 data-[active]:after:bg-text';
24
- /* The button that opens the tabs that do not fit reads as one more tab, at the very end of the strip. */
25
24
  const MORE = clsx(TAB, 'ml-auto data-[popup-open]:text-text');
26
25
  /* A tab as a key in a bar, for tabs that share a toolbar with buttons and must not read as the tabs of a pane under it. */
27
26
  const PILL = 'relative flex h-7 shrink-0 items-center gap-1.5 whitespace-nowrap rounded-md px-2 text-xs font-medium text-text-muted hover:bg-surface-hover hover:text-text data-[active]:bg-surface-active data-[active]:text-text data-[disabled]:opacity-50 has-[button]:pr-1';
@@ -149,9 +148,8 @@ export function TabsRoot(t0) {
149
148
  }
150
149
  const sameIndices = (left, right) => left !== null && left.length === right.length && left.every((index, at) => index === right[at]);
151
150
  /*
152
- * The tabs that fit, and a menu at the end of the strip with the ones that do not. Every tab is measured
153
- * in a row nobody sees, so the strip knows what fits before it draws. The tabs are the direct children,
154
- * since the menu repeats what a tab holds.
151
+ * Every tab is measured in a row nobody sees, so the strip knows what fits before it draws. The tabs
152
+ * are the direct children, since the menu repeats what a tab holds.
155
153
  */
156
154
  export function TabsList(t0) {
157
155
  const $ = _c(48);
@@ -503,7 +501,7 @@ function _temp(child) {
503
501
  return isValidElement(child) && child.type === TabsTab;
504
502
  }
505
503
  export function TabsTab(t0) {
506
- const $ = _c(52);
504
+ const $ = _c(46);
507
505
  let children;
508
506
  let className;
509
507
  let onClose;
@@ -535,7 +533,7 @@ export function TabsTab(t0) {
535
533
  t
536
534
  } = useTranslation("ui");
537
535
  const tab = STYLES[useContext(VariantContext)].tab;
538
- if (pinned) {
536
+ if (pinned || onClose === undefined) {
539
537
  let t2;
540
538
  if ($[6] !== className || $[7] !== tab) {
541
539
  t2 = withClass(tab, className);
@@ -545,11 +543,12 @@ export function TabsTab(t0) {
545
543
  } else {
546
544
  t2 = $[8];
547
545
  }
548
- let t3;
549
- if ($[9] !== children || $[10] !== props || $[11] !== t2) {
550
- t3 = /*#__PURE__*/_jsx(BaseTabs.Tab, {
546
+ const t3 = pinned ? "" : undefined;
547
+ let t4;
548
+ if ($[9] !== children || $[10] !== props || $[11] !== t2 || $[12] !== t3) {
549
+ t4 = /*#__PURE__*/_jsx(BaseTabs.Tab, {
551
550
  className: t2,
552
- "data-pinned": "",
551
+ "data-pinned": t3,
553
552
  ...props,
554
553
  children: children
555
554
  });
@@ -557,61 +556,36 @@ export function TabsTab(t0) {
557
556
  $[10] = props;
558
557
  $[11] = t2;
559
558
  $[12] = t3;
559
+ $[13] = t4;
560
560
  } else {
561
- t3 = $[12];
561
+ t4 = $[13];
562
562
  }
563
- return t3;
564
- }
565
- if (onClose === undefined) {
566
- let t2;
567
- if ($[13] !== className || $[14] !== tab) {
568
- t2 = withClass(tab, className);
569
- $[13] = className;
570
- $[14] = tab;
571
- $[15] = t2;
572
- } else {
573
- t2 = $[15];
574
- }
575
- let t3;
576
- if ($[16] !== children || $[17] !== props || $[18] !== t2) {
577
- t3 = /*#__PURE__*/_jsx(BaseTabs.Tab, {
578
- className: t2,
579
- ...props,
580
- children: children
581
- });
582
- $[16] = children;
583
- $[17] = props;
584
- $[18] = t2;
585
- $[19] = t3;
586
- } else {
587
- t3 = $[19];
588
- }
589
- return t3;
563
+ return t4;
590
564
  }
591
565
  let onAuxClick;
592
566
  let onKeyDown;
593
567
  let onMouseDown;
594
568
  let rest;
595
- if ($[20] !== props) {
569
+ if ($[14] !== props) {
596
570
  ({
597
571
  onKeyDown,
598
572
  onAuxClick,
599
573
  onMouseDown,
600
574
  ...rest
601
575
  } = props);
602
- $[20] = props;
603
- $[21] = onAuxClick;
604
- $[22] = onKeyDown;
605
- $[23] = onMouseDown;
606
- $[24] = rest;
576
+ $[14] = props;
577
+ $[15] = onAuxClick;
578
+ $[16] = onKeyDown;
579
+ $[17] = onMouseDown;
580
+ $[18] = rest;
607
581
  } else {
608
- onAuxClick = $[21];
609
- onKeyDown = $[22];
610
- onMouseDown = $[23];
611
- rest = $[24];
582
+ onAuxClick = $[15];
583
+ onKeyDown = $[16];
584
+ onMouseDown = $[17];
585
+ rest = $[18];
612
586
  }
613
587
  let t2;
614
- if ($[25] !== onClose || $[26] !== onKeyDown) {
588
+ if ($[19] !== onClose || $[20] !== onKeyDown) {
615
589
  t2 = e => {
616
590
  onKeyDown?.(e);
617
591
  if (!e.defaultPrevented && e.target === e.currentTarget && (e.key === "Delete" || e.key === "Backspace")) {
@@ -619,29 +593,29 @@ export function TabsTab(t0) {
619
593
  onClose();
620
594
  }
621
595
  };
622
- $[25] = onClose;
623
- $[26] = onKeyDown;
624
- $[27] = t2;
596
+ $[19] = onClose;
597
+ $[20] = onKeyDown;
598
+ $[21] = t2;
625
599
  } else {
626
- t2 = $[27];
600
+ t2 = $[21];
627
601
  }
628
602
  const handleKeyDown = t2;
629
603
  let t3;
630
- if ($[28] !== onMouseDown) {
604
+ if ($[22] !== onMouseDown) {
631
605
  t3 = e_0 => {
632
606
  onMouseDown?.(e_0);
633
607
  if (e_0.button === 1) {
634
608
  e_0.preventDefault();
635
609
  }
636
610
  };
637
- $[28] = onMouseDown;
638
- $[29] = t3;
611
+ $[22] = onMouseDown;
612
+ $[23] = t3;
639
613
  } else {
640
- t3 = $[29];
614
+ t3 = $[23];
641
615
  }
642
616
  const handleMouseDown = t3;
643
617
  let t4;
644
- if ($[30] !== onAuxClick || $[31] !== onClose) {
618
+ if ($[24] !== onAuxClick || $[25] !== onClose) {
645
619
  t4 = e_1 => {
646
620
  onAuxClick?.(e_1);
647
621
  if (!e_1.defaultPrevented && e_1.button === 1) {
@@ -649,50 +623,50 @@ export function TabsTab(t0) {
649
623
  onClose();
650
624
  }
651
625
  };
652
- $[30] = onAuxClick;
653
- $[31] = onClose;
654
- $[32] = t4;
626
+ $[24] = onAuxClick;
627
+ $[25] = onClose;
628
+ $[26] = t4;
655
629
  } else {
656
- t4 = $[32];
630
+ t4 = $[26];
657
631
  }
658
632
  const handleAuxClick = t4;
659
633
  let t5;
660
- if ($[33] === Symbol.for("react.memo_cache_sentinel")) {
634
+ if ($[27] === Symbol.for("react.memo_cache_sentinel")) {
661
635
  t5 = /*#__PURE__*/_jsx("div", {});
662
- $[33] = t5;
636
+ $[27] = t5;
663
637
  } else {
664
- t5 = $[33];
638
+ t5 = $[27];
665
639
  }
666
640
  let t6;
667
- if ($[34] !== className || $[35] !== tab) {
641
+ if ($[28] !== className || $[29] !== tab) {
668
642
  t6 = withClass(tab, className);
669
- $[34] = className;
670
- $[35] = tab;
671
- $[36] = t6;
643
+ $[28] = className;
644
+ $[29] = tab;
645
+ $[30] = t6;
672
646
  } else {
673
- t6 = $[36];
647
+ t6 = $[30];
674
648
  }
675
649
  let t7;
676
- if ($[37] !== t) {
650
+ if ($[31] !== t) {
677
651
  t7 = t("tabs.close");
678
- $[37] = t;
679
- $[38] = t7;
652
+ $[31] = t;
653
+ $[32] = t7;
680
654
  } else {
681
- t7 = $[38];
655
+ t7 = $[32];
682
656
  }
683
657
  let t8;
684
- if ($[39] !== onClose) {
658
+ if ($[33] !== onClose) {
685
659
  t8 = e_2 => {
686
660
  e_2.stopPropagation();
687
661
  onClose();
688
662
  };
689
- $[39] = onClose;
690
- $[40] = t8;
663
+ $[33] = onClose;
664
+ $[34] = t8;
691
665
  } else {
692
- t8 = $[40];
666
+ t8 = $[34];
693
667
  }
694
668
  let t9;
695
- if ($[41] !== t7 || $[42] !== t8) {
669
+ if ($[35] !== t7 || $[36] !== t8) {
696
670
  t9 = /*#__PURE__*/_jsx(IconButton, {
697
671
  icon: X,
698
672
  size: "2xs",
@@ -700,14 +674,14 @@ export function TabsTab(t0) {
700
674
  tabIndex: -1,
701
675
  onClick: t8
702
676
  });
703
- $[41] = t7;
704
- $[42] = t8;
705
- $[43] = t9;
677
+ $[35] = t7;
678
+ $[36] = t8;
679
+ $[37] = t9;
706
680
  } else {
707
- t9 = $[43];
681
+ t9 = $[37];
708
682
  }
709
683
  let t10;
710
- if ($[44] !== children || $[45] !== handleAuxClick || $[46] !== handleKeyDown || $[47] !== handleMouseDown || $[48] !== rest || $[49] !== t6 || $[50] !== t9) {
684
+ if ($[38] !== children || $[39] !== handleAuxClick || $[40] !== handleKeyDown || $[41] !== handleMouseDown || $[42] !== rest || $[43] !== t6 || $[44] !== t9) {
711
685
  t10 = /*#__PURE__*/_jsxs(BaseTabs.Tab, {
712
686
  nativeButton: false,
713
687
  render: t5,
@@ -718,21 +692,21 @@ export function TabsTab(t0) {
718
692
  ...rest,
719
693
  children: [children, t9]
720
694
  });
721
- $[44] = children;
722
- $[45] = handleAuxClick;
723
- $[46] = handleKeyDown;
724
- $[47] = handleMouseDown;
725
- $[48] = rest;
726
- $[49] = t6;
727
- $[50] = t9;
728
- $[51] = t10;
695
+ $[38] = children;
696
+ $[39] = handleAuxClick;
697
+ $[40] = handleKeyDown;
698
+ $[41] = handleMouseDown;
699
+ $[42] = rest;
700
+ $[43] = t6;
701
+ $[44] = t9;
702
+ $[45] = t10;
729
703
  } else {
730
- t10 = $[51];
704
+ t10 = $[45];
731
705
  }
732
706
  return t10;
733
707
  }
734
708
  export const TabsPanel = BaseTabs.Panel;
735
- /* How much a tab holds, after its label. Nothing at zero: an empty view needs no number to say so. */
709
+ /* Nothing at zero: an empty view needs no number to say so. */
736
710
  export function TabsCount(t0) {
737
711
  const $ = _c(21);
738
712
  let className;
@@ -2,11 +2,10 @@ import { existsSync, readdirSync, readFileSync, realpathSync } from 'node:fs';
2
2
  import { dirname, join, sep } from 'node:path';
3
3
  import { Glob, plugin } from 'bun';
4
4
  /*
5
- * A preload for `bun test` in an app that links a checkout of this library: what `resolve.dedupe`
6
- * does for Vite. The checkout has node_modules of its own, and a second React, i18next or Base UI
7
- * breaks every hook, every word and every compound part. Bun has no dedupe and its resolve hook never
8
- * sees a package import, so every file of these packages in the checkout loads as a stand-in for the
9
- * same file in the app's copy. Does nothing once the library is installed from the registry.
5
+ * What `resolve.dedupe` does for Vite, for `bun test` in an app that links a checkout: a second React,
6
+ * i18next or Base UI breaks every hook, word and compound part. Bun has no dedupe and its resolve hook
7
+ * never sees a package import, so each file of these packages in the checkout loads as a stand-in for
8
+ * the app's copy.
10
9
  *
11
10
  * CodeMirror and Lezer reject an extension, a facet or a node prop made by another copy, and the chat
12
11
  * views take both from the app; shiki is in the list for the highlighter an app hands them.
@@ -47,7 +46,6 @@ const checkoutFolders = () => {
47
46
  }
48
47
  return [library];
49
48
  };
50
- /* The packages a name of the list stands for in a folder: itself, or every package of the scope for `@scope/*`. */
51
49
  const namesIn = (folder, pattern) => {
52
50
  if (!pattern.endsWith('/*')) {
53
51
  return [pattern];
@@ -56,7 +54,7 @@ const namesIn = (folder, pattern) => {
56
54
  const path = join(folder, 'node_modules', scope);
57
55
  return existsSync(path) ? readdirSync(path).filter(entry => !entry.startsWith('.')).map(entry => `${scope}/${entry}`) : [];
58
56
  };
59
- /* The copy of a package that `from` resolves to, walking up the node_modules folders as Node does. */
57
+ /* Walks up the node_modules folders as Node does. */
60
58
  const copyFrom = (from, name) => {
61
59
  for (let folder = from;; folder = dirname(folder)) {
62
60
  const candidate = join(folder, 'node_modules', name);
package/dist/tint.js CHANGED
@@ -1,9 +1,7 @@
1
1
  /*
2
- * The custom properties that let what stands on a colored ground follow its color: the hover of a
3
- * button and a separator. The theme's utilities read `--surface-hover` and `--border` themselves
4
- * (`@theme inline`), so a host sets this on the colored element and its buttons and separators
5
- * take it. `--border` is mixed from `--border-strong`, since a property that reads itself is no
6
- * value at all.
2
+ * The theme's utilities read `--surface-hover` and `--border` themselves (`@theme inline`), so
3
+ * buttons and separators under the element take its color. `--border` mixes from `--border-strong`,
4
+ * since a property that reads itself is no value at all.
7
5
  */
8
6
  export function tintStyle(color, ground = 'var(--surface-raised)') {
9
7
  return {
@@ -1,16 +1,11 @@
1
1
  import { create } from 'zustand';
2
2
  // How long a toast that went well stays up; a failure waits for the person instead.
3
3
  export const SUCCESS_MS = 4000;
4
- // How long a deletion can still be taken back.
5
4
  export const UNDO_MS = 8000;
6
5
  // `setTimeout` fires at once past this, so a longer lifetime, `Infinity` too, is a toast that stays.
7
6
  const LONGEST_TIMER_MS = 2 ** 31 - 1;
8
- /* How far into its lifetime a toast is at `now`, held inside that lifetime. */
9
7
  export const elapsedOf = (deadline, now) => Math.min(Math.max(now - deadline.start, 0), deadline.end - deadline.start);
10
- /*
11
- * The one place an app says how something went that no surface on screen shows. A long action keeps
12
- * one id from progress to its outcome, so a person never watches two cards for one thing.
13
- */
8
+ /* A long action keeps one id from progress to its outcome, so a person never watches two cards for one thing. */
14
9
  export const createToastStore = () => {
15
10
  const timers = new Map();
16
11
  let counter = 0;
@@ -19,10 +14,7 @@ export const createToastStore = () => {
19
14
  clearTimeout(timers.get(id));
20
15
  timers.delete(id);
21
16
  };
22
- /*
23
- * A toast that went well takes itself away, and so does the offer to undo; a failure and a running
24
- * action stay, unless the toast names a lifetime of its own.
25
- */
17
+ // A failure and a running action stay, unless the toast names a lifetime of its own.
26
18
  const schedule = (id, toast) => {
27
19
  stop(id);
28
20
  const {
@@ -4,11 +4,7 @@ import { clampShift, maxShift, SHIFT_PROPERTY, shiftNeed, shiftThumb, sidewaysDe
4
4
  import { jsx as _jsx } from "react/jsx-runtime";
5
5
  const HIDE_AFTER = 900;
6
6
  const NEAR_BOTTOM = 16;
7
- /*
8
- * Rows that are wider than the tree slide sideways together, by a shift every row reads from the
9
- * frame's `--adecore-tree-shift`, with a thin bar that shows while a person scrolls or nears it. A
10
- * shift instead of a scroll keeps every row's background and the vertical scroll where they are.
11
- */
7
+ /* A shift every row reads from `--adecore-tree-shift` instead of a scroll keeps every row's background and the vertical scroll where they are. */
12
8
  export function useTreeShift(source, resetKey) {
13
9
  const $ = _c(12);
14
10
  const [frame, setFrame] = useState(null);
@@ -171,7 +167,7 @@ export function useTreeShift(source, resetKey) {
171
167
  }
172
168
  return t2;
173
169
  }
174
- /* The rows of `Tree.Root`: everything a row holds slides, so a row reaches as far as its last part. */
170
+ /* Everything a row of `Tree.Root` holds slides, so a row reaches as far as its last part. */
175
171
  function _temp(need) {
176
172
  return need !== null;
177
173
  }
@@ -1,13 +1,12 @@
1
+ const DRAG_ENDS = ['pointerup', 'pointercancel', 'lostpointercapture'];
1
2
  export const clampColumnSize = (options, size) => {
2
3
  const max = Math.max(options.min, options.max?.() ?? Number.MAX_SAFE_INTEGER);
3
4
  return Math.max(options.min, Math.min(Math.round(size), max));
4
5
  };
5
- /* Where the pointer sits on the axis this edge belongs to. */
6
6
  const along = (from, event) => from === 'left' || from === 'right' ? event.clientX : event.clientY;
7
7
  /*
8
- * One resizable column or row: a handle that drags the size its owner keeps. The handle takes the
9
- * pointer capture, so the drag survives leaving the few pixels it is wide, and `[data-resizing]` on
10
- * the column turns off any transition on that size for as long as it lasts.
8
+ * The handle takes the pointer capture, so the drag survives leaving the few pixels it is wide, and
9
+ * `[data-resizing]` on the column turns off any transition on that size for as long as it lasts.
11
10
  */
12
11
  export const useColumnResize = (ref, options) => {
13
12
  const startResize = event => {
@@ -26,9 +25,9 @@ export const useColumnResize = (ref, options) => {
26
25
  };
27
26
  const onUp = () => {
28
27
  handle.removeEventListener('pointermove', onMove);
29
- handle.removeEventListener('pointerup', onUp);
30
- handle.removeEventListener('pointercancel', onUp);
31
- handle.removeEventListener('lostpointercapture', onUp);
28
+ for (const type of DRAG_ENDS) {
29
+ handle.removeEventListener(type, onUp);
30
+ }
32
31
  if (handle.hasPointerCapture(event.pointerId)) {
33
32
  handle.releasePointerCapture(event.pointerId);
34
33
  }
@@ -36,9 +35,9 @@ export const useColumnResize = (ref, options) => {
36
35
  };
37
36
  handle.setPointerCapture(event.pointerId);
38
37
  handle.addEventListener('pointermove', onMove);
39
- handle.addEventListener('pointerup', onUp);
40
- handle.addEventListener('pointercancel', onUp);
41
- handle.addEventListener('lostpointercapture', onUp);
38
+ for (const type of DRAG_ENDS) {
39
+ handle.addEventListener(type, onUp);
40
+ }
42
41
  };
43
42
  return {
44
43
  startResize
package/dist/useNow.js CHANGED
@@ -1,10 +1,6 @@
1
1
  import { c as _c } from "react/compiler-runtime";
2
2
  import { useCallback, useEffect, useRef, useState } from 'react';
3
- /*
4
- * The clock a surface reads to say how long something has been running. One timer for the whole
5
- * surface, ticking only while there is something to count, and starting at the time it was mounted
6
- * so a panel that comes back mid-session does not read zero for a second first.
7
- */
3
+ /* Starts at the time it was mounted, so a panel that comes back mid-session does not read zero for a second first. */
8
4
  export const useNow = (intervalMs, t0) => {
9
5
  const $ = _c(4);
10
6
  const ticking = t0 === undefined ? true : t0;
@@ -31,10 +27,7 @@ export const useNow = (intervalMs, t0) => {
31
27
  useEffect(t1, t2);
32
28
  return now;
33
29
  };
34
- /*
35
- * A timer on one line of a long thread. The text is written straight into the node, because a chat
36
- * that re-renders every second while an agent works re-renders every row it is drawing with it.
37
- */
30
+ /* Written straight into the node: a thread that re-renders every second re-renders every row it draws with it. */
38
31
  export const useTickingText = (render, t0) => {
39
32
  const $ = _c(6);
40
33
  const intervalMs = t0 === undefined ? 1000 : t0;
@@ -1,11 +1,7 @@
1
1
  import { c as _c } from "react/compiler-runtime";
2
2
  import clsx from 'clsx';
3
3
  import { dropPreviewPath } from './preview.js';
4
- /*
5
- * The outline `SplitView` draws where a drag would land, for an app with a drag layer of its own. It
6
- * fills its nearest positioned ancestor. One shape moves into the next as a transition of its path,
7
- * and the first shape after a null appears in place.
8
- */
4
+ /* For an app with a drag layer of its own. It fills its nearest positioned ancestor; the first shape after a null appears in place. */
9
5
  import { jsx as _jsx } from "react/jsx-runtime";
10
6
  export function DropPreview(t0) {
11
7
  const $ = _c(10);
@@ -8,10 +8,7 @@ export const DROP_STROKE = 2;
8
8
  function coordinate(value) {
9
9
  return String(Math.round(value * 100) / 100 + 0);
10
10
  }
11
- /*
12
- * The preview for a split or a trade: the rectangle as a tab with no height, parked just inside its
13
- * top left corner so the corner keeps its radius. It is where a tab target grows out of the rectangle.
14
- */
11
+ /* The tab with no height parks just inside the top left corner, so the corner keeps its radius and a tab target grows out of it. */
15
12
  export function rectDropPreview({
16
13
  x,
17
14
  y,
@@ -30,7 +27,7 @@ export function rectDropPreview({
30
27
  radius: TAB_RADIUS
31
28
  };
32
29
  }
33
- /* The preview for a tab: the tab and the body of the cell it lands in, `origin` being the cell's top left in the grid. */
30
+ /* `origin` is the cell's top left in the grid. */
34
31
  export function tabDropPreview(drop, origin) {
35
32
  return {
36
33
  x: origin.x,
@@ -52,10 +49,8 @@ export function sameDropPreview(left, right) {
52
49
  return left.x === right.x && left.y === right.y && left.width === right.width && left.height === right.height && left.barHeight === right.barHeight && left.tabLeft === right.tabLeft && left.tabWidth === right.tabWidth && left.tabTop === right.tabTop && left.radius === right.radius;
53
50
  }
54
51
  /*
55
- * The outline of a tab grown into the body under it, as one closed path so no line runs between the
56
- * two. The commands are the same whatever the numbers are (an arc of radius 0 is a straight line), so
57
- * the browser can move one outline into another with a transition on `d`. `inset` is how far the
58
- * path runs inside the box, which is half the stroke, so the outer edge of the line is on the box.
52
+ * One closed path, so no line runs between tab and body. The commands are the same whatever the
53
+ * numbers (an arc of radius 0 is a straight line), so a transition on `d` can move one outline into another.
59
54
  */
60
55
  export function dropPreviewPath({
61
56
  x,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adecore/ui",
3
- "version": "0.39.0",
3
+ "version": "0.40.0",
4
4
  "description": "React components, a theme, formatters and a settings dialog for desktop-grade apps on React 19, Base UI and Tailwind 4.",
5
5
  "license": "FSL-1.1-MIT",
6
6
  "author": "Bas Milius",
@@ -69,8 +69,8 @@
69
69
  "@pierre/trees": "1.0.0-beta.6",
70
70
  "@tanstack/react-virtual": "^3.14.13",
71
71
  "clsx": "^2.1.1",
72
- "lucide-react": "^1.47.0",
73
- "zustand": "^5.0.15"
72
+ "lucide-react": "^1.61.0",
73
+ "zustand": "^5.0.16"
74
74
  },
75
75
  "peerDependencies": {
76
76
  "i18next": "^26.4.2",
@@ -79,16 +79,16 @@
79
79
  "react-i18next": "^17.0.15"
80
80
  },
81
81
  "devDependencies": {
82
- "@happy-dom/global-registrator": "^20.14.5",
83
- "@types/bun": "^1.4.2",
82
+ "@happy-dom/global-registrator": "^20.14.6",
83
+ "@types/bun": "^1.4.4",
84
84
  "@types/opentype.js": "^1.3.10",
85
85
  "@types/react": "^19.3.0",
86
86
  "@types/react-dom": "^19.3.0",
87
- "i18next": "^26.4.2",
87
+ "i18next": "^26.5.11",
88
88
  "opentype.js": "2.0.0",
89
- "react": "^19.3.0",
90
- "react-dom": "^19.3.0",
91
- "react-i18next": "^17.0.15",
89
+ "react": "^19.3.1",
90
+ "react-dom": "^19.3.1",
91
+ "react-i18next": "^17.1.9",
92
92
  "typescript": "^7.0.2"
93
93
  }
94
94
  }
@@ -11,26 +11,32 @@ export interface AccentSwatchesProps<Id extends string> {
11
11
  value: string | undefined;
12
12
  onValueChange(id: Id): void;
13
13
  label: string;
14
+
14
15
  /* Every color on offer, in the order of the list behind the featured ones. */
15
16
  accents: readonly { id: Id; color: string }[];
17
+
16
18
  /* The few drawn in the open, in the order they stand. */
17
19
  featured: readonly Id[];
20
+
18
21
  labelOf(id: Id): string;
19
22
  className?: string;
20
23
  ref?: Ref<HTMLDivElement>;
21
24
  }
22
25
 
23
26
  /*
24
- * An accent, a few colors at a time. A palette is more than a settings row can carry, so the list
25
- * behind them holds all of them, the featured ones included; the trigger wears the chosen color
26
- * itself whenever that color is not one of the few. A value that is no accent at all picks nothing.
27
+ * The list behind the featured swatches holds every accent, the featured ones included; its trigger
28
+ * wears the chosen color whenever that is not one of the few. A value that is no accent picks nothing.
27
29
  */
28
30
  export function AccentSwatches<Id extends string>({ value, onValueChange, label, accents, featured, labelOf, className, ref }: AccentSwatchesProps<Id>) {
29
31
  const { t } = useTranslation('ui');
32
+
30
33
  const isFeatured = (id: string): boolean => featured.some((entry) => entry === id);
34
+
31
35
  const colorOf = (id: string): string | undefined => accents.find((entry) => entry.id === id)?.color;
36
+
32
37
  const shown = accents.filter((entry) => isFeatured(entry.id)).sort((a, b) => featured.indexOf(a.id) - featured.indexOf(b.id));
33
38
  const hidden = value !== undefined && !isFeatured(value) && colorOf(value) !== undefined ? value : null;
39
+
34
40
  return (
35
41
  <div ref={ref} className={clsx('flex items-center gap-2', className)} role="radiogroup" aria-label={label}>
36
42
  {shown.map((entry) => (
package/src/Banner.tsx CHANGED
@@ -19,24 +19,18 @@ export interface BannerProps {
19
19
  icon: LucideIcon;
20
20
  tone: BannerTone;
21
21
  message: ReactNode;
22
+
22
23
  /* The buttons that answer the line. */
23
24
  children?: ReactNode;
24
- /*
25
- * `overlay` floats the glass strip centered along the top of the positioned parent; `inline` stands
26
- * in the flow and fills its row. Under `overlay` a `className` replaces the overlay position instead
27
- * of adding to it, so its utilities never meet the component's own.
28
- */
25
+
26
+ /* Under `overlay` a `className` replaces the overlay position instead of adding to it, so its utilities never meet the component's own. */
29
27
  placement?: 'overlay' | 'inline';
28
+
30
29
  className?: string;
31
30
  ref?: Ref<HTMLDivElement>;
32
31
  }
33
32
 
34
- /*
35
- * The strip over a view: one line and the buttons that answer it. It is where anything that waits
36
- * for a person goes (a conflict, a failure, a request), because a corner toast is read after the fact
37
- * and a decision has to be where the eyes already are. One at a time: the slot is one row and the
38
- * caller picks what stands in it. Inline, it is a notice that belongs to the page it stands in.
39
- */
33
+ /* Where anything that waits for a person goes: a corner toast is read after the fact, and a decision has to be where the eyes already are. */
40
34
  export function Banner({ icon, tone, message, children, placement = 'overlay', className, ref }: BannerProps) {
41
35
  const line = (
42
36
  <>
package/src/Button.tsx CHANGED
@@ -7,8 +7,10 @@ export type { ButtonShape, ButtonSize, ButtonVariant } from './button-class.ts';
7
7
  export interface ButtonProps extends ComponentProps<'button'> {
8
8
  variant?: ButtonVariant;
9
9
  size?: ButtonSize;
10
+
10
11
  /* `pill` is 36 pixels tall and fully rounded, and ignores `size`. */
11
12
  shape?: ButtonShape;
13
+
12
14
  /* Makes it a link that looks like a button, a real anchor, so it opens the way links open. */
13
15
  href?: string;
14
16
  }
@@ -16,6 +18,7 @@ export interface ButtonProps extends ComponentProps<'button'> {
16
18
  /* Every button with a word in it. A button that is only an icon is an `IconButton`, which is a square, not a label. */
17
19
  export function Button({ variant = 'ghost', size = 'md', shape = 'default', className, href, type = 'button', ref, ...rest }: ButtonProps) {
18
20
  const classes = clsx(buttonClass(variant, size, shape), className);
21
+
19
22
  if (href) {
20
23
  return (
21
24
  <a
@@ -28,5 +31,6 @@ export function Button({ variant = 'ghost', size = 'md', shape = 'default', clas
28
31
  />
29
32
  );
30
33
  }
34
+
31
35
  return <button ref={ref} type={type} className={classes} {...rest} />;
32
36
  }