@crewlethq/ui 0.4.4 → 0.5.1

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 +16 -16
  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 +70 -66
  209. package/dist/index.js +70 -66
  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
@@ -0,0 +1,112 @@
1
+ /*
2
+ * A button drawn as the field it stands in for.
3
+ *
4
+ * TWO PLACES, TWO GROUNDS. The approved design draws it in the rail, the
5
+ * whole width of the sidebar on the frame, and in a screen's own bar on the
6
+ * sheet. In each it is one rung up from what it stands on, the sheet on the
7
+ * frame and the card on the sheet, inside the default hairline, so it reads
8
+ * as a field sunk into neither and lifted off both.
9
+ */
10
+
11
+ .crewlet-search-trigger {
12
+ display: inline-flex;
13
+ align-items: center;
14
+ gap: var(--spacing-2);
15
+ /* The design's 10px inside each end: two steps and a half. */
16
+ padding: 0 calc(var(--spacing-2) + var(--spacing-1) / 2);
17
+ border: 1px solid var(--color-border-default);
18
+ border-radius: var(--radius-md);
19
+ color: var(--color-text-tertiary);
20
+ font-family: var(--font-family-sans);
21
+ font-size: var(--font-size-compact);
22
+ text-align: start;
23
+ cursor: pointer;
24
+ transition:
25
+ border-color var(--motion-duration-fast) var(--motion-easing-default),
26
+ color var(--motion-duration-fast) var(--motion-easing-default);
27
+ }
28
+
29
+ /*
30
+ * THE RAIL'S FIELD: the full width of the sidebar, on the SHEET's ground, and
31
+ * a step taller than a control. It is the rail's one field and the first
32
+ * thing in it under the company's name, and the design stands it at 34px,
33
+ * the medium control and one scale step, so it reads as the way in rather
34
+ * than as one more button.
35
+ */
36
+ .crewlet-search-trigger--rail {
37
+ display: flex;
38
+ width: 100%;
39
+ height: calc(var(--size-control-md) + var(--spacing-1));
40
+ background: var(--color-surface-background);
41
+ }
42
+
43
+ /*
44
+ * A SCREEN'S OWN SEARCH, in a bar on the sheet: the CARD's ground, the
45
+ * control height of the buttons beside it, and a resting width of its own.
46
+ */
47
+ .crewlet-search-trigger--toolbar {
48
+ /* The resting width of the box, the design's. A bar with less room sets it. */
49
+ --crewlet-search-trigger-width: 200px;
50
+
51
+ min-width: var(--crewlet-search-trigger-width);
52
+ height: var(--size-control-md);
53
+ background: var(--color-surface-subtle);
54
+ }
55
+
56
+ .crewlet-search-trigger:hover {
57
+ border-color: var(--color-border-hover);
58
+ color: var(--color-text-primary);
59
+ }
60
+
61
+ .crewlet-search-trigger:focus-visible {
62
+ outline: 2px solid var(--color-focus);
63
+ outline-offset: 2px;
64
+ }
65
+
66
+ .crewlet-search-trigger__icon {
67
+ display: inline-flex;
68
+ flex: none;
69
+ }
70
+
71
+ /* The glyph is quieter than the word beside it, on the decoration step, which
72
+ is the one thing that step is for. */
73
+ .crewlet-search-trigger__icon svg {
74
+ color: var(--color-text-muted);
75
+ }
76
+
77
+ /* The label takes the room, so the hint stands at the box's end. */
78
+ .crewlet-search-trigger__label {
79
+ flex: 1 1 auto;
80
+ min-width: 0;
81
+ overflow: hidden;
82
+ text-overflow: ellipsis;
83
+ white-space: nowrap;
84
+ }
85
+
86
+ /* The hint as a whole, so its keys stay together at the end of the box. */
87
+ .crewlet-search-trigger__shortcut {
88
+ display: inline-flex;
89
+ align-items: center;
90
+ margin-left: auto;
91
+ flex: none;
92
+ }
93
+
94
+ /* Under the shell's breakpoint, strictly, as the shell switches: a toolbar's
95
+ field collapses to its glyph where the rail becomes a drawer. The rail's
96
+ own field does not, because the drawer is as wide as the rail was. */
97
+ @media (width < 1024px) {
98
+ .crewlet-search-trigger--toolbar {
99
+ min-width: 0;
100
+ }
101
+
102
+ .crewlet-search-trigger--toolbar .crewlet-search-trigger__label,
103
+ .crewlet-search-trigger--toolbar .crewlet-search-trigger__shortcut {
104
+ display: none;
105
+ }
106
+ }
107
+
108
+ @media (prefers-reduced-motion: reduce) {
109
+ .crewlet-search-trigger {
110
+ transition: none;
111
+ }
112
+ }
@@ -1,5 +1,5 @@
1
- export { SegmentedControl } from '../chunk-7PEFUMQJ.js';
2
- import '../chunk-Q3B66TJM.js';
1
+ export { SegmentedControl } from '../chunk-DHPUMOTX.js';
2
+ import '../chunk-QY7UU5ZB.js';
3
3
  import '../chunk-BHHIIK3M.js';
