@crewlethq/ui 0.11.0 → 0.13.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 (165) hide show
  1. package/README.md +76 -5
  2. package/dist/AppShell/index.js +2 -1
  3. package/dist/Avatar/index.js +1 -1
  4. package/dist/{Avatar-QHYOFID3.css → Avatar-BPJ36QZR.css} +1 -1
  5. package/dist/AvatarPicker/index.js +6 -6
  6. package/dist/Breadcrumb/Breadcrumb.d.ts +68 -0
  7. package/dist/Breadcrumb/index.d.ts +3 -0
  8. package/dist/Breadcrumb/index.js +3 -0
  9. package/dist/Breadcrumb-YMWVM3SV.css +193 -0
  10. package/dist/ChoiceButtons/ChoiceButtons.d.ts +43 -0
  11. package/dist/ChoiceButtons/index.d.ts +3 -0
  12. package/dist/ChoiceButtons/index.js +3 -0
  13. package/dist/ChoiceButtons-DJ5EOGUA.css +127 -0
  14. package/dist/ChoiceList/ChoiceList.d.ts +45 -0
  15. package/dist/ChoiceList/index.d.ts +3 -0
  16. package/dist/ChoiceList/index.js +2 -0
  17. package/dist/ChoiceList-2PQJS4DX.css +109 -0
  18. package/dist/Combobox/index.js +2 -2
  19. package/dist/CommandPalette/CommandPalette.d.ts +48 -1
  20. package/dist/CommandPalette/index.js +3 -3
  21. package/dist/{CommandPalette-C5AMKGN2.css → CommandPalette-HBTNKHZQ.css} +55 -2
  22. package/dist/Composer/Composer.d.ts +27 -0
  23. package/dist/Composer/index.d.ts +3 -0
  24. package/dist/Composer/index.js +7 -0
  25. package/dist/Composer-ABGJIAIR.css +88 -0
  26. package/dist/DataTable/index.js +3 -3
  27. package/dist/DataView/index.js +11 -11
  28. package/dist/DateTimePicker/index.js +2 -2
  29. package/dist/Document/Document.d.ts +56 -0
  30. package/dist/Document/index.d.ts +3 -0
  31. package/dist/Document/index.js +2 -0
  32. package/dist/Document-PQGXJHB7.css +288 -0
  33. package/dist/EntityChip/index.js +1 -1
  34. package/dist/Highlight/Highlight.d.ts +45 -0
  35. package/dist/Highlight/index.d.ts +3 -0
  36. package/dist/Highlight/index.js +2 -0
  37. package/dist/Highlight-DXLV2R6L.css +29 -0
  38. package/dist/HuePicker/index.js +3 -3
  39. package/dist/ImageUpload/index.js +2 -2
  40. package/dist/{ImageUpload-L2GE4JUM.css → ImageUpload-NVGMN7DP.css} +9 -6
  41. package/dist/InboxList/InboxList.d.ts +116 -0
  42. package/dist/InboxList/index.d.ts +3 -0
  43. package/dist/InboxList/index.js +5 -0
  44. package/dist/InboxList-YMFWKGGS.css +252 -0
  45. package/dist/KeyChip/KeyChip.d.ts +21 -0
  46. package/dist/KeyChip/index.d.ts +3 -0
  47. package/dist/KeyChip/index.js +2 -0
  48. package/dist/KeyChip-4XJU4BBE.css +30 -0
  49. package/dist/Link/Link.d.ts +17 -2
  50. package/dist/Link/index.js +1 -1
  51. package/dist/{Link-6BEFNMN2.css → Link-WPMVLKLY.css} +36 -1
  52. package/dist/Listbox/index.d.ts +2 -0
  53. package/dist/Listbox/index.js +1 -1
  54. package/dist/Listbox/useHighlightRest.d.ts +35 -0
  55. package/dist/MarkdownEditor/MarkdownEditor.d.ts +93 -0
  56. package/dist/MarkdownEditor/format.d.ts +34 -0
  57. package/dist/MarkdownEditor/index.d.ts +5 -0
  58. package/dist/MarkdownEditor/index.js +12 -0
  59. package/dist/MarkdownEditor-ZLSHTOIZ.css +146 -0
  60. package/dist/Modal/Modal.d.ts +5 -1
  61. package/dist/Modal/index.js +1 -1
  62. package/dist/{Modal-BNT3TDV2.css → Modal-3YJ2GG2T.css} +33 -0
  63. package/dist/OrgLabel/index.js +1 -1
  64. package/dist/OrgNode/index.js +1 -1
  65. package/dist/OrgTable/index.js +5 -5
  66. package/dist/Outline/Outline.d.ts +72 -0
  67. package/dist/Outline/index.d.ts +3 -0
  68. package/dist/Outline/index.js +2 -0
  69. package/dist/Outline-VCXKKU3E.css +78 -0
  70. package/dist/Popover/Popover.d.ts +21 -1
  71. package/dist/Popover/index.js +1 -1
  72. package/dist/ReadingPane/ReadingPane.d.ts +95 -0
  73. package/dist/ReadingPane/index.d.ts +3 -0
  74. package/dist/ReadingPane/index.js +4 -0
  75. package/dist/ReadingPane-5UOLPWY5.css +194 -0
  76. package/dist/SegmentedControl/SegmentedControl.d.ts +9 -1
  77. package/dist/SegmentedControl/index.js +3 -3
  78. package/dist/{SegmentedControl-76HODRBT.css → SegmentedControl-PKBLJVSA.css} +18 -0
  79. package/dist/Select/Select.d.ts +22 -0
  80. package/dist/Select/index.js +2 -2
  81. package/dist/{Select-4ANVLHUY.css → Select-XMZ44RWY.css} +24 -0
  82. package/dist/SidebarNav/index.js +2 -1
  83. package/dist/{SidebarNav-X5NLZNWA.css → SidebarNav-KF66MLOM.css} +4 -19
  84. package/dist/Switcher/Switcher.d.ts +151 -0
  85. package/dist/Switcher/index.d.ts +3 -0
  86. package/dist/Switcher/index.js +16 -0
  87. package/dist/Switcher-B44Q4WF4.css +346 -0
  88. package/dist/Tabs/Tabs.d.ts +7 -1
  89. package/dist/Tabs/index.js +1 -1
  90. package/dist/{Tabs-5I5Q5KKM.css → Tabs-ITJYJFMU.css} +49 -0
  91. package/dist/TagsInput/index.js +2 -2
  92. package/dist/ThemeGallery/ThemeGallery.d.ts +65 -0
  93. package/dist/ThemeGallery/index.d.ts +3 -0
  94. package/dist/ThemeGallery/index.js +6 -0
  95. package/dist/ThemeGallery-NITASULQ.css +93 -0
  96. package/dist/ThemeSwatch/ThemeSwatch.d.ts +71 -0
  97. package/dist/ThemeSwatch/index.d.ts +3 -0
  98. package/dist/ThemeSwatch/index.js +2 -0
  99. package/dist/ThemeSwatch-4DL457ZB.css +256 -0
  100. package/dist/ThemeSwitcher/ThemeSwitcher.d.ts +5 -1
  101. package/dist/ThemeSwitcher/index.js +4 -4
  102. package/dist/ThemeToggle/ThemeToggle.d.ts +1 -1
  103. package/dist/ThemeToggle/index.js +1 -1
  104. package/dist/TimeWindowPicker/index.js +4 -4
  105. package/dist/Toaster/index.js +1 -1
  106. package/dist/{Toaster-NVDCEIP5.css → Toaster-KZ7YE2HA.css} +1 -0
  107. package/dist/Tree/index.d.ts +1 -1
  108. package/dist/Tree/index.js +1 -1
  109. package/dist/Tree/useTreeState.d.ts +37 -7
  110. package/dist/TreeCanvas/index.js +2 -2
  111. package/dist/TreeGrid/TreeGrid.d.ts +22 -2
  112. package/dist/TreeGrid/index.js +2 -2
  113. package/dist/{TreeGrid-NSW7VMOX.css → TreeGrid-FBX3MSJA.css} +19 -0
  114. package/dist/{chunk-EBBAAQDY.js → chunk-26PEPONN.js} +3 -1
  115. package/dist/{chunk-HV6IZFBK.js → chunk-4FFHJBEN.js} +2 -2
  116. package/dist/{chunk-JHQUT4WJ.js → chunk-4LDTQWS7.js} +1 -1
  117. package/dist/{chunk-ELZKOVEC.js → chunk-4Y7WKXAW.js} +1 -1
  118. package/dist/{chunk-MCPKHYMC.js → chunk-6LXMLQUM.js} +17 -4
  119. package/dist/{chunk-3UK4VFSK.js → chunk-6NIZCQUM.js} +1 -1
  120. package/dist/{chunk-ORNOOMVY.js → chunk-6TSZCBID.js} +2 -2
  121. package/dist/{chunk-ZMJHK7DR.js → chunk-75WOCYGC.js} +2 -2
  122. package/dist/chunk-77IEHFY4.js +299 -0
  123. package/dist/chunk-A5YKNRG6.js +94 -0
  124. package/dist/{chunk-HLBRPES3.js → chunk-B2CITO6R.js} +2 -2
  125. package/dist/{chunk-TEEJSTFG.js → chunk-CF6DTETT.js} +1 -1
  126. package/dist/{chunk-LAQK4V3Z.js → chunk-DJMLHCLD.js} +1 -1
  127. package/dist/{chunk-6MU7HNB4.js → chunk-F73MC7EZ.js} +47 -2
  128. package/dist/{chunk-ZPSOF6VL.js → chunk-FBSEJO2C.js} +1 -1
  129. package/dist/chunk-FYTIJM2T.js +40 -0
  130. package/dist/{chunk-7JGWSOLM.js → chunk-GG2QEZO2.js} +1 -1
  131. package/dist/chunk-H6VKCIWV.js +41 -0
  132. package/dist/{chunk-6SDGRKQ7.js → chunk-HKGS67VG.js} +94 -41
  133. package/dist/chunk-IG75YMUN.js +22 -0
  134. package/dist/{chunk-JCNUQ3US.js → chunk-JDPAA2JU.js} +1 -1
  135. package/dist/chunk-KLIEPFEZ.js +95 -0
  136. package/dist/{chunk-7LD6P32I.js → chunk-L3CTFFLZ.js} +2 -18
  137. package/dist/{chunk-UG5ZMAXW.js → chunk-LELD5KPA.js} +1 -1
  138. package/dist/chunk-MNFU2RNT.js +74 -0
  139. package/dist/{chunk-S3BCVWTU.js → chunk-MY374UUD.js} +49 -31
  140. package/dist/{chunk-K5Q2DK3P.js → chunk-NXDEPUVG.js} +1 -1
  141. package/dist/{chunk-PDUZO35I.js → chunk-O2ZDZZS7.js} +15 -6
  142. package/dist/chunk-QBXZLGK2.js +40 -0
  143. package/dist/chunk-QSLIN64M.js +47 -0
  144. package/dist/{chunk-5WEVLIB6.js → chunk-RZ7RGECB.js} +1 -1
  145. package/dist/chunk-S3IENQ3E.js +336 -0
  146. package/dist/{chunk-WEIINZPA.js → chunk-SBRE7IML.js} +6 -2
  147. package/dist/{chunk-IVFJD7WY.js → chunk-UCCC7YVZ.js} +3 -2
  148. package/dist/{chunk-CIOKUMVC.js → chunk-UZPHPW3Z.js} +7 -7
  149. package/dist/chunk-VWNC2L6W.js +110 -0
  150. package/dist/chunk-VYY56AMX.js +2 -0
  151. package/dist/chunk-WI6K5M5X.js +24 -0
  152. package/dist/{chunk-R4ZJB5YX.js → chunk-WY2NLRZN.js} +2 -2
  153. package/dist/{chunk-SEFMO2EV.js → chunk-XFE5W2I4.js} +44 -5
  154. package/dist/chunk-XYCADWZN.js +100 -0
  155. package/dist/chunk-YSJC7AZC.js +62 -0
  156. package/dist/chunk-ZAJHGDAW.js +93 -0
  157. package/dist/generated/index.d.ts +14 -0
  158. package/dist/generated/index.js +65 -50
  159. package/dist/index.js +65 -50
  160. package/dist/styles.css +4456 -1965
  161. package/dist/utils/highlight.d.ts +17 -0
  162. package/dist/utils/useMediaMatch.d.ts +12 -0
  163. package/package.json +3 -3
  164. package/dist/chunk-UAQIUSSK.js +0 -2
  165. /package/dist/{chunk-PQLMLG5K.js → chunk-6AR2T5Y4.js} +0 -0
