@crewlethq/ui 0.50.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 (119) hide show
  1. package/README.md +34 -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/{ArtifactCard-SOB63NV5.css → ArtifactCard-F7IVRL3A.css} +3 -0
  6. package/dist/AvatarPicker/index.js +2 -2
  7. package/dist/BrandSample/index.js +3 -3
  8. package/dist/BrandScope/index.js +2 -2
  9. package/dist/Callout/index.js +1 -1
  10. package/dist/{Callout-ZAVG3P66.css → Callout-G3N3IE6M.css} +9 -0
  11. package/dist/Checkbox/index.js +2 -2
  12. package/dist/ChoiceButtons/ChoiceButtons.d.ts +21 -1
  13. package/dist/ChoiceButtons/index.d.ts +1 -1
  14. package/dist/ChoiceButtons/index.js +1 -1
  15. package/dist/{ChoiceButtons-FLIFXFFS.css → ChoiceButtons-HWXEF2H3.css} +60 -0
  16. package/dist/ColorChip/ColorChip.d.ts +26 -0
  17. package/dist/ColorChip/index.d.ts +3 -0
  18. package/dist/ColorChip/index.js +3 -0
  19. package/dist/ColorChip-A5XHTH3J.css +46 -0
  20. package/dist/ColorField/ColorField.d.ts +16 -8
  21. package/dist/ColorField/index.js +3 -3
  22. package/dist/ColorSwatch/index.js +2 -2
  23. package/dist/Combobox/index.js +2 -2
  24. package/dist/CommandPalette/index.js +2 -2
  25. package/dist/CommentThread/index.js +3 -3
  26. package/dist/Composer/index.js +2 -2
  27. package/dist/ConfirmField/index.js +2 -2
  28. package/dist/ContrastBadge/ContrastBadge.d.ts +13 -0
  29. package/dist/ContrastBadge/index.d.ts +2 -2
  30. package/dist/ContrastBadge/index.js +2 -2
  31. package/dist/ContrastHelp/ContrastHelp.d.ts +40 -0
  32. package/dist/ContrastHelp/index.d.ts +3 -0
  33. package/dist/ContrastHelp/index.js +12 -0
  34. package/dist/ContrastHelp-MZCAW5WQ.css +43 -0
  35. package/dist/DataGrid/index.js +3 -3
  36. package/dist/DataTable/index.js +3 -3
  37. package/dist/DataView/index.js +4 -4
  38. package/dist/DocTabsEditor/index.js +2 -2
  39. package/dist/EditingStatus/EditingStatus.d.ts +3 -5
  40. package/dist/EditingStatus/index.js +1 -1
  41. package/dist/{EditingStatus-NNA2CKIL.css → EditingStatus-YU7EGM6Y.css} +22 -7
  42. package/dist/{Editor-MLGK3KOG.js → Editor-SZFWVDAU.js} +2 -2
  43. package/dist/FolderTile/index.js +1 -1
  44. package/dist/{FolderTile-FDT5Y63Z.css → FolderTile-MIUEB7SO.css} +12 -5
  45. package/dist/FollowBanner/index.js +2 -2
  46. package/dist/InlineEditor/index.js +2 -2
  47. package/dist/Input/FormField.d.ts +7 -1
  48. package/dist/Input/index.js +1 -1
  49. package/dist/{Input-VDSV7VWJ.css → Input-GMOWHZRG.css} +9 -0
  50. package/dist/LinkInterstitial/index.js +2 -2
  51. package/dist/ListInput/ListInput.d.ts +5 -1
  52. package/dist/ListInput/index.js +2 -2
  53. package/dist/{ListInput-WUP2YITQ.css → ListInput-RLQND5QK.css} +30 -6
  54. package/dist/LogoSlot/LogoSlot.d.ts +9 -1
  55. package/dist/LogoSlot/LogoSlotGroup.d.ts +38 -0
  56. package/dist/LogoSlot/index.d.ts +3 -1
  57. package/dist/LogoSlot/index.js +3 -3
  58. package/dist/{LogoSlot-T2UFOJXU.css → LogoSlot-ETD74ELF.css} +98 -0
  59. package/dist/PrincipalPicker/index.js +3 -3
  60. package/dist/RichEditor/index.js +2 -2
  61. package/dist/SandboxedFrame/index.js +2 -2
  62. package/dist/SetupWizard/SetupWizard.d.ts +13 -3
  63. package/dist/SetupWizard/index.js +1 -1
  64. package/dist/{SetupWizard-Y5BTXZX5.css → SetupWizard-GZK5UDKC.css} +27 -1
  65. package/dist/ShareDialog/index.js +2 -2
  66. package/dist/SheetColumnEditor/index.js +3 -3
  67. package/dist/Switcher/index.js +2 -2
  68. package/dist/TimeWindowPicker/index.js +2 -2
  69. package/dist/{chunk-ZCIL5IHU.js → chunk-2GIWL7IS.js} +1 -1
  70. package/dist/{chunk-4A4QG6UC.js → chunk-34C7NYIQ.js} +1 -1
  71. package/dist/{chunk-V7GOOXPK.js → chunk-3NXWH5NC.js} +1 -1
  72. package/dist/{chunk-WQ7S7CKZ.js → chunk-5O72FSOK.js} +1 -1
  73. package/dist/{chunk-W6FOEBIL.js → chunk-5WYPSVRX.js} +24 -15
  74. package/dist/chunk-6GTTRJWJ.js +24 -0
  75. package/dist/{chunk-QGRA2RHC.js → chunk-6RMZH7P7.js} +1 -1
  76. package/dist/{chunk-R6R2UHVG.js → chunk-6VQA2LZC.js} +1 -1
  77. package/dist/{chunk-FB5CFQTG.js → chunk-7PE56HHD.js} +1 -1
  78. package/dist/chunk-7W3LYIOC.js +27 -0
  79. package/dist/{chunk-OEEYL2CM.js → chunk-AVMQMY66.js} +2 -2
  80. package/dist/{chunk-SZZRIHGT.js → chunk-BPCY7ZID.js} +1 -1
  81. package/dist/{chunk-P5JBDHWC.js → chunk-C6Z3MLSA.js} +1 -1
  82. package/dist/{chunk-PGR2PKH6.js → chunk-CQEYF3UW.js} +14 -12
  83. package/dist/{chunk-Q44X36QC.js → chunk-CUL5XV6O.js} +2 -2
  84. package/dist/chunk-DTSZUH6H.js +124 -0
  85. package/dist/chunk-EJWPYEG4.js +38 -0
  86. package/dist/{chunk-H7NMJ5AI.js → chunk-EZ43L6T7.js} +1 -1
  87. package/dist/{chunk-627KFRON.js → chunk-FNPZ3LLQ.js} +1 -1
  88. package/dist/{chunk-M4QM477B.js → chunk-FXHWOXGD.js} +1 -1
  89. package/dist/{chunk-KHZYAEGZ.js → chunk-G5SUSCWL.js} +1 -1
  90. package/dist/{chunk-VBIM6HFC.js → chunk-GPZXBJFU.js} +1 -1
  91. package/dist/{chunk-NAWUXCBC.js → chunk-GRKGLZFM.js} +2 -2
  92. package/dist/{chunk-VTSJMDGP.js → chunk-J53T2QAH.js} +2 -2
  93. package/dist/{chunk-JWNYI7UD.js → chunk-KFR75JOK.js} +2 -2
  94. package/dist/chunk-KIRQZG3G.js +53 -0
  95. package/dist/{chunk-EXRRTKWT.js → chunk-LJHH4WWB.js} +8 -4
  96. package/dist/{chunk-MIEBOO7Y.js → chunk-NMR7AJSB.js} +1 -1
  97. package/dist/{chunk-JFDIMO3A.js → chunk-PGYIDNGG.js} +1 -1
  98. package/dist/{chunk-WLSEAIVC.js → chunk-RHPBTE3F.js} +1 -1
  99. package/dist/{chunk-NCHKKYPQ.js → chunk-RQI43UJ7.js} +1 -1
  100. package/dist/{chunk-H55D66IK.js → chunk-SSHDQBHR.js} +1 -1
  101. package/dist/{chunk-GP4YWZFO.js → chunk-U3LNU4B2.js} +1 -1
  102. package/dist/{chunk-GHY63X4C.js → chunk-UJ4VVK7R.js} +1 -1
  103. package/dist/{chunk-BEAXJARF.js → chunk-UKE7LTFZ.js} +29 -12
  104. package/dist/{chunk-356JNSER.js → chunk-WQQ5T5SA.js} +1 -1
  105. package/dist/{chunk-NSSOWQCJ.js → chunk-WW7TU6HE.js} +15 -12
  106. package/dist/chunk-WXRH7NZW.js +80 -0
  107. package/dist/{chunk-P3OIM6OC.js → chunk-X7WEE3EK.js} +1 -1
  108. package/dist/generated/index.d.ts +2 -0
  109. package/dist/generated/index.js +82 -80
  110. package/dist/index.js +82 -80
  111. package/dist/styles.css +374 -28
  112. package/dist/utils/hexColour.d.ts +13 -0
  113. package/package.json +3 -3
  114. package/dist/chunk-BWOIUOO3.js +0 -62
  115. package/dist/chunk-KKHCUHWS.js +0 -107
  116. package/dist/chunk-MMOXWAUG.js +0 -42
  117. package/dist/chunk-UZMNR366.js +0 -9
  118. package/dist/{chunk-3QSKDZR5.js → chunk-EW2N4FOD.js} +1 -1
  119. /package/dist/{chunk-HNQ2EIMR.js → chunk-P432I5DQ.js} +0 -0
