@crewlethq/ui 0.4.4 → 0.5.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 (231) hide show
  1. package/README.md +888 -24
  2. package/dist/Accordion/index.js +2 -2
  3. package/dist/AddPill/index.js +1 -1
  4. package/dist/{AddPill-DFWXYLIQ.css → AddPill-IJQYCY6C.css} +9 -0
  5. package/dist/AppShell/AppShell.d.ts +26 -5
  6. package/dist/AppShell/index.js +3 -3
  7. package/dist/{AppShell-NVE6LHNI.css → AppShell-XARELGIH.css} +178 -25
  8. package/dist/Avatar/Avatar.d.ts +85 -40
  9. package/dist/Avatar/AvatarStack.d.ts +76 -0
  10. package/dist/Avatar/index.d.ts +5 -2
  11. package/dist/Avatar/index.js +1 -1
  12. package/dist/Avatar-XID7Z74C.css +200 -0
  13. package/dist/AvatarStack-GEJBNV7E.css +72 -0
  14. package/dist/BrandLockup/index.js +1 -1
  15. package/dist/{BrandLockup-6ISDEHPJ.css → BrandLockup-JKGXFCZF.css} +25 -19
  16. package/dist/Button/Button.d.ts +7 -2
  17. package/dist/Button/index.js +1 -1
  18. package/dist/{Button-D4J6B4MA.css → Button-X4B2TJAQ.css} +50 -19
  19. package/dist/Callout/index.js +1 -1
  20. package/dist/Canvas/index.js +4 -4
  21. package/dist/Card/Card.d.ts +9 -5
  22. package/dist/Card/index.js +1 -1
  23. package/dist/{Card-RLR254LD.css → Card-GLP7SUV6.css} +25 -18
  24. package/dist/Charts/BarList.d.ts +18 -1
  25. package/dist/Charts/ChartTooltip.d.ts +68 -0
  26. package/dist/Charts/StackedBar.d.ts +25 -7
  27. package/dist/Charts/StackedColumns.d.ts +112 -0
  28. package/dist/Charts/TimeSeries.d.ts +33 -2
  29. package/dist/Charts/dataColor.d.ts +22 -14
  30. package/dist/Charts/index.d.ts +6 -0
  31. package/dist/Charts/index.js +1 -1
  32. package/dist/Charts/useChartHover.d.ts +56 -0
  33. package/dist/Charts-B3YEF7R4.css +742 -0
  34. package/dist/Checkbox/index.js +1 -1
  35. package/dist/{Checkbox-VGW26YLQ.css → Checkbox-BOXQ747I.css} +2 -2
  36. package/dist/CodeBlock/index.js +4 -4
  37. package/dist/Combobox/index.js +5 -5
  38. package/dist/CommandPalette/CommandPalette.d.ts +97 -6
  39. package/dist/CommandPalette/index.d.ts +1 -1
  40. package/dist/CommandPalette/index.js +9 -7
  41. package/dist/CommandPalette-C5AMKGN2.css +259 -0
  42. package/dist/Copyable/index.js +3 -3
  43. package/dist/DataTable/index.js +7 -7
  44. package/dist/{DataTable-37UWTRN6.css → DataTable-OLHPF7D4.css} +35 -38
  45. package/dist/DataView/index.js +15 -15
  46. package/dist/{DataView-256YF32J.css → DataView-N6JX464S.css} +5 -4
  47. package/dist/DateTimePicker/index.js +5 -5
  48. package/dist/DiffList/index.js +1 -1
  49. package/dist/Disclosure/index.js +2 -2
  50. package/dist/EntityChip/EntityChip.d.ts +9 -12
  51. package/dist/EntityChip/index.d.ts +1 -1
  52. package/dist/EntityChip/index.js +2 -2
  53. package/dist/ErrorBoundary/index.js +2 -2
  54. package/dist/{ErrorBoundary-ME36CQTA.css → ErrorBoundary-U2PA3LY2.css} +4 -4
  55. package/dist/IconButton/index.js +1 -1
  56. package/dist/{IconButton-VQGNMJDI.css → IconButton-TVEUWK6L.css} +2 -2
  57. package/dist/ImageUpload/ImageUpload.d.ts +10 -7
  58. package/dist/ImageUpload/index.js +2 -2
  59. package/dist/{ImageUpload-HKFIZR6D.css → ImageUpload-YCHJMUGX.css} +24 -10
  60. package/dist/Input/index.js +2 -2
  61. package/dist/Kbd/Kbd.d.ts +14 -4
  62. package/dist/Kbd/index.js +1 -1
  63. package/dist/Kbd-JPLDVJIP.css +71 -0
  64. package/dist/Layer/index.js +1 -1
  65. package/dist/Link/index.js +1 -1
  66. package/dist/List/index.js +1 -1
  67. package/dist/{List-XTHESXLR.css → List-MYJIV6MP.css} +12 -2
  68. package/dist/ListInput/index.js +6 -6
  69. package/dist/Listbox/index.js +2 -2
  70. package/dist/Listbox/useListbox.d.ts +2 -0
  71. package/dist/{Listbox-ZXYYNN6U.css → Listbox-6WJNJQVQ.css} +32 -7
  72. package/dist/Menu/index.js +4 -4
  73. package/dist/Meter/Meter.d.ts +103 -16
  74. package/dist/Meter/index.d.ts +2 -2
  75. package/dist/Meter/index.js +1 -1
  76. package/dist/{Meter-SKOOXQBC.css → Meter-5VCSFMZW.css} +46 -7
  77. package/dist/Modal/index.js +4 -4
  78. package/dist/{Modal-XYQJ4BL6.css → Modal-JAYBS2KS.css} +13 -4
  79. package/dist/OrgLabel/OrgLabel.d.ts +60 -24
  80. package/dist/OrgLabel/index.d.ts +1 -1
  81. package/dist/OrgLabel/index.js +2 -1
  82. package/dist/{OrgLabel-D7U6QJZD.css → OrgLabel-CR233G34.css} +9 -18
  83. package/dist/OrgNode/index.js +3 -2
  84. package/dist/OrgTable/OrgTable.d.ts +2 -2
  85. package/dist/OrgTable/index.js +8 -7
  86. package/dist/Popover/index.js +2 -2
  87. package/dist/PricingCard/index.js +3 -3
  88. package/dist/{PricingCard-JFI7RYXP.css → PricingCard-7EFXRSD2.css} +4 -5
  89. package/dist/SearchTrigger/SearchTrigger.d.ts +23 -4
  90. package/dist/SearchTrigger/index.d.ts +1 -1
  91. package/dist/SearchTrigger/index.js +1 -1
  92. package/dist/SearchTrigger-Z5D4AAY7.css +112 -0
  93. package/dist/SegmentedControl/index.js +2 -2
  94. package/dist/SegmentedMeter/SegmentedMeter.d.ts +107 -0
  95. package/dist/SegmentedMeter/index.d.ts +3 -0
  96. package/dist/SegmentedMeter/index.js +2 -0
  97. package/dist/SegmentedMeter-KQNML2TW.css +109 -0
  98. package/dist/Select/index.js +3 -3
  99. package/dist/Shortcut/index.js +2 -2
  100. package/dist/SidebarNav/SidebarNav.d.ts +85 -25
  101. package/dist/SidebarNav/index.d.ts +1 -1
  102. package/dist/SidebarNav/index.js +1 -1
  103. package/dist/SidebarNav-X5NLZNWA.css +424 -0
  104. package/dist/StatCard/StatCard.d.ts +59 -12
  105. package/dist/StatCard/index.d.ts +1 -1
  106. package/dist/StatCard/index.js +1 -1
  107. package/dist/StatCard-KPAFD4E2.css +204 -0
  108. package/dist/StatGroup/index.js +1 -1
  109. package/dist/{StatGroup-TGB6AEKM.css → StatGroup-HVG6O62W.css} +8 -9
  110. package/dist/StatusDot/StatusDot.d.ts +24 -6
  111. package/dist/StatusDot/index.js +1 -1
  112. package/dist/StatusDot-7OMCQCZF.css +186 -0
  113. package/dist/Stepper/Stepper.d.ts +78 -0
  114. package/dist/Stepper/index.d.ts +3 -0
  115. package/dist/Stepper/index.js +4 -0
  116. package/dist/Stepper-HW4JM3YH.css +176 -0
  117. package/dist/Tabs/index.js +1 -1
  118. package/dist/{Tabs-MJ2E3VPK.css → Tabs-XCNPHA7B.css} +46 -26
  119. package/dist/Tag/Tag.d.ts +29 -22
  120. package/dist/Tag/index.js +2 -2
  121. package/dist/{Tag-VNZEYLB6.css → Tag-GBE7LQJP.css} +82 -83
  122. package/dist/TagsInput/index.js +7 -7
  123. package/dist/ThemeSwitcher/ThemeSwitcher.d.ts +53 -21
  124. package/dist/ThemeSwitcher/index.d.ts +3 -3
  125. package/dist/ThemeSwitcher/index.js +4 -3
  126. package/dist/ThemeSwitcher/preferences.d.ts +19 -5
  127. package/dist/ThemeToggle/ThemeToggle.d.ts +40 -0
  128. package/dist/ThemeToggle/index.d.ts +2 -0
  129. package/dist/ThemeToggle/index.js +5 -0
  130. package/dist/TimeWindowPicker/index.js +8 -8
  131. package/dist/Toaster/index.js +2 -2
  132. package/dist/Toolbar/index.js +2 -2
  133. package/dist/{Toolbar-IP6LXN45.css → Toolbar-HUOSMNTH.css} +3 -1
  134. package/dist/Tooltip/index.js +2 -2
  135. package/dist/Tree/index.d.ts +2 -2
  136. package/dist/Tree/index.js +1 -1
  137. package/dist/Tree/layout.d.ts +103 -28
  138. package/dist/TreeCanvas/TreeCanvas.d.ts +60 -14
  139. package/dist/TreeCanvas/index.d.ts +1 -1
  140. package/dist/TreeCanvas/index.js +6 -6
  141. package/dist/TreeCanvas/motion.d.ts +3 -2
  142. package/dist/{TreeCanvas-WBNQPHC7.css → TreeCanvas-HVOV4SQN.css} +154 -30
  143. package/dist/TreeGrid/index.js +4 -4
  144. package/dist/{chunk-F6OE5FH3.js → chunk-2FPENTCF.js} +1 -1
  145. package/dist/chunk-4AK52VHB.js +88 -0
  146. package/dist/{chunk-7EM5T4ME.js → chunk-4IQD3HUQ.js} +2 -2
  147. package/dist/{chunk-YODNNSZL.js → chunk-4PZ6FJKW.js} +43 -13
  148. package/dist/{chunk-F27EPQ7D.js → chunk-4UQ7SMPK.js} +1 -1
  149. package/dist/chunk-5QWIJSQM.js +73 -0
  150. package/dist/{chunk-KIC7BZYJ.js → chunk-6MU7HNB4.js} +6 -5
  151. package/dist/{chunk-S2XHHEW4.js → chunk-74KMX7YH.js} +4 -4
  152. package/dist/{chunk-WNI2WSJF.js → chunk-7KBNFFM3.js} +1 -1
  153. package/dist/{chunk-EFSG7HNU.js → chunk-AUS5FNQE.js} +1 -1
  154. package/dist/{chunk-CMEE37QJ.js → chunk-BMYPGGPV.js} +4 -4
  155. package/dist/{chunk-H4FBTAYS.js → chunk-BNCCEER3.js} +8 -8
  156. package/dist/chunk-C5WJUZVR.js +56 -0
  157. package/dist/{chunk-5WS6L6FA.js → chunk-CAIHUYXV.js} +9 -9
  158. package/dist/{chunk-5KSRXHOW.js → chunk-CQY5NTRS.js} +1 -1
  159. package/dist/{chunk-MW356IVK.js → chunk-D6EVJUGU.js} +2 -2
  160. package/dist/{chunk-7PEFUMQJ.js → chunk-DHPUMOTX.js} +2 -2
  161. package/dist/{chunk-HZ5XZNPS.js → chunk-DS2C73RJ.js} +3 -3
  162. package/dist/{chunk-GKHAKGOF.js → chunk-DSUY5F4E.js} +3 -3
  163. package/dist/{chunk-Q4ZPPART.js → chunk-EFYPAJT3.js} +3 -3
  164. package/dist/{chunk-PATXSJGR.js → chunk-ERVO6OUF.js} +17 -17
  165. package/dist/{chunk-BZYDZBAN.js → chunk-ETYEBKR4.js} +3 -3
  166. package/dist/{chunk-CC67MUUO.js → chunk-FD5UEN6X.js} +30 -30
  167. package/dist/{chunk-5SDBMKUO.js → chunk-FIFNP6PL.js} +3 -3
  168. package/dist/{chunk-7HPRF5XN.js → chunk-FUF52K7E.js} +98 -16
  169. package/dist/{chunk-5KPQ6D7N.js → chunk-FZVJDJFN.js} +2 -2
  170. package/dist/chunk-IA232OTU.js +156 -0
  171. package/dist/{chunk-2EOKFKHX.js → chunk-IG27QX7Q.js} +7 -7
  172. package/dist/chunk-IKB6HFGK.js +55 -0
  173. package/dist/{chunk-T43A26SD.js → chunk-IPVQKAHO.js} +6 -6
  174. package/dist/{chunk-3EYF6HKB.js → chunk-IVFJD7WY.js} +28 -9
  175. package/dist/{chunk-XJWXPRSK.js → chunk-JGRNTBF2.js} +11 -11
  176. package/dist/chunk-K3OWD7BJ.js +121 -0
  177. package/dist/{chunk-6KCO2D5C.js → chunk-KD4H66L6.js} +7 -20
  178. package/dist/{chunk-SFZOKW2G.js → chunk-KJ34ZBBI.js} +8 -3
  179. package/dist/{chunk-AQTBF4EB.js → chunk-LFHCXZO5.js} +5 -5
  180. package/dist/{chunk-LWKJQTOM.js → chunk-MICH6QSJ.js} +1 -1
  181. package/dist/chunk-N3DPO6HG.js +226 -0
  182. package/dist/{chunk-S4GZWSKR.js → chunk-OM5E3TTK.js} +1 -1
  183. package/dist/{chunk-3QRYCPXQ.js → chunk-OPKIKM35.js} +6 -6
  184. package/dist/{chunk-5EKIWVOR.js → chunk-PGRPNDWM.js} +2 -2
  185. package/dist/{chunk-FSOW3ARP.js → chunk-PQNILU27.js} +9 -9
  186. package/dist/{chunk-QNCVHRZL.js → chunk-QVAFL2LE.js} +1 -1
  187. package/dist/{chunk-Q3B66TJM.js → chunk-QY7UU5ZB.js} +1 -1
  188. package/dist/{chunk-ITHXJHBB.js → chunk-R25RGPUB.js} +1 -0
  189. package/dist/{chunk-KLJCCMF3.js → chunk-R6735B37.js} +2 -2
  190. package/dist/{chunk-3ZP55QZE.js → chunk-R6FBDTP3.js} +4 -4
  191. package/dist/{chunk-7FZ53WDJ.js → chunk-RIAZM6L3.js} +1 -1
  192. package/dist/chunk-RJM4QCGG.js +550 -0
  193. package/dist/{chunk-NTRZGNEX.js → chunk-S3BCVWTU.js} +215 -46
  194. package/dist/chunk-S7KW47IQ.js +121 -0
  195. package/dist/{chunk-KNYYCWMK.js → chunk-SJQ546ID.js} +4 -4
  196. package/dist/{chunk-D35VTV2Z.js → chunk-SV7QAONL.js} +1 -1
  197. package/dist/{chunk-IAJLHVUA.js → chunk-TIWAHZZ6.js} +1 -1
  198. package/dist/{chunk-2PRH365R.js → chunk-UA7O3KKJ.js} +1 -1
  199. package/dist/{chunk-NPZY6YYL.js → chunk-UG5ZMAXW.js} +6 -6
  200. package/dist/{chunk-NDCATSW7.js → chunk-V34H2YCY.js} +1 -1
  201. package/dist/chunk-WIATRXEJ.js +22 -0
  202. package/dist/{chunk-5C5YMZQU.js → chunk-WOFOMTGB.js} +16 -10
  203. package/dist/{chunk-QYOFACSP.js → chunk-WSOFKOLP.js} +3 -3
  204. package/dist/{chunk-MNAXYY3R.js → chunk-WUVZDFHS.js} +31 -11
  205. package/dist/{chunk-DB2VDLVR.js → chunk-YIMOT5OO.js} +10 -10
  206. package/dist/{chunk-2ZQMA2WB.js → chunk-ZPSOF6VL.js} +2 -2
  207. package/dist/generated/index.d.ts +3 -0
  208. package/dist/generated/index.js +69 -65
  209. package/dist/index.js +69 -65
  210. package/dist/styles.css +2538 -741
  211. package/dist/utils/index.d.ts +1 -1
  212. package/dist/utils/tone.d.ts +7 -12
  213. package/package.json +4 -4
  214. package/scripts/check-css-literals.mjs +159 -23
  215. package/scripts/check-css-variables.mjs +5 -3
  216. package/scripts/css-source.mjs +97 -5
  217. package/dist/Avatar-P2KRQM2B.css +0 -156
  218. package/dist/Charts-D7G2BSXH.css +0 -277
  219. package/dist/CommandPalette-CSJDUCQA.css +0 -115
  220. package/dist/Kbd-W66MXQI5.css +0 -61
  221. package/dist/SearchTrigger-QXOYAUUY.css +0 -79
  222. package/dist/SidebarNav-QGSFKZYA.css +0 -319
  223. package/dist/StatCard-KYPKZUWX.css +0 -111
  224. package/dist/StatusDot-HA2L2FSX.css +0 -84
  225. package/dist/chunk-22O7LAW2.js +0 -41
  226. package/dist/chunk-AJNCATWZ.js +0 -144
  227. package/dist/chunk-F4PJZ4ED.js +0 -245
  228. package/dist/chunk-PNFASD6F.js +0 -98
  229. package/dist/chunk-PZSWF74H.js +0 -15
  230. package/dist/chunk-R66KLW7S.js +0 -143
  231. /package/dist/{chunk-ZCR6YGQ4.js → chunk-PKIN4IMB.js} +0 -0
