@crewlethq/ui 0.69.0 → 0.71.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 (156) hide show
  1. package/README.md +25 -1
  2. package/dist/AgentHandoffPanel/index.js +4 -4
  3. package/dist/AppShell/index.js +3 -3
  4. package/dist/ArtifactBar/index.js +5 -5
  5. package/dist/AvatarPicker/index.js +8 -8
  6. package/dist/BriefCard/index.js +3 -3
  7. package/dist/Button/Button.d.ts +10 -0
  8. package/dist/Button/index.js +1 -1
  9. package/dist/{Button-VRRYSXFN.css → Button-GDEBGBX6.css} +30 -3
  10. package/dist/Canvas/index.js +2 -2
  11. package/dist/CanvasBoard/index.js +4 -4
  12. package/dist/CanvasToolbar/index.js +3 -3
  13. package/dist/CharacterPicker/index.js +2 -2
  14. package/dist/ChatThread/index.js +2 -2
  15. package/dist/CodeBlock/index.js +3 -3
  16. package/dist/ColorSwatch/index.js +3 -3
  17. package/dist/CommandPalette/index.js +4 -4
  18. package/dist/CommentThread/index.js +4 -4
  19. package/dist/Composer/index.js +2 -2
  20. package/dist/ConflictNote/index.js +2 -2
  21. package/dist/Copyable/index.js +2 -2
  22. package/dist/DataGrid/DataGrid.d.ts +50 -4
  23. package/dist/DataGrid/index.d.ts +2 -2
  24. package/dist/DataGrid/index.js +2 -2
  25. package/dist/{DataGrid-NHIN2I42.css → DataGrid-Q26F2V5Q.css} +145 -24
  26. package/dist/DataTable/index.js +4 -4
  27. package/dist/DataView/index.js +8 -7
  28. package/dist/{DataView-RH5UDA5F.css → DataView-L7HLNW7C.css} +1 -112
  29. package/dist/DatasetSource/index.js +1 -1
  30. package/dist/DateTimePicker/index.js +2 -2
  31. package/dist/DeepWorkCard/index.js +4 -4
  32. package/dist/DocTabsEditor/index.js +3 -3
  33. package/dist/DownloadButton/index.js +2 -2
  34. package/dist/EditingStatus/index.js +2 -2
  35. package/dist/{Editor-NZRUKWB4.js → Editor-NNQEALNT.js} +3 -3
  36. package/dist/EntityList/index.js +1 -1
  37. package/dist/ErrorBoundary/index.js +2 -2
  38. package/dist/FileDrop/index.js +2 -2
  39. package/dist/FilterPill/FilterPill.d.ts +63 -0
  40. package/dist/FilterPill/index.d.ts +3 -0
  41. package/dist/FilterPill/index.js +4 -0
  42. package/dist/FilterPill-4GMNFZND.css +134 -0
  43. package/dist/FollowBanner/index.js +2 -2
  44. package/dist/HuePicker/index.js +5 -5
  45. package/dist/InlineEditor/index.js +4 -4
  46. package/dist/LinkInterstitial/index.js +3 -3
  47. package/dist/ListInput/index.js +3 -3
  48. package/dist/LogoSlot/index.js +3 -3
  49. package/dist/MarkdownEditor/index.js +5 -5
  50. package/dist/Menu/Menu.d.ts +10 -1
  51. package/dist/Menu/index.js +2 -2
  52. package/dist/{Menu-OLUGHX56.css → Menu-I4SNXHOT.css} +12 -0
  53. package/dist/MergeConflicts/index.js +5 -5
  54. package/dist/Modal/index.js +2 -2
  55. package/dist/OpenInAppCard/index.js +4 -4
  56. package/dist/PeekRail/index.js +2 -2
  57. package/dist/PeopleRail/index.js +2 -2
  58. package/dist/PresenterView/index.js +3 -3
  59. package/dist/ProposalCard/index.js +4 -4
  60. package/dist/ReceiptStrip/index.js +2 -2
  61. package/dist/RefusalCard/index.js +1 -1
  62. package/dist/ResultTableCard/index.js +4 -4
  63. package/dist/RichEditor/index.js +2 -2
  64. package/dist/SandboxedFrame/index.js +2 -2
  65. package/dist/SegmentedControl/index.js +4 -4
  66. package/dist/SelectionBar/index.js +2 -2
  67. package/dist/ShareDialog/index.js +4 -4
  68. package/dist/SheetColumnEditor/index.js +8 -8
  69. package/dist/SheetGrid/index.js +5 -5
  70. package/dist/SlideCompare/index.js +2 -2
  71. package/dist/SlideFilmstrip/index.js +3 -3
  72. package/dist/StatusCard/index.js +1 -1
  73. package/dist/Switcher/index.js +3 -3
  74. package/dist/TableCells/index.js +2 -2
  75. package/dist/{TableCells-F6MUV572.css → TableCells-TKSNLRK3.css} +1 -0
  76. package/dist/Tabs/index.js +3 -3
  77. package/dist/ThemeSwitcher/index.js +5 -5
  78. package/dist/TimeRangePicker/index.js +6 -6
  79. package/dist/TimeWindowPicker/index.js +2 -2
  80. package/dist/Toaster/Toaster.d.ts +14 -2
  81. package/dist/Toaster/index.d.ts +1 -1
  82. package/dist/Toaster/index.js +1 -1
  83. package/dist/TreeCanvas/index.js +3 -3
  84. package/dist/VersionCompare/index.js +5 -5
  85. package/dist/VersionTimeline/index.js +2 -2
  86. package/dist/{chunk-HXJHRQDR.js → chunk-3EY5SEGH.js} +2 -2
  87. package/dist/{chunk-DS5NBENV.js → chunk-3LP3VPLT.js} +2 -2
  88. package/dist/{chunk-6MI2GMYG.js → chunk-3WN5HUAK.js} +2 -2
  89. package/dist/{chunk-4E3CE2UK.js → chunk-4DL2BQJE.js} +2 -2
  90. package/dist/{chunk-PQWNK3N7.js → chunk-4MVLED6E.js} +3 -3
  91. package/dist/{chunk-BXEKD5NU.js → chunk-6C6YK75K.js} +2 -2
  92. package/dist/{chunk-2A6DL3K5.js → chunk-6FBPFG3C.js} +1 -1
  93. package/dist/{chunk-L4UO57YP.js → chunk-73SAOOR5.js} +3 -3
  94. package/dist/{chunk-WXLQJUGO.js → chunk-ADSOY7UM.js} +1 -1
  95. package/dist/{chunk-GNDKUSCG.js → chunk-AGLONIVV.js} +1 -1
  96. package/dist/{chunk-2EA2GSA2.js → chunk-AQIFKLXY.js} +1 -1
  97. package/dist/{chunk-SUJO3AHN.js → chunk-B3PK2LND.js} +1 -1
  98. package/dist/{chunk-UYK3SGZI.js → chunk-BWFJB5JD.js} +3 -3
  99. package/dist/{chunk-I24FI46B.js → chunk-C667GCU7.js} +1 -1
  100. package/dist/{chunk-CWYU7DNT.js → chunk-CDNZTCP2.js} +1 -1
  101. package/dist/{chunk-NJYB4VJI.js → chunk-DB7UVFOY.js} +2 -2
  102. package/dist/{chunk-OJGI4XJH.js → chunk-DGSK4LLS.js} +1 -1
  103. package/dist/{chunk-7QTPJDRF.js → chunk-DGXZ635L.js} +7 -4
  104. package/dist/{chunk-2SU735S3.js → chunk-DV5L2GRY.js} +1 -1
  105. package/dist/{chunk-NSCYGUDG.js → chunk-EHFQMY3B.js} +1 -1
  106. package/dist/{chunk-S2UHV52X.js → chunk-EN4UJQ63.js} +3 -3
  107. package/dist/{chunk-6ID4DVML.js → chunk-EOXI3CRG.js} +1 -1
  108. package/dist/{chunk-VTGIDEI5.js → chunk-ERFXYGRF.js} +2 -2
  109. package/dist/{chunk-JEA5OX54.js → chunk-FQI62PIZ.js} +2 -2
  110. package/dist/{chunk-ELLRZ5XR.js → chunk-FURJVZCT.js} +72 -26
  111. package/dist/{chunk-5K7GGQNX.js → chunk-G4QZWVAB.js} +2 -2
  112. package/dist/{chunk-IABWA76I.js → chunk-H32JW6CZ.js} +2 -2
  113. package/dist/{chunk-PX54PALQ.js → chunk-HPI5J6AR.js} +1 -1
  114. package/dist/{chunk-ZEPUKRO7.js → chunk-IJ7KLXUZ.js} +1 -1
  115. package/dist/{chunk-PVZOP3QK.js → chunk-IPUEVTRJ.js} +1 -1
  116. package/dist/{chunk-RLBGU35B.js → chunk-J5WWMC35.js} +45 -46
  117. package/dist/{chunk-O3BNL4TV.js → chunk-JD7P2GJP.js} +1 -1
  118. package/dist/{chunk-SZFKGH2W.js → chunk-JIBWNHTC.js} +42 -9
  119. package/dist/{chunk-KIJJD4YD.js → chunk-JQEXAH7G.js} +1 -1
  120. package/dist/{chunk-K4IVKHKU.js → chunk-JT7WRPZ6.js} +1 -1
  121. package/dist/chunk-K4LZXSKZ.js +62 -0
  122. package/dist/{chunk-ZHVLDRAT.js → chunk-KAA3GFTP.js} +4 -4
  123. package/dist/{chunk-WDNURPXU.js → chunk-KL6A7JGH.js} +1 -1
  124. package/dist/{chunk-2JHGPXYG.js → chunk-KQWJWTED.js} +1 -1
  125. package/dist/{chunk-WU5JDEEY.js → chunk-L4HHWG4V.js} +1 -1
  126. package/dist/{chunk-GDDVI4US.js → chunk-LQWORB5B.js} +1 -1
  127. package/dist/{chunk-EHB4TSP2.js → chunk-NXNLAZPK.js} +2 -2
  128. package/dist/{chunk-WPMZKZUH.js → chunk-O3HCFM3D.js} +1 -1
  129. package/dist/{chunk-F32FFE6I.js → chunk-OBPINJNO.js} +1 -1
  130. package/dist/{chunk-T73DMDU4.js → chunk-OQG4P5KU.js} +17 -3
  131. package/dist/{chunk-UWOYDHVW.js → chunk-P64MIA7C.js} +1 -1
  132. package/dist/{chunk-DMK2A4IK.js → chunk-QSWQJX27.js} +1 -1
  133. package/dist/{chunk-D2ZXIQ23.js → chunk-R5OATXWU.js} +1 -1
  134. package/dist/{chunk-OFABBAUR.js → chunk-SMZPUHBL.js} +1 -1
  135. package/dist/{chunk-7QTJO3PV.js → chunk-SO5SXSTP.js} +1 -1
  136. package/dist/{chunk-IYG4ETAQ.js → chunk-T5GBTXNC.js} +1 -1
  137. package/dist/{chunk-DXVJSBEW.js → chunk-TKBFRGUV.js} +3 -3
  138. package/dist/{chunk-U7J52N67.js → chunk-TPCBPGSB.js} +1 -1
  139. package/dist/{chunk-W6UVBBNH.js → chunk-TYIHFDMP.js} +1 -1
  140. package/dist/{chunk-GJ7VIQWL.js → chunk-UY3FWQWG.js} +1 -1
  141. package/dist/{chunk-KHHDCNYM.js → chunk-V6X3DJ2G.js} +2 -2
  142. package/dist/{chunk-NTFVEOYY.js → chunk-VBA5FSWV.js} +1 -1
  143. package/dist/{chunk-7EOUVWGQ.js → chunk-VWMB3CJN.js} +1 -1
  144. package/dist/{chunk-CX6QT4CH.js → chunk-W5AXJWOW.js} +1 -1
  145. package/dist/{chunk-OWQATZGW.js → chunk-YGWIWDXE.js} +2 -2
  146. package/dist/{chunk-2T32N2WD.js → chunk-YUHKRRWO.js} +2 -2
  147. package/dist/{chunk-M25IV5MH.js → chunk-ZWCK4N4L.js} +1 -1
  148. package/dist/generated/index.d.ts +1 -0
  149. package/dist/generated/index.js +93 -92
  150. package/dist/index.js +93 -92
  151. package/dist/styles.css +333 -146
  152. package/package.json +3 -3
  153. package/dist/{chunk-XWOH3UPZ.js → chunk-5OFRDX66.js} +1 -1
  154. package/dist/{chunk-KBXSOBLD.js → chunk-ABZC3NLM.js} +0 -0
  155. package/dist/{chunk-VZICPYGR.js → chunk-SNQRGH4A.js} +1 -1
  156. package/dist/{chunk-AIMMHN5J.js → chunk-VLGGLLKH.js} +1 -1