@@ -0,0 +1,43 @@
1
+ /*
2
+ * ContrastHelp: what the contrast levels mean, in a short panel opened from an
3
+ * info button (ContrastHelp.tsx).
4
+ */
5
+ .crewlet-contrast-help {
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: var(--spacing-2);
9
+ padding: var(--spacing-3);
10
+ font-family: var(--font-family-sans);
11
+ font-size: var(--font-size-xs);
12
+ line-height: var(--font-line-height-snug);
13
+ }
14
+
15
+ .crewlet-contrast-help__title {
16
+ margin: 0;
17
+ color: var(--color-text-primary);
18
+ font-size: var(--font-size-sm);
19
+ font-weight: var(--font-weight-semibold);
20
+ }
21
+
22
+ .crewlet-contrast-help__intro {
23
+ margin: 0;
24
+ color: var(--color-text-secondary);
25
+ }
26
+
27
+ /* Each level's word as the badge draws it, beside what it means. */
28
+ .crewlet-contrast-help__levels {
29
+ display: grid;
30
+ grid-template-columns: max-content minmax(0, 1fr);
31
+ align-items: baseline;
32
+ gap: var(--spacing-2) var(--spacing-3);
33
+ margin: 0;
34
+ }
35
+
36
+ .crewlet-contrast-help__levels dt,
37
+ .crewlet-contrast-help__levels dd {
38
+ margin: 0;
39
+ }
40
+
41
+ .crewlet-contrast-help__levels dd {
42
+ color: var(--color-text-secondary);
43
+ }
@@ -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,7 +1,7 @@
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-NAWUXCBC.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-5O72FSOK.js';
3
4
  import '../chunk-ZFM5L7M4.js';