4
4
  import '../chunk-BZFWDIV6.js';
5
5
  import '../chunk-ODEQTPFM.js';
@@ -0,0 +1,107 @@
1
+ import type { HTMLAttributes } from 'react';
2
+ import type { Tone } from '../utils/tone.js';
3
+ /**
4
+ * The states a part may be in: the four the approved design divides a crew or
5
+ * a project into. Info is working (or active), warning is waiting on a person,
6
+ * danger is stopped, success is done.
7
+ *
8
+ * NOT `neutral` and NOT `brand`. The quiet part of a whole, the idle seats or
9
+ * the work nobody has started, is the REMAINDER, which the meter draws itself
10
+ * from `total`; a neutral segment would be a second way to draw the same
11
+ * thing, and the two would sit side by side looking like one. The accent means
12
+ * "act here", and a share of a bar is not an action.
13
+ */
14
+ export type SegmentedMeterTone = Extract<Tone, 'info' | 'success' | 'warning' | 'danger'>;
15
+ /** One part of the whole. */
16
+ export interface SegmentedMeterSegment {
17
+ /** What tells two parts apart, unique within the meter: `working`, `done`. */
18
+ id: string;
19
+ /**
20
+ * How many. A finite number of at least 0, read as given ("4 working"), so a
21
+ * caller who needs a unit or a format names the whole meter with `label`. A
22
+ * part of 0 is neither drawn nor spoken.
23
+ */
24
+ value: number;
25
+ /** The state the part is in. */
26
+ tone: SegmentedMeterTone;
27
+ /** The word the count is read with: "working" in "4 working". */
28
+ label: string;
29
+ }
30
+ /**
31
+ * How the bar stands. `default` is the design's 8px state bar, the figure at
32
+ * the end of a stat tile's value line; `compact` is its 6px progress bar, the
33
+ * one a project row carries under its name, at the height of a `Meter`'s track.
34
+ */
35
+ export type SegmentedMeterSize = 'default' | 'compact';
36
+ export interface SegmentedMeterProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
37
+ /** The parts, in the order they are drawn from the leading end. */
38
+ segments: readonly SegmentedMeterSegment[];
39
+ /**
40
+ * The whole the parts belong to: seven seats, sixty-one tasks. What the
41
+ * parts leave of it is the REMAINDER, drawn after them in the quiet
42
+ * `--color-border-strong`. Without one the whole is the parts' own sum and
43
+ * there is no remainder.
44
+ *
45
+ * A total UNDER the parts' sum is not the whole of them. The bar cannot draw
46
+ * more than its length, so it draws the parts against their own sum, and the
47
+ * name keeps the figures it was given ("4 working, 3 waiting of 6"), as a
48
+ * `Meter` past its maximum keeps "140 of 100" rather than a bar that quietly
49
+ * rounds itself down to the limit it overran.
50
+ */
51
+ total?: number | undefined;
52
+ /**
53
+ * The word the remainder is read with: "idle" in "1 idle of 7". Without one
54
+ * the remainder is drawn and not named, and "of 7" still says there is more
55
+ * than the parts.
56
+ */
57
+ remainderLabel?: string | undefined;
58
+ size?: SegmentedMeterSize | undefined;
59
+ /**
60
+ * The accessible name, where the derived one ("4 working, 1 waiting, 1
61
+ * stopped, 1 idle of 7") is not what the bar means where it stands: a
62
+ * figure with a unit, or a count the caller formats.
63
+ */
64
+ label?: string | undefined;
65
+ /**
66
+ * The same figures are already written beside the bar, so it says nothing
67
+ * itself: a tile whose second line reads "1 waiting · 1 stopped · 1 idle"
68
+ * beside a bar that read out the same parts would say them twice.
69
+ */
70
+ decorative?: boolean | undefined;
71
+ }
72
+ /**
73
+ * What the bar says to somebody who cannot see it: every part it draws, in
74
+ * the order drawn, with its word, then the remainder when it has a word, then
75
+ * the whole. "4 working, 1 waiting, 1 stopped, 1 idle of 7".
76
+ *
77
+ * A PART OF 0 IS NOT SPOKEN, because it is not drawn: the name is the picture
78
+ * in words, and "0 stopped" would describe a segment nobody can see. A bar
79
+ * with nothing in it says "0 of 7".
80
+ */
81
+ export declare function segmentedMeterLabel(segments: readonly SegmentedMeterSegment[], total?: number, remainderLabel?: string): string;
82
+ /**
83
+ * A whole divided into the states its parts are in: how many seats are
84
+ * working, waiting, stopped and idle; how much of a project is done, active
85
+ * and still to do.
86
+ *
87
+ * EACH PART IS ITS SHARE OF THE BAR, and the shares add to the whole of it:
88
+ * each one's flex basis is its percentage of the whole, the remainder
89
+ * included, and the 2px gaps are taken out of them in proportion, so a part
90
+ * of 4 in 7 is 4/7 of the bar that is not gap. A part of 0 is not drawn at
91
+ * all, rather than drawn at no width: an empty box still takes a gap on each
92
+ * side, and its neighbours would stand 4px apart where every other pair
93
+ * stands 2px. No part is ever narrower than the kit's status dot, 7px, the
94
+ * smallest mark this kit asks a reader to tell by its hue, or than an equal
95
+ * share of the bar where so many parts would not fit at 7px: one stopped seat
96
+ * in sixty would otherwise be a sliver nobody could name.
97
+ *
98
+ * THE GAP IS WHAT SEPARATES TWO STATES, not a contrast between their fills:
99
+ * every fill is its tone's fill step, which the palette suite measures at 3:1
100
+ * as a mark on every opaque rung, and the ground shows between each pair.
101
+ *
102
+ * ONE IMAGE TO A SCREEN READER, named by `segmentedMeterLabel`, so the bar is
103
+ * read once as its figures rather than as five unlabelled shapes. It is not
104
+ * a `meter` role: that role carries ONE value against a range, and this is
105
+ * several.
106
+ */
107
+ export declare function SegmentedMeter({ segments, total, remainderLabel, size, label, decorative, className, style, ...rest }: SegmentedMeterProps): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import './SegmentedMeter.css';
2
+ export { SegmentedMeter, segmentedMeterLabel } from './SegmentedMeter.js';
3
+ export type { SegmentedMeterProps, SegmentedMeterSegment, SegmentedMeterSize, SegmentedMeterTone, } from './SegmentedMeter.js';
@@ -0,0 +1,2 @@
1
+ export { SegmentedMeter, segmentedMeterLabel } from '../chunk-4AK52VHB.js';
2
+ import '../chunk-ODEQTPFM.js';
@@ -0,0 +1,109 @@
1
+ /*
2
+ * The segmented meter: a whole divided into the states its parts are in
3
+ * (SegmentedMeter.tsx).
4
+ *
5
+ * THE APPROVED DESIGN'S STATE BAR. 8px tall with 2px between the parts, each
6
+ * part its tone's FILL step and the remainder the quiet --color-border-strong:
7
+ * "4 of 7 working" on the Home screen's first tile. The compact step is the
8
+ * design's 6px progress bar under a project's name, the height of a Meter's
9
+ * track. Both are the measure of one mark, fixed at every density, as a
10
+ * Meter's track and a status dot are: a bar read by its proportions does not
11
+ * shrink with the gaps around it.
12
+ *
13
+ * A FILL IS A MARK. Nothing is written on it, so it takes the fill step, which
14
+ * the palette suite in @crewlethq/tokens measures at 3:1 against every opaque
15
+ * rung, and the ground shows through the gap on either side of it: two states
16
+ * are told apart by the gap between them and by the hue each clears on the
17
+ * ground, never by a contrast between two fills, which no rule measures.
18
+ *
19
+ * THE REMAINDER IS THE EXTENT OF THE BAR, not a reading, as a Meter's track
20
+ * is: what is left of seven seats once four work, one waits and one has
21
+ * stopped. It is the strong hairline's colour, which stands dE 7.99 off its
22
+ * nearest rung (the light frame) and 17.19 off its farthest, far past the dE 3
23
+ * this kit holds every "can a reader notice it" difference to, so the whole is
24
+ * visible on any ground the bar is put on. It is quieter than a fill by design:
25
+ * the idle seats are the part of the picture nobody has to act on.
26
+ */
27
+
28
+ .crewlet-segmented-meter {
29
+ /* The gap between two parts, declared once because the width floor below
30
+ takes it out of the bar as well. */
31
+ --crewlet-segmented-meter-gap: 2px;
32
+ /* How many parts share the bar. The component sets it from the parts it
33
+ draws; one is what a bar that says nothing else holds. */
34
+ --crewlet-segmented-meter-count: 1;
35
+
36
+ display: flex;
37
+ gap: var(--crewlet-segmented-meter-gap);
38
+ height: 8px;
39
+ min-width: 0;
40
+ /*
41
+ * ROUND AT THE TWO ENDS AND SQUARE BETWEEN THE PARTS, which is the design's
42
+ * bar: the corner is the bar's, clipped, rather than each part's, so a part
43
+ * in the middle is a plain block and the ends are round whichever parts
44
+ * happen to stand there. The design writes 3px; the ramp's smallest step is
45
+ * --radius-xs, 4px, which is half the bar at both heights, so the ends are
46
+ * round.
47
+ */
48
+ border-radius: var(--radius-xs);
49
+ overflow: hidden;
50
+ }
51
+
52
+ .crewlet-segmented-meter--compact {
53
+ height: 6px;
54
+ }
55
+
56
+ /*
57
+ * A PART'S WIDTH IS ITS SHARE, set by the component as a flex basis in
58
+ * percent of the whole. The bases add to 100%, the gaps push the row past its
59
+ * box, and every part gives back in proportion to its basis, which is what
60
+ * flex-shrink at 1 does: each ends at its share of the bar less the gaps.
61
+ *
62
+ * THE FLOOR is the kit's 7px status dot, the smallest mark this kit asks a
63
+ * reader to tell by its hue: at its share alone one stopped seat in sixty is a
64
+ * sixth of a pixel. It yields to an equal share of the bar where so many parts
65
+ * are drawn that 7px each would not fit, so no part is ever pushed out of the
66
+ * end. A part held at the floor overstates its share, and the name says the
67
+ * exact figures.
68
+ */
69
+ .crewlet-segmented-meter__segment {
70
+ flex-grow: 0;
71
+ flex-shrink: 1;
72
+ min-width: min(
73
+ 7px,
74
+ calc(
75
+ (100% - (var(--crewlet-segmented-meter-count) - 1) * var(--crewlet-segmented-meter-gap)) /
76
+ var(--crewlet-segmented-meter-count)
77
+ )
78
+ );
79
+ height: 100%;
80
+ }
81
+
82
+ .crewlet-segmented-meter__segment[data-tone='info'] { background: var(--color-feedback-info); }
83
+ .crewlet-segmented-meter__segment[data-tone='success'] { background: var(--color-feedback-success); }
84
+ .crewlet-segmented-meter__segment[data-tone='warning'] { background: var(--color-feedback-warning); }
85
+ .crewlet-segmented-meter__segment[data-tone='danger'] { background: var(--color-feedback-danger); }
86
+
87
+ .crewlet-segmented-meter__remainder {
88
+ background: var(--color-border-strong);
89
+ }
90
+
91
+ /*
92
+ * FORCED COLORS. The mode repaints every author background to Canvas, so a bar
93
+ * drawn only in backgrounds disappears whole for exactly the reader who asked
94
+ * for more contrast, and a bar is read by its LENGTHS, which that reader needs
95
+ * as much as anybody. A system colour an author writes is kept, so the parts
96
+ * are drawn in CanvasText and the remainder in GrayText, the system's own
97
+ * pair for "there" and "quieter", and the gaps still stand between the parts.
98
+ * The hues go, as every hue does in this mode: the name says which part is
99
+ * which state.
100
+ */
101
+ @media (forced-colors: active) {
102
+ .crewlet-segmented-meter__segment[data-tone] {
103
+ background: CanvasText;
104
+ }
105
+
106
+ .crewlet-segmented-meter__remainder {
107
+ background: GrayText;
108
+ }
109
+ }
@@ -1,5 +1,5 @@
1
- export { Select } from '../chunk-KNYYCWMK.js';
2
- import '../chunk-KIC7BZYJ.js';
1
+ export { Select } from '../chunk-SJQ546ID.js';
2
+ import '../chunk-6MU7HNB4.js';
3
3
  import '../chunk-7RPGY3JE.js';
