@crewlethq/ui 0.51.0 → 0.52.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 (64) hide show
  1. package/README.md +14 -0
  2. package/dist/AgentHandoffPanel/index.js +3 -3
  3. package/dist/ArrangeList/index.js +3 -3
  4. package/dist/ArtifactCard/index.js +3 -3
  5. package/dist/Checkbox/index.js +2 -2
  6. package/dist/ChoiceButtons/ChoiceButtons.d.ts +21 -1
  7. package/dist/ChoiceButtons/index.d.ts +1 -1
  8. package/dist/ChoiceButtons/index.js +1 -1
  9. package/dist/{ChoiceButtons-FLIFXFFS.css → ChoiceButtons-HWXEF2H3.css} +60 -0
  10. package/dist/ColorField/index.js +2 -2
  11. package/dist/Combobox/index.js +2 -2
  12. package/dist/CommandPalette/index.js +2 -2
  13. package/dist/CommentThread/index.js +3 -3
  14. package/dist/Composer/index.js +2 -2
  15. package/dist/ConfirmField/index.js +2 -2
  16. package/dist/DataGrid/index.js +3 -3
  17. package/dist/DataTable/index.js +3 -3
  18. package/dist/DataView/index.js +4 -4
  19. package/dist/DocTabsEditor/index.js +2 -2
  20. package/dist/{Editor-MLGK3KOG.js → Editor-SZFWVDAU.js} +2 -2
  21. package/dist/Input/FormField.d.ts +7 -1
  22. package/dist/Input/index.js +1 -1
  23. package/dist/{Input-VDSV7VWJ.css → Input-GMOWHZRG.css} +9 -0
  24. package/dist/ListInput/ListInput.d.ts +2 -0
  25. package/dist/ListInput/index.js +2 -2
  26. package/dist/{ListInput-P2ECUQJ2.css → ListInput-RLQND5QK.css} +30 -6
  27. package/dist/LogoSlot/LogoSlot.d.ts +9 -1
  28. package/dist/LogoSlot/LogoSlotGroup.d.ts +38 -0
  29. package/dist/LogoSlot/index.d.ts +3 -1
  30. package/dist/LogoSlot/index.js +1 -1
  31. package/dist/{LogoSlot-T2UFOJXU.css → LogoSlot-ETD74ELF.css} +98 -0
  32. package/dist/PrincipalPicker/index.js +3 -3
  33. package/dist/RichEditor/index.js +1 -1
  34. package/dist/SheetColumnEditor/index.js +3 -3
  35. package/dist/Switcher/index.js +2 -2
  36. package/dist/TimeWindowPicker/index.js +2 -2
  37. package/dist/{chunk-ZCIL5IHU.js → chunk-2GIWL7IS.js} +1 -1
  38. package/dist/{chunk-V7GOOXPK.js → chunk-3NXWH5NC.js} +1 -1
  39. package/dist/{chunk-WQ7S7CKZ.js → chunk-5O72FSOK.js} +1 -1
  40. package/dist/{chunk-73WHPLWQ.js → chunk-5WYPSVRX.js} +1 -1
  41. package/dist/{chunk-R6R2UHVG.js → chunk-6VQA2LZC.js} +1 -1
  42. package/dist/{chunk-FB5CFQTG.js → chunk-7PE56HHD.js} +1 -1
  43. package/dist/{chunk-P5JBDHWC.js → chunk-C6Z3MLSA.js} +1 -1
  44. package/dist/{chunk-UUTEWGO6.js → chunk-CQEYF3UW.js} +6 -4
  45. package/dist/{chunk-S63QOMXC.js → chunk-CUL5XV6O.js} +1 -1
  46. package/dist/{chunk-H7NMJ5AI.js → chunk-EZ43L6T7.js} +1 -1
  47. package/dist/{chunk-627KFRON.js → chunk-FNPZ3LLQ.js} +1 -1
  48. package/dist/{chunk-KHZYAEGZ.js → chunk-G5SUSCWL.js} +1 -1
  49. package/dist/{chunk-VBIM6HFC.js → chunk-GPZXBJFU.js} +1 -1
  50. package/dist/{chunk-WX6IJJ4U.js → chunk-GRKGLZFM.js} +2 -2
  51. package/dist/{chunk-VTSJMDGP.js → chunk-J53T2QAH.js} +2 -2
  52. package/dist/{chunk-KHP7TJF7.js → chunk-KFR75JOK.js} +1 -1
  53. package/dist/{chunk-EXRRTKWT.js → chunk-LJHH4WWB.js} +8 -4
  54. package/dist/{chunk-MIEBOO7Y.js → chunk-NMR7AJSB.js} +1 -1
  55. package/dist/{chunk-NCHKKYPQ.js → chunk-RQI43UJ7.js} +1 -1
  56. package/dist/{chunk-H55D66IK.js → chunk-SSHDQBHR.js} +1 -1
  57. package/dist/{chunk-GHY63X4C.js → chunk-UJ4VVK7R.js} +1 -1
  58. package/dist/{chunk-2UFUP2ZH.js → chunk-UKE7LTFZ.js} +27 -10
  59. package/dist/chunk-WXRH7NZW.js +80 -0
  60. package/dist/generated/index.js +46 -46
  61. package/dist/index.js +46 -46
  62. package/dist/styles.css +201 -10
  63. package/package.json +3 -3
  64. package/dist/chunk-BWOIUOO3.js +0 -62