4
- import '../chunk-WQ7S7CKZ.js';
5
5
  import '../chunk-YCC2S7DF.js';
6
6
  import '../chunk-7KHM2FZH.js';
7
7
  import '../chunk-STJ7QBC3.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';
@@ -4,13 +4,11 @@ export interface EditingStatusLabels {
4
4
  editing: string;
5
5
  unsaved: string;
6
6
  saving: string;
7
- /** Shown once the last save landed, with how long ago: "Saved 2 min ago". */
8
- saved: (ago: string) => string;
9
7
  /**
10
- * Said in its place: the time is shown and not announced, so a screen
11
- * reader hears "Saved" when the save lands rather than every minute after.
8
+ * The state once the last save landed, followed by how long ago: "Saved",
9
+ * drawn "Saved 2m ago". The word is announced; the time is not.
12
10
  */
13
- savedSpoken: string;
11
+ saved: string;
14
12
  }
15
13
  export interface EditingStatusProps {
16
14
  /** Whether anything differs from what was opened. */
@@ -1,4 +1,4 @@
1
- export { EditingStatus } from '../chunk-MMOXWAUG.js';
1
+ export { EditingStatus } from '../chunk-EJWPYEG4.js';
2
2
  import '../chunk-3CZ7XAVY.js';
3
3
  import '../chunk-EUCC37WY.js';
4
4
  import '../chunk-BZFWDIV6.js';
@@ -26,20 +26,32 @@
26
26
  background: var(--color-brand-accent);
27
27
  }