4
- import '../chunk-ITHXJHBB.js';
4
+ import '../chunk-R25RGPUB.js';
5
5
  import '../chunk-ODEQTPFM.js';
@@ -1,4 +1,4 @@
1
- export { matchesShortcut, useShortcut } from '../chunk-F6OE5FH3.js';
1
+ export { matchesShortcut, useShortcut } from '../chunk-2FPENTCF.js';
2
2
  import '../chunk-7RPGY3JE.js';
3
- import '../chunk-ITHXJHBB.js';
3
+ import '../chunk-R25RGPUB.js';
4
4
  import '../chunk-ODEQTPFM.js';
@@ -1,19 +1,29 @@
1
1
  /**
2
2
  * The rail's navigation: groups of rows, one of which says where the reader is.
3
3
  *
4
- * THE ROW THE READER IS ON IS THE ONE PLACE THE ACCENT APPEARS IN THE CHROME,
5
- * and it takes the accent twice over: the accent's soft tint as its ground,
6
- * and the accent ink for its label and its glyph. Position AND hue, so the row
7
- * is found at a glance by a reader who sees the hue and by one who does not.
4
+ * THE ROW THE READER IS ON IS RAISED, WITH A HAIRLINE ROUND IT, AND NO HUE: it
5
+ * is found by its position, its lift and its line, by a reader who sees
6
+ * colour and by one who does not. The accent is the primary action's fill, so
7
+ * a violet row in the rail would read as a second primary on every screen.
8
8
  * `aria-current="page"` says the same thing to a screen reader, and the style
9
9
  * is drawn FROM that attribute, so the two cannot come apart. The stylesheet
10
- * carries why this replaced a one-pixel accent bar outside the row's edge.
10
+ * carries why the hairline is an outline rather than a shadow.
11
11
  *
12
12
  * THE LINK ELEMENT BELONGS TO THE APPLICATION (`renderLink`). A router's own
13
13
  * link is what carries a client navigation and a leave guard; a plain anchor is
14
14
  * what carries a middle click into a new tab. Neither is right everywhere, so
15
15
  * neither is built in: the engine keeps plain anchors and the console passes
16
16
  * its router's NavLink.
17
+ *
18
+ * A FIGURE AT THE END OF A ROW IS ONE OF TWO THINGS, and the two are two props
19
+ * rather than one prop with a tone. A `count` is how many of something the
20
+ * destination holds (the open tasks in a project), a quiet figure in the
21
+ * tertiary ink; a `badge` is how many things are waiting on the reader (the
22
+ * unread in the inbox), the one filled pill in the chrome. Both are READ as
23
+ * part of the row's name, with the words the caller gives them ("Inbox, 5
24
+ * unread"), because a bare "5" after a name says nothing about what it counts,
25
+ * and both carry those words as required props, so a figure without them does
26
+ * not type-check.
17
27
  */