@@ -120,6 +120,18 @@
120
120
  --crewlet-data-grid-cell-start: var(--spacing-3);
121
121
  }
122
122
 
123
+ /*
124
+ * AND AN ICON COLUMN, whose track (`DATA_GRID_ICON_TRACK`) is the target size
125
+ * and the cells' own step either side. At the grid's edge (a card's 16px) the
126
+ * edge inset left 20px for a 24px mark; the column keeps the cells' step on
127
+ * both sides wherever it stands, as the selection column does.
128
+ */
129
+ .crewlet-data-grid__th.crewlet-data-grid__th--icon,
130
+ .crewlet-data-grid__cell.crewlet-data-grid__cell--icon {
131
+ --crewlet-data-grid-cell-start: var(--spacing-3);
132
+ --crewlet-data-grid-cell-end: var(--spacing-3);
133
+ }
134
+
123
135
  /*
124
136
  * THE LIST TABLE'S HEAD: the micro-label register every table takes, 11/500
125
137
  * uppercase. A sortable head is a button with its chrome reset; the reset
@@ -127,6 +139,7 @@
127
139
  */
128
140
  .crewlet-data-grid__th {
129
141
  display: flex;
142
+ align-self: stretch;
130
143
  align-items: center;
131
144
  gap: var(--spacing-1);
132
145
  padding-block: var(--spacing-2);
@@ -173,22 +186,91 @@
173
186
  margin-inline: calc(-1 * var(--crewlet-data-grid-cell-start)) calc(-1 * var(--crewlet-data-grid-cell-end));
174
187
  padding-block: var(--spacing-2);
175
188
  padding-inline: var(--crewlet-data-grid-cell-start) var(--crewlet-data-grid-cell-end);
189
+ /* THE HEAD'S WHOLE HEIGHT, so a press anywhere in the cell sorts. */
190
+ align-self: stretch;
176
191
  cursor: pointer;
177
192
  }