28
28
 
29
+ /*
30
+ * THE WORDS RUN AS TEXT, not as flex items, so the space between the label
31
+ * and the state (which the ear needs) and the space before the time are real
32
+ * spaces, and the row is cut with an ellipsis rather than squeezed.
33
+ */
34
+ .crewlet-editing-status__text {
35
+ min-width: 0;
36
+ overflow: hidden;
37
+ text-overflow: ellipsis;
38
+ }
39
+
29
40
  .crewlet-editing-status__label {
30
41
  color: var(--color-text-primary);
31
42
  font-weight: var(--font-weight-medium);
32
43
  }
33
44
 
34
- .crewlet-editing-status__state {
35
- overflow: hidden;
45
+ .crewlet-editing-status__state,
46
+ .crewlet-editing-status__ago {
36
47
  color: var(--color-text-tertiary);
37
- text-overflow: ellipsis;
38
48
  }
39
49
 
50
+ /* The dot between the label and the state: drawn, never read. The space
51
+ before it in the text gives it the step on its left. */
40
52
  .crewlet-editing-status__state::before {
41
53
  content: '\00b7';
42
- margin-right: var(--spacing-2);
54
+ margin-inline: var(--spacing-1) var(--spacing-2);
43
55
  }
44
56
 
45
57
  /*
@@ -53,7 +65,8 @@
53
65
  * "Editing" folds too, and Cancel and Save beside the dot say an edit is open.
54
66
  */
55
67
  @media (width < 480px) {
56
- .crewlet-editing-status__state {
68
+ .crewlet-editing-status__state,
69
+ .crewlet-editing-status__ago {
57
70
  position: absolute;
58
71
  width: 1px;
59
72
  height: 1px;
@@ -64,7 +77,8 @@
64
77
  }
65
78
 
66
79
  @container crewlet-artifact-bar (width < 900px) {
67
- .crewlet-editing-status__state {
80
+ .crewlet-editing-status__state,
81
+ .crewlet-editing-status__ago {
68
82
  position: absolute;
69
83
  width: 1px;
70
84
  height: 1px;
@@ -76,7 +90,8 @@
76
90
 
77
91
  @container crewlet-artifact-bar (width < 640px) {
78
92
  .crewlet-editing-status__label,
79
- .crewlet-editing-status__state {
93
+ .crewlet-editing-status__state,
94
+ .crewlet-editing-status__ago {
80
95
  position: absolute;
81
96
  width: 1px;
82
97
  height: 1px;
@@ -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';
@@ -1,4 +1,4 @@
1
- export { FolderTile, describeFolderContents } from '../chunk-M4QM477B.js';
1
+ export { FolderTile, describeFolderContents } from '../chunk-FXHWOXGD.js';
2
2
  import '../chunk-INHXF2CL.js';
3
3
  import '../chunk-AV2DXAEL.js';
4
4
  import '../chunk-BHHIIK3M.js';
@@ -27,8 +27,17 @@
27
27
  --crewlet-folder-tile-floor: auto;
28
28
  --crewlet-folder-tile-glyph: 40px;
29
29
  --crewlet-folder-tile-glyph-radius: var(--radius-md);
30
+ /*
31
+ * THE WORDS ARE SET AS THE CARDS BESIDE THEM: a tile's name at a gallery
32
+ * card's title step and weight, its facts at the card's facts step, one
33
+ * line height for both and the card's step between them. The row (and a
34
+ * tile on a phone, which is the row) keeps the same two steps, since the
35
+ * cards it stands above keep theirs there too, with a tighter step between
36
+ * the lines so it stays one compact row.
37
+ */
30
38
  --crewlet-folder-tile-name: var(--font-size-md);
31
39
  --crewlet-folder-tile-facts: var(--font-size-sm);
40
+ --crewlet-folder-tile-words-gap: var(--spacing-1);
32
41
  --crewlet-folder-tile-actions-inset: var(--spacing-3);
33
42
  /*
34
43
  * A TILE STACKS: the glyph on top with the More menu level with it in the
@@ -61,8 +70,7 @@
61
70
  --crewlet-folder-tile-floor: var(--size-control-lg);
62
71
  --crewlet-folder-tile-glyph: 28px;
63
72
  --crewlet-folder-tile-glyph-radius: var(--radius-sm);
64
- --crewlet-folder-tile-name: var(--font-size-sm);
65
- --crewlet-folder-tile-facts: var(--font-size-xs);
73
+ --crewlet-folder-tile-words-gap: 2px;
66
74
  --crewlet-folder-tile-actions-inset: var(--spacing-2);
67
75
  --crewlet-folder-tile-direction: row;
68
76
  --crewlet-folder-tile-align: center;
@@ -82,8 +90,7 @@
82
90
  --crewlet-folder-tile-floor: var(--size-control-lg);
83
91
  --crewlet-folder-tile-glyph: 28px;
84
92
  --crewlet-folder-tile-glyph-radius: var(--radius-sm);
85
- --crewlet-folder-tile-name: var(--font-size-sm);
86
- --crewlet-folder-tile-facts: var(--font-size-xs);
93
+ --crewlet-folder-tile-words-gap: 2px;
87
94
  --crewlet-folder-tile-actions-inset: var(--spacing-2);
88
95
  --crewlet-folder-tile-direction: row;
89
96
  --crewlet-folder-tile-align: center;
@@ -151,7 +158,7 @@
151
158
  .crewlet-folder-tile__body {
152
159
  display: flex;
153
160
  flex-direction: column;
154
- gap: 2px;
161
+ gap: var(--crewlet-folder-tile-words-gap);
155
162
  min-width: 0;
156
163
  max-width: 100%;
157
164
  }
@@ -1,5 +1,5 @@
1
- export { FollowBanner } from '../chunk-4A4QG6UC.js';
2
- import '../chunk-SZZRIHGT.js';
1
+ export { FollowBanner } from '../chunk-34C7NYIQ.js';
2
+ import '../chunk-BPCY7ZID.js';
3
3
  import '../chunk-OMV5W53A.js';
4
4
  import '../chunk-OG6CL3EB.js';
5
5
  import '../chunk-H5XTJ7GJ.js';
@@ -1,5 +1,5 @@
1
- export { INLINE_EDITOR_LABELS, InlineEditor } from '../chunk-QGRA2RHC.js';
2
- import '../chunk-MMOXWAUG.js';
1
+ export { INLINE_EDITOR_LABELS, InlineEditor } from '../chunk-6RMZH7P7.js';
2
+ import '../chunk-EJWPYEG4.js';
3
3
  import '../chunk-3CZ7XAVY.js';
4
4
  import '../chunk-EUCC37WY.js';
5
5
  import '../chunk-SMBKXWML.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. */
@@ -1,7 +1,7 @@
1
- export { LinkInterstitial, openExternal } from '../chunk-GP4YWZFO.js';
1
+ export { LinkInterstitial, openExternal } from '../chunk-U3LNU4B2.js';
2
2
  import '../chunk-YCC2S7DF.js';
3
3
  import '../chunk-5CLW2CXT.js';
4
- import '../chunk-SZZRIHGT.js';
4
+ import '../chunk-BPCY7ZID.js';
5
5
  import '../chunk-PQADV6P6.js';
6
6
  import '../chunk-OMV5W53A.js';
7
7
  import '../chunk-OG6CL3EB.js';
@@ -109,8 +109,12 @@ 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
- /** The name of the control beside the legend that appends what the box holds. */
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;
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;
116
+ /** The word that button shows, which its name begins with: "Add". */
117
+ addText?: string | undefined;
114
118
  itemLabel?: ((name: string, position: string) => string) | undefined;
115
119
  newItemLabel?: ((itemName: string) => string) | undefined;
116
120
  moveUpLabel?: ((itemName: string, position: string) => string) | undefined;
@@ -1,7 +1,7 @@
1
- export { ListInput, withDraft } from '../chunk-PGR2PKH6.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
- /* With a hidden legend the add control stands at the end of the box's row. */
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,8 +1,8 @@
1
- export { LogoSlot } from '../chunk-BEAXJARF.js';
1
+ export { LogoSlot, LogoSlotGroup } from '../chunk-UKE7LTFZ.js';
2
2
  import '../chunk-THDGBD6Y.js';
3
- import '../chunk-NSSOWQCJ.js';
3
+ import '../chunk-WW7TU6HE.js';
4
4
  import '../chunk-KYIAFNU7.js';
5
- import '../chunk-UZMNR366.js';
5
+ import '../chunk-7W3LYIOC.js';
6
6
  import '../chunk-WIATRXEJ.js';
7
7
  import '../chunk-OG6CL3EB.js';
8
8
  import '../chunk-BZFWDIV6.js';
@@ -124,6 +124,13 @@
124
124
  opacity: 0.5;
125
125
  }
126
126
 
127
+ .crewlet-logo-slot__notes {
128
+ display: flex;
129
+ flex-direction: column;
130
+ gap: var(--spacing-1);
131
+ min-width: 0;
132
+ }
133
+
127
134
  .crewlet-logo-slot__empty {
128
135
  margin: 0;
129
136
  color: var(--color-text-tertiary);
@@ -157,3 +164,94 @@
157
164
  color: var(--color-text-tertiary);
158
165
  font-size: var(--font-size-xs);
159
166
  }
167
+
168
+ /*
169
+ * A GROUP OF SLOTS, aligned row by row (LogoSlotGroup.tsx). Each slot is a
170
+ * subgrid spanning the group's four rows: its name and description, its
171
+ * stage, what is said under it, and its actions. A row holds the tallest of
172
+ * its parts across the slots, so every stage, note and action row starts on
173
+ * one line. The steps between the parts are margins rather than the grid's
174
+ * gap, so a row no slot uses (no notes anywhere) takes no room at all.
175
+ */
176
+ .crewlet-logo-slot-group {
177
+ display: flex;
178
+ flex-direction: column;
179
+ gap: var(--spacing-3);
180
+ min-width: 0;
181
+ }
182
+
183
+ .crewlet-logo-slot-group__slots {
184
+ display: grid;
185
+ grid-template-columns: repeat(auto-fill, minmax(min(14rem, 100%), 1fr));
186
+ column-gap: var(--spacing-5);
187
+ row-gap: var(--spacing-6);
188
+ }
189
+
190
+ .crewlet-logo-slot-group__slots > .crewlet-logo-slot {
191
+ display: grid;
192
+ grid-row: span 4;
193
+ grid-template-rows: subgrid;
194
+ row-gap: 0;
195
+ align-content: start;
196
+ }
197
+
198
+ .crewlet-logo-slot-group__slots > .crewlet-logo-slot > .crewlet-logo-slot__head {
199
+ grid-row: 1;
200
+ margin-block-end: var(--spacing-2);
201
+ }
202
+
203
+ .crewlet-logo-slot-group__slots > .crewlet-logo-slot > :is(.crewlet-logo-slot__stage, .crewlet-file-drop) {
204
+ grid-row: 2;
205
+ }
206
+
207
+ .crewlet-logo-slot-group__slots > .crewlet-logo-slot > .crewlet-logo-slot__notes {
208
+ grid-row: 3;
209
+ margin-block-start: var(--spacing-2);
210
+ }
211
+
212
+ .crewlet-logo-slot-group__slots > .crewlet-logo-slot > .crewlet-logo-slot__foot {
213
+ grid-row: 4;
214
+ margin-block-start: var(--spacing-2);
215
+ }
216
+
217
+ .crewlet-logo-slot-group__hint {
218
+ margin: 0;
219
+ color: var(--color-text-tertiary);
220
+ font-size: var(--font-size-xs);
221
+ line-height: var(--font-line-height-normal);
222
+ }
223
+
224
+ /*
225
+ * SMALL: a thumbnail of the slot for a summary of what is set. The stage
226
+ * keeps its ground, its edge and the space the logo keeps, at half the height
227
+ * with a tighter inset, and the words step down to the summary's sizes.
228
+ */
229
+ .crewlet-logo-slot--sm {
230
+ --crewlet-logo-slot-height: calc(var(--size-row-lg) * 1.5);
231
+ --crewlet-logo-slot-padding: var(--spacing-2);
232
+ --crewlet-logo-slot-clear: var(--spacing-1);
233
+
234
+ gap: var(--spacing-1);
235
+ }
236
+
237
+ .crewlet-logo-slot--sm .crewlet-logo-slot__label {
238
+ font-size: var(--font-size-xs);
239
+ }
240
+
241
+ .crewlet-logo-slot--sm .crewlet-logo-slot__description,
242
+ .crewlet-logo-slot--sm .crewlet-logo-slot__empty {
243
+ font-size: var(--font-size-2xs);
244
+ }
245
+
246
+ .crewlet-logo-slot--sm .crewlet-logo-slot__stage {
247
+ border-radius: var(--radius-md);
248
+ }
249
+
250
+ .crewlet-logo-slot--sm .crewlet-logo-slot__placeholder {
251
+ width: calc(var(--size-row-lg) * 1.5);
252
+ height: var(--size-row-sm);
253
+ }
254
+
255
+ .crewlet-logo-slot--sm .crewlet-logo-slot__stage--square .crewlet-logo-slot__placeholder {
256
+ width: var(--size-row-sm);
257
+ }
@@ -1,10 +1,10 @@
1
- export { PrincipalPicker } from '../chunk-KHZYAEGZ.js';
2
- import '../chunk-P5JBDHWC.js';
1
+ export { PrincipalPicker } from '../chunk-G5SUSCWL.js';
2
+ import '../chunk-C6Z3MLSA.js';
3
3
  import '../chunk-7KHM2FZH.js';
4
4
  import '../chunk-CI3VPIJN.js';
5
5
  import '../chunk-5AQBPHZD.js';
6
6
  import '../chunk-PZKHBB7D.js';
7
- import '../chunk-EXRRTKWT.js';
7
+ import '../chunk-LJHH4WWB.js';
8
8
  import '../chunk-XCUUI7E7.js';
9
9
  import '../chunk-PQADV6P6.js';
10
10
  import '../chunk-RSAQOKH3.js';