@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
package/dist/styles.css CHANGED
@@ -2913,7 +2913,7 @@ button.crewlet-account-row__who:focus-visible {
2913
2913
  }
2914
2914
 
2915
2915
 
2916
- /* ArtifactCard-SOB63NV5.css */
2916
+ /* ArtifactCard-F7IVRL3A.css */
2917
2917
  /*
2918
2918
  * A card in a gallery: the preview on top at a fixed ratio, so a grid of them
2919
2919
  * lines up whatever each preview is, the kind's badge over its foot, then the
@@ -3131,6 +3131,9 @@ button.crewlet-account-row__who:focus-visible {
3131
3131
 
3132
3132
  .crewlet-artifact-card--card .crewlet-artifact-card__facts {
3133
3133
  font-size: var(--font-size-sm);
3134
+ /* The title's line height, so a card's words and a folder tile's beside it
3135
+ keep one rhythm. */
3136
+ line-height: 1.35;
3134
3137
  }
3135
3138
 
3136
3139
  .crewlet-artifact-card__meta {
@@ -5812,7 +5815,7 @@ a.crewlet-breadcrumb__crumb:focus-visible {
5812
5815
  }
5813
5816
 
5814
5817
 
5815
- /* Callout-ZAVG3P66.css */
5818
+ /* Callout-G3N3IE6M.css */
5816
5819
  /*
5817
5820
  * The callout: a status that stays in the content flow.
5818
5821
  *
@@ -5892,7 +5895,16 @@ a.crewlet-breadcrumb__crumb:focus-visible {
5892
5895
  font-weight: var(--font-weight-semibold);
5893
5896
  }
5894
5897
 
5898
+ /*
5899
+ * THE ACTIONS ARE A ROW one step apart, wrapping when there is no room, so a
5900
+ * callout with two (Continue setting up, Review and adopt) never draws them
5901
+ * touching, whatever the host wraps them in.
5902
+ */
5895
5903
  .crewlet-callout__action {
5904
+ display: flex;
5905
+ flex-wrap: wrap;
5906
+ align-items: center;
5907
+ gap: var(--spacing-2);
5896
5908
  grid-column: 3;
5897
5909
  grid-row: 1;
5898
5910
  align-self: center;
@@ -9025,7 +9037,7 @@ button.crewlet-histogram__bar[data-empty]:focus-visible > .crewlet-histogram__fi
9025
9037
  }
9026
9038
 
9027
9039
 
9028
- /* ChoiceButtons-FLIFXFFS.css */
9040
+ /* ChoiceButtons-HWXEF2H3.css */
9029
9041
  /*
9030
9042
  * One answer, sent with one press: a column of buttons as tall as a touch
9031
9043
  * target, the recommended one first and filled with the accent.
@@ -9083,6 +9095,17 @@ button.crewlet-histogram__bar[data-empty]:focus-visible > .crewlet-histogram__fi
9083
9095
  background: var(--color-surface-pressed);
9084
9096
  }
9085
9097
 
9098
+ /*
9099
+ * THE OPTION APPLIED is drawn as every chosen option in the package is: the
9100
+ * selected edge over the soft selected fill, calm beside the focus ring, and
9101
+ * held under the pointer so a hover never makes it look unchosen.
9102
+ */
9103
+ .crewlet-choice-buttons__option.is-chosen,
9104
+ .crewlet-choice-buttons__option.is-chosen:hover {
9105
+ border-color: var(--color-border-selected);
9106
+ background: var(--color-surface-selected);
9107
+ }
9108
+
9086
9109
  /*
9087
9110
  * The plain option draws the strong hairline, so its ring is drawn over that
9088
9111
  * edge rather than a gap away from it, which would read as a second outline.
@@ -9158,6 +9181,55 @@ button.crewlet-histogram__bar[data-empty]:focus-visible > .crewlet-histogram__fi
9158
9181
  text-transform: uppercase;
9159
9182
  }
9160
9183
 
9184
+ /* The picture before the words, centred on the label's line. */
9185
+ .crewlet-choice-buttons__media {
9186
+ display: inline-flex;
9187
+ flex: none;
9188
+ align-items: center;
9189
+ align-self: center;
9190
+ }
9191
+
9192
+ /* Before the words, not at the far end with the recommended mark. */
9193
+ .crewlet-choice-buttons__option:has(.crewlet-choice-buttons__media) {
9194
+ justify-content: flex-start;
9195
+ }
9196
+
9197
+ .crewlet-choice-buttons__option:has(.crewlet-choice-buttons__media) .crewlet-choice-buttons__note {
9198
+ margin-inline-start: auto;
9199
+ }
9200
+
9201
+ /*
9202
+ * SMALL: the same option, compact, in a row that wraps. A step and a half
9203
+ * inside, the field's small height, the label at the compact step and its
9204
+ * detail at the micro step, so three suggestions sit under a field without
9205
+ * outweighing it. Every state (hover, press, focus, chosen) is the Inbox's.
9206
+ */
9207
+ .crewlet-choice-buttons--sm {
9208
+ display: flex;
9209
+ flex-wrap: wrap;
9210
+ gap: var(--spacing-2);
9211
+ }
9212
+
9213
+ .crewlet-choice-buttons--sm .crewlet-choice-buttons__option {
9214
+ gap: var(--spacing-2);
9215
+ min-height: var(--size-control-sm);
9216
+ padding: var(--spacing-1) calc(var(--spacing-2) + var(--spacing-1) / 2);
9217
+ font-size: var(--font-size-xs);
9218
+ line-height: var(--font-line-height-tight);
9219
+ }
9220
+
9221
+ .crewlet-choice-buttons--sm .crewlet-choice-buttons__option:has(.crewlet-choice-buttons__detail) {
9222
+ align-items: center;
9223
+ }
9224
+
9225
+ .crewlet-choice-buttons--sm .crewlet-choice-buttons__text {
9226
+ gap: 1px;
9227
+ }
9228
+
9229
+ .crewlet-choice-buttons--sm .crewlet-choice-buttons__detail {
9230
+ font-size: var(--font-size-2xs);
9231
+ }
9232
+
9161
9233
  @media (prefers-reduced-motion: reduce) {
9162
9234
  .crewlet-choice-buttons__option {
9163
9235
  transition: none;
@@ -9573,6 +9645,55 @@ button.crewlet-histogram__bar[data-empty]:focus-visible > .crewlet-histogram__fi
9573
9645
  }
9574
9646
 
9575
9647
 
9648
+ /* ColorChip-A5XHTH3J.css */
9649
+ /*
9650
+ * A colour as a small chip (ColorChip.tsx). Its fill is the one value that is
9651
+ * not a token, and it arrives through `--crewlet-color-chip-value` only after
9652
+ * it has passed `#rrggbb`.
9653
+ */
9654
+ .crewlet-color-chip {
9655
+ display: inline-block;
9656
+ flex: none;
9657
+ box-sizing: border-box;
9658
+ width: var(--spacing-3);
9659
+ height: var(--spacing-3);
9660
+ background: var(--crewlet-color-chip-value, var(--color-surface-inset));
9661
+ /* An edge of its own, so a colour that matches its ground is still a chip. */
9662
+ box-shadow: inset 0 0 0 1px var(--color-border-hover);
9663
+ vertical-align: middle;
9664
+ }
9665
+
9666
+ .crewlet-color-chip--sm {
9667
+ width: var(--spacing-4);
9668
+ height: var(--spacing-4);
9669
+ }
9670
+
9671
+ .crewlet-color-chip--round {
9672
+ border-radius: var(--radius-circle);
9673
+ }
9674
+
9675
+ .crewlet-color-chip--square {
9676
+ border-radius: var(--radius-xs);
9677
+ }
9678
+
9679
+ /* The hatch of no colour, as every swatch in the package draws it. */
9680
+ .crewlet-color-chip.is-empty {
9681
+ background: repeating-linear-gradient(-45deg, var(--color-border-hatch) 0 1px, transparent 1px var(--spacing-1));
9682
+ }
9683
+
9684
+ /*
9685
+ * FORCED COLORS drops backgrounds, which is all a chip is, so the mode keeps
9686
+ * this one: the colour is the information, and the edge is drawn in the
9687
+ * system's text colour so the chip still has a boundary.
9688
+ */
9689
+ @media (forced-colors: active) {
9690
+ .crewlet-color-chip {
9691
+ forced-color-adjust: none;
9692
+ box-shadow: inset 0 0 0 1px CanvasText;
9693
+ }
9694
+ }
9695
+
9696
+
9576
9697
  /* ColorField-2OIOWT3Z.css */
9577
9698
  /*
9578
9699
  * A colour a person chooses: the swatch that opens the platform's picker,
@@ -10551,6 +10672,52 @@ button.crewlet-histogram__bar[data-empty]:focus-visible > .crewlet-histogram__fi
10551
10672
  }
10552
10673
 
10553
10674
 
10675
+ /* ContrastHelp-MZCAW5WQ.css */
10676
+ /*
10677
+ * ContrastHelp: what the contrast levels mean, in a short panel opened from an
10678
+ * info button (ContrastHelp.tsx).
10679
+ */
10680
+ .crewlet-contrast-help {
10681
+ display: flex;
10682
+ flex-direction: column;
10683
+ gap: var(--spacing-2);
10684
+ padding: var(--spacing-3);
10685
+ font-family: var(--font-family-sans);
10686
+ font-size: var(--font-size-xs);
10687
+ line-height: var(--font-line-height-snug);
10688
+ }
10689
+
10690
+ .crewlet-contrast-help__title {
10691
+ margin: 0;
10692
+ color: var(--color-text-primary);
10693
+ font-size: var(--font-size-sm);
10694
+ font-weight: var(--font-weight-semibold);
10695
+ }
10696
+
10697
+ .crewlet-contrast-help__intro {
10698
+ margin: 0;
10699
+ color: var(--color-text-secondary);
10700
+ }
10701
+
10702
+ /* Each level's word as the badge draws it, beside what it means. */
10703
+ .crewlet-contrast-help__levels {
10704
+ display: grid;
10705
+ grid-template-columns: max-content minmax(0, 1fr);
10706
+ align-items: baseline;
10707
+ gap: var(--spacing-2) var(--spacing-3);
10708
+ margin: 0;
10709
+ }
10710
+
10711
+ .crewlet-contrast-help__levels dt,
10712
+ .crewlet-contrast-help__levels dd {
10713
+ margin: 0;
10714
+ }
10715
+
10716
+ .crewlet-contrast-help__levels dd {
10717
+ color: var(--color-text-secondary);
10718
+ }
10719
+
10720
+
10554
10721
  /* Copyable-5PNRFOLS.css */
10555
10722
  /*
10556
10723
  * Copyable: a value and the one control that copies it.
@@ -15678,7 +15845,7 @@ svg.crewlet-datetime__chevron {
15678
15845
  }
15679
15846
 
15680
15847
 
15681
- /* EditingStatus-NNA2CKIL.css */
15848
+ /* EditingStatus-YU7EGM6Y.css */
15682
15849
  /*
15683
15850
  * The editing status (EditingStatus.tsx): a word and a dot, in the bar's own
15684
15851
  * small step, quiet until something is unsaved.
@@ -15707,20 +15874,32 @@ svg.crewlet-datetime__chevron {
15707
15874
  background: var(--color-brand-accent);
15708
15875
  }
15709
15876
 
15877
+ /*
15878
+ * THE WORDS RUN AS TEXT, not as flex items, so the space between the label
15879
+ * and the state (which the ear needs) and the space before the time are real
15880
+ * spaces, and the row is cut with an ellipsis rather than squeezed.
15881
+ */
15882
+ .crewlet-editing-status__text {
15883
+ min-width: 0;
15884
+ overflow: hidden;
15885
+ text-overflow: ellipsis;
15886
+ }
15887
+
15710
15888
  .crewlet-editing-status__label {
15711
15889
  color: var(--color-text-primary);
15712
15890
  font-weight: var(--font-weight-medium);
15713
15891
  }
15714
15892
 
15715
- .crewlet-editing-status__state {
15716
- overflow: hidden;
15893
+ .crewlet-editing-status__state,
15894
+ .crewlet-editing-status__ago {
15717
15895
  color: var(--color-text-tertiary);
15718
- text-overflow: ellipsis;
15719
15896
  }
15720
15897
 
15898
+ /* The dot between the label and the state: drawn, never read. The space
15899
+ before it in the text gives it the step on its left. */
15721
15900
  .crewlet-editing-status__state::before {
15722
15901
  content: '\00b7';
15723
- margin-right: var(--spacing-2);
15902
+ margin-inline: var(--spacing-1) var(--spacing-2);
15724
15903
  }
15725
15904
 
15726
15905
  /*
@@ -15734,7 +15913,8 @@ svg.crewlet-datetime__chevron {
15734
15913
  * "Editing" folds too, and Cancel and Save beside the dot say an edit is open.
15735
15914
  */
15736
15915
  @media (width < 480px) {
15737
- .crewlet-editing-status__state {
15916
+ .crewlet-editing-status__state,
15917
+ .crewlet-editing-status__ago {
15738
15918
  position: absolute;
15739
15919
  width: 1px;
15740
15920
  height: 1px;
@@ -15745,7 +15925,8 @@ svg.crewlet-datetime__chevron {
15745
15925
  }
15746
15926
 
15747
15927
  @container crewlet-artifact-bar (width < 900px) {
15748
- .crewlet-editing-status__state {
15928
+ .crewlet-editing-status__state,
15929
+ .crewlet-editing-status__ago {
15749
15930
  position: absolute;
15750
15931
  width: 1px;
15751
15932
  height: 1px;
@@ -15757,7 +15938,8 @@ svg.crewlet-datetime__chevron {
15757
15938
 
15758
15939
  @container crewlet-artifact-bar (width < 640px) {
15759
15940
  .crewlet-editing-status__label,
15760
- .crewlet-editing-status__state {
15941
+ .crewlet-editing-status__state,
15942
+ .crewlet-editing-status__ago {
15761
15943
  position: absolute;
15762
15944
  width: 1px;
15763
15945
  height: 1px;
@@ -16405,7 +16587,7 @@ button.crewlet-finding-list__row:focus-visible {
16405
16587
  }
16406
16588
 
16407
16589
 
16408
- /* FolderTile-FDT5Y63Z.css */
16590
+ /* FolderTile-MIUEB7SO.css */
16409
16591
  /*
16410
16592
  * A folder in a gallery: a short tile on Card (no preview), the folder glyph
16411
16593
  * on a neutral tint over the name and one quiet line, and a More menu in the
@@ -16435,8 +16617,17 @@ button.crewlet-finding-list__row:focus-visible {
16435
16617
  --crewlet-folder-tile-floor: auto;
16436
16618
  --crewlet-folder-tile-glyph: 40px;
16437
16619
  --crewlet-folder-tile-glyph-radius: var(--radius-md);
16620
+ /*
16621
+ * THE WORDS ARE SET AS THE CARDS BESIDE THEM: a tile's name at a gallery
16622
+ * card's title step and weight, its facts at the card's facts step, one
16623
+ * line height for both and the card's step between them. The row (and a
16624
+ * tile on a phone, which is the row) keeps the same two steps, since the
16625
+ * cards it stands above keep theirs there too, with a tighter step between
16626
+ * the lines so it stays one compact row.
16627
+ */
16438
16628
  --crewlet-folder-tile-name: var(--font-size-md);
16439
16629
  --crewlet-folder-tile-facts: var(--font-size-sm);
16630
+ --crewlet-folder-tile-words-gap: var(--spacing-1);
16440
16631
  --crewlet-folder-tile-actions-inset: var(--spacing-3);
16441
16632
  /*
16442
16633
  * A TILE STACKS: the glyph on top with the More menu level with it in the
@@ -16469,8 +16660,7 @@ button.crewlet-finding-list__row:focus-visible {
16469
16660
  --crewlet-folder-tile-floor: var(--size-control-lg);
16470
16661
  --crewlet-folder-tile-glyph: 28px;
16471
16662
  --crewlet-folder-tile-glyph-radius: var(--radius-sm);
16472
- --crewlet-folder-tile-name: var(--font-size-sm);
16473
- --crewlet-folder-tile-facts: var(--font-size-xs);
16663
+ --crewlet-folder-tile-words-gap: 2px;
16474
16664
  --crewlet-folder-tile-actions-inset: var(--spacing-2);
16475
16665
  --crewlet-folder-tile-direction: row;
16476
16666
  --crewlet-folder-tile-align: center;
@@ -16490,8 +16680,7 @@ button.crewlet-finding-list__row:focus-visible {
16490
16680
  --crewlet-folder-tile-floor: var(--size-control-lg);
16491
16681
  --crewlet-folder-tile-glyph: 28px;
16492
16682
  --crewlet-folder-tile-glyph-radius: var(--radius-sm);
16493
- --crewlet-folder-tile-name: var(--font-size-sm);
16494
- --crewlet-folder-tile-facts: var(--font-size-xs);
16683
+ --crewlet-folder-tile-words-gap: 2px;
16495
16684
  --crewlet-folder-tile-actions-inset: var(--spacing-2);
16496
16685
  --crewlet-folder-tile-direction: row;
16497
16686
  --crewlet-folder-tile-align: center;
@@ -16559,7 +16748,7 @@ button.crewlet-finding-list__row:focus-visible {
16559
16748
  .crewlet-folder-tile__body {
16560
16749
  display: flex;
16561
16750
  flex-direction: column;
16562
- gap: 2px;
16751
+ gap: var(--crewlet-folder-tile-words-gap);
16563
16752
  min-width: 0;
16564
16753
  max-width: 100%;
16565
16754
  }
@@ -17590,7 +17779,7 @@ a.crewlet-icon-btn {
17590
17779
  }
17591
17780
 
17592
17781
 
17593
- /* Input-VDSV7VWJ.css */
17782
+ /* Input-GMOWHZRG.css */
17594
17783
  /*
17595
17784
  * The form row: Input, Textarea, Label, FormField, FormRow, FormSection and
17596
17785
  * ReadOnlyField.
@@ -18173,6 +18362,15 @@ a.crewlet-icon-btn {
18173
18362
  min-width: 0;
18174
18363
  }
18175
18364
 
18365
+ /* A count that is not a length ("3 of 5"), in the help line's own quiet ink. */
18366
+ .crewlet-form-field__tally {
18367
+ flex: none;
18368
+ color: var(--color-text-tertiary);
18369
+ font-size: var(--font-size-xs);
18370
+ font-variant-numeric: tabular-nums;
18371
+ line-height: var(--font-line-height-normal);
18372
+ }
18373
+
18176
18374
  /* SHOWN ONLY WHILE THE FIELD HAS FOCUS (`helperOnFocus`): a dense form reads as
18177
18375
  labels and values at rest, and the sentence appears under the field the
18178
18376
  reader is in. Still described, so a screen reader hears it on entry. */
@@ -19230,7 +19428,7 @@ a.crewlet-icon-btn {
19230
19428
  }
19231
19429
 
19232
19430
 
19233
- /* ListInput-WUP2YITQ.css */
19431
+ /* ListInput-RLQND5QK.css */
19234
19432
  /*
19235
19433
  * ListInput: an ordered list of sentences, written in the box at the top and
19236
19434
  * listed under it.
@@ -19294,7 +19492,9 @@ a.crewlet-icon-btn {
19294
19492
  .crewlet-list-input__item {
19295
19493
  display: flex;
19296
19494
  align-items: center;
19297
- gap: var(--spacing-2);
19495
+ /* A step and the control's own inset: the ring an edited item draws stands
19496
+ a step clear of its number. */
19497
+ gap: var(--spacing-3);
19298
19498
  padding: var(--spacing-1) var(--spacing-3);
19299
19499
  border-block-end-width: 1px;
19300
19500
  border-block-end-style: solid;
@@ -19402,11 +19602,28 @@ a.crewlet-icon-btn {
19402
19602
  .crewlet-list-input__item .crewlet-input__control,
19403
19603
  .crewlet-list-input__item .crewlet-textarea {
19404
19604
  padding-block: var(--spacing-1);
19405
- padding-inline: 0;
19605
+ /*
19606
+ * EDITING NEVER MOVES THE WORDS. The control keeps an inset of its own, so
19607
+ * the boundary that hover and focus draw stands clear of the text rather
19608
+ * than touching its first letter, and a negative margin of the same step
19609
+ * takes it back, so the words sit exactly where they sat at rest and the
19610
+ * caret lands on them without a jump.
19611
+ */
19612
+ padding-inline: var(--spacing-2);
19613
+ margin-inline: calc(var(--spacing-2) * -1);
19406
19614
  }
19407
19615
 
19408
19616
  .crewlet-list-input__index {
19409
19617
  flex: none;
19618
+ /*
19619
+ * ON THE TEXT'S FIRST LINE, never centred on a wrapped item: it starts where
19620
+ * the words start (the control's edge and its block inset below the row's
19621
+ * own padding) and takes their line's height, so the number and the words
19622
+ * share a baseline however many lines the item runs to.
19623
+ */
19624
+ align-self: flex-start;
19625
+ padding-block-start: calc(1px + var(--spacing-1));
19626
+ line-height: calc(var(--font-size-compact) * var(--font-line-height-normal));
19410
19627
  min-width: var(--spacing-4);
19411
19628
  text-align: center;
19412
19629
  font-size: var(--font-size-xs);
@@ -19490,11 +19707,16 @@ a.crewlet-icon-btn {
19490
19707
  }
19491
19708
  }
19492
19709
 
19493
- /* With a hidden legend the add control stands at the end of the box's row. */
19710
+ /*
19711
+ * The Add button ends the box's row: the field and its Add read as one
19712
+ * control. It is the field's height (the medium control step a one-line box
19713
+ * stands at) and sits on the box's first line, so the two share one line and
19714
+ * the button stays put as a long item grows the box under it.
19715
+ */
19494
19716
  .crewlet-list-input__add-control {
19495
19717
  display: inline-flex;
19496
19718
  flex: none;
19497
- align-self: center;
19719
+ align-self: flex-start;
19498
19720
  }
19499
19721
 
19500
19722
  /*
@@ -19512,11 +19734,11 @@ a.crewlet-icon-btn {
19512
19734
  }
19513
19735
 
19514
19736
  .crewlet-list-input__item > .crewlet-list-input__field {
19515
- flex-basis: calc(100% - var(--spacing-4) - var(--spacing-2));
19737
+ flex-basis: calc(100% - var(--spacing-4) - var(--spacing-3));
19516
19738
  }
19517
19739
 
19518
19740
  .crewlet-list-input__item--draggable > .crewlet-list-input__field {
19519
- flex-basis: calc(100% - var(--spacing-4) * 2 - var(--spacing-2) * 2);
19741
+ flex-basis: calc(100% - var(--spacing-4) * 2 - var(--spacing-3) * 2);
19520
19742
  }
19521
19743
 
19522
19744
  .crewlet-list-input__item > .crewlet-list-input__actions {
@@ -19892,7 +20114,7 @@ a.crewlet-icon-btn {
19892
20114
  }
19893
20115
 
19894
20116
 
19895
- /* LogoSlot-T2UFOJXU.css */
20117
+ /* LogoSlot-ETD74ELF.css */
19896
20118
  /*
19897
20119
  * One of a brand's logos on the ground it is made for. The ground and the ink
19898
20120
  * of its guide are the only values here that are not tokens: they arrive
@@ -20019,6 +20241,13 @@ a.crewlet-icon-btn {
20019
20241
  opacity: 0.5;
20020
20242
  }
20021
20243
 
20244
+ .crewlet-logo-slot__notes {
20245
+ display: flex;
20246
+ flex-direction: column;
20247
+ gap: var(--spacing-1);
20248
+ min-width: 0;
20249
+ }
20250
+
20022
20251
  .crewlet-logo-slot__empty {
20023
20252
  margin: 0;
20024
20253
  color: var(--color-text-tertiary);
@@ -20053,6 +20282,97 @@ a.crewlet-icon-btn {
20053
20282
  font-size: var(--font-size-xs);
20054
20283
  }
20055
20284
 
20285
+ /*
20286
+ * A GROUP OF SLOTS, aligned row by row (LogoSlotGroup.tsx). Each slot is a
20287
+ * subgrid spanning the group's four rows: its name and description, its
20288
+ * stage, what is said under it, and its actions. A row holds the tallest of
20289
+ * its parts across the slots, so every stage, note and action row starts on
20290
+ * one line. The steps between the parts are margins rather than the grid's
20291
+ * gap, so a row no slot uses (no notes anywhere) takes no room at all.
20292
+ */
20293
+ .crewlet-logo-slot-group {
20294
+ display: flex;
20295
+ flex-direction: column;
20296
+ gap: var(--spacing-3);
20297
+ min-width: 0;
20298
+ }
20299
+
20300
+ .crewlet-logo-slot-group__slots {
20301
+ display: grid;
20302
+ grid-template-columns: repeat(auto-fill, minmax(min(14rem, 100%), 1fr));
20303
+ column-gap: var(--spacing-5);
20304
+ row-gap: var(--spacing-6);
20305
+ }
20306
+
20307
+ .crewlet-logo-slot-group__slots > .crewlet-logo-slot {
20308
+ display: grid;
20309
+ grid-row: span 4;
20310
+ grid-template-rows: subgrid;
20311
+ row-gap: 0;
20312
+ align-content: start;
20313
+ }
20314
+
20315
+ .crewlet-logo-slot-group__slots > .crewlet-logo-slot > .crewlet-logo-slot__head {
20316
+ grid-row: 1;
20317
+ margin-block-end: var(--spacing-2);
20318
+ }
20319
+
20320
+ .crewlet-logo-slot-group__slots > .crewlet-logo-slot > :is(.crewlet-logo-slot__stage, .crewlet-file-drop) {
20321
+ grid-row: 2;
20322
+ }
20323
+
20324
+ .crewlet-logo-slot-group__slots > .crewlet-logo-slot > .crewlet-logo-slot__notes {
20325
+ grid-row: 3;
20326
+ margin-block-start: var(--spacing-2);
20327
+ }
20328
+
20329
+ .crewlet-logo-slot-group__slots > .crewlet-logo-slot > .crewlet-logo-slot__foot {
20330
+ grid-row: 4;
20331
+ margin-block-start: var(--spacing-2);
20332
+ }
20333
+
20334
+ .crewlet-logo-slot-group__hint {
20335
+ margin: 0;
20336
+ color: var(--color-text-tertiary);
20337
+ font-size: var(--font-size-xs);
20338
+ line-height: var(--font-line-height-normal);
20339
+ }
20340
+
20341
+ /*
20342
+ * SMALL: a thumbnail of the slot for a summary of what is set. The stage
20343
+ * keeps its ground, its edge and the space the logo keeps, at half the height
20344
+ * with a tighter inset, and the words step down to the summary's sizes.
20345
+ */
20346
+ .crewlet-logo-slot--sm {
20347
+ --crewlet-logo-slot-height: calc(var(--size-row-lg) * 1.5);
20348
+ --crewlet-logo-slot-padding: var(--spacing-2);
20349
+ --crewlet-logo-slot-clear: var(--spacing-1);
20350
+
20351
+ gap: var(--spacing-1);
20352
+ }
20353
+
20354
+ .crewlet-logo-slot--sm .crewlet-logo-slot__label {
20355
+ font-size: var(--font-size-xs);
20356
+ }
20357
+
20358
+ .crewlet-logo-slot--sm .crewlet-logo-slot__description,
20359
+ .crewlet-logo-slot--sm .crewlet-logo-slot__empty {
20360
+ font-size: var(--font-size-2xs);
20361
+ }
20362
+
20363
+ .crewlet-logo-slot--sm .crewlet-logo-slot__stage {
20364
+ border-radius: var(--radius-md);
20365
+ }
20366
+
20367
+ .crewlet-logo-slot--sm .crewlet-logo-slot__placeholder {
20368
+ width: calc(var(--size-row-lg) * 1.5);
20369
+ height: var(--size-row-sm);
20370
+ }
20371
+
20372
+ .crewlet-logo-slot--sm .crewlet-logo-slot__stage--square .crewlet-logo-slot__placeholder {
20373
+ width: var(--size-row-sm);
20374
+ }
20375
+
20056
20376
 
20057
20377
  /* MarkdownEditor-WOKV7CLK.css */
20058
20378
  /*
@@ -26349,7 +26669,7 @@ svg.crewlet-select__chevron {
26349
26669
  }
26350
26670
 
26351
26671
 
26352
- /* SetupWizard-Y5BTXZX5.css */
26672
+ /* SetupWizard-GZK5UDKC.css */
26353
26673
  /*
26354
26674
  * SetupWizard: a setup walked step by step on a page of its own
26355
26675
  * (SetupWizard.tsx).
@@ -26472,7 +26792,6 @@ svg.crewlet-select__chevron {
26472
26792
  display: flex;
26473
26793
  flex-wrap: wrap;
26474
26794
  align-items: center;
26475
- justify-content: flex-end;
26476
26795
  gap: var(--spacing-2);
26477
26796
  grid-area: foot;
26478
26797
  padding: var(--spacing-3) 0 calc(var(--spacing-3) + env(safe-area-inset-bottom, var(--spacing-0)));
@@ -26480,6 +26799,24 @@ svg.crewlet-select__chevron {
26480
26799
  background: var(--color-surface-background);
26481
26800
  }
26482
26801
 
26802
+ /* The way out at the start of the row, the step's actions at its end. */
26803
+ .crewlet-setup-wizard__footer-start,
26804
+ .crewlet-setup-wizard__footer-end {
26805
+ display: flex;
26806
+ flex-wrap: wrap;
26807
+ align-items: center;
26808
+ gap: var(--spacing-2);
26809
+ }
26810
+
26811
+ .crewlet-setup-wizard__footer-end {
26812
+ margin-inline-start: auto;
26813
+ }
26814
+
26815
+ /* A WIDE STEP lays out columns of its own across the whole width beside the rail. */
26816
+ .crewlet-setup-wizard--wide .crewlet-setup-wizard__content {
26817
+ max-width: none;
26818
+ }
26819
+
26483
26820
  /* BESIDE THE CONTENT, from 70rem of the wizard's own width: the aside holds in view. */
26484
26821
  @container (min-width: 70rem) {
26485
26822
  .crewlet-setup-wizard__frame {
@@ -26491,6 +26828,15 @@ svg.crewlet-select__chevron {
26491
26828
  grid-template-rows: auto 1fr auto;
26492
26829
  }
26493
26830
 
26831
+ /* With no aside, nothing is held for one: the content takes its column too. */
26832
+ .crewlet-setup-wizard--no-aside .crewlet-setup-wizard__frame {
26833
+ grid-template-columns: 240px minmax(0, 1fr);
26834
+ grid-template-areas:
26835
+ 'head head'
26836
+ 'rail content'
26837
+ 'foot foot';
26838
+ }
26839
+
26494
26840
  .crewlet-setup-wizard__aside {
26495
26841
  position: sticky;
26496
26842
  top: var(--spacing-5);
@@ -10,3 +10,16 @@
10
10
  * engine stores, so a value read back compares equal to the value written.
11
11
  */
12
12
  export declare function normalizeHex(value: string | null | undefined): string | null;
13
+ /**
14
+ * A colour as a person types or pastes it, read into the one stored spelling
15
+ * (`#` and six lowercase hex digits), or null for anything else.
16
+ *
17
+ * Taken: `#rrggbb` and `rrggbb`, the three digit shorthand with or without
18
+ * its `#` (each digit doubled), and `rgb(r, g, b)` or `rgb(r g b)` with each
19
+ * channel a whole number from 0 to 255. Refused: the eight and four digit
20
+ * forms (a stored brand colour has no alpha), percentages, names and every
21
+ * other notation, so what is stored is never a value a stylesheet would read
22
+ * as something else. The result passes `normalizeHex`, the gate every brand
23
+ * part reads a colour through.
24
+ */
25
+ export declare function parseColourInput(value: string | null | undefined): string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewlethq/ui",
3
- "version": "0.50.0",
3
+ "version": "0.52.0",
4
4
  "description": "Crewlet shared React components built on @crewlethq/tokens and @crewlethq/icons.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -42,8 +42,8 @@
42
42
  "clean": "rm -rf dist src/generated"
43
43
  },
44
44
  "dependencies": {
45
- "@crewlethq/icons": "0.50.0",
46
- "@crewlethq/tokens": "0.50.0",
45
+ "@crewlethq/icons": "0.52.0",
46
+ "@crewlethq/tokens": "0.52.0",
47
47
  "prosemirror-commands": "1.7.2",
48
48
  "prosemirror-gapcursor": "1.4.1",
49
49
  "prosemirror-history": "1.5.1",