178
193
 
194
+ /*
195
+ * ONE EDGE PER COLUMN, shared by its head and its values. `align` gives the
196
+ * head and every cell the same modifier, and both take the same inline inset
197
+ * (`--crewlet-data-grid-cell-start` and `-end`), so the word in the head and
198
+ * the values under it start (or end, or centre) on one line. A head that
199
+ * sorts is a button filling its head, and takes the same edge.
200
+ */
179
201
  .crewlet-data-grid__th--right .crewlet-data-grid__sort {
180
202
  justify-content: flex-end;
181
203
  }
182
204
 
205
+ .crewlet-data-grid__th--center .crewlet-data-grid__sort {
206
+ justify-content: center;
207
+ }
208
+
183
209
  .crewlet-data-grid__th:not(.crewlet-data-grid__th--plain):hover,
184
210
  .crewlet-data-grid__th--sorted {
185
211
  color: var(--color-text-primary);
186
212
  }
187
213
 
214
+ /*
215
+ * A SORTABLE HEAD SAYS SO UNDER THE POINTER: the row's own hover overlay over
216
+ * the whole cell, the way a row says it opens, so the target is the head and
217
+ * not the word in it.
218
+ */
219
+ .crewlet-data-grid__th:not(.crewlet-data-grid__th--plain):hover {
220
+ background: var(--color-surface-hover);
221
+ }
222
+
223
+ /*
224
+ * THE SORT ARROW. Its box is always laid out, so a head never changes width
225
+ * when the arrow appears and the fit measured at rest still holds under the
226
+ * pointer. The two-way arrow of a head that is not the sort shows only on
227
+ * hover and focus, in the head's own ink; the sorted head's arrow is always
228
+ * shown, at full ink, and names the direction.
229
+ */
230
+ .crewlet-data-grid__sort-mark {
231
+ display: inline-flex;
232
+ flex: none;
233
+ inline-size: var(--spacing-3);
234
+ color: inherit;
235
+ transition: opacity var(--motion-duration-fast) var(--motion-easing-default);
236
+ }
237
+
238
+ .crewlet-data-grid__th:not(.crewlet-data-grid__th--sorted) .crewlet-data-grid__sort-mark {
239
+ opacity: 0;
240
+ }
241
+
242
+ /* BEFORE THE WORD IN A RIGHT-ALIGNED COLUMN, so the word stays on the column's
243
+ right edge over its figures, arrow or not. */
244
+ .crewlet-data-grid__th--right .crewlet-data-grid__sort-mark {
245
+ order: -1;
246
+ }
247
+
248
+ /*
249
+ * AND MIRRORED IN A CENTRED COLUMN: a box the arrow's size before the word, a
250
+ * gap away, so the word stands on the column's middle over its values rather
251
+ * than half an arrow off it. ONLY BEFORE A WORD: a head with none (a sortable
252
+ * mark column) draws its arrow alone, already on the middle, and the reserve
253
+ * would push it off.
254
+ */
255
+ .crewlet-data-grid__th--center .crewlet-data-grid__sort:has(> .crewlet-data-grid__truncate)::before {
256
+ content: '';
257
+ flex: none;
258
+ inline-size: var(--spacing-3);
259
+ }
260
+
261
+ .crewlet-data-grid__th:hover .crewlet-data-grid__sort-mark,
262
+ .crewlet-data-grid__sort:focus-visible .crewlet-data-grid__sort-mark {
263
+ opacity: 1;
264
+ }
265
+
188
266
  .crewlet-data-grid__th--right {
189
267
  justify-content: flex-end;
190
268
  }