package/README.md CHANGED
@@ -204,6 +204,20 @@ places:
204
204
  - A surface that pans or zooms dispatches `LAYER_REPOSITION_EVENT` on its host
205
205
  when the content beneath it moves, and every panel anchored inside follows.
206
206
 
207
+ ## Changes in 0.52.0
208
+
209
+ A second polish of the brand setup pieces.
210
+
211
+ **`LogoSlotGroup` is new**: logo slots side by side, aligned row by row. Each slot is a subgrid of one set of rows, so the names and descriptions, the stages, the notes under them and the action rows each start on one line across the slots whatever their copy; a row no slot uses takes no room. What may be brought is written once under the row (`hint`) and describes every slot's picker, and a slot inside a group draws no caption of its own. The columns are as many as fit at 14rem, then one under another on a phone. A slot's empty note and refusal now share one element (`.crewlet-logo-slot__notes`).
212
+
213
+ **`LogoSlot` takes `size="sm"`**: a thumbnail for a summary of what is set, at half the stage's height with a tighter inset and smaller words, best read-only.
214
+
215
+ **`ChoiceButtons` takes `size="sm"`, per-option `media` and `chosen`.** The Inbox's one-press answer option, compact (the small control height, the compact and micro type steps) in a row that wraps, for suggestions beside a field. `media` is a decorative picture before the words (a `ColorChip` on a suggested colour). `chosen` keeps an applied option marked in the selected edge and fill, with every option a toggle button (`aria-pressed`) saying whether it is the one applied; left out, the options send and say nothing of a choice, as in the Inbox. Hover, press and focus are the Inbox's own.
216
+
217
+ **`ListInput` counts its items, matches its Add to the field and aligns its rows.** With `maxItems` the help line ends in a plain count (`tallyLabel`, "3 of 5"), joined into the group's description, and a full list says "That's the most. Remove one to add another." (`fullMessage`'s new default). The Add button stands at the field's medium height on the box's first line. A row's number sits on the text's first line at its line height, so the two share a baseline however long the item; the row's gap is a step and a half; and an edited item keeps an inset for its ring that a margin takes back, so the words never move when it is focused. What to change: a test that reads the old "The list is full at N" sentence.
218
+
219
+ **`FormField` takes `tally`**: a count that is not a length, drawn at the end of the help line where a length count would be and joined into the description the same way.
220
+
207
221
  ## Changes in 0.51.0
208
222
 
209
223
  Polish of the setup wizard pieces, and the parts the brand setup asked for.
@@ -1,11 +1,11 @@
1
- export { AGENT_HANDOFF_LABELS, AgentHandoffPanel } from '../chunk-V7GOOXPK.js';
1
+ export { AGENT_HANDOFF_LABELS, AgentHandoffPanel } from '../chunk-3NXWH5NC.js';
2
2
  import '../chunk-AUQPBL4O.js';
3
3
  import '../chunk-JQ7IFSF6.js';
4
4
  import '../chunk-OGXHZHRX.js';
5
- import '../chunk-GHY63X4C.js';
5
+ import '../chunk-UJ4VVK7R.js';
6
6
  import '../chunk-NBDN5JZV.js';
7
7
  import '../chunk-SMBKXWML.js';
8
- import '../chunk-EXRRTKWT.js';
8
+ import '../chunk-LJHH4WWB.js';
9
9
  import '../chunk-XCUUI7E7.js';
10
10
  import '../chunk-FZVJDJFN.js';
11
11
  import '../chunk-BHHIIK3M.js';
@@ -1,8 +1,8 @@
1
- export { ArrangeList, DEFAULT_ARRANGE_LABELS } from '../chunk-H55D66IK.js';
1
+ export { ArrangeList, DEFAULT_ARRANGE_LABELS } from '../chunk-SSHDQBHR.js';
2
2
  import '../chunk-A722MUNR.js';
3
3
  import '../chunk-XJ2QEBMM.js';
4
- import '../chunk-NCHKKYPQ.js';
5
- import '../chunk-EXRRTKWT.js';
4
+ import '../chunk-RQI43UJ7.js';
5
+ import '../chunk-LJHH4WWB.js';
6
6
  import '../chunk-XCUUI7E7.js';
7
7
  import '../chunk-PQADV6P6.js';
8
8
  import '../chunk-RSAQOKH3.js';
