@crewlethq/ui 0.12.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 (157) hide show
  1. package/README.md +66 -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/Combobox/index.js +2 -2
  15. package/dist/CommandPalette/CommandPalette.d.ts +48 -1
  16. package/dist/CommandPalette/index.js +3 -3
  17. package/dist/{CommandPalette-C5AMKGN2.css → CommandPalette-HBTNKHZQ.css} +55 -2
  18. package/dist/DataTable/index.js +4 -4
  19. package/dist/DataView/index.js +11 -11
  20. package/dist/DateTimePicker/index.js +2 -2
  21. package/dist/Document/Document.d.ts +56 -0
  22. package/dist/Document/index.d.ts +3 -0
  23. package/dist/Document/index.js +2 -0
  24. package/dist/Document-PQGXJHB7.css +288 -0
  25. package/dist/EntityChip/index.js +1 -1
  26. package/dist/Highlight/Highlight.d.ts +45 -0
  27. package/dist/Highlight/index.d.ts +3 -0
  28. package/dist/Highlight/index.js +2 -0
  29. package/dist/Highlight-DXLV2R6L.css +29 -0
  30. package/dist/HuePicker/index.js +3 -3
  31. package/dist/ImageUpload/index.js +2 -2
  32. package/dist/{ImageUpload-L2GE4JUM.css → ImageUpload-NVGMN7DP.css} +9 -6
  33. package/dist/InboxList/InboxList.d.ts +116 -0
  34. package/dist/InboxList/index.d.ts +3 -0
  35. package/dist/InboxList/index.js +5 -0
  36. package/dist/InboxList-YMFWKGGS.css +252 -0
  37. package/dist/KeyChip/KeyChip.d.ts +21 -0
  38. package/dist/KeyChip/index.d.ts +3 -0
  39. package/dist/KeyChip/index.js +2 -0
  40. package/dist/KeyChip-4XJU4BBE.css +30 -0
  41. package/dist/Link/Link.d.ts +17 -2
  42. package/dist/Link/index.js +1 -1
  43. package/dist/{Link-6BEFNMN2.css → Link-WPMVLKLY.css} +36 -1
  44. package/dist/ListInput/index.js +2 -2
  45. package/dist/Listbox/index.d.ts +2 -0
  46. package/dist/Listbox/index.js +1 -1
  47. package/dist/Listbox/useHighlightRest.d.ts +35 -0
  48. package/dist/MarkdownEditor/MarkdownEditor.d.ts +93 -0
  49. package/dist/MarkdownEditor/format.d.ts +34 -0
  50. package/dist/MarkdownEditor/index.d.ts +5 -0
  51. package/dist/MarkdownEditor/index.js +12 -0
  52. package/dist/MarkdownEditor-ZLSHTOIZ.css +146 -0
  53. package/dist/Modal/Modal.d.ts +5 -1
  54. package/dist/Modal/index.js +1 -1
  55. package/dist/{Modal-BNT3TDV2.css → Modal-3YJ2GG2T.css} +33 -0
  56. package/dist/OrgLabel/index.js +1 -1
  57. package/dist/OrgNode/index.js +1 -1
  58. package/dist/OrgTable/index.js +5 -5
  59. package/dist/Outline/Outline.d.ts +72 -0
  60. package/dist/Outline/index.d.ts +3 -0
  61. package/dist/Outline/index.js +2 -0
  62. package/dist/Outline-VCXKKU3E.css +78 -0
  63. package/dist/Popover/Popover.d.ts +21 -1
  64. package/dist/Popover/index.js +1 -1
  65. package/dist/ReadingPane/ReadingPane.d.ts +95 -0
  66. package/dist/ReadingPane/index.d.ts +3 -0
  67. package/dist/ReadingPane/index.js +4 -0
  68. package/dist/ReadingPane-5UOLPWY5.css +194 -0
  69. package/dist/SegmentedControl/SegmentedControl.d.ts +9 -1
  70. package/dist/SegmentedControl/index.js +3 -3
  71. package/dist/{SegmentedControl-76HODRBT.css → SegmentedControl-PKBLJVSA.css} +18 -0
  72. package/dist/Select/Select.d.ts +22 -0
  73. package/dist/Select/index.js +2 -2
  74. package/dist/{Select-4ANVLHUY.css → Select-XMZ44RWY.css} +24 -0
  75. package/dist/SidebarNav/index.js +2 -1
  76. package/dist/{SidebarNav-X5NLZNWA.css → SidebarNav-KF66MLOM.css} +4 -19
  77. package/dist/Switcher/Switcher.d.ts +151 -0
  78. package/dist/Switcher/index.d.ts +3 -0
  79. package/dist/Switcher/index.js +16 -0
  80. package/dist/Switcher-B44Q4WF4.css +346 -0
  81. package/dist/Tabs/Tabs.d.ts +7 -1
  82. package/dist/Tabs/index.js +1 -1
  83. package/dist/{Tabs-5I5Q5KKM.css → Tabs-ITJYJFMU.css} +49 -0
  84. package/dist/TagsInput/index.js +3 -3
  85. package/dist/ThemeGallery/ThemeGallery.d.ts +65 -0
  86. package/dist/ThemeGallery/index.d.ts +3 -0
  87. package/dist/ThemeGallery/index.js +6 -0
  88. package/dist/ThemeGallery-NITASULQ.css +93 -0
  89. package/dist/ThemeSwatch/ThemeSwatch.d.ts +71 -0
  90. package/dist/ThemeSwatch/index.d.ts +3 -0
  91. package/dist/ThemeSwatch/index.js +2 -0
  92. package/dist/ThemeSwatch-4DL457ZB.css +256 -0
  93. package/dist/ThemeSwitcher/ThemeSwitcher.d.ts +5 -1
  94. package/dist/ThemeSwitcher/index.js +4 -4
  95. package/dist/ThemeToggle/ThemeToggle.d.ts +1 -1
  96. package/dist/ThemeToggle/index.js +1 -1
  97. package/dist/TimeWindowPicker/index.js +4 -4
  98. package/dist/Toaster/index.js +1 -1
  99. package/dist/{Toaster-NVDCEIP5.css → Toaster-KZ7YE2HA.css} +1 -0
  100. package/dist/Tree/index.d.ts +1 -1
  101. package/dist/Tree/index.js +1 -1
  102. package/dist/Tree/useTreeState.d.ts +37 -7
  103. package/dist/TreeCanvas/index.js +2 -2
  104. package/dist/TreeGrid/TreeGrid.d.ts +22 -2
  105. package/dist/TreeGrid/index.js +2 -2
  106. package/dist/{TreeGrid-NSW7VMOX.css → TreeGrid-FBX3MSJA.css} +19 -0
  107. package/dist/{chunk-EBBAAQDY.js → chunk-26PEPONN.js} +3 -1
  108. package/dist/{chunk-HV6IZFBK.js → chunk-4FFHJBEN.js} +2 -2
  109. package/dist/{chunk-JHQUT4WJ.js → chunk-4LDTQWS7.js} +1 -1
  110. package/dist/{chunk-GXYNEDNA.js → chunk-4Y7WKXAW.js} +1 -1
  111. package/dist/{chunk-MCPKHYMC.js → chunk-6LXMLQUM.js} +17 -4
  112. package/dist/{chunk-3UK4VFSK.js → chunk-6NIZCQUM.js} +1 -1
  113. package/dist/{chunk-ORNOOMVY.js → chunk-6TSZCBID.js} +2 -2
  114. package/dist/{chunk-ZMJHK7DR.js → chunk-75WOCYGC.js} +2 -2
  115. package/dist/chunk-77IEHFY4.js +299 -0
  116. package/dist/chunk-A5YKNRG6.js +94 -0
  117. package/dist/{chunk-HLBRPES3.js → chunk-B2CITO6R.js} +2 -2
  118. package/dist/{chunk-TEEJSTFG.js → chunk-CF6DTETT.js} +1 -1
  119. package/dist/{chunk-LAQK4V3Z.js → chunk-DJMLHCLD.js} +1 -1
  120. package/dist/{chunk-6MU7HNB4.js → chunk-F73MC7EZ.js} +47 -2
  121. package/dist/{chunk-ZPSOF6VL.js → chunk-FBSEJO2C.js} +1 -1
  122. package/dist/chunk-FYTIJM2T.js +40 -0
  123. package/dist/{chunk-ZHOM65MI.js → chunk-GG2QEZO2.js} +2 -2
  124. package/dist/chunk-H6VKCIWV.js +41 -0
  125. package/dist/{chunk-XV65NTIT.js → chunk-HKGS67VG.js} +94 -41
  126. package/dist/chunk-IG75YMUN.js +22 -0
  127. package/dist/{chunk-JCNUQ3US.js → chunk-JDPAA2JU.js} +1 -1
  128. package/dist/chunk-KLIEPFEZ.js +95 -0
  129. package/dist/{chunk-7LD6P32I.js → chunk-L3CTFFLZ.js} +2 -18
  130. package/dist/{chunk-UG5ZMAXW.js → chunk-LELD5KPA.js} +1 -1
  131. package/dist/chunk-MNFU2RNT.js +74 -0
  132. package/dist/{chunk-S3BCVWTU.js → chunk-MY374UUD.js} +49 -31
  133. package/dist/{chunk-K5Q2DK3P.js → chunk-NXDEPUVG.js} +1 -1
  134. package/dist/{chunk-PDUZO35I.js → chunk-O2ZDZZS7.js} +15 -6
  135. package/dist/{chunk-5WEVLIB6.js → chunk-RZ7RGECB.js} +1 -1
  136. package/dist/chunk-S3IENQ3E.js +336 -0
  137. package/dist/{chunk-WEIINZPA.js → chunk-SBRE7IML.js} +6 -2
  138. package/dist/{chunk-IVFJD7WY.js → chunk-UCCC7YVZ.js} +3 -2
  139. package/dist/{chunk-IINFVK3W.js → chunk-UZPHPW3Z.js} +6 -6
  140. package/dist/chunk-VWNC2L6W.js +110 -0
  141. package/dist/chunk-VYY56AMX.js +2 -0
  142. package/dist/chunk-WI6K5M5X.js +24 -0
  143. package/dist/{chunk-GOUKOXJK.js → chunk-WY2NLRZN.js} +3 -3
  144. package/dist/{chunk-SEFMO2EV.js → chunk-XFE5W2I4.js} +44 -5
  145. package/dist/chunk-XYCADWZN.js +100 -0
  146. package/dist/chunk-YSJC7AZC.js +62 -0
  147. package/dist/chunk-ZAJHGDAW.js +93 -0
  148. package/dist/generated/index.d.ts +12 -0
  149. package/dist/generated/index.js +65 -52
  150. package/dist/index.js +65 -52
  151. package/dist/styles.css +2449 -161
  152. package/dist/utils/highlight.d.ts +17 -0
  153. package/dist/utils/useMediaMatch.d.ts +12 -0
  154. package/package.json +3 -3
  155. package/dist/chunk-UAQIUSSK.js +0 -2
  156. package/dist/{chunk-74OVQWA5.js → chunk-6AR2T5Y4.js} +0 -0
  157. package/dist/{chunk-GARACZAH.js → chunk-LZP7FGT7.js} +1 -1