@@ -0,0 +1,288 @@
1
+ /*
2
+ * Rendered markdown, set as a document (Document.tsx).
3
+ *
4
+ * Every size here is a step on the type ramp and every gap a spacing step,
5
+ * because a reading column set in sizes of its own (32, 20, 18, 15 and 14.5px
6
+ * were measured on one) is a column that drifts from every other surface.
7
+ */
8
+
9
+ .crewlet-document {
10
+ /* The two rhythms a size sets: between blocks, and above a section. */
11
+ --crewlet-document-gap: var(--spacing-4);
12
+ --crewlet-document-section-gap: var(--spacing-6);
13
+ margin: 0;
14
+ min-width: 0;
15
+ font-family: var(--font-family-sans);
16
+ font-size: var(--font-size-sm);
17
+ line-height: var(--font-line-height-relaxed);
18
+ color: var(--color-text-secondary);
19
+ /* The renderer decides what a break is, so the whitespace rule is normal. */
20
+ white-space: normal;
21
+ overflow-wrap: break-word;
22
+ }
23
+
24
+ .crewlet-document--sm {
25
+ --crewlet-document-gap: var(--spacing-3);
26
+ --crewlet-document-section-gap: var(--spacing-5);
27
+ font-size: var(--font-size-compact);
28
+ line-height: var(--font-line-height-normal);
29
+ }
30
+
31
+ .crewlet-document--measure {
32
+ max-width: var(--size-measure);
33
+ }
34
+
35
+ /*
36
+ * EVERY BLOCK'S OWN MARGIN IS ZEROED FIRST, and the rhythm is one rule over
37
+ * siblings. The other way round, a margin reset per element after the sibling
38
+ * rule, is how a rhythm dies: the shorthand resets the top margin too, at the
39
+ * same specificity and later in the file, and every block runs into the next.
40
+ */
41
+ .crewlet-document :where(p, h1, h2, h3, h4, h5, h6, ul, ol, pre, blockquote, table, figure) {
42
+ margin: 0;
43
+ }
44
+
45
+ .crewlet-document > * + * {
46
+ margin-block-start: var(--crewlet-document-gap);
47
+ }
48
+
49
+ .crewlet-document :where(h1, h2, h3, h4, h5, h6) {
50
+ font-weight: var(--font-weight-semibold);
51
+ line-height: var(--font-line-height-tight);
52
+ letter-spacing: var(--font-letter-spacing-snug);
53
+ color: var(--color-text-primary);
54
+ /* An outline that scrolls a heading into view leaves it a little air. */
55
+ scroll-margin-block-start: var(--spacing-6);
56
+ }
57
+
58
+ /* A heading opens a section, so it gets more air above it than a paragraph. */
59
+ .crewlet-document > * + :where(h1, h2, h3, h4, h5, h6) {
60
+ margin-block-start: var(--crewlet-document-section-gap);
61
+ }
62
+
63
+ .crewlet-document h1 {
64
+ font-size: var(--font-size-2xl);
65
+ }
66
+
67
+ .crewlet-document h2 {
68
+ font-size: var(--font-size-xl);
69
+ }
70
+
71
+ .crewlet-document h3 {
72
+ font-size: var(--font-size-lg);
73
+ }
74
+
75
+ .crewlet-document :where(h4, h5, h6) {
76
+ font-size: var(--font-size-md);
77
+ }
78
+
79
+ .crewlet-document--sm h1 {
80
+ font-size: var(--font-size-lg);
81
+ }
82
+
83
+ .crewlet-document--sm h2 {
84
+ font-size: var(--font-size-md);
85
+ }
86
+
87
+ .crewlet-document--sm h3 {
88
+ font-size: var(--font-size-sm);
89
+ }
90
+
91
+ .crewlet-document--sm :where(h4, h5, h6) {
92
+ font-size: var(--font-size-compact);
93
+ color: var(--color-text-secondary);
94
+ }
95
+
96
+ /*
97
+ * A HEADING AN OUTLINE MOVED TO takes focus, so a keyboard carries on from it.
98
+ * A press draws no ring (`:focus-visible` does not match one); a keyboard's is
99
+ * drawn off the text, because the heading is not a control.
100
+ */
101
+ .crewlet-document :where(h1, h2, h3, h4, h5, h6):focus-visible {
102
+ outline: 2px solid var(--color-focus);
103
+ outline-offset: var(--spacing-1);
104
+ border-radius: var(--radius-xs);
105
+ }
106
+
107
+ .crewlet-document :where(strong, b) {
108
+ font-weight: var(--font-weight-semibold);
109
+ color: var(--color-text-primary);
110
+ }
111
+
112
+ .crewlet-document :where(ul, ol) {
113
+ padding-inline-start: var(--spacing-5);
114
+ }
115
+
116
+ .crewlet-document li + li,
117
+ .crewlet-document li > :where(ul, ol) {
118
+ margin-block-start: var(--spacing-1);
119
+ }
120
+
121
+ .crewlet-document li::marker {
122
+ color: var(--color-text-tertiary);
123
+ }
124
+
125
+ /*
126
+ * A TASK LIST keeps its box on the line rather than in the marker's place: the
127
+ * marker is what says "list", and the box is what says "done". The item's
128
+ * content is ONE column beside the box, never a second cell of the row, so a
129
+ * sublist hangs under the line it belongs to.
130
+ */
131
+ .crewlet-document ul:has(> li > input[type='checkbox']) {
132
+ list-style: none;
133
+ padding-inline-start: 0;
134
+ }
135
+
136
+ .crewlet-document li:has(> input[type='checkbox']) {
137
+ display: flex;
138
+ align-items: flex-start;
139
+ gap: var(--spacing-2);
140
+ }
141
+
142
+ .crewlet-document li:has(> input[type='checkbox']) > :not(input) {
143
+ flex: 1;
144
+ min-width: 0;
145
+ }
146
+
147
+ .crewlet-document li > input[type='checkbox'] {
148
+ flex: none;
149
+ margin: 0;
150
+ /* On the first line's centre rather than on the top of its box. */
151
+ margin-block-start: 0.35em;
152
+ accent-color: var(--color-brand-accent);
153
+ }
154
+
155
+ /*
156
+ * A FENCED BLOCK WRAPS RATHER THAN SCROLLING. One long line of JSON in a body
157
+ * otherwise pushes the whole page sideways, and a block that scrolled instead
158
+ * would owe a tab stop, since a scroller no keyboard reaches is content no
159
+ * keyboard reads. `anywhere` because these lines have no spaces to break at.
160
+ */
161
+ .crewlet-document pre {
162
+ padding: var(--spacing-2) var(--spacing-3);
163
+ border-radius: var(--radius-sm);
164
+ background: var(--color-surface-inset);
165
+ font-family: var(--font-family-mono);
166
+ font-size: var(--font-size-xs);
167
+ line-height: var(--font-line-height-normal);
168
+ color: var(--color-text-primary);
169
+ white-space: pre-wrap;
170
+ overflow-wrap: anywhere;
171
+ }
172
+
173
+ .crewlet-document pre code {
174
+ padding: 0;
175
+ background: none;
176
+ font: inherit;
177
+ }
178
+
179
+ .crewlet-document :not(pre) > code {
180
+ padding: 0 var(--spacing-1);
181
+ border-radius: var(--radius-xs);
182
+ background: var(--color-surface-inset);
183
+ font-family: var(--font-family-mono);
184
+ font-size: var(--font-size-xs);
185
+ color: var(--color-text-primary);
186
+ overflow-wrap: anywhere;
187
+ }
188
+
189
+ .crewlet-document blockquote {
190
+ padding-inline-start: var(--spacing-3);
191
+ border-inline-start: 2px solid var(--color-border-strong);
192
+ color: var(--color-text-secondary);
193
+ }
194
+
195
+ .crewlet-document hr {
196
+ margin-block: var(--crewlet-document-section-gap);
197
+ border: 0;
198
+ border-block-start: 1px solid var(--color-border-default);
199
+ }
200
+
201
+ /*
202
+ * A link in running prose keeps a permanent underline, through hover too:
203
+ * colour alone is not what says "link" (WCAG 1.4.1). The pointer is answered
204
+ * by the ink moving to the primary step.
205
+ */
206
+ .crewlet-document a,
207
+ .crewlet-document a:hover {
208
+ text-decoration: underline;
209
+ text-underline-offset: 2px;
210
+ }
211
+
212
+ .crewlet-document a {
213
+ color: var(--color-brand-accent-ink);
214
+ }
215
+
216
+ .crewlet-document a:hover {
217
+ color: var(--color-text-primary);
218
+ }
219
+
220
+ .crewlet-document a:focus-visible {
221
+ outline: 2px solid var(--color-focus);
222
+ outline-offset: 2px;
223
+ border-radius: var(--radius-xs);
224
+ }
225
+
226
+ .crewlet-document img {
227
+ max-width: 100%;
228
+ height: auto;
229
+ border-radius: var(--radius-sm);
230
+ }
231
+
232
+ /*
233
+ * A TABLE WRITTEN FOR A DOCUMENT can be wider than the column it lands in, so
234
+ * the element a renderer wraps it in scrolls rather than the page. The table
235
+ * itself keeps its display, because a table set `display: block` loses its
236
+ * table semantics to more than one screen reader.
237
+ */
238
+ .crewlet-document :where(div):has(> table) {
239
+ overflow-x: auto;
240
+ }
241
+
242
+ /* The scroller is a tab stop (see Document.tsx), so it draws the ring inside
243
+ its own box, where the table's edge would otherwise clip an outset one. */
244
+ .crewlet-document :where(div):has(> table):focus-visible {
245
+ outline: 2px solid var(--color-focus);
246
+ outline-offset: var(--size-focus-ring-inset-offset);
247
+ border-radius: var(--radius-xs);
248
+ }
249
+
250
+ .crewlet-document table {
251
+ width: 100%;
252
+ border-collapse: collapse;
253
+ font-size: var(--font-size-compact);
254
+ line-height: var(--font-line-height-snug);
255
+ }
256
+
257
+ .crewlet-document--sm table {
258
+ font-size: var(--font-size-xs);
259
+ }
260
+
261
+ .crewlet-document :where(th, td) {
262
+ padding: var(--spacing-1) var(--spacing-2);
263
+ border-block-end: 1px solid var(--color-border-default);
264
+ text-align: start;
265
+ vertical-align: top;
266
+ }
267
+
268
+ .crewlet-document th {
269
+ font-weight: var(--font-weight-semibold);
270
+ color: var(--color-text-primary);
271
+ white-space: nowrap;
272
+ }
273
+
274
+ /*
275
+ * The title above a body. The largest step a reading screen spends, at the
276
+ * tight tracking every title on the ramp takes, and it wraps anywhere because
277
+ * a title is an address somebody typed and may hold no space at all.
278
+ */
279
+ .crewlet-document-title {
280
+ margin: 0;
281
+ font-family: var(--font-family-sans);
282
+ font-size: var(--font-size-3xl);
283
+ font-weight: var(--font-weight-semibold);
284
+ line-height: var(--font-line-height-tight);
285
+ letter-spacing: var(--font-letter-spacing-tight);
286
+ color: var(--color-text-primary);
287
+ overflow-wrap: anywhere;
288
+ }
@@ -1,4 +1,4 @@
1
1
  export { EntityChip } from '../chunk-DDTDN5L2.js';
