@crewlethq/ui 0.4.3 → 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 (237) 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-ITNACQ2X.css → DataTable-OLHPF7D4.css} +44 -43
  45. package/dist/DataView/index.js +14 -14
  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 +5 -5
  69. package/dist/Listbox/index.js +2 -2
  70. package/dist/Listbox/useListbox.d.ts +16 -0
  71. package/dist/Listbox/useOptionKeys.d.ts +12 -1
  72. package/dist/{Listbox-X2DOTSQA.css → Listbox-6WJNJQVQ.css} +60 -7
  73. package/dist/Menu/index.js +4 -4
  74. package/dist/{Menu-6DE7I66I.css → Menu-BT5PMFJI.css} +15 -0
  75. package/dist/Meter/Meter.d.ts +103 -16
  76. package/dist/Meter/index.d.ts +2 -2
  77. package/dist/Meter/index.js +1 -1
  78. package/dist/{Meter-SKOOXQBC.css → Meter-5VCSFMZW.css} +46 -7
  79. package/dist/Modal/index.js +4 -4
  80. package/dist/{Modal-XYQJ4BL6.css → Modal-JAYBS2KS.css} +13 -4
  81. package/dist/OrgLabel/OrgLabel.d.ts +60 -24
  82. package/dist/OrgLabel/index.d.ts +1 -1
  83. package/dist/OrgLabel/index.js +2 -1
  84. package/dist/{OrgLabel-D7U6QJZD.css → OrgLabel-CR233G34.css} +9 -18
  85. package/dist/OrgNode/index.js +3 -2
  86. package/dist/OrgTable/OrgTable.d.ts +2 -2
  87. package/dist/OrgTable/index.js +8 -7
  88. package/dist/Popover/index.js +2 -2
  89. package/dist/PricingCard/index.js +3 -3
  90. package/dist/{PricingCard-JFI7RYXP.css → PricingCard-7EFXRSD2.css} +4 -5
  91. package/dist/SearchTrigger/SearchTrigger.d.ts +23 -4
  92. package/dist/SearchTrigger/index.d.ts +1 -1
  93. package/dist/SearchTrigger/index.js +1 -1
  94. package/dist/SearchTrigger-Z5D4AAY7.css +112 -0
  95. package/dist/SegmentedControl/index.js +2 -2
  96. package/dist/SegmentedMeter/SegmentedMeter.d.ts +107 -0
  97. package/dist/SegmentedMeter/index.d.ts +3 -0
  98. package/dist/SegmentedMeter/index.js +2 -0
  99. package/dist/SegmentedMeter-KQNML2TW.css +109 -0
  100. package/dist/Select/index.js +3 -3
  101. package/dist/{Select-2X77FSWR.css → Select-E24U5LBC.css} +34 -0
  102. package/dist/Shortcut/index.js +2 -2
  103. package/dist/SidebarNav/SidebarNav.d.ts +85 -25
  104. package/dist/SidebarNav/index.d.ts +1 -1
  105. package/dist/SidebarNav/index.js +1 -1
  106. package/dist/SidebarNav-X5NLZNWA.css +424 -0
  107. package/dist/StatCard/StatCard.d.ts +59 -12
  108. package/dist/StatCard/index.d.ts +1 -1
  109. package/dist/StatCard/index.js +1 -1
  110. package/dist/StatCard-KPAFD4E2.css +204 -0
  111. package/dist/StatGroup/index.js +1 -1
  112. package/dist/{StatGroup-TGB6AEKM.css → StatGroup-HVG6O62W.css} +8 -9
  113. package/dist/StatusDot/StatusDot.d.ts +24 -6
  114. package/dist/StatusDot/index.js +1 -1
  115. package/dist/StatusDot-7OMCQCZF.css +186 -0
  116. package/dist/Stepper/Stepper.d.ts +78 -0
  117. package/dist/Stepper/index.d.ts +3 -0
  118. package/dist/Stepper/index.js +4 -0
  119. package/dist/Stepper-HW4JM3YH.css +176 -0
  120. package/dist/Table/index.js +1 -1
  121. package/dist/{Table-MDOLVUAW.css → Table-TGCS4C3F.css} +14 -4
  122. package/dist/Tabs/index.js +1 -1
  123. package/dist/{Tabs-VLICJFVB.css → Tabs-XCNPHA7B.css} +79 -27
  124. package/dist/Tag/Tag.d.ts +29 -22
  125. package/dist/Tag/index.js +2 -2
  126. package/dist/{Tag-VNZEYLB6.css → Tag-GBE7LQJP.css} +82 -83
  127. package/dist/TagsInput/index.js +6 -6
  128. package/dist/ThemeSwitcher/ThemeSwitcher.d.ts +53 -21
  129. package/dist/ThemeSwitcher/index.d.ts +3 -3
  130. package/dist/ThemeSwitcher/index.js +4 -3
  131. package/dist/ThemeSwitcher/preferences.d.ts +19 -5
  132. package/dist/ThemeToggle/ThemeToggle.d.ts +40 -0
  133. package/dist/ThemeToggle/index.d.ts +2 -0
  134. package/dist/ThemeToggle/index.js +5 -0
  135. package/dist/TimeWindowPicker/index.js +8 -8
  136. package/dist/Toaster/index.js +2 -2
  137. package/dist/Toolbar/index.js +2 -2
  138. package/dist/{Toolbar-IP6LXN45.css → Toolbar-HUOSMNTH.css} +3 -1
  139. package/dist/Tooltip/index.js +2 -2
  140. package/dist/Tree/index.d.ts +2 -2
  141. package/dist/Tree/index.js +1 -1
  142. package/dist/Tree/layout.d.ts +103 -28
  143. package/dist/TreeCanvas/TreeCanvas.d.ts +60 -14
  144. package/dist/TreeCanvas/index.d.ts +1 -1
  145. package/dist/TreeCanvas/index.js +6 -6
  146. package/dist/TreeCanvas/motion.d.ts +3 -2
  147. package/dist/{TreeCanvas-WBNQPHC7.css → TreeCanvas-HVOV4SQN.css} +154 -30
  148. package/dist/TreeGrid/index.js +4 -4
  149. package/dist/{chunk-F6OE5FH3.js → chunk-2FPENTCF.js} +1 -1
  150. package/dist/chunk-4AK52VHB.js +88 -0
  151. package/dist/{chunk-7EM5T4ME.js → chunk-4IQD3HUQ.js} +2 -2
  152. package/dist/{chunk-YODNNSZL.js → chunk-4PZ6FJKW.js} +43 -13
  153. package/dist/{chunk-F27EPQ7D.js → chunk-4UQ7SMPK.js} +1 -1
  154. package/dist/chunk-5QWIJSQM.js +73 -0
  155. package/dist/{chunk-GTOUGQQK.js → chunk-6MU7HNB4.js} +13 -10
  156. package/dist/{chunk-S2XHHEW4.js → chunk-74KMX7YH.js} +4 -4
  157. package/dist/{chunk-WNI2WSJF.js → chunk-7KBNFFM3.js} +1 -1
  158. package/dist/{chunk-DD5BBGBE.js → chunk-AUS5FNQE.js} +9 -5
  159. package/dist/{chunk-CMEE37QJ.js → chunk-BMYPGGPV.js} +4 -4
  160. package/dist/{chunk-H4FBTAYS.js → chunk-BNCCEER3.js} +8 -8
  161. package/dist/chunk-C5WJUZVR.js +56 -0
  162. package/dist/{chunk-5WS6L6FA.js → chunk-CAIHUYXV.js} +9 -9
  163. package/dist/{chunk-XV6WRMBC.js → chunk-CQY5NTRS.js} +4 -1
  164. package/dist/{chunk-UOGSZKLT.js → chunk-D6EVJUGU.js} +2 -2
  165. package/dist/{chunk-6ZFVFA56.js → chunk-DHPUMOTX.js} +2 -2
  166. package/dist/{chunk-HZ5XZNPS.js → chunk-DS2C73RJ.js} +3 -3
  167. package/dist/{chunk-O6232G37.js → chunk-DSUY5F4E.js} +17 -5
  168. package/dist/{chunk-Q4ZPPART.js → chunk-EFYPAJT3.js} +3 -3
  169. package/dist/{chunk-WQX73TWF.js → chunk-ERVO6OUF.js} +18 -17
  170. package/dist/{chunk-BZYDZBAN.js → chunk-ETYEBKR4.js} +3 -3
  171. package/dist/{chunk-34VGEDVV.js → chunk-FD5UEN6X.js} +30 -30
  172. package/dist/{chunk-5SDBMKUO.js → chunk-FIFNP6PL.js} +3 -3
  173. package/dist/{chunk-7HPRF5XN.js → chunk-FUF52K7E.js} +98 -16
  174. package/dist/{chunk-5KPQ6D7N.js → chunk-FZVJDJFN.js} +2 -2
  175. package/dist/chunk-IA232OTU.js +156 -0
  176. package/dist/{chunk-2EOKFKHX.js → chunk-IG27QX7Q.js} +7 -7
  177. package/dist/chunk-IKB6HFGK.js +55 -0
  178. package/dist/{chunk-FBZAKNSX.js → chunk-IPVQKAHO.js} +10 -7
  179. package/dist/{chunk-3EYF6HKB.js → chunk-IVFJD7WY.js} +28 -9
  180. package/dist/{chunk-WOYYD2YR.js → chunk-JGRNTBF2.js} +11 -11
  181. package/dist/chunk-K3OWD7BJ.js +121 -0
  182. package/dist/{chunk-BJSKPEZI.js → chunk-KD4H66L6.js} +7 -20
  183. package/dist/{chunk-SFZOKW2G.js → chunk-KJ34ZBBI.js} +8 -3
  184. package/dist/{chunk-HQNHV7D6.js → chunk-LFHCXZO5.js} +6 -6
  185. package/dist/{chunk-LWKJQTOM.js → chunk-MICH6QSJ.js} +1 -1
  186. package/dist/chunk-N3DPO6HG.js +226 -0
  187. package/dist/{chunk-S4GZWSKR.js → chunk-OM5E3TTK.js} +1 -1
  188. package/dist/{chunk-3QRYCPXQ.js → chunk-OPKIKM35.js} +6 -6
  189. package/dist/{chunk-5EKIWVOR.js → chunk-PGRPNDWM.js} +2 -2
  190. package/dist/{chunk-LFJ6UJTI.js → chunk-PQNILU27.js} +9 -9
  191. package/dist/{chunk-QNCVHRZL.js → chunk-QVAFL2LE.js} +1 -1
  192. package/dist/{chunk-QEUY3A5P.js → chunk-QY7UU5ZB.js} +3 -2
  193. package/dist/{chunk-ITHXJHBB.js → chunk-R25RGPUB.js} +1 -0
  194. package/dist/{chunk-KLJCCMF3.js → chunk-R6735B37.js} +2 -2
  195. package/dist/{chunk-3ZP55QZE.js → chunk-R6FBDTP3.js} +4 -4
  196. package/dist/{chunk-7FZ53WDJ.js → chunk-RIAZM6L3.js} +1 -1
  197. package/dist/chunk-RJM4QCGG.js +550 -0
  198. package/dist/{chunk-NTRZGNEX.js → chunk-S3BCVWTU.js} +215 -46
  199. package/dist/chunk-S7KW47IQ.js +121 -0
  200. package/dist/{chunk-OFHBK7RI.js → chunk-SJQ546ID.js} +34 -14
  201. package/dist/{chunk-D35VTV2Z.js → chunk-SV7QAONL.js} +1 -1
  202. package/dist/{chunk-IAJLHVUA.js → chunk-TIWAHZZ6.js} +1 -1
  203. package/dist/{chunk-2PRH365R.js → chunk-UA7O3KKJ.js} +1 -1
  204. package/dist/{chunk-NPZY6YYL.js → chunk-UG5ZMAXW.js} +6 -6
  205. package/dist/{chunk-FEFTGVMF.js → chunk-V2N3BMOT.js} +7 -2
  206. package/dist/{chunk-NDCATSW7.js → chunk-V34H2YCY.js} +1 -1
  207. package/dist/chunk-WIATRXEJ.js +22 -0
  208. package/dist/{chunk-5C5YMZQU.js → chunk-WOFOMTGB.js} +16 -10
  209. package/dist/{chunk-QYOFACSP.js → chunk-WSOFKOLP.js} +3 -3
  210. package/dist/{chunk-MNAXYY3R.js → chunk-WUVZDFHS.js} +31 -11
  211. package/dist/{chunk-UG46QBLT.js → chunk-YIMOT5OO.js} +10 -10
  212. package/dist/{chunk-2ZQMA2WB.js → chunk-ZPSOF6VL.js} +2 -2
  213. package/dist/generated/index.d.ts +3 -0
  214. package/dist/generated/index.js +66 -62
  215. package/dist/index.js +66 -62
  216. package/dist/styles.css +2719 -799
  217. package/dist/utils/index.d.ts +1 -1
  218. package/dist/utils/tone.d.ts +7 -12
  219. package/package.json +4 -4
  220. package/scripts/check-css-literals.mjs +159 -23
  221. package/scripts/check-css-variables.mjs +5 -3
  222. package/scripts/css-source.mjs +97 -5
  223. package/dist/Avatar-P2KRQM2B.css +0 -156
  224. package/dist/Charts-D7G2BSXH.css +0 -277
  225. package/dist/CommandPalette-CSJDUCQA.css +0 -115
  226. package/dist/Kbd-W66MXQI5.css +0 -61
  227. package/dist/SearchTrigger-QXOYAUUY.css +0 -79
  228. package/dist/SidebarNav-QGSFKZYA.css +0 -319
  229. package/dist/StatCard-KYPKZUWX.css +0 -111
  230. package/dist/StatusDot-HA2L2FSX.css +0 -84
  231. package/dist/chunk-22O7LAW2.js +0 -41
  232. package/dist/chunk-2HQR4U4D.js +0 -143
  233. package/dist/chunk-ESCO4XYW.js +0 -144
  234. package/dist/chunk-F4PJZ4ED.js +0 -245
  235. package/dist/chunk-PNFASD6F.js +0 -98
  236. package/dist/chunk-PZSWF74H.js +0 -15
  237. /package/dist/{chunk-ZCR6YGQ4.js → chunk-PKIN4IMB.js} +0 -0