@@ -17,7 +17,12 @@ export interface CommandPaletteItem {
17
17
  * the palette's `onKeyDown`, like the chord that opens it.
18
18
  */
19
19
  meta?: ReactNode;
20
- onSelect: () => void;
20
+ /**
21
+ * Taking the row. The surface closes after it, which is what a launcher's
22
+ * row means; a row that leads somewhere INSIDE the surface (into a step) or
23
+ * waits on an answer the reader is owed returns `false` to keep it open.
24
+ */
25
+ onSelect: () => boolean | void;
21
26
  }
22
27
  export interface CommandPaletteGroup {
23
28
  id: string;
@@ -25,6 +30,28 @@ export interface CommandPaletteGroup {
25
30
  label: string;
26
31
  items: CommandPaletteItem[];
27
32
  }
33
+ /**
34
+ * A STEP the palette has gone into: a second list in place of the results,
35
+ * for a choice the first one led to (which project to file into, which theme
36
+ * to use). The caller hands over the step's own rows as `groups` and its own
37
+ * query; this draws where the reader is and the way back.
38
+ */
39
+ export interface CommandPaletteStep {
40
+ /** What the step chooses, on the chip at the field's start: "Change theme". */
41
+ label: string;
42
+ /**
43
+ * Back to where the step was opened from: the chip, Escape, and Backspace in
44
+ * an empty field. The palette stays open; closing is the veil's and the
45
+ * caller's chord.
46
+ */
47
+ onBack: () => void;
48
+ /**
49
+ * The id of the row the step's list opens on: the choice already in effect,
50
+ * so a step that previews its rows opens on what is on screen rather than
51
+ * previewing its first row. The first row without it.
52
+ */
53
+ startAt?: string | undefined;
54
+ }
28
55
  /** One scope the search can be narrowed to: a tab over the results. */
29
56
  export interface CommandPaletteScope {
30
57
  /** Stable identity: the value `scope`, `onScopeChange` and `groupsScope` carry. */
@@ -105,6 +132,19 @@ export type CommandPaletteProps = Omit<HTMLAttributes<HTMLElement>, 'children' |
105
132
  pendingMessage?: string | undefined;
106
133
  /** Names the result list itself. */
107
134
  resultsLabel?: string | undefined;
135
+ /**
136
+ * The step the palette is in, or none. In a step the field starts with a
137
+ * chip naming it, which goes back on a press, and Escape and Backspace in
138
+ * an empty field go back rather than closing the surface.
139
+ */
140
+ step?: CommandPaletteStep | undefined;
141
+ /**
142
+ * Told where the highlight COMES TO REST, and `null` when the list empties,
143
+ * the pointer leaves it or the surface closes: at once for a key, and once
144
+ * the pointer has rested on a row for `HIGHLIGHT_REST_MS`. What a step that
145
+ * previews its rows listens to.
146
+ */
147
+ onHighlight?: ((item: CommandPaletteItem | null) => void) | undefined;
108
148
  };
109
149
  /**
110
150
  * One search surface for a whole product: screens, records, and any id pasted
@@ -158,6 +198,13 @@ export type CommandPaletteProps = Omit<HTMLAttributes<HTMLElement>, 'children' |
158
198
  * prevented, so it does not move focus off the field: a combobox that loses its
159
199
  * input names no highlight, and typing reaches nothing.
160
200
  *
201
+ * A STEP IS A SECOND LIST, NOT A SECOND SURFACE (`step`). The field stays
202
+ * where it is, so focus and the reader's place survive going in and coming
203
+ * back; its search glyph gives way to a chip naming the step, and the keys
204
+ * that would close the surface go back instead: Escape, and Backspace in an
205
+ * empty field, which is where a reader who has erased their query is asking to
206
+ * go. The veil still closes it, as does the caller's own chord.
207
+ *
161
208
  * THE CHORD THAT OPENS IT IS THE APPLICATION'S, not this component's. Pass an
162
209
  * `onKeyDown`: it reaches the frame, which is every key pressed inside the
163
210
  * surface, and closing from there is one line the caller already has the
@@ -1,8 +1,8 @@
1
- export { CommandPalette } from '../chunk-XV65NTIT.js';
2
- import '../chunk-6MU7HNB4.js';
1
+ export { CommandPalette } from '../chunk-HKGS67VG.js';
2
+ import '../chunk-CF6DTETT.js';
3
+ import '../chunk-F73MC7EZ.js';
3
4
  import '../chunk-SMBKXWML.js';
4
5
  import '../chunk-FTEJPHBI.js';
5
- import '../chunk-TEEJSTFG.js';
6
6
  import '../chunk-OG6CL3EB.js';
7
7
  import '../chunk-PQADV6P6.js';
8
8
  import '../chunk-4FQT6ZAY.js';
@@ -56,17 +56,70 @@
56
56
  * glyph stood 24px in and the keycap 28px from the edge; at 12px they stand
57
57
  * 20px and 16px in, where the approved palette draws them, and the query still
58
58
  * starts on the line the design's does.
59
+ *
60
+ * The band is the BAR around the field, so a step's chip shares it: the field
61
+ * itself draws no box and fills what the chip leaves.
59
62
  */
60
- .crewlet-input.crewlet-palette__field {
63
+ .crewlet-palette__bar {
64
+ display: flex;
65
+ align-items: center;
66
+ gap: var(--spacing-2);
61
67
  flex-shrink: 0;
62
68
  min-height: var(--size-row-lg);
63
69
  padding-inline: var(--spacing-3);
64
- border: none;
65
70
  border-bottom: 1px solid var(--color-border-default);
71
+ }
72
+
73
+ .crewlet-input.crewlet-palette__field {
74
+ flex: 1;
75
+ min-width: 0;
76
+ align-self: stretch;
77
+ padding-inline: 0;
78
+ border: none;
66
79
  border-radius: 0;
67
80
  background: transparent;
68
81
  }
69
82
 
83
+ /*
84
+ * THE STEP'S CHIP: where the reader is, and the way back. It wears the
85
+ * accent's soft tint and ink, the kit's mark for "this is on", because a step
86
+ * is a narrowing the reader chose, as a filter that is on is; it is a control,
87
+ * so it takes the pointer and draws its own ring.
88
+ */
89
+ .crewlet-palette__step {
90
+ display: inline-flex;
91
+ align-items: center;
92
+ gap: var(--spacing-1);
93
+ flex: none;
94
+ min-height: var(--size-target-min);
95
+ padding: 0 var(--spacing-2) 0 var(--spacing-1);
96
+ border: none;
97
+ border-radius: var(--radius-sm);
98
+ background: var(--color-brand-accent-soft);
99
+ color: var(--color-brand-accent-ink);
100
+ font: inherit;
101
+ font-size: var(--font-size-xs);
102
+ font-weight: var(--font-weight-medium);
103
+ white-space: nowrap;
104
+ cursor: pointer;
105
+ }
106
+
107
+ /* Under the pointer it draws the line the soft tint is paired with, rather
108
+ than a stronger fill its ink was never measured on. */
109
+ .crewlet-palette__step:hover {
110
+ box-shadow: inset 0 0 0 1px var(--color-brand-accent-soft-strong);
111
+ }
112
+
113
+ .crewlet-palette__step:focus-visible {
114
+ outline: 2px solid var(--color-focus);
115
+ outline-offset: 1px;
116
+ }
117
+
118
+ /* In a step the query starts a gap after the chip, not a text inset after it. */
119
+ .crewlet-palette__bar.is-step .crewlet-input__control {
120
+ padding-left: 0;
121
+ }
122
+
70
123
  .crewlet-input.crewlet-palette__field .crewlet-input__control {
71
124
  font-size: var(--font-size-md);
72
125
  }
@@ -1,11 +1,11 @@
1
- export { ALL_ITEMS, CopyableCell, DATA_TABLE_LABELS, DataTable, RowActionsMenu } from '../chunk-GOUKOXJK.js';
2
- import '../chunk-AV2DXAEL.js';
1
+ export { ALL_ITEMS, CopyableCell, DATA_TABLE_LABELS, DataTable, RowActionsMenu } from '../chunk-WY2NLRZN.js';
3
2
  import '../chunk-TFH6SYWB.js';
4
3
  import '../chunk-EUCC37WY.js';
5
- import '../chunk-TEEJSTFG.js';
4
+ import '../chunk-YCTMKKRA.js';
6
5
  import '../chunk-5VNUYO76.js';
6
+ import '../chunk-CF6DTETT.js';
7
7
  import '../chunk-OG6CL3EB.js';
8
- import '../chunk-YCTMKKRA.js';
8
+ import '../chunk-AV2DXAEL.js';
9
9
  import '../chunk-PQADV6P6.js';
10
10
  import '../chunk-4FQT6ZAY.js';
11
11
  import '../chunk-7RPGY3JE.js';
@@ -1,23 +1,23 @@
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-IINFVK3W.js';
2
- import '../chunk-PGRPNDWM.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-UZPHPW3Z.js';
3
2
  import '../chunk-HOXGBLEY.js';
4
3
  import '../chunk-3CZ7XAVY.js';
5
- import '../chunk-JCNUQ3US.js';
6
- import '../chunk-6MU7HNB4.js';
7
- import '../chunk-SMBKXWML.js';
8
- import '../chunk-FTEJPHBI.js';
9
- import '../chunk-GOUKOXJK.js';
10
- import '../chunk-AV2DXAEL.js';
4
+ import '../chunk-PGRPNDWM.js';
5
+ import '../chunk-WY2NLRZN.js';
11
6
  import '../chunk-TFH6SYWB.js';
12
7
  import '../chunk-EUCC37WY.js';
13
- import '../chunk-TEEJSTFG.js';
8
+ import '../chunk-JDPAA2JU.js';
9
+ import '../chunk-YCTMKKRA.js';
14
10
  import '../chunk-5VNUYO76.js';
11
+ import '../chunk-CF6DTETT.js';
12
+ import '../chunk-F73MC7EZ.js';
13
+ import '../chunk-SMBKXWML.js';
14
+ import '../chunk-FTEJPHBI.js';
15
15
  import '../chunk-GXQ3B46I.js';
16
16
  import '../chunk-OG6CL3EB.js';
17
- import '../chunk-YCTMKKRA.js';
17
+ import '../chunk-AV2DXAEL.js';
18
18
  import '../chunk-PQADV6P6.js';
19
19
  import '../chunk-4FQT6ZAY.js';
20
- import '../chunk-PDUZO35I.js';
20
+ import '../chunk-O2ZDZZS7.js';
21
21
  import '../chunk-BHHIIK3M.js';
22
22
  import '../chunk-7RPGY3JE.js';
23
23
  import '../chunk-R25RGPUB.js';
@@ -1,8 +1,8 @@
1
- export { DEFAULT_DATE_TIME_PICKER_LABELS, DateTimePicker } from '../chunk-JCNUQ3US.js';
1
+ export { DEFAULT_DATE_TIME_PICKER_LABELS, DateTimePicker } from '../chunk-JDPAA2JU.js';
2
2
  import '../chunk-GXQ3B46I.js';
3
3
  import '../chunk-OG6CL3EB.js';
4
4
  import '../chunk-4FQT6ZAY.js';
5
- import '../chunk-PDUZO35I.js';
5
+ import '../chunk-O2ZDZZS7.js';
6
6
  import '../chunk-7RPGY3JE.js';
7
7
  import '../chunk-R25RGPUB.js';
8
8
  import '../chunk-BZFWDIV6.js';
@@ -0,0 +1,56 @@
1
+ import type { HTMLAttributes } from 'react';
2
+ export type DocumentSize =
3
+ /**
4
+ * A page read on its own: the small step at the relaxed leading, sections at
5
+ * the ramp's xl and lg. THE DEFAULT, because a knowledge page, a runbook and
6
+ * a design are what this is for.
7
+ */
8
+ 'md'
9
+ /**
10
+ * A document read beside other things: a comment, a preview in a side
11
+ * pane, a result's peek. The body's own size, sections a step over it.
12
+ */
13
+ | 'sm';
14
+ export type DocumentElement = 'div' | 'article' | 'section';
15
+ export interface DocumentProps extends HTMLAttributes<HTMLElement> {
16
+ /** The element to draw. A `div` by default; an `article` for a page that stands alone. */
17
+ as?: DocumentElement | undefined;
18
+ size?: DocumentSize | undefined;
19
+ /** Bounds the line length at the measure token. On by default; a measure is the point. */
20
+ measure?: 'normal' | 'none' | undefined;
21
+ }
22
+ /**
23
+ * Rendered markdown, set as a document: headings, paragraphs, lists and task
24
+ * lists, quotes, code, tables, rules, links and images.
25
+ *
26
+ * A STYLESHEET OVER ELEMENTS, NOT A RENDERER. What a body may contain (which
27
+ * link schemes are safe, whether raw HTML is text) is a decision about the
28
+ * application's own content, so the parser stays with the application and
29
+ * emits plain semantic elements, and this draws them. Any renderer that emits
30
+ * `h2`, `ul`, `table` and the rest works unchanged, and nothing here reads a
31
+ * class name a renderer would have to know about.
32
+ *
33
+ * WHAT IT RECOGNISES BY SHAPE. A task item is a list item whose first child is
34
+ * a checkbox; a table that may be wider than the column sits in an element of
35
+ * its own, and that element scrolls. Both are read off the structure, so a
36
+ * renderer gets them by emitting the markup it would emit anyway. A renderer
37
+ * gives that element `tabIndex={0}`, a `region` role and a name, because a
38
+ * scroller no keyboard can reach is a table no keyboard can read to its end.
39
+ *
40
+ * THE TITLE IS NOT PART OF IT. A page's title is its address and its `h1`, set
41
+ * above the body by `DocumentTitle`, so a renderer draws the body's own
42
+ * headings from `h2` down and the outline of the page starts there.
43
+ */
44
+ export declare function Document({ as: Tag, size, measure, className, children, ...rest }: DocumentProps): import("react").JSX.Element;
45
+ export interface DocumentTitleProps extends HTMLAttributes<HTMLHeadingElement> {
46
+ /** The heading level. An `h1` by default: on a page of its own, the title is the page's. */
47
+ as?: 'h1' | 'h2' | undefined;
48
+ }
49
+ /**
50
+ * A document's title: the largest step a reading screen spends, at the tight
51
+ * tracking every title on the ramp takes.
52
+ *
53
+ * A component rather than a class, so a screen does not set a page's title in
54
+ * a size of its own beside the body it heads.
55
+ */
56
+ export declare function DocumentTitle({ as: Tag, className, children, ...rest }: DocumentTitleProps): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import './Document.css';
2
+ export { Document, DocumentTitle } from './Document.js';
3
+ export type { DocumentElement, DocumentProps, DocumentSize, DocumentTitleProps } from './Document.js';
@@ -0,0 +1,2 @@
1
+ export { Document, DocumentTitle } from '../chunk-WI6K5M5X.js';
2
+ import '../chunk-ODEQTPFM.js';
@@ -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
+ }