2
- import '../chunk-3UK4VFSK.js';
2
+ import '../chunk-6NIZCQUM.js';
3
3
  import '../chunk-HI6Q2UXQ.js';
4
4
  import '../chunk-ODEQTPFM.js';
@@ -0,0 +1,45 @@
1
+ import { type HTMLAttributes } from 'react';
2
+ /** One marked stretch of a text, as `[start, end)` offsets into it. */
3
+ export type HighlightRange = readonly [start: number, end: number];
4
+ /**
5
+ * The words of a query a reader typed, as the terms a match is made of:
6
+ * folded to lower case, each one once, the longest first, and none shorter than
7
+ * two characters.
8
+ *
9
+ * A ONE LETTER TERM MARKS NOTHING. "a plan for q3" would otherwise mark every
10
+ * `a` in a snippet, and a page of yellow is a page with nothing marked.
11
+ *
12
+ * THE LONGEST FIRST, so where two terms start at the same place the mark covers
13
+ * the longer one: "settle" and "settlement" in one query mark "settlement"
14
+ * whole rather than its first six letters.
15
+ */
16
+ export declare function highlightTerms(query: string): string[];
17
+ /**
18
+ * Where `terms` start a word of `text`, as ranges in reading order.
19
+ *
20
+ * A TERM MATCHES THE START OF A WORD, never its middle: "cent" marks "cents"
21
+ * and "centre" but not "percent", because a search engine matches words, and a
22
+ * mark inside a word points at a match the engine never made.
23
+ *
24
+ * THE OFFSETS ARE THE TEXT'S OWN. The match is made by one case-insensitive
25
+ * Unicode pattern over the original string rather than over a lower-cased copy,
26
+ * because lower-casing can change a string's length ("İ" becomes two code
27
+ * units) and every offset after it would point one character off.
28
+ */
29
+ export declare function highlightRanges(text: string, terms: readonly string[]): HighlightRange[];
30
+ export interface HighlightProps extends HTMLAttributes<HTMLSpanElement> {
31
+ /** The text to draw. */
32
+ text: string;
33
+ /** What to mark, usually `highlightTerms(query)`. */
34
+ terms: readonly string[];
35
+ }
36
+ /**
37
+ * A line of text with the words a search matched marked in it: a result's
38
+ * title, its snippet, a passage of a page opened from a search.
39
+ *
40
+ * A `mark` ELEMENT, because a match is part of what the text says to a reader
41
+ * who came looking for it, and the element is what tells assistive technology
42
+ * so. The ink stays the text's own and the mark is a ground behind it, so a
43
+ * marked word reads at the same contrast as the words beside it.
44
+ */
45
+ export declare function Highlight({ text, terms, className, ...rest }: HighlightProps): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import './Highlight.css';
2
+ export { Highlight, highlightRanges, highlightTerms } from './Highlight.js';
3
+ export type { HighlightProps, HighlightRange } from './Highlight.js';
@@ -0,0 +1,2 @@
1
+ export { Highlight, highlightRanges, highlightTerms } from '../chunk-H6VKCIWV.js';
2
+ import '../chunk-ODEQTPFM.js';
@@ -0,0 +1,29 @@
1
+ /*
2
+ * Words a search matched (Highlight.tsx).
3
+ */
4
+
5
+ /*
6
+ * A GROUND, NEVER AN INK. The marked word keeps the ink of the text around it,
7
+ * so it reads at the contrast that text was measured at, and the accent's soft
8
+ * step behind it says "this is what you searched for" without making the word
9
+ * louder than its sentence. The accent is the one colour that means "where the
10
+ * reader is", and a match is exactly that: the reader's own question, found.
11
+ */
12
+ .crewlet-highlight__match {
13
+ border-radius: var(--radius-xs);
14
+ background: var(--color-brand-accent-soft-strong);
15
+ color: inherit;
16
+ }
17
+
18
+ /*
19
+ * Forced colours replaces every author ground with the canvas, which would
20
+ * leave a match drawn exactly like the words beside it. The system's own pair
21
+ * for a mark is what that mode reserves for this job.
22
+ */
23
+ @media (forced-colors: active) {
24
+ .crewlet-highlight__match {
25
+ forced-color-adjust: none;
26
+ background: Mark;
27
+ color: MarkText;
28
+ }
29
+ }
@@ -1,8 +1,8 @@
1
1
  import '../chunk-EXHQ2QVW.js';