191
269
 
270
+ .crewlet-data-grid__th--center {
271
+ justify-content: center;
272
+ }
273
+
192
274
  .crewlet-data-grid__sort:focus-visible,
193
275
  .crewlet-data-grid__cols-reset:focus-visible {
194
276
  outline: 2px solid var(--color-focus);
@@ -295,23 +377,30 @@ button.crewlet-data-grid__row-link {
295
377
  * A GHOST CONTROL STARTS ON THE COLUMN'S TEXT EDGE. A small ghost button that
296
378
  * opens a cell ("Open ENG-12", a choice made in place through a menu) drew its
297
379
  * word one padding and one edge (9px) inside the line its column starts on.
298
- * Its padding and edge are taken back, as a card's foot does (StatusCard.css):
299
- * the word sits on the line and only the hover's ground reaches past it, into
300
- * the step between two columns. A column of figures ends its controls on the
301
- * far edge, so it is left alone.
380
+ * ONE MECHANISM, Button's `flush`: a flush control anywhere in a cell takes
381
+ * its padding and edge back, and a ghost control written straight into a cell
382
+ * (or as a menu's trigger there) is drawn flush without being asked, by the
383
+ * same declaration. The word sits on the line and only the hover's ground
384
+ * reaches past it, into the step between two columns.
385
+ *
386
+ * THE EXEMPTIONS ARE ONE VARIABLE, `--crewlet-btn-flush-outdent: 0`, which
387
+ * the flush declaration reads:
302
388
  *
303
- * NEVER AT THE GRID'S OWN EDGE: its first column, and every line of a phone's
304
- * card (below). A grid standing alone has only its 12px edge there, and with
305
- * the 9px taken back, the 4px the control's focus ring stands off it ran past
306
- * the grid's clip: the ring lost a pixel and the hover ground stood 3px from
307
- * the frame.
389
+ * - THE GRID'S OWN EDGE, its first column and every line of a phone's card
390
+ * (below). A grid standing alone has only its 12px edge there, and with the
391
+ * 9px taken back the control's focus ring ran past the grid's clip and the
392
+ * hover ground stood 3px from the frame.
393
+ * - A RIGHT OR A CENTRED COLUMN, which lines its values up by their end or
394
+ * their middle, where a control taken back at its start would stand off
395
+ * both.
308
396
  */
309
- .crewlet-data-grid__cell:not(:first-child, .crewlet-data-grid__cell--right)
310
- > .crewlet-btn--ghost.crewlet-btn--small:first-child,
311
- .crewlet-data-grid__cell:not(:first-child, .crewlet-data-grid__cell--right)
312
- > .crewlet-menu-anchor:first-child
313
- > .crewlet-btn--ghost.crewlet-btn--small {
314
- margin-inline-start: var(--crewlet-data-grid-control-outdent, calc(-1 * (var(--spacing-2) + 1px)));
397
+ .crewlet-data-grid__cell > .crewlet-btn--ghost.crewlet-btn--small:first-child,
398
+ .crewlet-data-grid__cell > .crewlet-menu-anchor:first-child > .crewlet-btn--ghost.crewlet-btn--small {
399
+ margin-inline-start: var(--crewlet-btn-flush-outdent, calc(-1 * (var(--crewlet-btn-inset) + 1px)));
400
+ }
401
+
402
+ .crewlet-data-grid__cell:is(:first-child, .crewlet-data-grid__cell--right, .crewlet-data-grid__cell--center) {
403
+ --crewlet-btn-flush-outdent: 0px;
315
404
  }
316
405
 
317
406
  /*
@@ -325,10 +414,18 @@ button.crewlet-data-grid__row-link {
325
414
  overflow: clip;
326
415
  }
327
416
 
417
+ /* A RIGHT-ALIGNED COLUMN holds figures, times and dates: tabular digits, so
418
+ "53s ago" and "12h ago" end on one edge and their digits stand in columns. */
328
419
  .crewlet-data-grid__cell--right {
329
420
  justify-content: flex-end;
421
+ font-variant-numeric: tabular-nums;
330
422
  }
331
423
 
424
+ .crewlet-data-grid__cell--center {
425
+ justify-content: center;
426
+ }
427
+
428
+
332
429
  .crewlet-data-grid__truncate {
333
430
  min-width: 0;
334
431
  overflow: hidden;
@@ -401,14 +498,25 @@ button.crewlet-data-grid__row-link {
401
498
  color: var(--color-text-primary);
402
499
  }
403
500
 
501
+ /*
502
+ * THE FOOT IS A CAPTION, NOT A ROW. At the row's height and on the head's
503
+ * raised ground it read as one more row, so a grid's head, rows and foot
504
+ * blurred into one stack. It takes the micro step of type, the tertiary ink,
505
+ * half the row's inset and the grid's own ground under the rows' hairline:
506
+ * quieter than either neighbour, and plainly the end of the list.
507
+ */
404
508
  .crewlet-data-grid__foot {
405
509
  display: flex;
406
510
  align-items: center;
407
- gap: var(--spacing-2);
408
- padding: var(--spacing-2) var(--crewlet-data-grid-edge);
409
- border-top: 1px solid var(--color-border-hover);
410
- background: var(--color-surface-elevated);
411
- font-size: var(--font-size-xs);
511
+ flex-wrap: wrap;
512
+ gap: var(--spacing-1) var(--spacing-3);
513
+ min-height: var(--size-control-sm);
514
+ padding: var(--spacing-1) var(--crewlet-data-grid-edge);
515
+ border-top: 1px solid var(--color-border-default);
516
+ background: transparent;
517
+ color: var(--color-text-tertiary);
518
+ font-size: var(--font-size-2xs);
519
+ line-height: var(--font-line-height-tight);
412
520
  }
413
521
 
414
522
  .crewlet-data-grid__foot-spacer {
@@ -416,7 +524,7 @@ button.crewlet-data-grid__row-link {
416
524
  }
417
525
 
418
526
  .crewlet-data-grid__note {
419
- font-size: var(--font-size-xs);
527
+ font-size: inherit;
420
528
  color: var(--color-text-tertiary);
421
529
  }
422
530
 
@@ -460,9 +568,21 @@ button.crewlet-data-grid__row-link {
460
568
  cursor: pointer;
461
569
  }
462
570
 
571
+ /*
572
+ * WHERE NOTHING HOVERS (a touch screen), a sortable head shows its arrow at
573
+ * rest: there is no pointer to bring it out, and a head that only says it
574
+ * sorts under a pointer says nothing there.
575
+ */
576
+ @media (hover: none) {
577
+ .crewlet-data-grid__th:not(.crewlet-data-grid__th--plain) .crewlet-data-grid__sort-mark {
578
+ opacity: 1;
579
+ }
580
+ }
581
+
463
582
  @media (prefers-reduced-motion: reduce) {
464
583
  .crewlet-data-grid__th,
465
- .crewlet-data-grid__row {
584
+ .crewlet-data-grid__row,
585
+ .crewlet-data-grid__sort-mark {
466
586
  transition: none;
467
587
  }
468
588
  }
@@ -486,7 +606,7 @@ button.crewlet-data-grid__row-link {
486
606
  /* No ghost control is pulled out here (see above): every line of a card
487
607
  starts at the grid's edge, and a compact row's marks run on one line,
488
608
  where the hover ground swallowed the gap before it. */
489
- --crewlet-data-grid-control-outdent: 0px;
609
+ --crewlet-btn-flush-outdent: 0px;
490
610
 
491
611
  display: block;
492
612
  }
@@ -532,7 +652,8 @@ button.crewlet-data-grid__row-link {
532
652
 
533
653
  /* `shrink` and `right` are column shapes, and there are no columns here. */
534
654
  :where(.crewlet-data-grid[data-stacked]) .crewlet-data-grid__cell--shrink,
535
- :where(.crewlet-data-grid[data-stacked]) .crewlet-data-grid__cell--right {
655
+ :where(.crewlet-data-grid[data-stacked]) .crewlet-data-grid__cell--right,
656
+ :where(.crewlet-data-grid[data-stacked]) .crewlet-data-grid__cell--center {
536
657
  white-space: normal;
537
658
  justify-content: flex-start;
538
659
  }
@@ -1,5 +1,5 @@
1
- export { ALL_ITEMS, CopyableCell, DATA_TABLE_LABELS, DataTable, RowActionsMenu } from '../chunk-UYK3SGZI.js';
2
- import '../chunk-I24FI46B.js';
1
+ export { ALL_ITEMS, CopyableCell, DATA_TABLE_LABELS, DataTable, RowActionsMenu } from '../chunk-BWFJB5JD.js';
2
+ import '../chunk-C667GCU7.js';
3
3
  import '../chunk-STJ7QBC3.js';
4
4
  import '../chunk-DTIW4CHZ.js';
5
5
  import '../chunk-RE3FBGQQ.js';
@@ -9,8 +9,8 @@ import '../chunk-ETSF7SU6.js';
9
9
  import '../chunk-PGCLHYVP.js';
10
10
  import '../chunk-PQADV6P6.js';
11
11
  import '../chunk-2G355KDJ.js';
12
- import '../chunk-T73DMDU4.js';
13
- import '../chunk-7QTPJDRF.js';
12
+ import '../chunk-OQG4P5KU.js';
13
+ import '../chunk-DGXZ635L.js';
14
14
  import '../chunk-OMV5W53A.js';
15
15
  import '../chunk-XSPCITPN.js';
16
16
  import '../chunk-H5XTJ7GJ.js';
@@ -1,8 +1,9 @@
1
- export { DATA_VIEW_TOOLBAR_LABELS, DataView, DataViewToolbar, FILTER_AXIS_LABELS, FilterAxisBar, FilterAxisChip, applyColumnFilters, applyFilters, blankFilterValue, defaultOperator, filterDefsFromColumns, filterHasValue, filterPredicate, formatFilterValue, operatorOf, tableColumns } from '../chunk-RLBGU35B.js';
1
+ export { DATA_VIEW_TOOLBAR_LABELS, DataView, DataViewToolbar, FILTER_AXIS_LABELS, FilterAxisBar, FilterAxisChip, applyColumnFilters, applyFilters, blankFilterValue, defaultOperator, filterDefsFromColumns, filterHasValue, filterPredicate, formatFilterValue, operatorOf, tableColumns } from '../chunk-J5WWMC35.js';
2
2
  import '../chunk-FPDIHEM4.js';
3
- import '../chunk-UYK3SGZI.js';
4
- import '../chunk-PX54PALQ.js';
5
- import '../chunk-I24FI46B.js';
3
+ import '../chunk-K4LZXSKZ.js';
4
+ import '../chunk-BWFJB5JD.js';
5
+ import '../chunk-HPI5J6AR.js';
6
+ import '../chunk-C667GCU7.js';
6
7
  import '../chunk-STJ7QBC3.js';
7
8
  import '../chunk-DTIW4CHZ.js';
8
9
  import '../chunk-7KHM2FZH.js';
@@ -13,14 +14,14 @@ import '../chunk-EJNJMHQG.js';
13
14
  import '../chunk-RE3FBGQQ.js';
14
15
  import '../chunk-AV2DXAEL.js';
15
16
  import '../chunk-PBCNINMB.js';
17
+ import '../chunk-ANTAQAR4.js';
16
18
  import '../chunk-ETSF7SU6.js';
17
19
  import '../chunk-PGCLHYVP.js';
18
- import '../chunk-ANTAQAR4.js';
19
20
  import '../chunk-MLDTLZAO.js';
20
21
  import '../chunk-PQADV6P6.js';
21
22
  import '../chunk-2G355KDJ.js';
22
- import '../chunk-T73DMDU4.js';
23
- import '../chunk-7QTPJDRF.js';
23
+ import '../chunk-OQG4P5KU.js';
24
+ import '../chunk-DGXZ635L.js';
24
25
  import '../chunk-OMV5W53A.js';
25
26
  import '../chunk-XSPCITPN.js';
26
27
  import '../chunk-H5XTJ7GJ.js';
@@ -220,118 +220,7 @@
220
220
 
221
221
  /* ── One chip ─────────────────────────────────────────────────────────── */
222
222
 
223
- /*
224
- * TWO CONTROLS IN ONE PILL: pressing the chip opens its editor, pressing the
225
- * cross takes the filter off. They are drawn as one object with a divider
226
- * because they are one filter, and they are two BUTTONS because they do two
227
- * different things, which is also why the cross carries its own name rather
228
- * than relying on the chip's.
229
- */
230
- .crewlet-filter-axis-chip {
231
- display: inline-flex;
232
- align-items: stretch;
233
- height: var(--size-control-sm);
234
- background: var(--color-brand-accent-soft);
235
- border: 1px solid var(--color-brand-accent-soft-strong);
236
- border-radius: var(--radius-pill);
237
- overflow: hidden;
238
- max-width: 100%;
239
- transition: border-color var(--motion-duration-fast) var(--motion-easing-default);
240
- }
241
-
242
- /*
243
- * THE EDGE, NOT THE FILL. `--color-surface-hover` is the overlay a row at rest
244
- * carries, and the token says a surface shows it OR a selected tint, never
245
- * both: put on a chip it REPLACED the accent fill, so the one control on screen
246
- * that means "this filter is on" went pale under the pointer and read as the
247
- * filter being switched off.
248
- *
249
- * The fill stays where it is and the boundary takes the accent itself.
250
- * Deepening the fill to the next accent step instead measures 4.48:1 under the
251
- * chip's own ink on the light ground, and 4.18:1 on a card, which is why that
252
- * step is a BORDER value in the palette and is used as one here.
253
- */
254
- .crewlet-filter-axis-chip:hover {
255
- border-color: var(--color-brand-accent);
256
- }
257
-
258
- .crewlet-filter-axis-chip__trigger {
259
- display: inline-flex;
260
- align-items: center;
261
- gap: var(--spacing-1);
262
- min-width: 0;
263
- padding: 0 var(--spacing-2) 0 var(--spacing-3);
264
- background: transparent;
265
- border: none;
266
- cursor: pointer;
267
- color: var(--color-brand-accent-ink);
268
- font-family: var(--font-family-sans);
269
- font-size: var(--font-size-xs);
270
- line-height: 1;
271
- }
272
-
273
- .crewlet-filter-axis-chip__trigger:focus-visible {
274
- outline: 2px solid var(--color-focus);
275
- outline-offset: var(--size-focus-ring-inset-offset);
276
- }
277
-
278
- /*
279
- * THE AXIS NAME IS NOT DIMMED. It read at 0.85 opacity, which takes the chip's
280
- * own ink off the step the pairing was measured at, and the name of the axis
281
- * is exactly what a reader checks before the value: "status" and "stage" narrow
282
- * a list to very different things. The value's own weight is what separates
283
- * the halves, which is a difference a reader can see at any contrast.
284
- */
285
- .crewlet-filter-axis-chip__label {
286
- white-space: nowrap;
287
- }
288
-
289
- .crewlet-filter-axis-chip__value {
290
- font-weight: var(--font-weight-semibold);
291
- overflow: hidden;
292
- text-overflow: ellipsis;
293
- white-space: nowrap;
294
- }
295
-
296
- /*
297
- * The chevron carries the chip's own ink rather than a fainter version of it,
298
- * for the reason every mark beside its words does: a grey glyph next to
299
- * coloured text reads as two things. At 0.7 it measured 3.00:1 on a card in
300
- * light, which is the 3:1 floor for a glyph to the second decimal place.
301
- */
302
- .crewlet-filter-axis-chip__chevron {
303
- flex: none;
304
- }
305
-
306
- /*
307
- * The remove control keeps the chip's own ink rather than taking the critical
308
- * hue on hover: removing a filter destroys nothing, and a row of chips that
309
- * turns red under the pointer reads as a row of dangerous things.
310
- */
311
- .crewlet-filter-axis-chip__remove {
312
- /* AS TALL AS THE PILL'S INSIDE, as the trigger beside it is. At the small
313
- control's own height it stood 2px past the pill's inner edge, cut off at
314
- the bottom, and its cross sat 1px under the chip's middle. */
315
- height: auto;
316
- border-radius: 0;
317
- border-left: 1px solid var(--color-brand-accent-soft-strong);
318
- color: var(--color-brand-accent-ink);
319
- }
320
-
321
- /*
322
- * Its ring is drawn INSIDE it, like the trigger's beside it. The pill clips to
323
- * its own radius, so the outset ring an icon button carries everywhere else is
324
- * cut off on every edge the control touches, which here is all of them.
325
- */
326
- .crewlet-filter-axis-chip__remove:focus-visible {
327
- outline-offset: var(--size-focus-ring-inset-offset);
328
- }
329
-
330
- @media (prefers-reduced-motion: reduce) {
331
- .crewlet-filter-axis-chip {
332
- transition: none;
333
- }
334
- }
223
+ /* A chip is a [FilterPill] (FilterPill.css) whose words open its editor. */
335
224
 
336
225
  /* ── A chip's editor ──────────────────────────────────────────────────── */
337
226
 
@@ -1,8 +1,8 @@
1
1
  export { DATASET_SOURCE_KINDS, DatasetSource, DatasetSourceList } from '../chunk-R6K62EXV.js';
2
2
  import '../chunk-I5OIKDX2.js';
3
+ import '../chunk-WIATRXEJ.js';
3
4
  import '../chunk-EJNJMHQG.js';
4
5
  import '../chunk-RE3FBGQQ.js';
5
- import '../chunk-WIATRXEJ.js';
6
6
  import '../chunk-2YTOOH3A.js';
7
7
  import '../chunk-UT6CW3C7.js';
8
8
  import '../chunk-ODEQTPFM.js';
@@ -1,7 +1,7 @@
1
- export { DEFAULT_DATE_TIME_PICKER_LABELS, DateTimePicker } from '../chunk-PX54PALQ.js';
1
+ export { DEFAULT_DATE_TIME_PICKER_LABELS, DateTimePicker } from '../chunk-HPI5J6AR.js';
2
2
  import '../chunk-EE3DJMSQ.js';
3
3
  import '../chunk-KHJIEPZV.js';
4
- import '../chunk-7QTPJDRF.js';
4
+ import '../chunk-DGXZ635L.js';
5
5
  import '../chunk-OMV5W53A.js';
6
6
  import '../chunk-XSPCITPN.js';
7
7
  import '../chunk-H5XTJ7GJ.js';
@@ -1,17 +1,17 @@
1
- export { DEEP_WORK_CARD_LABELS, DEEP_WORK_STATES, DEEP_WORK_STATE_LABELS, DeepWorkCard } from '../chunk-UWOYDHVW.js';
1
+ export { DEEP_WORK_CARD_LABELS, DEEP_WORK_STATES, DEEP_WORK_STATE_LABELS, DeepWorkCard } from '../chunk-P64MIA7C.js';
2
2
  import '../chunk-HJBHP66O.js';
3
+ import '../chunk-ZWCK4N4L.js';
3
4
  import '../chunk-RQFRRPV6.js';
4
- import '../chunk-M25IV5MH.js';
5
5
  import '../chunk-NTQPJJAN.js';
6
6
  import '../chunk-I5OIKDX2.js';
7
+ import '../chunk-WIATRXEJ.js';
7
8
  import '../chunk-4AUTALJA.js';
8
9
  import '../chunk-AV2DXAEL.js';
9
- import '../chunk-WIATRXEJ.js';
10
10
  import '../chunk-222VILSP.js';
11
11
  import '../chunk-IVTQWOXV.js';
12
12
  import '../chunk-MLDTLZAO.js';
13
13
  import '../chunk-PQADV6P6.js';
14
- import '../chunk-7QTPJDRF.js';
14
+ import '../chunk-DGXZ635L.js';
15
15
  import '../chunk-XSPCITPN.js';
16
16
  import '../chunk-UT6CW3C7.js';
17
17
  import '../chunk-ODEQTPFM.js';
@@ -1,11 +1,11 @@
1
- export { DOC_TABS_EDITOR_LABELS, DocTabsEditor } from '../chunk-CX6QT4CH.js';
1
+ export { DOC_TABS_EDITOR_LABELS, DocTabsEditor } from '../chunk-W5AXJWOW.js';
2
2
  import '../chunk-MPVMB2DV.js';
3
3
  import '../chunk-ETSF7SU6.js';
4
4
  import '../chunk-PGCLHYVP.js';
5
5
  import '../chunk-PQADV6P6.js';
6
6
  import '../chunk-2G355KDJ.js';
7
- import '../chunk-T73DMDU4.js';
8
- import '../chunk-7QTPJDRF.js';
7
+ import '../chunk-OQG4P5KU.js';
8
+ import '../chunk-DGXZ635L.js';
9
9
  import '../chunk-OMV5W53A.js';
10
10
  import '../chunk-XSPCITPN.js';
11
11
  import '../chunk-H5XTJ7GJ.js';
@@ -1,7 +1,7 @@
1
- export { DownloadButton } from '../chunk-NSCYGUDG.js';
1
+ export { DownloadButton } from '../chunk-EHFQMY3B.js';
2
2
  import '../chunk-YNRKVY7X.js';
3
3
  import '../chunk-DTIW4CHZ.js';
4
- import '../chunk-7QTPJDRF.js';
4
+ import '../chunk-DGXZ635L.js';
5
5
  import '../chunk-XSPCITPN.js';
6
6
  import '../chunk-UT6CW3C7.js';
7
7
  import '../chunk-ODEQTPFM.js';
@@ -1,6 +1,6 @@
1
- export { EditingStatus } from '../chunk-AIMMHN5J.js';
1
+ export { EditingStatus } from '../chunk-VLGGLLKH.js';
2
+ import '../chunk-WIATRXEJ.js';
2
3
  import '../chunk-EJNJMHQG.js';
3
4
  import '../chunk-RE3FBGQQ.js';
4
- import '../chunk-WIATRXEJ.js';
5
5
  import '../chunk-UT6CW3C7.js';
6
6
  import '../chunk-ODEQTPFM.js';
@@ -1,13 +1,13 @@
1
- import { schema, readMarkdown, writeMarkdown } from './chunk-QH6VYJ3X.js';
2
1
  import { richEditorLabels } from './chunk-CSQTDGTS.js';
2
+ import { schema, readMarkdown, writeMarkdown } from './chunk-QH6VYJ3X.js';
3
3
  import { safeHref, MARKDOWN_CALLOUT_TONES } from './chunk-BAKPMH3S.js';
4
4
  import { Toolbar } from './chunk-NR4CPM4T.js';
5
5
  import { FormField, Input } from './chunk-ETSF7SU6.js';
6
6
  import './chunk-PGCLHYVP.js';
7
7
  import './chunk-PQADV6P6.js';
8
8
  import './chunk-2G355KDJ.js';
9
- import { Menu } from './chunk-T73DMDU4.js';
10
- import { Button } from './chunk-7QTPJDRF.js';
9
+ import { Menu } from './chunk-OQG4P5KU.js';
10
+ import { Button } from './chunk-DGXZ635L.js';
11
11
  import { placePopup, viewportBounds } from './chunk-OMV5W53A.js';
12
12
  import './chunk-XSPCITPN.js';
13
13
  import { usePopupLayer } from './chunk-H5XTJ7GJ.js';
@@ -1,9 +1,9 @@
1
1
  export { EntityList } from '../chunk-7IW3P6FH.js';
2
2
  import '../chunk-NTQPJJAN.js';
3
3
  import '../chunk-I5OIKDX2.js';
4
+ import '../chunk-WIATRXEJ.js';
4
5
  import '../chunk-4AUTALJA.js';
5
6
  import '../chunk-AV2DXAEL.js';
6
- import '../chunk-WIATRXEJ.js';
7
7
  import '../chunk-MLDTLZAO.js';
8
8
  import '../chunk-PQADV6P6.js';
9
9
  import '../chunk-UT6CW3C7.js';
@@ -1,5 +1,5 @@
1
- export { ErrorBoundary } from '../chunk-ZEPUKRO7.js';
2
- import '../chunk-7QTPJDRF.js';
1
+ export { ErrorBoundary } from '../chunk-IJ7KLXUZ.js';
2
+ import '../chunk-DGXZ635L.js';
3
3
  import '../chunk-XSPCITPN.js';
4
4
  import '../chunk-UT6CW3C7.js';
5
5
  import '../chunk-ODEQTPFM.js';
@@ -1,5 +1,5 @@
1
- export { FileDrop, FilePickButton, droppedFiles, pickedFiles } from '../chunk-2JHGPXYG.js';
2
- import '../chunk-7QTPJDRF.js';
1
+ export { FileDrop, FilePickButton, droppedFiles, pickedFiles } from '../chunk-KQWJWTED.js';
2
+ import '../chunk-DGXZ635L.js';
3
3
  import '../chunk-XSPCITPN.js';
4
4
  import '../chunk-UT6CW3C7.js';
5
5
  import '../chunk-ODEQTPFM.js';
@@ -0,0 +1,63 @@
1
+ import { type ReactElement, type ReactNode } from 'react';
2
+ /** The words a pill says, for an application that says them otherwise. */
3
+ export interface FilterPillLabels {
4
+ /** The remove control's name, from the filter as a sentence: "Remove the Status is Done filter". */
5
+ remove: (sentence: string) => string;
6
+ /** Its name where the filter's parts are not words to build a sentence from. */
7
+ removeUnnamed: string;
8
+ /** What ends the field where no operator joins it to the value: "Role: Admin". */
9
+ fieldEnd: string;
10
+ }
11
+ export declare const FILTER_PILL_LABELS: FilterPillLabels;
12
+ export interface FilterPillProps {
13
+ /** What the filter is on: "Status". */
14
+ field: ReactNode;
15
+ /**
16
+ * How the value is compared: "is", "contains", "is any of". Left out, the
17
+ * field and the value are joined by a colon ("Role: Admin").
18
+ */
19
+ operator?: ReactNode;
20
+ /**
21
+ * What the filter is set to: "In progress". Left out for a filter that is a
22
+ * switch with no value ("Blocked"), which the field alone names.
23
+ */
24
+ value?: ReactNode;
25
+ /** Takes the filter off. Left out, the pill has no remove control. */
26
+ onRemove?: (() => void) | undefined;
27
+ /**
28
+ * Names the remove control. Defaults to the whole filter as a sentence
29
+ * (`labels.remove`), "Remove the Status is In progress filter", where its
30
+ * parts are words: a row of pills each announcing "Remove" names nothing.
31
+ */
32
+ removeLabel?: string | undefined;
33
+ /**
34
+ * Draws the words as a control, for a pill whose words open the filter's
35
+ * editor (a popover's trigger). Called with the words and the class the
36
+ * control takes; it returns that control, a `<button>`.
37
+ */
38
+ renderWords?: ((words: ReactNode, className: string) => ReactElement) | undefined;
39
+ labels?: Partial<FilterPillLabels> | undefined;
40
+ className?: string | undefined;
41
+ }
42
+ /** The class the words take, as text or as the control `renderWords` returns. */
43
+ export declare const FILTER_PILL_WORDS_CLASS = "crewlet-filter-pill__words";
44
+ /** The parts as one sentence, where every part is a word: "Status is In progress". */
45
+ export declare function filterPillSentence(field: ReactNode, operator?: ReactNode, value?: ReactNode): string | undefined;
46
+ /**
47
+ * One filter in force on a list: the field, how it compares, the value, and
48
+ * the control that takes it off.
49
+ *
50
+ * THREE PARTS IN THREE REGISTERS, because a filter is a sentence and a pill
51
+ * set in one register reads as a label. The field and the relation are the
52
+ * secondary ink at the regular weight; the value, the answer a reader checks,
53
+ * is the accent ink at the semibold weight. The parts are drawn a step apart
54
+ * AND separated by real spaces, so the pill reads, copies and is announced as
55
+ * the sentence it is, never as "StatusisIn progress".
56
+ *
57
+ * THE ACCENT GROUND, because a filter in force is where the reader is in the
58
+ * data: the same soft fill and edge a pressed [FilterChip] and the selected row
59
+ * carry. The remove control is a second button beside the words, behind a
60
+ * hairline, named by the whole filter; it keeps the pill's ink rather than
61
+ * turning red, because taking a filter off destroys nothing.
62
+ */
63
+ export declare function FilterPill({ field, operator, value, onRemove, removeLabel, renderWords, labels, className, }: FilterPillProps): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import './FilterPill.css';
2
+ export { FILTER_PILL_LABELS, FILTER_PILL_WORDS_CLASS, FilterPill, filterPillSentence } from './FilterPill.js';
3
+ export type { FilterPillLabels, FilterPillProps } from './FilterPill.js';
@@ -0,0 +1,4 @@
1
+ export { FILTER_PILL_LABELS, FILTER_PILL_WORDS_CLASS, FilterPill, filterPillSentence } from '../chunk-K4LZXSKZ.js';
2
+ import '../chunk-UAUP6XGK.js';
3
+ import '../chunk-UT6CW3C7.js';
4
+ import '../chunk-ODEQTPFM.js';