@@ -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. */
@@ -31,7 +31,10 @@
31
31
  .crewlet-tree-canvas__card,
32
32
  .crewlet-tree-canvas__links,
33
33
  .crewlet-tree-canvas__gap,
34
- .crewlet-tree-canvas__margin {
34
+ .crewlet-tree-canvas__margin,
35
+ .crewlet-tree-canvas__group,
36
+ .crewlet-tree-canvas__group-head,
37
+ .crewlet-tree-canvas__group-pad {
35
38
  position: absolute;
36
39
  top: 0;
37
40
  left: 0;
@@ -170,15 +173,6 @@
170
173
  --crewlet-tree-canvas-card-accent: var(--color-node-blue);
171
174
  }
172
175
 
173
- /*
174
- * A card that stands for somebody outside the system takes the dashed edge
175
- * every such seat wears. The BOUNDARY says it rather than a hue, so it reads
176
- * to somebody who cannot separate the hue at all.
177
- */
178
- .crewlet-tree-canvas__card--outline {
179
- border-style: dashed;
180
- }
181
-
182
176
  /*
183
177
  * THE NODES INSIDE THE CARD. `role="treeitem"` is this component's own
184
178
  * contract, handed to the caller by `ctx.item(id)`, so the inset a node sits
@@ -338,13 +332,13 @@
338
332
  /*
339
333
  * A reveal is a state change rather than an entrance, so under reduced motion
340
334
  * it simply happens. The control is still shown and still reached the same way.
335
+ * The `node` appearance's own quiet controls are stopped in its own section,
336
+ * below the rules that start them: named here, above those rules, the stops
337
+ * tied with them on specificity and lost on source order.
341
338
  */
342
339
  @media (prefers-reduced-motion: reduce) {
343
340
  .crewlet-tree-canvas__actions,
344
- .crewlet-tree-canvas__under,
345
- .crewlet-tree-canvas--node .crewlet-tree-canvas__under > :not(.crewlet-add-pill),
346
- .crewlet-tree-canvas--node .crewlet-org-node__leading,
347
- .crewlet-tree-canvas--node .crewlet-org-node-lead__clear {
341
+ .crewlet-tree-canvas__under {
348
342
  transition: none;
349
343
  }
350
344
  }
@@ -376,6 +370,92 @@
376
370
  pointer-events: none;
377
371
  }
378
372
 
373
+ /* ---------------------------------------------------------------------------
374
+ * A GROUP: a box round a run of sibling cards, with a label along its top.
375
+ *
376
+ * The approved design's unit box: a hairline on the card rung with the unit's
377
+ * name in the tertiary ink at 12px, and the project key chip at the end of
378
+ * that line. The hairline is `--color-border-default` over
379
+ * `--color-surface-subtle` standing on the canvas's own ground, which is the
380
+ * pair the palette suite already holds to a visible step (the card hairline
381
+ * rule); a card inside the box is the same rung and is found by its own
382
+ * hairline, exactly as a card on a sheet is.
383
+ *
384
+ * THE ROOM IS THE LAYOUT'S. The padding round the members is the probe below,
385
+ * and the room above them is the header's own measured height, so the box is
386
+ * never drawn over a card it does not hold and a branch is never run through
387
+ * it: both are reserved by `layoutForest` before anything is placed.
388
+ * ------------------------------------------------------------------------- */
389
+
390
+ /*
391
+ * The room beside and below a group's members, as a token: `--spacing-3`,
392
+ * which is also the label's own inset, so the label starts on the line the
393
+ * first member's edge does.
394
+ */
395
+ .crewlet-tree-canvas__group-pad {
396
+ width: var(--spacing-3);
397
+ height: var(--spacing-3);
398
+ visibility: hidden;
399
+ pointer-events: none;
400
+ }
401
+
402
+ /*
403
+ * THE BOX IS DASHED, as the approved org chart draws a unit: a card's own
404
+ * edge is solid, and a box round several cards drawn the same way read as one
405
+ * more, larger card. A dash says the edge is a grouping rather than a thing.
406
+ * It is the STRONG border step, the artboard's, because a dash spends half its
407
+ * length on gaps: at the plain hairline's step the edge all but disappeared
408
+ * against the box's own fill.
409
+ */
410
+ .crewlet-tree-canvas__group {
411
+ box-sizing: border-box;
412
+ background: var(--color-surface-subtle);
413
+ border: 1px dashed var(--color-border-strong);
414
+ border-radius: var(--radius-xl);
415
+ pointer-events: none;
416
+ }
417
+
418
+ /*
419
+ * THE LABEL'S LINE, and what the room above the members is measured from: one
420
+ * line, at the box's width, truncated rather than wrapped, because a label
421
+ * that wrapped would move every rank below it.
422
+ */
423
+ .crewlet-tree-canvas__group-head {
424
+ box-sizing: border-box;
425
+ display: flex;
426
+ align-items: center;
427
+ gap: var(--spacing-2);
428
+ padding: var(--spacing-2) var(--spacing-3);
429
+ font-size: var(--font-size-xs);
430
+ line-height: var(--font-line-height-snug);
431
+ color: var(--color-text-tertiary);
432
+ white-space: nowrap;
433
+ pointer-events: none;
434
+ }
435
+
436
+ /*
437
+ * ON THE BOX'S OWN FILL, over the branches: a branch dropping into a member
438
+ * passes behind the words rather than striking through them, and the fill is
439
+ * the box's, so nothing about the label reads as a second surface.
440
+ */
441
+ .crewlet-tree-canvas__group-label,
442
+ .crewlet-tree-canvas__group-lead {
443
+ background: var(--color-surface-subtle);
444
+ }
445
+
446
+ .crewlet-tree-canvas__group-label {
447
+ min-width: 0;
448
+ overflow: hidden;
449
+ text-overflow: ellipsis;
450
+ }
451
+
452
+ /* The key AHEAD of the name, a project key chip, never cut: the name after
453
+ it is what gives way when the line is short. */
454
+ .crewlet-tree-canvas__group-lead {
455
+ display: inline-flex;
456
+ flex: none;
457
+ }
458
+
379
459
  /* ---------------------------------------------------------------------------
380
460
  * THE CHART ARRIVING, AND REARRANGING.
381
461
  *
@@ -392,11 +472,16 @@
392
472
  * ------------------------------------------------------------------------- */
393
473
 
394
474
  .crewlet-tree-canvas__card[data-enter='waiting'],
395
- .crewlet-tree-canvas__links path[data-enter='waiting'] {
475
+ .crewlet-tree-canvas__links path[data-enter='waiting'],
476
+ .crewlet-tree-canvas__group[data-enter='waiting'],
477
+ .crewlet-tree-canvas__group-head[data-enter='waiting'] {
396
478
  opacity: 0;
397
479
  }
398
480
 
399
- .crewlet-tree-canvas__card[data-enter='shown'] {
481
+ /* A group arrives with its first member, at the card's pace. */
482
+ .crewlet-tree-canvas__card[data-enter='shown'],
483
+ .crewlet-tree-canvas__group[data-enter='shown'],
484
+ .crewlet-tree-canvas__group-head[data-enter='shown'] {
400
485
  animation: crewlet-tree-canvas-arrive var(--motion-duration-slow) var(--motion-easing-default) both;
401
486
  }
402
487
 
@@ -422,9 +507,20 @@
422
507
  * when the setting changed.
423
508
  */
424
509
  @media (prefers-reduced-motion: reduce) {
510
+ /* Drawn, whatever step of the entrance it had reached: a card still WAITING
511
+ is otherwise held at nothing. */
425
512
  .crewlet-tree-canvas__card[data-enter],
426
- .crewlet-tree-canvas__links path[data-enter] {
513
+ .crewlet-tree-canvas__links path[data-enter],
514
+ .crewlet-tree-canvas__group[data-enter],
515
+ .crewlet-tree-canvas__group-head[data-enter] {
427
516
  opacity: 1;
517
+ }
518
+
519
+ /* And the entrance stopped by the selectors that start it. */
520
+ .crewlet-tree-canvas__card[data-enter='shown'],
521
+ .crewlet-tree-canvas__links path[data-enter='shown'],
522
+ .crewlet-tree-canvas__group[data-enter='shown'],
523
+ .crewlet-tree-canvas__group-head[data-enter='shown'] {
428
524
  animation: none;
429
525
  }
430
526
  }
@@ -436,10 +532,11 @@
436
532
 
437
533
  /*
438
534
  * THE CONNECTORS ARE THE CONTENT, and they take the step that is measured to
439
- * be resolvable. The SHAPE is `layoutConnectors`, which draws a rounded step
440
- * from each parent's bottom into each child's top; what is decided here is only
441
- * how dark it is, and that the joins are round so a corner reads as a turn
442
- * rather than as two lines meeting.
535
+ * be resolvable. The SHAPE is `layoutConnectors`, which draws an orthogonal
536
+ * elbow from each parent's bottom into each child's top, in SVG attributes
537
+ * the layout computes rather than in a style a policy has to allow; what is
538
+ * decided here is only how dark and how heavy it is, and that the joins are
539
+ * round so a corner reads as a turn rather than as two lines meeting.
443
540
  *
444
541
  * A connector is the only thing on the chart that says who reports to whom:
445
542
  * remove it and the picture is a scatter of cards. That makes it a graphical
@@ -450,11 +547,22 @@
450
547
  * boundary step, which the palette suite already holds at 3:1 on every ground,
451
548
  * measures 4.83:1 and 4.78:1. Darker than the chart this is drawn from, and
452
549
  * deliberately: there the hierarchy was a line a reader had to hunt for.
550
+ *
551
+ * THE APPROVED DESIGN DRAWS IT IN `--color-border-strong`, AND THE FLOOR WINS.
552
+ * The artboard's connector is the strong border step at 1.5px, and on the
553
+ * canvas's ground that step measures 1.45:1 in dark and 1.43:1 in light (1.40
554
+ * and 1.50 on a group box's card rung): a line a reader cannot make out, for
555
+ * the one mark that says who reports to whom. The palette suite's data-mark
556
+ * table holds a chart's connector to 3:1 on `--color-border-control`, so the
557
+ * value moves up the border family to the first step that clears it, 4.40:1
558
+ * and 4.04:1 (4.25 and 4.26 on the card rung). The WEIGHT is the design's:
559
+ * 1.5px, heavier than the hairline this used to be, so a branch between two
560
+ * ranks of 90px cards reads as a line of the chart rather than as a seam.
453
561
  */
454
562
  .crewlet-tree-canvas__links path {
455
563
  fill: none;
456
564
  stroke: var(--color-border-control);
457
- stroke-width: 1;
565
+ stroke-width: 1.5;
458
566
  stroke-linecap: round;
459
567
  stroke-linejoin: round;
460
568
  }
@@ -829,6 +937,20 @@
829
937
  pointer-events: auto;
830
938
  }
831
939
 
940
+ /*
941
+ * The node's quiet controls arrive as a state change too, so under reduced
942
+ * motion they simply appear. Stopped HERE, after the rules that start their
943
+ * fades: the three selectors tie with those rules on specificity, so the stop
944
+ * has to come later in the file to win.
945
+ */
946
+ @media (prefers-reduced-motion: reduce) {
947
+ .crewlet-tree-canvas--node .crewlet-tree-canvas__under > :not(.crewlet-add-pill),
948
+ .crewlet-tree-canvas--node .crewlet-org-node__leading,
949
+ .crewlet-tree-canvas--node .crewlet-org-node-lead__clear {
950
+ transition: none;
951
+ }
952
+ }
953
+
832
954
  /*
833
955
  * THE BRANCHES ARE HEAVIER HERE. A node is half the height of a card, so a
834
956
  * hairline between two ranks of them is a thread; this is the console chart's
@@ -929,12 +1051,11 @@
929
1051
  * chart this package is drawn to match does exactly this, and every step below
930
1052
  * is its step.
931
1053
  *
932
- * IT IS THE ONLY DASHED THING ON THE CHART THAT IS NOT A HUMAN SEAT, and the
933
- * two never collide: `cardOutline` marks a node of the data and this marks a
934
- * node that is not one yet, so no card can carry both. What tells them apart
935
- * is the hue and the breath: a human seat's edge is the chart's own boundary
936
- * step and does not move, and this one is the accent, with a ring outside it
937
- * that pulses for as long as the form is open.
1054
+ * IT IS THE ONLY DASHED CARD ON THE CHART, because a dashed edge marks a
1055
+ * place nothing fills yet and this is the one card that is not a node of the
1056
+ * data. Every node's card is solid, a person's seat included: who holds a seat
1057
+ * is its badge's outline, never the card's frame, which is why the chart has
1058
+ * no second dashed card for a person to be confused with this one.
938
1059
  *
939
1060
  * ITS GROUND IS EVERY OTHER CARD'S. The ghost holds a real form with real
940
1061
  * labels, helps and refusals in it, so it is NOT tinted: every contrast
@@ -1078,8 +1199,11 @@
1078
1199
  @media (prefers-reduced-motion: reduce) {
1079
1200
  /* NOT `transform` on the card itself: its transform is where the layout
1080
1201
  put it, written as an inline style, and a rule here saying `none` would
1081
- be a rule that only ever fires when something else drops that style. */
1082
- .crewlet-tree-canvas__card--composing,
1202
+ be a rule that only ever fires when something else drops that style.
1203
+ Named with the chart's class, as the rule that starts its arrival names
1204
+ it: by its own class alone the stop was one class short of that rule,
1205
+ and the arrival played for a reader who had asked for none. */
1206
+ .crewlet-tree-canvas .crewlet-tree-canvas__card--composing,
1083
1207
  .crewlet-tree-canvas__links path[data-composing='true'] {
1084
1208
  opacity: 1;
1085
1209
  animation: none;
@@ -1,8 +1,8 @@
1
- export { TreeGrid } from '../chunk-5SDBMKUO.js';
2
- import '../chunk-NTRZGNEX.js';
1
+ export { TreeGrid } from '../chunk-FIFNP6PL.js';
2
+ import '../chunk-S3BCVWTU.js';
3
3
  import '../chunk-53DVJCVW.js';
4
4
  import '../chunk-7RPGY3JE.js';
5
- import '../chunk-ITHXJHBB.js';
6
- import '../chunk-F27EPQ7D.js';
5
+ import '../chunk-R25RGPUB.js';
6
+ import '../chunk-4UQ7SMPK.js';
7
7
  import '../chunk-BZFWDIV6.js';
8
8
  import '../chunk-ODEQTPFM.js';
@@ -1,4 +1,4 @@
1
- import { isComposing, isModalLayerOpen } from './chunk-ITHXJHBB.js';
1
+ import { isComposing, isModalLayerOpen } from './chunk-R25RGPUB.js';
2
2
  import { useRef, useEffect } from 'react';
3
3
 
4
4
  var TYPING_ROLES = /* @__PURE__ */ new Set(["combobox", "listbox", "textbox", "searchbox", "spinbutton"]);