@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,319 +0,0 @@
1
- /*
2
- * The rail's navigation.
3
- *
4
- * ONE VERTICAL LINE. The rail pads by --size-nav-gutter and each row pads by
5
- * --size-nav-row-pad, so the mark, the group labels and every row's text start
6
- * on the same line: shrink the gutter and grow the pad by the same step and
7
- * nothing moves. That is why the row's own background takes the full width the
8
- * gutter leaves it, rather than each row carrying a horizontal margin of its
9
- * own.
10
- */
11
-
12
- .crewlet-sidebar-nav {
13
- display: flex;
14
- flex-direction: column;
15
- gap: var(--spacing-1);
16
- min-width: 0;
17
- padding: var(--spacing-2) var(--size-nav-gutter) var(--spacing-4);
18
- }
19
-
20
- /*
21
- * THE ROWS INSIDE A GROUP ARE FLUSH. A group is a run of destinations read as
22
- * one block, and the space between two of them is already the row's own height
23
- * against a 13px line; a step on top of that spends four pixels a rail cannot
24
- * afford fifteen times over. It is what the group LABEL's bottom pad is for,
25
- * and the rail's own gap between groups is what separates one run from the
26
- * next.
27
- *
28
- * Measured rather than chosen: at one step per row the rail stood 823px in a
29
- * 755px scroller, so the last two destinations in the product were reachable
30
- * only by scrolling the rail. Flush it is 746px and every row is on screen.
31
- */
32
- .crewlet-nav-group {
33
- display: flex;
34
- flex-direction: column;
35
- gap: var(--spacing-0);
36
- min-width: 0;
37
- }
38
-
39
- .crewlet-nav-group__label {
40
- padding: var(--spacing-3) var(--size-nav-row-pad) var(--spacing-1);
41
- font-family: var(--font-family-sans);
42
- font-size: var(--font-size-2xs);
43
- font-weight: var(--font-weight-medium);
44
- /* The rail's own micro-label register, which is one step tighter than the
45
- wider step an Eyebrow takes: a group name here sits four pixels above the
46
- row it names, and at the wider step "OPERATIONS" was visibly broader than
47
- the rows beneath it rather than quieter than them. */
48
- letter-spacing: var(--font-letter-spacing-wide);
49
- text-transform: uppercase;
50
- /* The 4.5:1 step: a group name is a fact a reader has to read, not
51
- decoration. */
52
- color: var(--color-text-tertiary);
53
- }
54
-
55
- .crewlet-nav-item {
56
- min-width: 0;
57
- }
58
-
59
- .crewlet-nav-item__head {
60
- display: flex;
61
- align-items: center;
62
- gap: var(--spacing-1);
63
- min-width: 0;
64
- }
65
-
66
- .crewlet-nav-item__row {
67
- display: flex;
68
- align-items: center;
69
- gap: var(--spacing-2);
70
- flex: 1 1 auto;
71
- min-width: 0;
72
- width: 100%;
73
- min-height: var(--size-row-md);
74
- padding: 0 var(--size-nav-row-pad);
75
- border: none;
76
- /* The chrome's radius, not a card's. A 12px corner on a 36px row leaves the
77
- tint reading as a lozenge floating in the gutter rather than as a band the
78
- width of the rail. */
79
- border-radius: var(--radius-md);
80
- background: transparent;
81
- /*
82
- * THE RAIL READS AT FULL INK. A destination is not secondary text: a rail of
83
- * fifteen rows in the quiet step is a column of grey a reader has to hunt
84
- * through, and the step down bought nothing the row's own tint does not
85
- * already say. It is also the darker of the two on light and the lighter on
86
- * dark, so the contrast on every ground the row can have goes up rather than
87
- * down.
88
- *
89
- * WHAT CARRIES HOVER IS THEREFORE THE TINT, not an ink step: there is no
90
- * step left above this one. The glyph is the second half of it, lifting from
91
- * the decoration ramp to the row's own ink.
92
- */
93
- color: var(--color-text-primary);
94
- font-family: var(--font-family-sans);
95
- /* THE CHROME IS NOT BODY TEXT. A rail row names a destination; it is read at
96
- a glance and never read through, so it takes the compact step in the
97
- medium weight, which is what keeps a one-word row legible at 13px. */
98
- font-size: var(--font-size-compact);
99
- font-weight: var(--font-weight-medium);
100
- letter-spacing: var(--font-letter-spacing-snug);
101
- line-height: var(--font-line-height-tight);
102
- text-align: left;
103
- text-decoration: none;
104
- cursor: pointer;
105
- transition:
106
- background var(--motion-duration-fast) var(--motion-easing-default),
107
- color var(--motion-duration-fast) var(--motion-easing-default);
108
- }
109
-
110
- .crewlet-nav-item__row:hover {
111
- background: var(--color-surface-hover);
112
- text-decoration: none;
113
- }
114
-
115
- .crewlet-nav-item__row:focus-visible {
116
- outline: 2px solid var(--color-focus);
117
- /* Inside the row's own box: the rail is a clipping scroller, so an outset
118
- ring on the first or last row is cut off by it. */
119
- outline-offset: var(--size-focus-ring-inset-offset);
120
- }
121
-
122
- /*
123
- * WHERE THE READER IS: the accent's own soft tint, with the label and the
124
- * glyph in the accent ink. That is the whole job of an accent in a chrome, and
125
- * the rail is the one place in the chrome it appears.
126
- *
127
- * It was a neutral lift with the accent as a one-pixel bar outside the row's
128
- * left edge, on the reading that accent text in a rail competes with the
129
- * status hues beside it and cannot be separated from the row above by a reader
130
- * with a colour vision deficiency. Neither holds here. Nothing in this rail
131
- * carries a status hue except the attention count below, which is a tint
132
- * BEHIND a word rather than a word in a hue; and the tint is what answers the
133
- * second objection, because the row still lifts off its ground by more than a
134
- * hovered one does whether or not the hue is seen at all (@crewlethq/tokens
135
- * measures exactly that, and measures this ink on this composite: 5.76:1 in
136
- * light, 5.96:1 in dark).
137
- *
138
- * What the bar cost was that one pixel of hue was the entire signal, at the
139
- * one moment a reader is scanning the rail to find out where they are.
140
- *
141
- * Drawn from aria-current, so the picture and what a screen reader is told
142
- * cannot come apart. It is declared after :hover deliberately: both selectors
143
- * weigh the same, a row shows the current tint or the hover overlay and never
144
- * both, and later is what decides which.
145
- */
146
- .crewlet-nav-item__row[aria-current='page'] {
147
- background: var(--color-brand-accent-soft);
148
- color: var(--color-brand-accent-ink);
149
- }
150
-
151
- .crewlet-nav-item__row[aria-disabled='true'] {
152
- cursor: not-allowed;
153
- opacity: 0.55;
154
- }
155
-
156
- .crewlet-nav-item__row[aria-disabled='true']:hover {
157
- background: transparent;
158
- color: var(--color-text-primary);
159
- }
160
-
161
- /*
162
- * THE GLYPH FOLLOWS THE LABEL. At rest it is quieter than the word beside it
163
- * and takes the decoration step; on a hovered row and on the reader's own it
164
- * takes the row's own colour, which on the current row is the accent ink.
165
- *
166
- * ONE inherit rather than a second ramp, because a second ramp is how a row
167
- * comes to paint its label and its glyph two different answers to "where am
168
- * I". The colour is set on the DRAWING rather than on the box around it, which
169
- * is what says the decoration step is being spent on a glyph and not on text:
170
- * the package's variable check holds that rule, and it is the rule the step
171
- * exists for.
172
- */
173
- .crewlet-nav-item__icon {
174
- display: inline-flex;
175
- align-items: center;
176
- justify-content: center;
177
- flex: none;
178
- }
179
-
180
- .crewlet-nav-item__icon svg {
181
- color: var(--color-text-muted);
182
- transition: color var(--motion-duration-fast) var(--motion-easing-default);
183
- }
184
-
185
- .crewlet-nav-item__row:hover .crewlet-nav-item__icon svg,
186
- .crewlet-nav-item__row[aria-current='page'] .crewlet-nav-item__icon svg {
187
- color: inherit;
188
- }
189
-
190
- .crewlet-nav-item__label {
191
- flex: 1 1 auto;
192
- min-width: 0;
193
- overflow: hidden;
194
- text-overflow: ellipsis;
195
- white-space: nowrap;
196
- }
197
-
198
- .crewlet-nav-item__badge {
199
- display: inline-flex;
200
- align-items: center;
201
- flex: none;
202
- margin-left: auto;
203
- font-size: var(--font-size-2xs);
204
- font-variant-numeric: tabular-nums;
205
- color: var(--color-text-tertiary);
206
- }
207
-
208
- /*
209
- * THE SLOT IS WHAT PAINTS. A caller hands in the figure and the name a screen
210
- * reader reads after the row's own ("3 things waiting on somebody"); the rail
211
- * decides whether that is a quiet number at the end of the row or the one
212
- * thing on the screen that should pull the eye. So whatever arrives
213
- * contributes its text and its accessible name and nothing else, which is why
214
- * a <Count> here draws its own text rather than a second pill inside this one.
215
- */
216
- .crewlet-nav-item__badge > * {
217
- padding: 0;
218
- border: none;
219
- border-radius: 0;
220
- background: transparent;
221
- color: inherit;
222
- min-width: 0;
223
- font-size: inherit;
224
- font-weight: inherit;
225
- /* Not the `font` shorthand, which would reset font-variant and take the
226
- tabular figures with it. */
227
- font-variant-numeric: inherit;
228
- line-height: inherit;
229
- }
230
-
231
- /* A quiet badge takes the row's ink, the current row's accent included. The
232
- attention badge keeps its own, which is the whole point of it, and the
233
- :not() is what says so: both selectors would otherwise weigh the same and a
234
- tone would be decided by which rule a later edit happened to move. */
235
- .crewlet-nav-item__row[aria-current='page'] .crewlet-nav-item__badge:not(.crewlet-nav-item__badge--attention) {
236
- color: inherit;
237
- }
238
-
239
- /*
240
- * THE ONE BADGE IN THE CHROME ALLOWED A STATUS HUE. A count of what is waiting
241
- * on a person is the one thing that should pull the eye out of whatever screen
242
- * the reader is on, and it stays a tint BEHIND a word rather than a word in a
243
- * hue, so it reads to somebody who cannot separate the hue at all.
244
- *
245
- * Measured on every ground a row can have, the reader's own row included,
246
- * which is a warning tint on the accent tint on the rail: @crewlethq/tokens'
247
- * palette suite has that composite by name, at 5.08:1 in light and 9.75:1 in
248
- * dark.
249
- */
250
- .crewlet-nav-item__badge--attention {
251
- padding: 0 var(--spacing-2);
252
- border-radius: var(--radius-pill);
253
- background: var(--color-feedback-warning-soft);
254
- color: var(--color-feedback-warning-ink);
255
- font-weight: var(--font-weight-semibold);
256
- }
257
-
258
- .crewlet-nav-item__toggle {
259
- display: inline-flex;
260
- align-items: center;
261
- justify-content: center;
262
- flex: none;
263
- width: var(--size-control-sm);
264
- height: var(--size-control-sm);
265
- padding: 0;
266
- border: none;
267
- border-radius: var(--radius-sm);
268
- background: transparent;
269
- color: var(--color-text-tertiary);
270
- cursor: pointer;
271
- }
272
-
273
- .crewlet-nav-item__toggle:hover {
274
- background: var(--color-surface-hover);
275
- color: var(--color-text-primary);
276
- }
277
-
278
- .crewlet-nav-item__toggle:focus-visible {
279
- outline: 2px solid var(--color-focus);
280
- outline-offset: var(--size-focus-ring-inset-offset);
281
- }
282
-
283
- .crewlet-nav-item__chevron {
284
- display: inline-flex;
285
- transition: transform var(--motion-duration-fast) var(--motion-easing-default);
286
- }
287
-
288
- .crewlet-nav-item__chevron--open {
289
- transform: rotate(180deg);
290
- }
291
-
292
- /*
293
- * Nested rows carry an indent guide rather than more padding, because a run of
294
- * indents with no line is a hierarchy a reader has to measure by eye. The
295
- * guide takes the accent on the path the reader is on, which is the same
296
- * signal the top-level rail gives.
297
- */
298
- .crewlet-nav-item__children {
299
- display: flex;
300
- flex-direction: column;
301
- gap: var(--spacing-1);
302
- margin-left: var(--size-nav-row-pad);
303
- padding-left: var(--spacing-2);
304
- border-left: 1px solid var(--color-border-default);
305
- }
306
-
307
- /* No type step of its own any more: every row in the rail reads at the compact
308
- step now, and the indent guide is what says a row is nested. */
309
- .crewlet-nav-item__children:has(.crewlet-nav-item__row[aria-current='page']) {
310
- border-left-color: var(--color-brand-accent);
311
- }
312
-
313
- @media (prefers-reduced-motion: reduce) {
314
- .crewlet-nav-item__row,
315
- .crewlet-nav-item__icon svg,
316
- .crewlet-nav-item__chevron {
317
- transition: none;
318
- }
319
- }
@@ -1,111 +0,0 @@
1
- /*
2
- * The stat tile.
3
- *
4
- * THE TONE PAINTS THE VALUE, which is what the props always said and what the
5
- * stylesheet never did: 0.2.0 tinted the ICON, so a caller who passed a tone
6
- * and no icon got a tile identical to a neutral one. Ink only, and never a
7
- * fill: a tinted block behind a 24px number reads as a button.
8
- */
9
-
10
- .crewlet-statcard {
11
- display: flex;
12
- flex-direction: column;
13
- gap: var(--spacing-1);
14
- padding: var(--spacing-3) var(--spacing-4);
15
- /* The panel recipe: the surface, the hairline, the 12px corner and the
16
- elevation the engine gives every card on a screen, so a lone tile is the
17
- same object as the panel beside it rather than a flatter cousin. */
18
- background: var(--color-surface-subtle);
19
- border: 1px solid var(--color-border-default);
20
- border-radius: var(--radius-lg);
21
- box-shadow: var(--shadow-xs), var(--shadow-hairline);
22
- color: var(--color-text-primary);
23
- font-family: var(--font-family-sans);
24
- min-width: 0;
25
- }
26
-
27
- /* Inside a StatGroup the row is one card and the tiles are its columns, so a
28
- tile brings no surface of its own. */
29
- .crewlet-statcard--flush {
30
- background: transparent;
31
- border: 0;
32
- border-radius: var(--radius-none);
33
- box-shadow: none;
34
- }
35
-
36
- .crewlet-statcard__value {
37
- display: flex;
38
- align-items: baseline;
39
- gap: var(--spacing-2);
40
- min-width: 0;
41
- font-size: var(--font-size-2xl);
42
- font-weight: var(--font-weight-semibold);
43
- letter-spacing: var(--font-letter-spacing-tight);
44
- /* 1.1, the engine's, which is tighter than the tight step: a 24px number
45
- with 1.2 of leading sits low in its box and opens a gap between the value
46
- and the line under it that the 4px gap was already spending. */
47
- line-height: 1.1;
48
- /* A number that ticks up must not move the label under it. */
49
- font-variant-numeric: tabular-nums;
50
- overflow: hidden;
51
- text-overflow: ellipsis;
52
- white-space: nowrap;
53
- }
54
-
55
- .crewlet-statcard__unit {
56
- font-size: var(--font-size-sm);
57
- font-weight: var(--font-weight-regular);
58
- letter-spacing: var(--font-letter-spacing-normal);
59
- color: var(--color-text-tertiary);
60
- }
61
-
62
- /*
63
- * The placeholder is a line, not a pair of dashes. `--` is read aloud as
64
- * "dash dash" and looks exactly like a measured value of nothing; the tile
65
- * carries aria-busy instead, and the line says the number is on its way.
66
- */
67
- .crewlet-statcard__placeholder {
68
- display: inline-block;
69
- width: 3ch;
70
- height: 0.7em;
71
- border-radius: var(--radius-xs);
72
- background: var(--color-surface-inset);
73
- }
74
-
75
- .crewlet-statcard__label {
76
- display: flex;
77
- align-items: center;
78
- gap: var(--spacing-1);
79
- font-size: var(--font-size-2xs);
80
- font-weight: var(--font-weight-medium);
81
- letter-spacing: var(--font-letter-spacing-wide);
82
- text-transform: uppercase;
83
- color: var(--color-text-tertiary);
84
- min-width: 0;
85
- }
86
-
87
- .crewlet-statcard__icon {
88
- display: inline-flex;
89
- flex: none;
90
- }
91
-
92
- /*
93
- * The second line keeps its space whether or not there is one, so a row of
94
- * tiles where only some carry a sub still sits on one baseline.
95
- */
96
- .crewlet-statcard__sub {
97
- min-height: 1.2em;
98
- font-size: var(--font-size-xs);
99
- /* The quiet step, with the label. The sub qualifies the number rather than
100
- being a second one, and the engine keeps both of them a step under the
101
- value they belong to. */
102
- color: var(--color-text-tertiary);
103
- overflow: hidden;
104
- text-overflow: ellipsis;
105
- white-space: nowrap;
106
- }
107
-
108
- .crewlet-statcard--success .crewlet-statcard__value { color: var(--color-feedback-success-ink); }
109
- .crewlet-statcard--warning .crewlet-statcard__value { color: var(--color-feedback-warning-ink); }
110
- .crewlet-statcard--danger .crewlet-statcard__value { color: var(--color-feedback-danger-ink); }
111
- .crewlet-statcard--info .crewlet-statcard__value { color: var(--color-feedback-info-ink); }
@@ -1,84 +0,0 @@
1
- /*
2
- * The status dot: a 6px mark in its tone's fill, beside the word it belongs
3
- * to. See the component doc for why it is hidden from assistive technology.
4
- */
5
-
6
- .crewlet-status-dot {
7
- display: inline-block;
8
- width: 6px;
9
- height: 6px;
10
- border-radius: var(--radius-circle);
11
- /*
12
- * The quiet state is still a mark, so it takes the tertiary step rather than
13
- * the decoration one the engine spends here: a 6px dot has to clear 3:1 to
14
- * be seen at all, and --color-text-muted measures 2.33:1 on a light page and
15
- * 2.25:1 on a dark one at their worst grounds. The tertiary step measures
16
- * 4.87:1 and 4.65:1 on the same pair, and is the nearest step that holds.
17
- */
18
- background: var(--color-text-tertiary);
19
- flex: none;
20
- }
21
-
22
- .crewlet-status-dot--info {
23
- background: var(--color-feedback-info);
24
- }
25
-
26
- .crewlet-status-dot--success {
27
- background: var(--color-feedback-success);
28
- }
29
-
30
- .crewlet-status-dot--warning {
31
- background: var(--color-feedback-warning);
32
- }
33
-
34
- .crewlet-status-dot--danger {
35
- background: var(--color-feedback-danger);
36
- }
37
-
38
- .crewlet-status-dot--brand {
39
- background: var(--color-brand-accent);
40
- }
41
-
42
- .crewlet-status-dot--phase-onboarding {
43
- background: var(--color-phase-onboarding);
44
- }
45
-
46
- .crewlet-status-dot--phase-execute {
47
- background: var(--color-phase-execute);
48
- }
49
-
50
- .crewlet-status-dot--phase-review {
51
- background: var(--color-phase-review);
52
- }
53
-
54
- /*
55
- * Still happening. Three things are deliberate: the pulse never goes to
56
- * nothing, because a mark that disappears reads as a fault rather than as work
57
- * in progress; it alternates rather than sawtooths, so the mark comes back the
58
- * way it went; and the round trip is 1.8s, which is the engine's own breath
59
- * and is 0.55 flashes a second, well clear of the three that are a seizure
60
- * risk. Three of the slow step each way makes that round trip.
61
- */
62
- .crewlet-status-dot.is-pulsing {
63
- animation: crewlet-status-dot-pulse calc(var(--motion-duration-slow) * 3) var(--motion-easing-default) infinite
64
- alternate;
65
- }
66
-
67
- @keyframes crewlet-status-dot-pulse {
68
- from {
69
- opacity: 1;
70
- }
71
- to {
72
- opacity: 0.35;
73
- }
74
- }
75
-
76
- /*
77
- * A mark that cannot move should not pretend to. The dot still reads as its
78
- * tone, and the word beside it still says what is happening.
79
- */
80
- @media (prefers-reduced-motion: reduce) {
81
- .crewlet-status-dot.is-pulsing {
82
- animation: none;
83
- }
84
- }
@@ -1,41 +0,0 @@
1
- import { VisuallyHidden } from './chunk-BZFWDIV6.js';
2
- import { cx } from './chunk-ODEQTPFM.js';
3
- import './StatCard-KYPKZUWX.css';
4
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
-
6
- var StatCard = ({
7
- label,
8
- value,
9
- unit,
10
- sub,
11
- icon,
12
- tone = "neutral",
13
- loading = false,
14
- loadingLabel = "Loading",
15
- flush = false,
16
- className,
17
- ...rest
18
- }) => /* @__PURE__ */ jsxs(
19
- "div",
20
- {
21
- ...rest,
22
- className: cx("crewlet-statcard", `crewlet-statcard--${tone}`, flush && "crewlet-statcard--flush", className),
23
- "aria-busy": loading || void 0,
24
- children: [
25
- /* @__PURE__ */ jsxs("div", { className: "crewlet-statcard__label", children: [
26
- icon ? /* @__PURE__ */ jsx("span", { className: "crewlet-statcard__icon", "aria-hidden": true, children: icon }) : null,
27
- label
28
- ] }),
29
- /* @__PURE__ */ jsx("div", { className: "crewlet-statcard__value", children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
30
- /* @__PURE__ */ jsx("span", { className: "crewlet-statcard__placeholder", "aria-hidden": true }),
31
- /* @__PURE__ */ jsx(VisuallyHidden, { children: loadingLabel })
32
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
33
- value,
34
- unit ? /* @__PURE__ */ jsx("span", { className: "crewlet-statcard__unit", children: unit }) : null
35
- ] }) }),
36
- /* @__PURE__ */ jsx("div", { className: "crewlet-statcard__sub", children: sub })
37
- ]
38
- }
39
- );
40
-
41
- export { StatCard };
@@ -1,144 +0,0 @@
1
- import { useListbox } from './chunk-KIC7BZYJ.js';
2
- import { Input } from './chunk-GKHAKGOF.js';
3
- import { Modal } from './chunk-2EOKFKHX.js';
4
- import { cx } from './chunk-ODEQTPFM.js';
5
- import './CommandPalette-CSJDUCQA.css';
6
- import { useId, useMemo } from 'react';
7
- import { jsx, jsxs } from 'react/jsx-runtime';
8
-
9
- function CommandPalette({ open, ...rest }) {
10
- return open ? /* @__PURE__ */ jsx(Palette, { ...rest }) : null;
11
- }
12
- function Palette({
13
- onClose,
14
- label = "Search",
15
- query,
16
- onQueryChange,
17
- groups,
18
- placeholder = "Search",
19
- footer,
20
- emptyMessage = "Nothing matches that search.",
21
- resultsLabel = "Results",
22
- className,
23
- ...rest
24
- }) {
25
- const id = useId();
26
- const flat = useMemo(() => groups.flatMap((group) => group.items), [groups]);
27
- const listbox = useListbox({
28
- id,
29
- open: true,
30
- count: flat.length,
31
- popup: false,
32
- onCommit: (at) => {
33
- const item = flat[at];
34
- if (!item) return;
35
- item.onSelect();
36
- onClose();
37
- },
38
- onClose
39
- });
40
- const active = listbox.active;
41
- let index = -1;
42
- return /* @__PURE__ */ jsxs(
43
- Modal,
44
- {
45
- ...rest,
46
- open: true,
47
- onClose,
48
- placement: "top",
49
- size: "md",
50
- ariaLabel: label,
51
- showCloseButton: false,
52
- flush: true,
53
- className: cx("crewlet-palette", className),
54
- footerStart: footer,
55
- children: [
56
- /* @__PURE__ */ jsx(
57
- Input,
58
- {
59
- appearance: "command",
60
- containerClassName: "crewlet-palette__field",
61
- value: query,
62
- onChange: (event) => {
63
- onQueryChange(event.target.value);
64
- listbox.setActive(0);
65
- },
66
- onKeyDown: listbox.onKeyDown,
67
- placeholder,
68
- role: "combobox",
69
- "aria-label": label,
70
- "aria-expanded": true,
71
- "aria-controls": listbox.listId,
72
- "aria-autocomplete": "list",
73
- "aria-activedescendant": active >= 0 ? listbox.optionId(active) : void 0,
74
- autoComplete: "off",
75
- spellCheck: false
76
- }
77
- ),
78
- /* @__PURE__ */ jsx(
79
- "div",
80
- {
81
- className: "crewlet-palette__results",
82
- ref: listbox.listRef,
83
- id: listbox.listId,
84
- role: "listbox",
85
- "aria-label": resultsLabel,
86
- children: groups.map((group) => (
87
- // Named by the id of its own heading, never by the heading's text:
88
- // `aria-label` would repeat words already on screen, and
89
- // `aria-labelledby` given a name with a space in it splits on it.
90
- /* @__PURE__ */ jsxs("div", { role: "group", "aria-labelledby": `${id}-group-${group.id}`, children: [
91
- /* @__PURE__ */ jsx("div", { className: "crewlet-listbox__heading", id: `${id}-group-${group.id}`, role: "presentation", children: group.label }),
92
- group.items.map((item) => {
93
- index += 1;
94
- const mine = index;
95
- return (
96
- /*
97
- * NOT A BUTTON, and not focusable: focus never leaves the
98
- * field, so a row is reached by the arrows and by the pointer.
99
- *
100
- * The two rules turned off here are both asking for the shape
101
- * this pattern is defined NOT to have. A combobox points at its
102
- * active option with `aria-activedescendant`, which requires
103
- * that the option itself never take focus, and the keys that
104
- * take a row (Enter) are handled on the field, where the rule
105
- * cannot see them. Making a row focusable would put one tab
106
- * stop per result between the field and itself, which is the
107
- * defect this replaced. The axe run in the suite beside this
108
- * file is what actually holds the surface accessible.
109
- */
110
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/interactive-supports-focus
111
- /* @__PURE__ */ jsxs(
112
- "div",
113
- {
114
- id: listbox.optionId(mine),
115
- className: "crewlet-listbox__option",
116
- role: "option",
117
- "aria-selected": mine === active,
118
- onMouseEnter: listbox.optionHandlers(mine).onMouseEnter,
119
- onMouseDown: (event) => event.preventDefault(),
120
- onClick: () => {
121
- item.onSelect();
122
- onClose();
123
- },
124
- children: [
125
- item.icon !== void 0 ? /* @__PURE__ */ jsx("span", { className: "crewlet-palette__icon", "aria-hidden": "true", children: item.icon }) : null,
126
- /* @__PURE__ */ jsx("span", { className: "crewlet-palette__label", children: item.label }),
127
- item.hint !== void 0 ? /* @__PURE__ */ jsx("span", { className: "crewlet-listbox__hint", children: item.hint }) : null
128
- ]
129
- },
130
- item.id
131
- )
132
- );
133
- })
134
- ] }, group.id)
135
- ))
136
- }
137
- ),
138
- flat.length === 0 ? /* @__PURE__ */ jsx("p", { className: "crewlet-palette__empty", children: emptyMessage }) : null
139
- ]
140
- }
141
- );
142
- }
143
-
144
- export { CommandPalette };