@@ -1,10 +1,10 @@
1
- export { TagsInput } from '../chunk-6KCO2D5C.js';
2
- import '../chunk-S2XHHEW4.js';
3
- import '../chunk-PZSWF74H.js';
4
- import '../chunk-KIC7BZYJ.js';
5
- import '../chunk-7RPGY3JE.js';
6
- import '../chunk-ITHXJHBB.js';
7
- import '../chunk-F27EPQ7D.js';
1
+ export { TagsInput } from '../chunk-KD4H66L6.js';
2
+ import '../chunk-74KMX7YH.js';
3
+ import '../chunk-WIATRXEJ.js';
4
+ import '../chunk-6MU7HNB4.js';
8
5
  import '../chunk-RSAQOKH3.js';
6
+ import '../chunk-7RPGY3JE.js';
7
+ import '../chunk-R25RGPUB.js';
8
+ import '../chunk-4UQ7SMPK.js';
9
9
  import '../chunk-BZFWDIV6.js';
10
10
  import '../chunk-ODEQTPFM.js';
@@ -1,15 +1,46 @@
1
- export interface ThemeSwitcherProps {
1
+ import { type DensityPreference, type ThemePreference } from './preferences.js';
2
+ /**
3
+ * Who holds a preference: the control, or the application around it.
4
+ *
5
+ * STORED, the default: the control reads the choice kept under `storageKey`,
6
+ * writes the root attribute and storage when it changes, and tells `onChange`
7
+ * afterwards. Every stored control on one key reads one value, so two of them
8
+ * on a page agree.
9
+ *
10
+ * CONTROLLED, with `value`: the control draws `value`, calls `onChange` with
11
+ * the reader's pick and WRITES NOTHING, neither the root attribute nor
12
+ * storage. The application owns the preference (normally one
13
+ * `useThemePreference` it hands to every control that shows it), so a second
14
+ * writer here would be a second opinion about which theme is on. A
15
+ * `storageKey` has nothing to name in that mode, and the types refuse one.
16
+ *
17
+ * A control is one or the other for its whole life: the two are different
18
+ * components underneath, so switching remounts it.
19
+ */
20
+ export type PreferenceControl<T extends string> = {
21
+ value?: undefined;
22
+ /** Told after a pick is applied and stored. */
23
+ onChange?: ((next: T) => void) | undefined;
2
24
  /** Where the choice is kept. */
3
- storageKey?: string;
25
+ storageKey?: string | undefined;
26
+ } | {
27
+ /** The choice to draw. The control writes nothing of its own. */
28
+ value: T;
29
+ /** The reader's pick. Nothing changes until `value` does. */
30
+ onChange: (next: T) => void;
31
+ storageKey?: undefined;
32
+ };
33
+ interface ThemeRowProps {
4
34
  /** Names the group. */
5
- label?: string;
35
+ label?: string | undefined;
6
36
  /** What each choice is called out loud. The glyphs say nothing on their own. */
7
- lightLabel?: string;
8
- systemLabel?: string;
9
- darkLabel?: string;
10
- size?: 'sm' | 'md';
11
- className?: string;
37
+ lightLabel?: string | undefined;
38
+ systemLabel?: string | undefined;
39
+ darkLabel?: string | undefined;
40
+ size?: 'sm' | 'md' | undefined;
41
+ className?: string | undefined;
12
42
  }
43
+ export type ThemeSwitcherProps = ThemeRowProps & PreferenceControl<ThemePreference>;
13
44
  /**
14
45
  * Light, the system's, or dark.
15
46
  *
@@ -21,21 +52,21 @@ export interface ThemeSwitcherProps {
21
52
  * EACH OPTION IS A WORD, not a picture of one. The glyphs are the whole of
22
53
  * what is drawn, so without a spoken name the row is three unnamed buttons.
23
54
  */
24
- export declare function ThemeSwitcher({ storageKey, label, lightLabel, systemLabel, darkLabel, size, className, }: ThemeSwitcherProps): import("react").JSX.Element;
25
- export interface DensitySwitcherProps {
26
- storageKey?: string;
27
- label?: string;
55
+ export declare function ThemeSwitcher(props: ThemeSwitcherProps): import("react").JSX.Element;
56
+ interface DensityRowProps {
57
+ label?: string | undefined;
28
58
  /** What each choice is called out loud. */
29
- compactLabel?: string;
30
- normalLabel?: string;
31
- comfortableLabel?: string;
59
+ compactLabel?: string | undefined;
60
+ normalLabel?: string | undefined;
61
+ comfortableLabel?: string | undefined;
32
62
  /** What each choice is drawn as. One letter, which is a picture of a size. */
33
- compactMark?: string;
34
- normalMark?: string;
35
- comfortableMark?: string;
36
- size?: 'sm' | 'md';
37
- className?: string;
63
+ compactMark?: string | undefined;
64
+ normalMark?: string | undefined;
65
+ comfortableMark?: string | undefined;
66
+ size?: 'sm' | 'md' | undefined;
67
+ className?: string | undefined;
38
68
  }
69
+ export type DensitySwitcherProps = DensityRowProps & PreferenceControl<DensityPreference>;
39
70
  /**
40
71
  * How much room the interface gives itself.
41
72
  *
@@ -44,4 +75,5 @@ export interface DensitySwitcherProps {
44
75
  * nothing: a reader was offered "S" and left to guess. The mark stays, and
45
76
  * each option is called Compact, Normal or Comfortable.
46
77
  */
47
- export declare function DensitySwitcher({ storageKey, label, compactLabel, normalLabel, comfortableLabel, compactMark, normalMark, comfortableMark, size, className, }: DensitySwitcherProps): import("react").JSX.Element;
78
+ export declare function DensitySwitcher(props: DensitySwitcherProps): import("react").JSX.Element;
79
+ export {};
@@ -1,4 +1,4 @@
1
1
  export { DensitySwitcher, ThemeSwitcher } from './ThemeSwitcher.js';
2
- export type { DensitySwitcherProps, ThemeSwitcherProps } from './ThemeSwitcher.js';
3
- export { applyDensity, applyStoredPreferences, applyTheme, useDensityPreference, useThemePreference, } from './preferences.js';
4
- export type { DensityPreference, PreferenceOptions, StoredPreferences, ThemePreference, } from './preferences.js';
2
+ export type { DensitySwitcherProps, PreferenceControl, ThemeSwitcherProps } from './ThemeSwitcher.js';
3
+ export { applyDensity, applyStoredPreferences, applyTheme, resolveTheme, useDensityPreference, useSystemTheme, useThemePreference, } from './preferences.js';
4
+ export type { DensityPreference, PreferenceOptions, ResolvedTheme, StoredPreferences, ThemePreference, } from './preferences.js';
@@ -1,6 +1,7 @@
1
- export { DensitySwitcher, ThemeSwitcher, applyDensity, applyStoredPreferences, applyTheme, useDensityPreference, useThemePreference } from '../chunk-R66KLW7S.js';
2
- import '../chunk-7PEFUMQJ.js';
3
- import '../chunk-Q3B66TJM.js';
1
+ export { DensitySwitcher, ThemeSwitcher } from '../chunk-S7KW47IQ.js';
2
+ export { applyDensity, applyStoredPreferences, applyTheme, resolveTheme, useDensityPreference, useSystemTheme, useThemePreference } from '../chunk-K3OWD7BJ.js';
3
+ import '../chunk-DHPUMOTX.js';
4
+ import '../chunk-QY7UU5ZB.js';
4
5
  import '../chunk-BHHIIK3M.js';
5
6
  import '../chunk-BZFWDIV6.js';
6
7
  import '../chunk-ODEQTPFM.js';
@@ -6,10 +6,13 @@ export type DensityPreference = 'normal' | 'compact' | 'comfortable';
6
6
  * Puts the theme on the root element.
7
7
  *
8
8
  * `system` REMOVES the attribute rather than writing a third value, because
9
- * the stylesheet's own default is the system's: a document with no attribute
10
- * is light, or dark where the platform asks for dark. A `data-theme="system"`
11
- * would match neither selector and paint the light palette on a reader who
12
- * asked for dark.
9
+ * following the system IS the absence of a choice, and the stylesheet's own
10
+ * default is the system's: a document with no attribute is dark, or light
11
+ * where the platform asks for light. What beats the system is an explicit
12
+ * value, in both directions: `light` by a block of its own, `dark` by keeping
13
+ * the light media block from matching. A `data-theme="system"` names no
14
+ * palette, so it would be a choice only to the code that asks whether the
15
+ * attribute is there at all, which is the wrong answer to give it.
13
16
  */
14
17
  export declare function applyTheme(theme: ThemePreference): void;
15
18
  /** Puts the density on the root element. `normal` removes the attribute. */
@@ -24,11 +27,22 @@ export interface PreferenceOptions {
24
27
  * WHY IT IS A HOOK RATHER THAN A CONTEXT. Nothing renders differently by
25
28
  * theme: the palette is CSS custom properties on the root, so the only state
26
29
  * is which attribute is set, and a context would make every component that
27
- * reads it re-render for a change none of them draw.
30
+ * reads it re-render for a change none of them draw. Two calls with one
31
+ * `storageKey` read one value, so a toggle and a row on the same page agree.
28
32
  */
29
33
  export declare function useThemePreference({ storageKey, }: PreferenceOptions): [ThemePreference, (next: ThemePreference) => void];
30
34
  /** The reader's density, kept on the root element and in storage. */
31
35
  export declare function useDensityPreference({ storageKey, }: PreferenceOptions): [DensityPreference, (next: DensityPreference) => void];
36
+ /** The palette the root actually paints: a choice, or the system's answer. */
37
+ export type ResolvedTheme = 'light' | 'dark';
38
+ /**
39
+ * The palette the platform asks for, now and whenever it changes. A server,
40
+ * and a browser that cannot be asked, are answered dark, which is what the
41
+ * theme layer paints for them.
42
+ */
43
+ export declare function useSystemTheme(): ResolvedTheme;
44
+ /** What a preference paints on a platform that asks for `system`. */
45
+ export declare function resolveTheme(preference: ThemePreference, system: ResolvedTheme): ResolvedTheme;
32
46
  export interface StoredPreferences {
33
47
  themeKey?: string | undefined;
34
48
  densityKey?: string | undefined;
@@ -0,0 +1,40 @@
1
+ import { type IconButtonSize, type IconButtonVariant } from '../IconButton/index.js';
2
+ import type { PreferenceControl } from '../ThemeSwitcher/ThemeSwitcher.js';
3
+ import { type ThemePreference } from '../ThemeSwitcher/preferences.js';
4
+ interface ToggleButtonProps {
5
+ /** Named for what a press does, while the page is dark. */
6
+ toLightLabel?: string | undefined;
7
+ /** Named for what a press does, while the page is light. */
8
+ toDarkLabel?: string | undefined;
9
+ /** The rail's foot wears `sm`, the quiet step beside the identity row. */
10
+ size?: IconButtonSize | undefined;
11
+ variant?: IconButtonVariant | undefined;
12
+ className?: string | undefined;
13
+ }
14
+ /**
15
+ * `onChange` receives `light` or `dark`, never `system`: a press is a choice.
16
+ * Stored (the default) or controlled by `value`, as `ThemeSwitcher` is, and a
17
+ * controlled toggle writes nothing of its own.
18
+ */
19
+ export type ThemeToggleProps = ToggleButtonProps & PreferenceControl<ThemePreference>;
20
+ /**
21
+ * One press from the palette on the screen to the other one.
22
+ *
23
+ * IT FLIPS WHAT IS PAINTED, NOT WHAT WAS CHOSEN. A reader following a dark
24
+ * system has the preference `system`; toggling that preference has no
25
+ * opposite to go to, and cycling light, system, dark would spend a press on
26
+ * `system`, which repaints nothing and reads as a button that did not work.
27
+ * So the toggle RESOLVES the preference against the platform (the query the
28
+ * theme layer itself answers) and writes the explicit opposite, which beats
29
+ * the system in both directions. Following the system again is a choice in the
30
+ * full `ThemeSwitcher`, which is where a settings screen offers it.
31
+ *
32
+ * NAMED FOR THE ACTION, drawn as the destination. The name changes with the
33
+ * palette ("Switch to the light theme" on a dark page), so a screen reader
34
+ * hears what a press will do, and the glyph is the palette it goes to: a sun
35
+ * on a dark page, a moon on a light one. It is NOT `aria-pressed`, because
36
+ * neither palette is the "on" state of the other, and a pressed state beside a
37
+ * changing name would announce the change twice in two contradicting ways.
38
+ */
39
+ export declare function ThemeToggle(props: ThemeToggleProps): import("react").JSX.Element;
40
+ export {};
@@ -0,0 +1,2 @@
1
+ export { ThemeToggle } from './ThemeToggle.js';
2
+ export type { ThemeToggleProps } from './ThemeToggle.js';
@@ -0,0 +1,5 @@
1
+ export { ThemeToggle } from '../chunk-C5WJUZVR.js';
2
+ import '../chunk-K3OWD7BJ.js';
3
+ import '../chunk-4UQ7SMPK.js';
4
+ import '../chunk-BZFWDIV6.js';
5
+ import '../chunk-ODEQTPFM.js';
@@ -1,13 +1,13 @@
1
- export { DEFAULT_TIME_WINDOW_LABELS, TIME_WINDOW_SPANS, TimeWindowPicker, describeTimeWindow, isTimeWindowSet, parseTimeWindowDuration, resolveTimeWindow, timeWindowMatchesPreset } from '../chunk-XJWXPRSK.js';
2
- import '../chunk-KNYYCWMK.js';
3
- import '../chunk-EFSG7HNU.js';
1
+ export { DEFAULT_TIME_WINDOW_LABELS, TIME_WINDOW_SPANS, TimeWindowPicker, describeTimeWindow, isTimeWindowSet, parseTimeWindowDuration, resolveTimeWindow, timeWindowMatchesPreset } from '../chunk-JGRNTBF2.js';
2
+ import '../chunk-SJQ546ID.js';
3
+ import '../chunk-AUS5FNQE.js';
4
4
  import '../chunk-GXQ3B46I.js';
5
- import '../chunk-KIC7BZYJ.js';
6
- import '../chunk-GKHAKGOF.js';
5
+ import '../chunk-6MU7HNB4.js';
6
+ import '../chunk-DSUY5F4E.js';
7
7
  import '../chunk-PQADV6P6.js';
8
8
  import '../chunk-7RPGY3JE.js';
9
- import '../chunk-ITHXJHBB.js';
10
- import '../chunk-F27EPQ7D.js';
11
- import '../chunk-BZYDZBAN.js';
9
+ import '../chunk-R25RGPUB.js';
10
+ import '../chunk-4UQ7SMPK.js';
11
+ import '../chunk-ETYEBKR4.js';
12
12
  import '../chunk-BZFWDIV6.js';
13
13
  import '../chunk-ODEQTPFM.js';
@@ -1,5 +1,5 @@
1
- export { ToastProvider, Toaster, useToast } from '../chunk-NPZY6YYL.js';
1
+ export { ToastProvider, Toaster, useToast } from '../chunk-UG5ZMAXW.js';
2
2
  import '../chunk-7RPGY3JE.js';
3
- import '../chunk-ITHXJHBB.js';
3
+ import '../chunk-R25RGPUB.js';
4
4
  import '../chunk-BZFWDIV6.js';
5
5
  import '../chunk-ODEQTPFM.js';
@@ -1,4 +1,4 @@
1
- export { Toolbar, ToolbarOverflow, ToolbarWide } from '../chunk-5EKIWVOR.js';
1
+ export { Toolbar, ToolbarOverflow, ToolbarWide } from '../chunk-PGRPNDWM.js';
2
2
  import '../chunk-7RPGY3JE.js';
3
- import '../chunk-ITHXJHBB.js';
3
+ import '../chunk-R25RGPUB.js';
4
4
  import '../chunk-ODEQTPFM.js';
@@ -37,7 +37,9 @@
37
37
  display: none;
38
38
  }
39
39
 
40
- @media (max-width: 900px) {
40
+ /* Under the shell's breakpoint, strictly, as the shell switches: the wide
41
+ controls fold into the overflow where the rail becomes a drawer. */
42
+ @media (width < 1024px) {
41
43
  .crewlet-toolbar__wide {
42
44
  display: none;
43
45
  }
@@ -1,4 +1,4 @@
1
- export { Tooltip } from '../chunk-5KSRXHOW.js';
1
+ export { Tooltip } from '../chunk-CQY5NTRS.js';
2
2
  import '../chunk-7RPGY3JE.js';
3
- import '../chunk-ITHXJHBB.js';
3
+ import '../chunk-R25RGPUB.js';
4
4
  import '../chunk-ODEQTPFM.js';
@@ -1,7 +1,7 @@
1
1
  export { createTreeModel, isTypeAheadKey, treeAllExpandable, treeAncestors, treeCollapseOrAscend, treeExpandOrDescend, treeExpandTo, treeExpandable, treeFirst, treeFirstChild, treeLast, treeLevel, treeNext, treeParent, treePosInSet, treePrevious, treeSetSize, treeTypeAhead, treeVisible, typeAheadBuffer, TYPE_AHEAD_RESET_MS, } from './model.js';
2
2
  export type { TreeInput, TreeModel, TypeAheadState } from './model.js';
3
- export { layoutConnectors, layoutForest } from './layout.js';
4
- export type { ForestLayout, LayoutGaps, LayoutNode, LayoutRanks, PlacedNode, TreeConnector, TreeConnectorShape, } from './layout.js';
3
+ export { layoutConnectors, layoutForest, placeGroups } from './layout.js';
4
+ export type { ForestLayout, LayoutGaps, LayoutGroup, LayoutGroupInset, LayoutNode, LayoutRanks, PlacedGroup, PlacedNode, TreeConnector, TreeConnectorShape, } from './layout.js';
5
5
  export { treeItemAction, treeStep, useTreeState } from './useTreeState.js';
6
6
  export type { TreeItemAction, TreeKeyEvent, TreeState, TreeStep, TreeViewHandle } from './useTreeState.js';
7
7
  export { SIZE_EPSILON, useLayoutAnchor, useMeasuredSizes } from './useMeasuredSizes.js';
@@ -1 +1 @@
1
- export { SIZE_EPSILON, TYPE_AHEAD_RESET_MS, createTreeModel, isTypeAheadKey, layoutConnectors, layoutForest, treeAllExpandable, treeAncestors, treeCollapseOrAscend, treeExpandOrDescend, treeExpandTo, treeExpandable, treeFirst, treeFirstChild, treeItemAction, treeLast, treeLevel, treeNext, treeParent, treePosInSet, treePrevious, treeSetSize, treeStep, treeTypeAhead, treeVisible, typeAheadBuffer, useLayoutAnchor, useMeasuredSizes, useTreeState } from '../chunk-NTRZGNEX.js';
1
+ export { SIZE_EPSILON, TYPE_AHEAD_RESET_MS, createTreeModel, isTypeAheadKey, layoutConnectors, layoutForest, placeGroups, treeAllExpandable, treeAncestors, treeCollapseOrAscend, treeExpandOrDescend, treeExpandTo, treeExpandable, treeFirst, treeFirstChild, treeItemAction, treeLast, treeLevel, treeNext, treeParent, treePosInSet, treePrevious, treeSetSize, treeStep, treeTypeAhead, treeVisible, typeAheadBuffer, useLayoutAnchor, useMeasuredSizes, useTreeState } from '../chunk-S3BCVWTU.js';
@@ -38,6 +38,14 @@
38
38
  * which is what reads as tidy.
39
39
  * - A ZERO HEIGHT BOX STILL OCCUPIES ITS ROW, so two of them are never drawn
40
40
  * on top of each other.
41
+ * - A GROUP IS ROOM THE LAYOUT KEEPS, NOT A BOX DRAWN OVER IT AFTERWARDS. A
42
+ * run of siblings can be enclosed in a box (a unit's seats, say) whose
43
+ * padding and header are part of every member's outline, so a neighbour
44
+ * that is not a member is held `gapX` clear of the BOX rather than of the
45
+ * member card, while two members of one box stay `gapX` apart from each
46
+ * other. The header is reserved above the run's rank and the padding below
47
+ * it, on both rank modes, so a box never reaches into the gap a connector
48
+ * runs through. See [LayoutGroup].
41
49
  *
42
50
  * Coordinates come back with the forest's top left corner at the origin plus
43
51
  * `margin`, and boxes in pre-order. The outline merge costs time proportional to a subtree's
@@ -79,6 +87,10 @@ export interface LayoutGaps {
79
87
  gapY: number;
80
88
  /** Where a box's top edge sits. Unset, `per-parent`. */
81
89
  ranks?: LayoutRanks | undefined;
90
+ /**
91
+ * Runs of siblings enclosed in a box: see [LayoutGroup]. Unset, none.
92
+ */
93
+ groups?: readonly LayoutGroup[] | undefined;
82
94
  /**
83
95
  * Space kept on all four sides of the forest.
84
96
  *
@@ -90,6 +102,44 @@ export interface LayoutGaps {
90
102
  */
91
103
  margin?: number | undefined;
92
104
  }
105
+ /** The room a group's box keeps around its members: see [LayoutGroup]. */
106
+ export interface LayoutGroupInset {
107
+ /** Between the box's side and its outermost member, on each side. */
108
+ x: number;
109
+ /** Between the box's top and its members' tops: its header lives here. */
110
+ top: number;
111
+ /** Between its members' bottoms and the box's bottom. */
112
+ bottom: number;
113
+ }
114
+ /**
115
+ * A box drawn round a RUN OF SIBLINGS: consecutive children of one parent, or
116
+ * consecutive roots.
117
+ *
118
+ * WHY SIBLINGS, AND WHY CONSECUTIVE. A box is one rectangle, and a rectangle
119
+ * round boxes that are not next to each other in the drawing encloses
120
+ * whatever lies between them: a member two ranks down, or a neighbour placed
121
+ * between two members, would be drawn inside a group it does not belong to.
122
+ * A run of siblings is the one shape a tidy layout keeps together on one rank
123
+ * with nothing between its members, so it is the shape a box can be drawn
124
+ * round honestly; anything else is refused by name rather than drawn wrong.
125
+ * An organization's unit is such a run: the seats that report to one lead.
126
+ *
127
+ * Each group carries its own inset because a header's height is a MEASURED
128
+ * value (a label and whatever chip rides beside it), and two groups need not
129
+ * say the same amount.
130
+ */
131
+ export interface LayoutGroup {
132
+ id: string;
133
+ /** The boxes it encloses, in any order. Every one is a box of the forest. */
134
+ members: readonly string[];
135
+ inset: LayoutGroupInset;
136
+ }
137
+ /** A group where the layout put it: its members' extent plus its inset. */
138
+ export interface PlacedGroup extends CanvasRect {
139
+ id: string;
140
+ members: readonly string[];
141
+ inset: LayoutGroupInset;
142
+ }
93
143
  /** A box where the layout put it. */
94
144
  export interface PlacedNode extends CanvasRect {
95
145
  id: string;
@@ -100,13 +150,39 @@ export interface ForestLayout {
100
150
  /** Every box, in pre-order. */
101
151
  nodes: PlacedNode[];
102
152
  byId: Map<string, PlacedNode>;
103
- /** The forest's extent: always at the origin. */
153
+ /**
154
+ * Every group, in the order it was given, as the rectangle its box is drawn
155
+ * in. Absent from a layout built by hand with none.
156
+ */
157
+ groups?: PlacedGroup[];
158
+ /**
159
+ * The rank mode it was laid out on, which is where a connector's run goes:
160
+ * see [layoutConnectors]. Absent from a layout built by hand, which is then
161
+ * read as `per-parent`.
162
+ */
163
+ ranks?: LayoutRanks;
164
+ /** The forest's extent, groups included: always at the origin. */
104
165
  bounds: CanvasRect;
105
166
  }
167
+ /**
168
+ * Each group's rectangle: its members' extent, plus its inset on every side.
169
+ *
170
+ * Exported because the extent is a function of where the members are DRAWN,
171
+ * which during a relayout is on the way to where the layout put them: a box
172
+ * computed once from the target would sit at the end of a journey its members
173
+ * are still making.
174
+ */
175
+ export declare function placeGroups(byId: ReadonlyMap<string, CanvasRect>, groups: readonly Pick<LayoutGroup, 'id' | 'members' | 'inset'>[]): PlacedGroup[];
106
176
  /** Lays out a forest of measured boxes: see the module doc for the rules. */
107
177
  export declare function layoutForest(roots: readonly LayoutNode[], gaps: LayoutGaps): ForestLayout;
108
- /** The two shapes a connector is drawn in: see [layoutConnectors]. */
109
- export type TreeConnectorShape = 'step' | 'curve';
178
+ /**
179
+ * The shapes a connector is drawn in: see [layoutConnectors].
180
+ *
181
+ * `elbow` (the default) and `straight` are the org chart's own pair; `step` and
182
+ * `curve` are the two drawings this chart had before the elbow, kept because
183
+ * each is a real choice a caller makes knowing what it costs.
184
+ */
185
+ export type TreeConnectorShape = 'elbow' | 'straight' | 'step' | 'curve';
110
186
  /**
111
187
  * One connector: the child it arrives at, the parent it leaves, and the path.
112
188
  *
@@ -128,31 +204,30 @@ export interface TreeConnector {
128
204
  * The connector from each box to its parent, as SVG path data: down from the
129
205
  * parent's bottom centre and into the child's top centre.
130
206
  *
131
- * TWO SHAPES, AND THE DEFAULT IS THE STEP: down, a rounded corner, across the
132
- * middle of the gap, another rounded corner, and down into the child. The
133
- * square step and the single cubic were both tried here first.
134
- *
135
- * A SQUARE step reads correctly at any width but meets its own siblings at a
136
- * right angle on the shared horizontal run, so a parent with four children
137
- * draws one long line with four corners on it and which corner belongs to
138
- * which child is read by tracing.
139
- *
140
- * A single CUBIC from the parent's bottom to the child's top (`curve`) fixes
141
- * that when the children sit close together, and loses definition exactly
142
- * where a chart is widest. A subtree is as wide as everything under it, so the
143
- * horizontal distance between a parent and an outer child grows without bound
144
- * while the vertical gap stays one rank; with both control points halfway down
145
- * that gap, the curve spends most of its length running horizontally in the
146
- * middle of the gap and reads as a long flat line passing under the parent,
147
- * its ends two stubs nowhere near it. Measured on a three-unit company: 430
148
- * units across, 105 down.
149
- *
150
- * The rounded step is the shape that keeps both properties, so it is what a
151
- * chart gets unless it asks otherwise: the corner is where the branch turns,
152
- * so it sits near the CHILD rather than shared with its siblings, and the drop
153
- * into each child is vertical however far to the side it is. `curve` is the
154
- * shape of the console's own org chart, which this package is drawn to match,
155
- * and a caller that wants that drawing asks for it knowing the above.
207
+ * `elbow`, THE DEFAULT, is ORTHOGONAL: down, a quarter circle of
208
+ * [ELBOW_RADIUS], across the run the parent's children share, another quarter
209
+ * circle, and down into the child. Every straight piece of it is vertical or
210
+ * horizontal, so a branch reads as a line of the org chart rather than as a
211
+ * drawing, and the corner is where the branch turns, near the CHILD, so which
212
+ * corner belongs to which child is read without tracing. The corners are true
213
+ * circular arcs (`A`), which is what a radius is; a quadratic through the
214
+ * corner point is not round and bulges at the size the design draws.
215
+ *
216
+ * `straight` is one segment from the parent's bottom centre to the child's
217
+ * top: the drawing for a chart dense enough that the run a parent's children
218
+ * share would be a line with forty corners on it.
219
+ *
220
+ * `step` is the elbow with a softer [STEP_RADIUS] turn drawn in quadratics,
221
+ * which this chart drew before the elbow. `curve` is a single cubic from the
222
+ * parent's bottom to the child's top, both handles on the run: the console's
223
+ * own org chart draws it, and it loses definition exactly where a chart is
224
+ * widest, because a subtree is as wide as everything under it while the gap
225
+ * stays one rank, so an outer child's curve spends most of its length running
226
+ * flat through the gap. Measured on a three-unit company: 430 units across,
227
+ * 105 down.
228
+ *
229
+ * Every shape but `straight` runs across at the same height, [busOf], which
230
+ * keeps it clear of every group box.
156
231
  *
157
232
  * Here rather than in the component that draws them, because it is arithmetic
158
233
  * over the layout and nothing about it is React's.
@@ -46,6 +46,17 @@
46
46
  * still on screen. Nothing else is an input to the layout: a badge whose text
47
47
  * changes inside a slot that keeps its size lays nothing out again.
48
48
  *
49
+ * A RUN OF SIBLINGS CAN BE ENCLOSED IN A BOX, a unit round its seats, with a
50
+ * label along its top (`groups`). The box is room the layout KEEPS rather than
51
+ * a rectangle drawn over it afterwards: its padding and header are part of the
52
+ * members' outlines, so a card that is not a member is never drawn inside one
53
+ * and two boxes are never drawn over each other. The label rides OVER the
54
+ * connectors, on the box's own fill, so a branch dropping into a member passes
55
+ * behind the words rather than through them. The box is drawing, like the
56
+ * connectors, and hidden from assistive technology; what it SAYS is given to
57
+ * each member card as its description, which is where a reader of the tree
58
+ * meets it.
59
+ *
49
60
  * AND IT MOVES. A chart arrives rank by rank rather than all at once, and a
50
61
  * relayout TWEENS every card from where it was to where it is, connectors and
51
62
  * all, so adding a seat is visibly the same chart rearranging rather than a
@@ -107,6 +118,11 @@ export interface TreeItemProps {
107
118
  'aria-posinset': number;
108
119
  'aria-expanded': boolean | undefined;
109
120
  'aria-selected': boolean;
121
+ /**
122
+ * The label of the group box the node's card is drawn in, for the card's
123
+ * own node: see `TreeCanvasProps.groups`. Unset for every other node.
124
+ */
125
+ 'aria-describedby': string | undefined;
110
126
  'data-tree-id': string;
111
127
  ref: (el: HTMLElement | null) => void;
112
128
  onClick: (event: MouseEvent<HTMLElement>) => void;
@@ -224,6 +240,33 @@ export interface TreeComposing {
224
240
  /** Escape inside the ghost. Cancelling is the caller's: it owns the form. */
225
241
  onCancel: () => void;
226
242
  }
243
+ /**
244
+ * A box drawn round a run of sibling cards, with a label along its top: a unit
245
+ * round the seats in it, say. See `TreeCanvasProps.groups`.
246
+ */
247
+ export interface TreeCanvasGroup {
248
+ /** The group's own id. Unique among the groups, and never a card's id. */
249
+ id: string;
250
+ /**
251
+ * What the box is called, such as "Engineering · Core". Drawn along its top
252
+ * in the tertiary ink, and read as the description of every member card.
253
+ */
254
+ label: string;
255
+ /**
256
+ * A short key AHEAD of the label, such as the project key chip a unit's
257
+ * work is filed under: "ENG Engineering · Core", as the approved org chart
258
+ * reads it and as a rail row's `lead` puts a project's key before its name.
259
+ * Drawn and described with the label.
260
+ */
261
+ lead?: ReactNode | undefined;
262
+ /**
263
+ * The CARDS it encloses: ids `cards` returns, all children of one card (or
264
+ * all roots) and consecutive among them. A member that is not drawn right
265
+ * now (inside a closed card) is left out, and a group with none drawn is not
266
+ * drawn at all. Anything else is refused: see [LayoutGroup].
267
+ */
268
+ memberIds: readonly string[];
269
+ }
227
270
  export interface TreeCanvasProps {
228
271
  /** The accessible name of the chart, such as "Structure chart". */
229
272
  label: string;
@@ -268,16 +311,6 @@ export interface TreeCanvasProps {
268
311
  * the pointer would move the card somebody was aiming at out from under them.
269
312
  */
270
313
  renderUnder?: ((id: string, card: TreeCardContext) => ReactNode) | undefined;
271
- /**
272
- * Whether a card is drawn with the dashed edge.
273
- *
274
- * It is the mark a card carries when it stands for somebody outside the
275
- * system: a person rather than an agent, a seat nobody holds. The BOUNDARY
276
- * says it rather than a hue, so it reads to a reader who cannot separate the
277
- * hue at all, and the card's frame is this component's to draw so the mark
278
- * is too. Unset, every card takes the solid edge.
279
- */
280
- cardOutline?: ((id: string) => boolean) | undefined;
281
314
  /**
282
315
  * The hue a card is tinted with, and the connector arriving at it.
283
316
  *
@@ -317,11 +350,24 @@ export interface TreeCanvasProps {
317
350
  */
318
351
  ranks?: LayoutRanks | undefined;
319
352
  /**
320
- * The shape of the connectors: a rounded step (the default) or the single
321
- * cubic the console's org chart draws. See [layoutConnectors], which states
322
- * what each shape costs.
353
+ * The shape of the connectors: `elbow` (the default), orthogonal with a
354
+ * small round corner; `straight`, one segment; or the two older drawings,
355
+ * the softer `step` and the single `curve` the console's org chart draws.
356
+ * See [layoutConnectors], which states what each shape costs.
323
357
  */
324
358
  connector?: TreeConnectorShape | undefined;
359
+ /**
360
+ * Boxes drawn round runs of sibling cards, each with a label along its top:
361
+ * see [TreeCanvasGroup]. Keep it stable, as `nodes` is: it is an input to
362
+ * the layout.
363
+ *
364
+ * WHAT A GROUP IS FOR. A chart's cards say who reports to whom; a group says
365
+ * which of them work TOGETHER, the seats of one unit under the lead they
366
+ * report to, which the lines alone cannot: two units under one lead are two
367
+ * runs of children with nothing between them. The box is laid out, not
368
+ * painted over the layout, so a card outside it is never drawn inside it.
369
+ */
370
+ groups?: readonly TreeCanvasGroup[] | undefined;
325
371
  /**
326
372
  * Carries out Enter (activate) or Delete and Backspace (remove) on a node.
327
373
  * Return false when the node has no such action, so the key travels on.
@@ -381,4 +427,4 @@ export interface TreeCanvasProps {
381
427
  ref?: Ref<TreeCanvasHandle> | undefined;
382
428
  className?: string | undefined;
383
429
  }
384
- export declare function TreeCanvas({ label, nodes, cards, cardOf, renderCard, renderUnder, cardOutline, cardTone, appearance, ranks, connector, onNodeKey, onNodeKeyDown, hasNodeMenu, selectedId, onSelect, anchorNode, overlay, controlsPlacement, controlsExtra, controlsBelow, hint, dimmed, composing, labels, ref, className, }: TreeCanvasProps): import("react").JSX.Element;
430
+ export declare function TreeCanvas({ label, nodes, cards, cardOf, renderCard, renderUnder, cardTone, appearance, ranks, connector, groups, onNodeKey, onNodeKeyDown, hasNodeMenu, selectedId, onSelect, anchorNode, overlay, controlsPlacement, controlsExtra, controlsBelow, hint, dimmed, composing, labels, ref, className, }: TreeCanvasProps): import("react").JSX.Element;
@@ -1,3 +1,3 @@
1
1
  import './TreeCanvas.css';
2
2
  export { TreeCanvas } from './TreeCanvas.js';
3
- export type { TreeActionsProps, TreeCanvasHandle, TreeCanvasProps, TreeCardContext, TreeCardInput, TreeCardTone, TreeComposing, TreeItemProps, } from './TreeCanvas.js';
3
+ export type { TreeActionsProps, TreeCanvasGroup, TreeCanvasHandle, TreeCanvasProps, TreeCardContext, TreeCardInput, TreeCardTone, TreeComposing, TreeItemProps, } from './TreeCanvas.js';
@@ -1,10 +1,10 @@
1
- export { TreeCanvas } from '../chunk-7HPRF5XN.js';
2
- import '../chunk-NTRZGNEX.js';
3
- import '../chunk-CMEE37QJ.js';
1
+ export { TreeCanvas } from '../chunk-FUF52K7E.js';
2
+ import '../chunk-S3BCVWTU.js';
3
+ import '../chunk-BMYPGGPV.js';
4
4
  import '../chunk-53DVJCVW.js';
5
5
  import '../chunk-7RPGY3JE.js';
6
- import '../chunk-ITHXJHBB.js';
7
- import '../chunk-F27EPQ7D.js';
8
- import '../chunk-BZYDZBAN.js';
6
+ import '../chunk-R25RGPUB.js';
7
+ import '../chunk-4UQ7SMPK.js';
8
+ import '../chunk-ETYEBKR4.js';
9
9
  import '../chunk-BZFWDIV6.js';
10
10
  import '../chunk-ODEQTPFM.js';
@@ -29,9 +29,10 @@
29
29
  * two speeds. The tween is over the layout's own numbers, so a frame is a
30
30
  * position rather than a promise about one, and the connectors are recomputed
31
31
  * from those same numbers: a line that did not travel with its cards would
32
- * spend the whole relayout pointing at where a card used to be.
32
+ * spend the whole relayout pointing at where a card used to be, and so is every
33
+ * group's box, which is drawn round wherever its members are this frame.
33
34
  */
34
- import type { ForestLayout } from '../Tree/index.js';
35
+ import { type ForestLayout } from '../Tree/index.js';
35
36
  /** How far apart two cards are revealed, in milliseconds. */
36
37
  export declare const ENTRANCE_STEP_MS = 60;
37
38
  /** How long a relayout takes to move every card from where it was to where it is. */