2
- export { HuePicker } from '../chunk-K5Q2DK3P.js';
2
+ export { HuePicker } from '../chunk-NXDEPUVG.js';
3
3
  import '../chunk-AYKXMIOR.js';
4
- import '../chunk-EBBAAQDY.js';
5
- import '../chunk-JHQUT4WJ.js';
4
+ import '../chunk-26PEPONN.js';
5
+ import '../chunk-4LDTQWS7.js';
6
6
  import '../chunk-CBOICT64.js';
7
7
  import '../chunk-BHHIIK3M.js';
8
8
  import '../chunk-BZFWDIV6.js';
@@ -1,4 +1,4 @@
1
- export { ImageUpload } from '../chunk-LAQK4V3Z.js';
2
- import '../chunk-3UK4VFSK.js';
1
+ export { ImageUpload } from '../chunk-DJMLHCLD.js';
2
+ import '../chunk-6NIZCQUM.js';
3
3
  import '../chunk-HI6Q2UXQ.js';
4
4
  import '../chunk-ODEQTPFM.js';
@@ -1,10 +1,13 @@
1
1
  /*
2
2
  * ImageUpload, the click-to-upload affordance built on Avatar.
3
3
  *
4
- * WHITE ON THE SCRIM, from tokens, in both palettes. The overlay used to spell
4
+ * WHITE ON THE SCRIM, from tokens, in every theme. The overlay used to spell
5
5
  * its own rgba(0, 0, 0, 0.5) and three shades of white; the scrim and the
6
- * on-accent step are the two values the palette already measures for exactly
7
- * this, which is a label drawn on something dark whatever is behind it.
6
+ * on-scrim step are the two values the palette measures for exactly this,
7
+ * which is a label drawn on something dark whatever is behind it. The
8
+ * on-accent step is not: a theme whose accent is light labels it dark. The
9
+ * remove button is the danger fill, and takes the on-danger step for the
10
+ * same reason.
8
11
  *
9
12
  * NO LITERAL FALLBACKS INSIDE var(). A fallback is what renders whenever the
10
13
  * token name is misspelt, so it hides the very failure it looks like
@@ -91,7 +94,7 @@
91
94
  justify-content: center;
92
95
  gap: 2px;
93
96
  background: var(--color-surface-scrim);
94
- color: var(--color-text-on-accent);
97
+ color: var(--color-text-on-scrim);
95
98
  opacity: 0;
96
99
  transition: opacity var(--motion-duration-base) var(--motion-easing-default);
97
100
  pointer-events: none;
@@ -136,7 +139,7 @@
136
139
  height: calc(var(--crewlet-image-upload-size) * 0.3);
137
140
  border-radius: var(--radius-circle);
138
141
  border: 2px solid var(--color-surface-scrim);
139
- border-top-color: var(--color-text-on-accent);
142
+ border-top-color: var(--color-text-on-scrim);
140
143
  animation: crewlet-image-upload-spin calc(var(--motion-duration-slow) * 2.5) linear infinite;
141
144
  }
142
145
 
@@ -166,7 +169,7 @@
166
169
  border-radius: var(--radius-circle);
167
170
  background: var(--color-feedback-danger);
168
171
  border: 2px solid var(--color-surface-background);
169
- color: var(--color-text-on-accent);
172
+ color: var(--color-text-on-danger);
170
173
  cursor: pointer;
171
174
  opacity: 0;
172
175
  transition: opacity var(--motion-duration-fast) var(--motion-easing-default);
@@ -0,0 +1,116 @@
1
+ import { type ButtonHTMLAttributes, type HTMLAttributes, type LiHTMLAttributes, type MouseEvent, type ReactNode } from 'react';
2
+ import { type HeadingLevel } from '../utils/headingLevel.js';
3
+ export interface InboxListProps extends HTMLAttributes<HTMLElement> {
4
+ /** Names the list as a landmark: "Inbox". */
5
+ label: string;
6
+ }
7
+ /**
8
+ * The column of an inbox: what reached a person, grouped, one row each, read
9
+ * in full in a pane beside it.
10
+ *
11
+ * A NAVIGATION, NOT A TABLE. Every row opens something, and a reader moves
12
+ * between them to read one at a time. It promises no columns, so it draws
13
+ * none, and its rows are as tall as their words rather than one fixed height.
14
+ */
15
+ export declare function InboxList({ label, className, children, ...rest }: InboxListProps): import("react").JSX.Element;
16
+ export declare namespace InboxList {
17
+ var Group: typeof InboxGroup;
18
+ var Row: typeof InboxRow;
19
+ var More: typeof InboxMore;
20
+ var Toggle: typeof InboxToggle;
21
+ }
22
+ export interface InboxGroupProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
23
+ /** The group's name: "Needs you", "Updates". */
24
+ label: ReactNode;
25
+ /**
26
+ * Names the group for a screen reader only. For rows a control above them
27
+ * already introduces, such as the snoozed ones under their own toggle.
28
+ */
29
+ hideLabel?: boolean | undefined;
30
+ /** Overrides the level the label is rendered at. */
31
+ headingLevel?: HeadingLevel | undefined;
32
+ }
33
+ /**
34
+ * A labelled run of rows. The label is a heading set in the micro-label
35
+ * register, so a reader navigating by heading lands on each group and a
36
+ * reader scanning sees where one ends.
37
+ */
38
+ export declare function InboxGroup({ label, hideLabel, headingLevel, className, children, ...rest }: InboxGroupProps): import("react").JSX.Element;
39
+ export type InboxRowTone = 'default' | 'danger';
40
+ export interface InboxRowProps extends Omit<LiHTMLAttributes<HTMLLIElement>, 'onClick' | 'title'> {
41
+ /** Who the row is from: a seat's or a person's name. */
42
+ title: ReactNode;
43
+ /** A word after the name where the row is not a plain question or update: "coding run", "stopped". */
44
+ qualifier?: ReactNode;
45
+ /** `danger` sets the qualifier in the danger ink, for a seat that has stopped. */
46
+ qualifierTone?: InboxRowTone | undefined;
47
+ /** At the end of the first line: when it arrived. */
48
+ meta?: ReactNode;
49
+ /** Before the words: an avatar, drawn at the target size. */
50
+ leading?: ReactNode;
51
+ /** What the row says, in up to three lines. */
52
+ children?: ReactNode;
53
+ /** Drawn after the words in the quiet ink, inside the same three lines: a comment's own text. */
54
+ excerpt?: ReactNode;
55
+ /**
56
+ * Under the row and OUTSIDE its control, so it can be a control of its own:
57
+ * the task the row is about, as a link.
58
+ */
59
+ aside?: ReactNode;
60
+ /** This row is the one open beside the list. */
61
+ selected?: boolean | undefined;
62
+ /** Not read yet: the name is heavier, the words take the primary ink, and the state is read out. */
63
+ unread?: boolean | undefined;
64
+ /** Read after the row's words when `unread`. */
65
+ unreadLabel?: string | undefined;
66
+ /** It waits on the reader: the words take the primary ink. */
67
+ actionable?: boolean | undefined;
68
+ /** Settled: the words are struck through in the quiet ink, and the state is read out. */
69
+ done?: boolean | undefined;
70
+ /** Read after the row's words when `done`: "Answered", "Resolved". */
71
+ doneLabel?: string | undefined;
72
+ /** Opens the row as a link. */
73
+ href?: string | undefined;
74
+ /**
75
+ * Opens the row as a button, or, beside `href`, takes the press first: a
76
+ * router calls `preventDefault` on a plain click and lets a modified one
77
+ * open the link in a tab.
78
+ */
79
+ onClick?: ((event: MouseEvent<HTMLElement>) => void) | undefined;
80
+ }
81
+ /**
82
+ * One row: WHO, then WHAT in up to three lines, then the task it is about.
83
+ *
84
+ * THE ROW IS ONE CONTROL and the task is another. A link nested inside a
85
+ * button is invalid and unreachable by keyboard, so the task sits under the
86
+ * control, in the same item, and lines up with the words above it. The item
87
+ * takes the hover and the selected fill as a whole, so the two read as one row.
88
+ *
89
+ * THE SELECTED FILL IS NEUTRAL. An inbox is read one row after another, and an
90
+ * accent tint on the open row made the column read as a column of alerts; the
91
+ * pressed fill says "here" without saying "look". The control carries
92
+ * `aria-current`, so the row is announced as the open one where focus is.
93
+ *
94
+ * NOTHING IS CUT AT THE EDGE. The name ellipsizes, the time never wraps, and
95
+ * the words take up to three lines before they stop, so a row says what it is
96
+ * rather than its first few words.
97
+ */
98
+ export declare function InboxRow({ title, qualifier, qualifierTone, meta, leading, excerpt, aside, selected, unread, unreadLabel, actionable, done, doneLabel, href, onClick, className, children, ...rest }: InboxRowProps): import("react").JSX.Element;
99
+ export type InboxMoreProps = HTMLAttributes<HTMLDivElement>;
100
+ /**
101
+ * The end of the list: the quiet toggles that open what is not in it by
102
+ * default, the snoozed rows and the earlier ones. Two words at the bottom
103
+ * rather than a filter bar at the top, because a reader opens them rarely
104
+ * and a filter bar is read every time.
105
+ */
106
+ export declare function InboxMore({ className, children, ...rest }: InboxMoreProps): import("react").JSX.Element;
107
+ export interface InboxToggleProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {
108
+ /** Whether the rows it opens are shown. */
109
+ expanded: boolean;
110
+ }
111
+ /**
112
+ * One of those toggles: a word in the quiet ink that opens rows under it.
113
+ * Its own `aria-expanded` says whether they are open, and the ink steps up to
114
+ * the primary while they are.
115
+ */
116
+ export declare function InboxToggle({ expanded, className, children, ...rest }: InboxToggleProps): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import './InboxList.css';
2
+ export { InboxList, InboxGroup, InboxRow, InboxMore, InboxToggle } from './InboxList.js';
3
+ export type { InboxListProps, InboxGroupProps, InboxRowProps, InboxRowTone, InboxMoreProps, InboxToggleProps, } from './InboxList.js';
@@ -0,0 +1,5 @@
1
+ export { InboxGroup, InboxList, InboxMore, InboxRow, InboxToggle } from '../chunk-XYCADWZN.js';
2
+ import '../chunk-RK4XPHVG.js';
3
+ import '../chunk-PQADV6P6.js';
4
+ import '../chunk-BZFWDIV6.js';
5
+ import '../chunk-ODEQTPFM.js';