@@ -1,4 +1,4 @@
1
- export { ArtifactCard, ArtifactCardSkeleton, ArtifactPreviewGlyph } from '../chunk-S63QOMXC.js';
1
+ export { ArtifactCard, ArtifactCardSkeleton, ArtifactPreviewGlyph } from '../chunk-CUL5XV6O.js';
2
2
  import '../chunk-TEUQWOWZ.js';
3
3
  import '../chunk-CI3VPIJN.js';
4
4
  import '../chunk-3CZ7XAVY.js';
@@ -8,10 +8,10 @@ import '../chunk-PZKHBB7D.js';
8
8
  import '../chunk-RV6XB5UV.js';
9
9
  import '../chunk-INHXF2CL.js';
10
10
  import '../chunk-AV2DXAEL.js';
11
- import '../chunk-NCHKKYPQ.js';
11
+ import '../chunk-RQI43UJ7.js';
12
12
  import '../chunk-BGLKLXL3.js';
13
13
  export { ARTIFACT_KINDS, ArtifactKindGlyph } from '../chunk-RSKW25Y5.js';
14
- import '../chunk-EXRRTKWT.js';
14
+ import '../chunk-LJHH4WWB.js';
15
15
  import '../chunk-XCUUI7E7.js';
16
16
  import '../chunk-BHHIIK3M.js';
17
17
  import '../chunk-PQADV6P6.js';
@@ -1,5 +1,5 @@
1
- export { Checkbox, CheckboxGroup } from '../chunk-NCHKKYPQ.js';
2
- import '../chunk-EXRRTKWT.js';
1
+ export { Checkbox, CheckboxGroup } from '../chunk-RQI43UJ7.js';
2
+ import '../chunk-LJHH4WWB.js';
3
3
  import '../chunk-XCUUI7E7.js';
4
4
  import '../chunk-PQADV6P6.js';
5
5
  import '../chunk-RSAQOKH3.js';
@@ -4,7 +4,17 @@ export interface ChoiceButtonOption {
4
4
  label: ReactNode;
5
5
  /** A line under the label: what choosing it means. */
6
6
  detail?: ReactNode;
7
+ /**
8
+ * A small picture before the words, decorative (the label names the
9
+ * option): a `ColorChip` on a suggested colour.
10
+ */
11
+ media?: ReactNode;
7
12
  }
13
+ /**
14
+ * `md` is the Inbox's answer, as tall as a touch target, in a column. `sm` is
15
+ * the same option, compact, in a row that wraps: suggestions beside a field.
16
+ */
17
+ export type ChoiceButtonsSize = 'md' | 'sm';
8
18
  export interface ChoiceButtonsProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
9
19
  /** Names the group: "Answers". */
10
20
  label: string;
@@ -15,6 +25,16 @@ export interface ChoiceButtonsProps extends Omit<HTMLAttributes<HTMLDivElement>,
15
25
  recommendedLabel?: string | undefined;
16
26
  /** Sends one option. */
17
27
  onChoose: (value: string) => void;
28
+ /** `md` (the Inbox's answer) by default, or `sm`, compact and in a wrapping row. */
29
+ size?: ChoiceButtonsSize | undefined;
30
+ /**
31
+ * The option already applied, for options that stay on screen after a
32
+ * press (a suggestion that updated a field). Given, every option is a
33
+ * toggle button that says whether it is the one applied, and that one is
34
+ * drawn chosen: the selected edge and fill, never the accent. `null` when
35
+ * none is; left out, the options send and say nothing of a choice.
36
+ */
37
+ chosen?: string | null | undefined;
18
38
  /**
19
39
  * The option being sent. It is announced as busy, and every option holds
20
40
  * still until the answer lands, so a second press cannot send a second
@@ -40,4 +60,4 @@ export interface ChoiceButtonsProps extends Omit<HTMLAttributes<HTMLDivElement>,
40
60
  * the control the reader just pressed and drops it on the page body.
41
61
  * `aria-disabled` and `aria-busy` say the same and leave focus where it was.
42
62
  */
43
- export declare function ChoiceButtons({ label, options, recommended, recommendedLabel, onChoose, pending, disabledReason, className, ...rest }: ChoiceButtonsProps): import("react").JSX.Element;
63
+ export declare function ChoiceButtons({ label, options, recommended, recommendedLabel, onChoose, pending, disabledReason, size, chosen, className, ...rest }: ChoiceButtonsProps): import("react").JSX.Element;
@@ -1,3 +1,3 @@
1
1
  import './ChoiceButtons.css';
2
2
  export { ChoiceButtons } from './ChoiceButtons.js';
3
- export type { ChoiceButtonOption, ChoiceButtonsProps } from './ChoiceButtons.js';
3
+ export type { ChoiceButtonOption, ChoiceButtonsProps, ChoiceButtonsSize } from './ChoiceButtons.js';
@@ -1,3 +1,3 @@
1
- export { ChoiceButtons } from '../chunk-BWOIUOO3.js';
1
+ export { ChoiceButtons } from '../chunk-WXRH7NZW.js';
2
2
  import '../chunk-BZFWDIV6.js';