18
28
  import { type MouseEventHandler, type ReactNode } from 'react';
19
29
  export interface SidebarNavProps {
@@ -26,6 +36,24 @@ export interface SidebarNavProps {
26
36
  className?: string | undefined;
27
37
  children?: ReactNode;
28
38
  }
39
+ /**
40
+ * The one control a group's heading can carry at its end: the add beside
41
+ * "Projects".
42
+ *
43
+ * A DESCRIPTION RATHER THAN AN ELEMENT, because the rail is what draws it: a
44
+ * square at the pointer-target floor, which is exactly the heading's height,
45
+ * named by `label`, with its ring inside its own box like every row in a
46
+ * clipping scroller. A control handed in whole would bring its own step, and
47
+ * the smallest one in the kit is two pixels taller than the heading it sits
48
+ * in.
49
+ */
50
+ export interface NavGroupAction {
51
+ /** What pressing it does, in words: "New project". It is the control's name. */
52
+ label: string;
53
+ /** The glyph. Decoration: the label is the name. */
54
+ icon: ReactNode;
55
+ onClick: MouseEventHandler<HTMLButtonElement>;
56
+ }
29
57
  export interface NavGroupProps {
30
58
  /**
31
59
  * The group's heading. Without one the rows are simply a run of rows, and an
@@ -34,6 +62,13 @@ export interface NavGroupProps {
34
62
  * rail spent on nothing.
35
63
  */
36
64
  label?: ReactNode;
65
+ /**
66
+ * A control at the end of the heading. It is a sibling of the heading's
67
+ * words rather than part of them, so the group is still named by its label
68
+ * alone, and it takes its own place in the tab order before the group's
69
+ * first row.
70
+ */
71
+ action?: NavGroupAction | undefined;
37
72
  className?: string | undefined;
38
73
  children?: ReactNode;
39
74
  }
@@ -46,33 +81,58 @@ export interface NavLinkProps {
46
81
  onClick?: MouseEventHandler<HTMLElement> | undefined;
47
82
  }
48
83
  /**
49
- * How loudly a row's badge is drawn.
84
+ * A figure at the end of a row, and what it counts.
50
85
  *
51
- * `neutral` is a quiet figure at the end of the row, in the row's own ink.
52
- * `attention` is the one badge in the chrome allowed a status hue: a count of
53
- * what is waiting on a person is the one thing that should pull the eye out of
54
- * whatever screen the reader is on. It is a tint behind a word rather than a
55
- * word in a hue, so it still reads to somebody who cannot separate the hue.
56
- *
57
- * A TONE RATHER THAN A COMPONENT THE CALLER PASSES IN, because the tint has to
58
- * clear its floor on the ground the ROW has, which is the accent tint on the
59
- * reader's own row. That is a fact about the rail, measured in the rail's own
60
- * stylesheet, and not something a call site can be asked to know.
86
+ * VALUES RATHER THAN AN ELEMENT, because the rail is what paints them: the
87
+ * pair has to clear its floor on every ground a ROW can have, the reader's
88
+ * own raised row included, and that is a fact about the rail, measured in the
89
+ * rail's own stylesheet, not something a call site can be asked to know.
61
90
  */
62
- export type NavBadgeTone = 'neutral' | 'attention';
91
+ export interface NavFigure {
92
+ /** The figure, drawn as given, so the caller decides its formatting. */
93
+ value: number | string;
94
+ /**
95
+ * What is counted, read after the figure as part of the row's name:
96
+ * `unread` makes the inbox row "Inbox, 5 unread". Required, because a
97
+ * figure read with no word after it is a number nobody can place.
98
+ */
99
+ label: string;
100
+ }
101
+ /** A quiet figure: how many of something the destination holds. */
102
+ export interface NavCount extends NavFigure {
103
+ /**
104
+ * A mark before the figure: the working dot beside a count of agents at
105
+ * work. Decoration, because the label says the same thing in words.
106
+ */
107
+ mark?: ReactNode;
108
+ }
63
109
  export interface NavItemProps {
64
110
  /** What the row is called. */
65
111
  label: ReactNode;
66
112
  /** The row's glyph. Decoration: the label beside it carries the meaning. */
67
113
  icon?: ReactNode;
68
114
  /**
69
- * A count or a state at the end of the row. The slot draws it: whatever is
70
- * passed contributes its text and the name a screen reader reads after the
71
- * row's own, so a `<Count>` here is a figure rather than a second pill.
115
+ * A short key drawn as a chip before the label, in place of a glyph: a
116
+ * project's `ENG`. It is text, and READ as the start of the row's name
117
+ * ("ENG Core platform"), because it is the prefix every item in that project
118
+ * is filed under and a reader who hears it can find them. A string rather
119
+ * than an element, because the rail paints the chip and measures it.
120
+ */
121
+ lead?: string | undefined;
122
+ /**
123
+ * How many of something the destination holds, as a quiet figure at the end
124
+ * of the row in the tertiary ink: the open tasks in a project.
125
+ */
126
+ count?: NavCount | undefined;
127
+ /**
128
+ * How many things at this destination are waiting on the reader, as the one
129
+ * filled pill in the chrome, in the accent: the unread in the inbox. A count
130
+ * of what is waiting on the reader is the one thing in the rail that asks
131
+ * them to act, which is what the accent means; it is a FILL carrying a
132
+ * figure rather than a figure in a hue, so it still reads to somebody who
133
+ * cannot separate the hue. Anything else is a `count`.
72
134
  */
73
- badge?: ReactNode;
74
- /** How loudly. Neutral unless this row is what needs a person. */
75
- badgeTone?: NavBadgeTone | undefined;
135
+ badge?: NavFigure | undefined;
76
136
  href?: string | undefined;
77
137
  /** Whether this row is the screen the reader is on. */
78
138
  current?: boolean | undefined;
@@ -112,6 +172,6 @@ export declare namespace SidebarNav {
112
172
  * `<div>` here still carries the label's own padding, which put sixteen blank
113
173
  * pixels at the top of the rail and named a group nothing could read.
114
174
  */
115
- export declare function NavGroup({ label, className, children }: NavGroupProps): import("react").JSX.Element;
175
+ export declare function NavGroup({ label, action, className, children }: NavGroupProps): import("react").JSX.Element;
116
176
  /** One row: a glyph, a label, an optional badge, and optionally rows beneath. */
117
- export declare function NavItem({ label, icon, badge, badgeTone, href, current, disabledReason, renderLink, onClick, children, expanded, defaultExpanded, onExpandedChange, expandLabel, className, }: NavItemProps): import("react").JSX.Element;
177
+ export declare function NavItem({ label, icon, lead, count, badge, href, current, disabledReason, renderLink, onClick, children, expanded, defaultExpanded, onExpandedChange, expandLabel, className, }: NavItemProps): import("react").JSX.Element;
@@ -1,3 +1,3 @@
1
1
  import './SidebarNav.css';
2
2
  export { NavGroup, NavItem, SidebarNav } from './SidebarNav.js';
3
- export type { NavBadgeTone, NavGroupProps, NavItemProps, NavLinkProps, SidebarNavProps } from './SidebarNav.js';
3
+ export type { NavCount, NavFigure, NavGroupAction, NavGroupProps, NavItemProps, NavLinkProps, SidebarNavProps, } from './SidebarNav.js';
@@ -1,3 +1,3 @@
1
- export { NavGroup, NavItem, SidebarNav } from '../chunk-3EYF6HKB.js';
1
+ export { NavGroup, NavItem, SidebarNav } from '../chunk-IVFJD7WY.js';
2
2
  import '../chunk-BZFWDIV6.js';
3
3
  import '../chunk-ODEQTPFM.js';