3
3
  import '../chunk-ODEQTPFM.js';
@@ -55,6 +55,17 @@
55
55
  background: var(--color-surface-pressed);
56
56
  }
57
57
 
58
+ /*
59
+ * THE OPTION APPLIED is drawn as every chosen option in the package is: the
60
+ * selected edge over the soft selected fill, calm beside the focus ring, and
61
+ * held under the pointer so a hover never makes it look unchosen.
62
+ */
63
+ .crewlet-choice-buttons__option.is-chosen,
64
+ .crewlet-choice-buttons__option.is-chosen:hover {
65
+ border-color: var(--color-border-selected);
66
+ background: var(--color-surface-selected);
67
+ }
68
+
58
69
  /*
59
70
  * The plain option draws the strong hairline, so its ring is drawn over that
60
71
  * edge rather than a gap away from it, which would read as a second outline.
@@ -130,6 +141,55 @@
130
141
  text-transform: uppercase;
131
142
  }
132
143
 
144
+ /* The picture before the words, centred on the label's line. */
145
+ .crewlet-choice-buttons__media {
146
+ display: inline-flex;
147
+ flex: none;
148
+ align-items: center;
149
+ align-self: center;
150
+ }
151
+
152
+ /* Before the words, not at the far end with the recommended mark. */
153
+ .crewlet-choice-buttons__option:has(.crewlet-choice-buttons__media) {
154
+ justify-content: flex-start;
155
+ }
156
+
157
+ .crewlet-choice-buttons__option:has(.crewlet-choice-buttons__media) .crewlet-choice-buttons__note {
158
+ margin-inline-start: auto;
159
+ }
160
+
161
+ /*
162
+ * SMALL: the same option, compact, in a row that wraps. A step and a half
163
+ * inside, the field's small height, the label at the compact step and its
164
+ * detail at the micro step, so three suggestions sit under a field without
165
+ * outweighing it. Every state (hover, press, focus, chosen) is the Inbox's.
166
+ */
167
+ .crewlet-choice-buttons--sm {
168
+ display: flex;
169
+ flex-wrap: wrap;
170
+ gap: var(--spacing-2);
171
+ }
172
+
173
+ .crewlet-choice-buttons--sm .crewlet-choice-buttons__option {
174
+ gap: var(--spacing-2);
175
+ min-height: var(--size-control-sm);
176
+ padding: var(--spacing-1) calc(var(--spacing-2) + var(--spacing-1) / 2);
177
+ font-size: var(--font-size-xs);
178
+ line-height: var(--font-line-height-tight);
179
+ }
180
+
181
+ .crewlet-choice-buttons--sm .crewlet-choice-buttons__option:has(.crewlet-choice-buttons__detail) {
182
+ align-items: center;
183
+ }
184
+
185
+ .crewlet-choice-buttons--sm .crewlet-choice-buttons__text {
186
+ gap: 1px;
187
+ }
188
+
189
+ .crewlet-choice-buttons--sm .crewlet-choice-buttons__detail {
190
+ font-size: var(--font-size-2xs);
191
+ }
192
+
133
193
  @media (prefers-reduced-motion: reduce) {
134
194
  .crewlet-choice-buttons__option {
135
195
  transition: none;
@@ -1,6 +1,6 @@
1
- export { ColorField } from '../chunk-73WHPLWQ.js';
1
+ export { ColorField } from '../chunk-5WYPSVRX.js';
2
2
  import '../chunk-7W3LYIOC.js';
3
- import '../chunk-EXRRTKWT.js';
3
+ import '../chunk-LJHH4WWB.js';
4
4
  import '../chunk-XCUUI7E7.js';
5
5
  import '../chunk-PQADV6P6.js';
6
6
  import '../chunk-RSAQOKH3.js';
@@ -1,6 +1,6 @@
1
- export { Combobox } from '../chunk-P5JBDHWC.js';
1
+ export { Combobox } from '../chunk-C6Z3MLSA.js';
2
2
  import '../chunk-7KHM2FZH.js';
3
- import '../chunk-EXRRTKWT.js';
3
+ import '../chunk-LJHH4WWB.js';
4
4
  import '../chunk-XCUUI7E7.js';
5
5
  import '../chunk-PQADV6P6.js';
6
6
  import '../chunk-RSAQOKH3.js';
@@ -1,8 +1,8 @@
1
- export { CommandPalette } from '../chunk-MIEBOO7Y.js';
1
+ export { CommandPalette } from '../chunk-NMR7AJSB.js';
2
2
  import '../chunk-YCC2S7DF.js';
3
3
  import '../chunk-7KHM2FZH.js';
4
4
  import '../chunk-SMBKXWML.js';
5
- import '../chunk-EXRRTKWT.js';
5
+ import '../chunk-LJHH4WWB.js';
6
6
  import '../chunk-XCUUI7E7.js';
7
7
  import '../chunk-BHHIIK3M.js';
8
8
  import '../chunk-PQADV6P6.js';
@@ -1,13 +1,13 @@
1
- export { COMMENT_THREAD_LABELS, CommentThread } from '../chunk-H7NMJ5AI.js';
1
+ export { COMMENT_THREAD_LABELS, CommentThread } from '../chunk-EZ43L6T7.js';
2
2
  import '../chunk-CI3VPIJN.js';
3
3
  import '../chunk-3CZ7XAVY.js';
4
4
  import '../chunk-EUCC37WY.js';
5
5
  import '../chunk-5AQBPHZD.js';
6
6
  import '../chunk-PZKHBB7D.js';
7
7
  import '../chunk-PWG3VHRQ.js';
8
- import '../chunk-GHY63X4C.js';
8
+ import '../chunk-UJ4VVK7R.js';
9
9
  import '../chunk-SMBKXWML.js';
10
- import '../chunk-EXRRTKWT.js';
10
+ import '../chunk-LJHH4WWB.js';
11
11
  import '../chunk-XCUUI7E7.js';
12
12
  import '../chunk-BHHIIK3M.js';
13
13
  import '../chunk-PQADV6P6.js';
@@ -1,6 +1,6 @@
1
- export { COMPOSER_COUNTER_AT, Composer } from '../chunk-GHY63X4C.js';
1
+ export { COMPOSER_COUNTER_AT, Composer } from '../chunk-UJ4VVK7R.js';
2
2
  import '../chunk-SMBKXWML.js';
3
- import '../chunk-EXRRTKWT.js';
3
+ import '../chunk-LJHH4WWB.js';
4
4
  import '../chunk-XCUUI7E7.js';
5
5
  import '../chunk-PQADV6P6.js';
6
6
  import '../chunk-RSAQOKH3.js';
@@ -1,6 +1,6 @@
1
- export { ConfirmField, confirmMatches } from '../chunk-ZCIL5IHU.js';
1
+ export { ConfirmField, confirmMatches } from '../chunk-2GIWL7IS.js';
2
2
  import '../chunk-5CLW2CXT.js';
3
- import '../chunk-EXRRTKWT.js';
3
+ import '../chunk-LJHH4WWB.js';
4
4
  import '../chunk-XCUUI7E7.js';
5
5
  import '../chunk-PQADV6P6.js';
6
6
  import '../chunk-RSAQOKH3.js';
@@ -1,7 +1,7 @@
1
- export { ChooserList, ColumnChooser, DataGrid, columnChoicesOf, fitGridColumns, parseGridSort } from '../chunk-FB5CFQTG.js';
2
- import '../chunk-NCHKKYPQ.js';
1
+ export { ChooserList, ColumnChooser, DataGrid, columnChoicesOf, fitGridColumns, parseGridSort } from '../chunk-7PE56HHD.js';
2
+ import '../chunk-RQI43UJ7.js';
3
3
  import '../chunk-PPUR46MK.js';
4
- import '../chunk-EXRRTKWT.js';
4
+ import '../chunk-LJHH4WWB.js';
5
5
  import '../chunk-XCUUI7E7.js';
6
6
  import '../chunk-PQADV6P6.js';
7
7
  import '../chunk-RSAQOKH3.js';
@@ -1,11 +1,11 @@
1
- export { ALL_ITEMS, CopyableCell, DATA_TABLE_LABELS, DataTable, RowActionsMenu } from '../chunk-WQ7S7CKZ.js';
1
+ export { ALL_ITEMS, CopyableCell, DATA_TABLE_LABELS, DataTable, RowActionsMenu } from '../chunk-5O72FSOK.js';
2
2
  import '../chunk-YCC2S7DF.js';
3
3
  import '../chunk-STJ7QBC3.js';
4
4
  import '../chunk-DTIW4CHZ.js';
5
5
  import '../chunk-EUCC37WY.js';
6
6
  import '../chunk-AV2DXAEL.js';
7
- import '../chunk-NCHKKYPQ.js';
8
- import '../chunk-EXRRTKWT.js';
7
+ import '../chunk-RQI43UJ7.js';
8
+ import '../chunk-LJHH4WWB.js';
9
9
  import '../chunk-XCUUI7E7.js';
10
10
  import '../chunk-PQADV6P6.js';
11
11
  import '../chunk-RSAQOKH3.js';
@@ -1,6 +1,6 @@
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-WX6IJJ4U.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-GRKGLZFM.js';
2
2
  import '../chunk-DKB73KZI.js';
3
- import '../chunk-WQ7S7CKZ.js';
3
+ import '../chunk-5O72FSOK.js';
4
4
  import '../chunk-ZFM5L7M4.js';
5
5
  import '../chunk-YCC2S7DF.js';
6
6
  import '../chunk-7KHM2FZH.js';
@@ -12,9 +12,9 @@ import '../chunk-KHJIEPZV.js';
12
12
  import '../chunk-3CZ7XAVY.js';
13
13
  import '../chunk-EUCC37WY.js';
14
14
  import '../chunk-AV2DXAEL.js';
15
- import '../chunk-NCHKKYPQ.js';
15
+ import '../chunk-RQI43UJ7.js';
16
16
  import '../chunk-SMBKXWML.js';
17
- import '../chunk-EXRRTKWT.js';
17
+ import '../chunk-LJHH4WWB.js';
18
18
  import '../chunk-XCUUI7E7.js';
19
19
  import '../chunk-BHHIIK3M.js';
20
20
  import '../chunk-PQADV6P6.js';
@@ -1,6 +1,6 @@
1
- export { DOC_TABS_EDITOR_LABELS, DocTabsEditor } from '../chunk-627KFRON.js';
1
+ export { DOC_TABS_EDITOR_LABELS, DocTabsEditor } from '../chunk-FNPZ3LLQ.js';
2
2
  import '../chunk-XJ2QEBMM.js';
3
- import '../chunk-EXRRTKWT.js';
3
+ import '../chunk-LJHH4WWB.js';
4
4
  import '../chunk-XCUUI7E7.js';
5
5
  import '../chunk-PQADV6P6.js';
6
6
  import '../chunk-RSAQOKH3.js';
@@ -1,8 +1,8 @@
1
- import { richEditorLabels } from './chunk-CSQTDGTS.js';
2
1
  import { schema, readMarkdown, writeMarkdown } from './chunk-QH6VYJ3X.js';
2
+ import { richEditorLabels } from './chunk-CSQTDGTS.js';
3
3
  import { safeHref, MARKDOWN_CALLOUT_TONES } from './chunk-BAKPMH3S.js';
4
4
  import { Toolbar } from './chunk-NR4CPM4T.js';
5
- import { FormField, Input } from './chunk-EXRRTKWT.js';
5
+ import { FormField, Input } from './chunk-LJHH4WWB.js';
6
6
  import './chunk-XCUUI7E7.js';
7
7
  import './chunk-PQADV6P6.js';
8
8
  import './chunk-RSAQOKH3.js';
@@ -45,6 +45,12 @@ export interface FormFieldProps extends Omit<HTMLAttributes<HTMLElement>, 'child
45
45
  * much it is over. See `CharacterCount`.
46
46
  */
47
47
  limit?: FormFieldLimit | undefined;
48
+ /**
49
+ * A count that is not a length, drawn where a length count would be (at the
50
+ * end of the help line) and joined into the description the same way: how
51
+ * many items a list holds of the most it may, "3 of 5".
52
+ */
53
+ tally?: ReactNode;
48
54
  /** A control rendered beside the label, such as an Add button. */
49
55
  labelAction?: ReactNode;
50
56
  /**
@@ -91,4 +97,4 @@ export interface FormFieldProps extends Omit<HTMLAttributes<HTMLElement>, 'child
91
97
  * instant, the only line that said what right looks like disappeared. Both
92
98
  * lines are joined into `aria-describedby` in reading order, help first.
93
99
  */
94
- export declare const FormField: ({ label, required, optional, requiredNews, helper, helperOnFocus, error, limit, labelAction, hideLabel, as, describedBy, htmlFor, className, children, ...rest }: FormFieldProps) => import("react").JSX.Element;
100
+ export declare const FormField: ({ label, required, optional, requiredNews, helper, helperOnFocus, error, limit, tally, labelAction, hideLabel, as, describedBy, htmlFor, className, children, ...rest }: FormFieldProps) => import("react").JSX.Element;
@@ -1,4 +1,4 @@
1
- export { FormField, FormRow, FormSection, Input, InputAffix, Label, ReadOnlyField, Textarea, foldLineBreaks } from '../chunk-EXRRTKWT.js';
1
+ export { FormField, FormRow, FormSection, Input, InputAffix, Label, ReadOnlyField, Textarea, foldLineBreaks } from '../chunk-LJHH4WWB.js';
2
2
  import '../chunk-XCUUI7E7.js';
3
3
  import '../chunk-PQADV6P6.js';
4
4
  import '../chunk-RSAQOKH3.js';
@@ -580,6 +580,15 @@
580
580
  min-width: 0;
581
581
  }
582
582
 
583
+ /* A count that is not a length ("3 of 5"), in the help line's own quiet ink. */
584
+ .crewlet-form-field__tally {
585
+ flex: none;
586
+ color: var(--color-text-tertiary);
587
+ font-size: var(--font-size-xs);
588
+ font-variant-numeric: tabular-nums;
589
+ line-height: var(--font-line-height-normal);
590
+ }
591
+
583
592
  /* SHOWN ONLY WHILE THE FIELD HAS FOCUS (`helperOnFocus`): a dense form reads as
584
593
  labels and values at rest, and the sentence appears under the field the
585
594
  reader is in. Still described, so a screen reader hears it on entry. */
@@ -109,6 +109,8 @@ export interface ListInputProps {
109
109
  itemError?: ((index: number, value: string) => ReactNode) | undefined;
110
110
  /** What the list says in place of the new-item box once it is full. */
111
111
  fullMessage?: ((max: number) => string) | undefined;
112
+ /** How many items the list holds of the most it may, at the end of the help line: "3 of 5". Drawn only with `maxItems`. */
113
+ tallyLabel?: ((count: number, max: number) => string) | undefined;
112
114
  /** The name of the button at the end of the box's row that appends what the box holds: "Add policy". */
113
115
  addLabel?: ((itemName: string) => string) | undefined;
114
116
  /** The word that button shows, which its name begins with: "Add". */
@@ -1,7 +1,7 @@
1
- export { ListInput, withDraft } from '../chunk-UUTEWGO6.js';
1
+ export { ListInput, withDraft } from '../chunk-CQEYF3UW.js';
2
2
  import '../chunk-XJ2QEBMM.js';
3
3
  import '../chunk-SMBKXWML.js';
4
- import '../chunk-EXRRTKWT.js';
4
+ import '../chunk-LJHH4WWB.js';
5
5
  import '../chunk-XCUUI7E7.js';
6
6
  import '../chunk-PQADV6P6.js';
7
7
  import '../chunk-RSAQOKH3.js';
@@ -61,7 +61,9 @@
61
61
  .crewlet-list-input__item {
62
62
  display: flex;
63
63
  align-items: center;
64
- gap: var(--spacing-2);
64
+ /* A step and the control's own inset: the ring an edited item draws stands
65
+ a step clear of its number. */
66
+ gap: var(--spacing-3);
65
67
  padding: var(--spacing-1) var(--spacing-3);
66
68
  border-block-end-width: 1px;
67
69
  border-block-end-style: solid;
@@ -169,11 +171,28 @@
169
171
  .crewlet-list-input__item .crewlet-input__control,
170
172
  .crewlet-list-input__item .crewlet-textarea {
171
173
  padding-block: var(--spacing-1);
172
- padding-inline: 0;
174
+ /*
175
+ * EDITING NEVER MOVES THE WORDS. The control keeps an inset of its own, so
176
+ * the boundary that hover and focus draw stands clear of the text rather
177
+ * than touching its first letter, and a negative margin of the same step
178
+ * takes it back, so the words sit exactly where they sat at rest and the
179
+ * caret lands on them without a jump.
180
+ */
181
+ padding-inline: var(--spacing-2);
182
+ margin-inline: calc(var(--spacing-2) * -1);
173
183
  }
174
184
 
175
185
  .crewlet-list-input__index {
176
186
  flex: none;
187
+ /*
188
+ * ON THE TEXT'S FIRST LINE, never centred on a wrapped item: it starts where
189
+ * the words start (the control's edge and its block inset below the row's
190
+ * own padding) and takes their line's height, so the number and the words
191
+ * share a baseline however many lines the item runs to.
192
+ */
193
+ align-self: flex-start;
194
+ padding-block-start: calc(1px + var(--spacing-1));
195
+ line-height: calc(var(--font-size-compact) * var(--font-line-height-normal));
177
196
  min-width: var(--spacing-4);
178
197
  text-align: center;
179
198
  font-size: var(--font-size-xs);
@@ -257,11 +276,16 @@
257
276
  }
258
277
  }
259
278
 
260
- /* The Add button ends the box's row: the field and its Add read as one control. */
279
+ /*
280
+ * The Add button ends the box's row: the field and its Add read as one
281
+ * control. It is the field's height (the medium control step a one-line box
282
+ * stands at) and sits on the box's first line, so the two share one line and
283
+ * the button stays put as a long item grows the box under it.
284
+ */
261
285
  .crewlet-list-input__add-control {
262
286
  display: inline-flex;
263
287
  flex: none;
264
- align-self: center;
288
+ align-self: flex-start;
265
289
  }
266
290
 
267
291
  /*
@@ -279,11 +303,11 @@
279
303
  }
280
304
 
281
305
  .crewlet-list-input__item > .crewlet-list-input__field {
282
- flex-basis: calc(100% - var(--spacing-4) - var(--spacing-2));
306
+ flex-basis: calc(100% - var(--spacing-4) - var(--spacing-3));
283
307
  }
284
308
 
285
309
  .crewlet-list-input__item--draggable > .crewlet-list-input__field {
286
- flex-basis: calc(100% - var(--spacing-4) * 2 - var(--spacing-2) * 2);
310
+ flex-basis: calc(100% - var(--spacing-4) * 2 - var(--spacing-3) * 2);
287
311
  }
288
312
 
289
313
  .crewlet-list-input__item > .crewlet-list-input__actions {
@@ -3,6 +3,12 @@ import { type ReactNode } from 'react';
3
3
  export type LogoSlotGround = 'light' | 'dark';
4
4
  /** A wide logo (a wordmark, a lockup) or a square mark. */
5
5
  export type LogoSlotShape = 'wide' | 'square';
6
+ /**
7
+ * `md` is the slot a logo is chosen in. `sm` is a thumbnail of it, for a
8
+ * summary that shows what is set (a review of the brand): a third of the
9
+ * stage's height with a tighter inset and smaller words, best read-only.
10
+ */
11
+ export type LogoSlotSize = 'md' | 'sm';
6
12
  export interface LogoSlotLabels {
7
13
  /** The picker's label while the slot is empty. */
8
14
  choose: string;
@@ -31,6 +37,8 @@ export interface LogoSlotProps {
31
37
  */
32
38
  groundColor?: string | undefined;
33
39
  shape?: LogoSlotShape | undefined;
40
+ /** `md` (the default), or `sm`, a thumbnail for a summary. */
41
+ size?: LogoSlotSize | undefined;
34
42
  /**
35
43
  * The logo, as an address the host has already validated (the engine's file
36
44
  * route, through the dashboard's checked blob path). Empty, the slot shows
@@ -81,4 +89,4 @@ export interface LogoSlotProps {
81
89
  * The engine checks every file; a refusal comes back as `error`, drawn under
82
90
  * the slot and announced, saying what to change.
83
91
  */
84
- export declare function LogoSlot({ label, description, ground, groundColor, shape, src, alt, guide, uploading, error, editable, onFile, onRemove, accept, download, emptyNote, className, labels, }: LogoSlotProps): import("react").JSX.Element;
92
+ export declare function LogoSlot({ label, description, ground, groundColor, shape, size, src, alt, guide, uploading, error, editable, onFile, onRemove, accept, download, emptyNote, className, labels, }: LogoSlotProps): import("react").JSX.Element;
@@ -0,0 +1,38 @@
1
+ import { type HTMLAttributes, type ReactNode } from 'react';
2
+ /** What a slot inside a group needs: the shared caption it is described by. */
3
+ interface LogoSlotGroupContextValue {
4
+ hintId: string | undefined;
5
+ }
6
+ /** The group a slot stands in, or null for a slot on its own. */
7
+ export declare function useLogoSlotGroup(): LogoSlotGroupContextValue | null;
8
+ export interface LogoSlotGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
9
+ /** The slots, side by side: `LogoSlot`s. */
10
+ children: ReactNode;
11
+ /** Names the group for a screen reader: "Logos". */
12
+ label?: string | undefined;
13
+ /**
14
+ * What may be brought, written once under the row rather than under every
15
+ * slot: "SVG up to 512 KB; PNG or WebP up to 2 MB and 4096 px." Every slot's
16
+ * picker is described by it. Left out, no caption is drawn.
17
+ */
18
+ hint?: ReactNode;
19
+ }
20
+ /**
21
+ * Logo slots side by side, aligned row by row.
22
+ *
23
+ * ONE ROW PER PART ACROSS THE SLOTS. Each slot is a subgrid of the group's
24
+ * rows, so the names and their descriptions, the stages, the notes under them
25
+ * and the action rows each start on one line across every slot, whatever the
26
+ * copy in each: a description that wraps to two lines moves every stage down
27
+ * together rather than its own. The stages are one height, so the previews
28
+ * are one size.
29
+ *
30
+ * THE CAPTION IS WRITTEN ONCE. What may be brought is the same for every
31
+ * slot, so it is drawn once under the row (`hint`) and each picker is
32
+ * described by it, rather than repeated three times.
33
+ *
34
+ * THE COLUMNS FOLLOW THE ROOM: as many as fit at 14rem each, then one under
35
+ * another on a phone, each still aligned within itself.
36
+ */
37
+ export declare function LogoSlotGroup({ children, label, hint, className, ...rest }: LogoSlotGroupProps): import("react").JSX.Element;
38
+ export {};
@@ -1,3 +1,5 @@
1
1
  import './LogoSlot.css';
2
2
  export { LogoSlot } from './LogoSlot.js';
3
- export type { LogoSlotGround, LogoSlotLabels, LogoSlotProps, LogoSlotShape } from './LogoSlot.js';
3
+ export { LogoSlotGroup } from './LogoSlotGroup.js';
4
+ export type { LogoSlotGround, LogoSlotLabels, LogoSlotProps, LogoSlotShape, LogoSlotSize } from './LogoSlot.js';
5
+ export type { LogoSlotGroupProps } from './LogoSlotGroup.js';
@@ -1,4 +1,4 @@
1
- export { LogoSlot } from '../chunk-2UFUP2ZH.js';
1
+ export { LogoSlot, LogoSlotGroup } from '../chunk-UKE7LTFZ.js';
2
2
  import '../chunk-THDGBD6Y.js';
3
3
  import '../chunk-WW7TU6HE.js';
4
4
  import '../chunk-KYIAFNU7.js';