@crewlethq/ui 0.48.3 → 0.49.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 (144) hide show
  1. package/README.md +56 -0
  2. package/dist/AgentHandoffPanel/index.js +3 -3
  3. package/dist/ArrangeList/index.js +2 -2
  4. package/dist/ArtifactBar/index.js +4 -4
  5. package/dist/{ArtifactBar-6PGWGKN2.css → ArtifactBar-UMZCTARR.css} +9 -0
  6. package/dist/ArtifactCard/ArtifactCard.d.ts +30 -1
  7. package/dist/ArtifactCard/index.js +10 -3
  8. package/dist/{ArtifactCard-OGTMO2KI.css → ArtifactCard-SOB63NV5.css} +72 -1
  9. package/dist/ArtifactCover/index.js +2 -2
  10. package/dist/ArtifactIcon/index.js +2 -2
  11. package/dist/ArtifactKindGlyph/ArtifactKindGlyph.d.ts +7 -3
  12. package/dist/ArtifactKindGlyph/index.js +1 -1
  13. package/dist/ArtifactKindIllustration/ArtifactKindIllustration.d.ts +4 -3
  14. package/dist/ArtifactKindIllustration/index.js +1 -1
  15. package/dist/{ArtifactKinds-CVD3FCYO.css → ArtifactKinds-O3CALPVX.css} +1 -0
  16. package/dist/ArtifactMakeRow/index.js +2 -2
  17. package/dist/ArtifactNameCell/ArtifactNameCell.d.ts +14 -1
  18. package/dist/ArtifactNameCell/index.d.ts +1 -1
  19. package/dist/ArtifactNameCell/index.js +2 -2
  20. package/dist/{ArtifactNameCell-RTVP4LO4.css → ArtifactNameCell-3AHLUSE5.css} +12 -0
  21. package/dist/BrandChip/BrandChip.d.ts +26 -0
  22. package/dist/BrandChip/index.d.ts +3 -0
  23. package/dist/BrandChip/index.js +2 -0
  24. package/dist/BrandChip-SQWBC2WU.css +81 -0
  25. package/dist/BrandSample/BrandSample.d.ts +75 -0
  26. package/dist/BrandSample/index.d.ts +3 -0
  27. package/dist/BrandSample/index.js +5 -0
  28. package/dist/BrandSample-G5V7GKR2.css +185 -0
  29. package/dist/BrandScope/BrandScope.d.ts +61 -0
  30. package/dist/BrandScope/index.d.ts +4 -0
  31. package/dist/BrandScope/index.js +4 -0
  32. package/dist/BrandScope-H2KZHGT7.css +29 -0
  33. package/dist/Checkbox/Checkbox.d.ts +8 -0
  34. package/dist/Checkbox/index.js +1 -1
  35. package/dist/{Checkbox-ALWG3WV2.css → Checkbox-MB22OW6P.css} +18 -0
  36. package/dist/ColorField/ColorField.d.ts +63 -0
  37. package/dist/ColorField/index.d.ts +3 -0
  38. package/dist/ColorField/index.js +11 -0
  39. package/dist/ColorField-2OIOWT3Z.css +68 -0
  40. package/dist/ColorSwatch/ColorSwatch.d.ts +43 -0
  41. package/dist/ColorSwatch/index.d.ts +3 -0
  42. package/dist/ColorSwatch/index.js +9 -0
  43. package/dist/ColorSwatch-DNMUFHNS.css +83 -0
  44. package/dist/Combobox/Combobox.d.ts +45 -4
  45. package/dist/Combobox/index.d.ts +1 -1
  46. package/dist/Combobox/index.js +1 -1
  47. package/dist/Combobox-GBCWXWEB.css +163 -0
  48. package/dist/CommandPalette/index.js +3 -3
  49. package/dist/CommentThread/index.js +3 -3
  50. package/dist/Composer/index.js +2 -2
  51. package/dist/ContrastBadge/ContrastBadge.d.ts +63 -0
  52. package/dist/ContrastBadge/index.d.ts +3 -0
  53. package/dist/ContrastBadge/index.js +6 -0
  54. package/dist/ContrastBadge-CBZPGG3G.css +47 -0
  55. package/dist/DataGrid/DataGrid.d.ts +28 -1
  56. package/dist/DataGrid/index.js +8 -1
  57. package/dist/{DataGrid-AQKPJD7W.css → DataGrid-VNGQESJA.css} +15 -0
  58. package/dist/DataTable/index.js +3 -3
  59. package/dist/DataView/index.js +8 -8
  60. package/dist/DateTimePicker/index.js +2 -2
  61. package/dist/FolderTile/FolderTile.d.ts +91 -0
  62. package/dist/FolderTile/index.d.ts +3 -0
  63. package/dist/FolderTile/index.js +7 -0
  64. package/dist/FolderTile-FDT5Y63Z.css +231 -0
  65. package/dist/LinkInterstitial/index.js +2 -2
  66. package/dist/ListInput/index.js +2 -2
  67. package/dist/LogoSlot/LogoSlot.d.ts +84 -0
  68. package/dist/LogoSlot/index.d.ts +3 -0
  69. package/dist/LogoSlot/index.js +9 -0
  70. package/dist/LogoSlot-T2UFOJXU.css +159 -0
  71. package/dist/Modal/Modal.d.ts +13 -0
  72. package/dist/Modal/index.js +1 -1
  73. package/dist/{Modal-TOEWHDCQ.css → Modal-3HMP7WAZ.css} +30 -0
  74. package/dist/PresenterView/index.js +2 -2
  75. package/dist/PrincipalPicker/index.js +2 -2
  76. package/dist/SelectionBar/SelectionBar.d.ts +50 -0
  77. package/dist/SelectionBar/index.d.ts +3 -0
  78. package/dist/SelectionBar/index.js +9 -0
  79. package/dist/SelectionBar-XPWKUOSC.css +61 -0
  80. package/dist/ShareDialog/index.js +3 -3
  81. package/dist/SheetColumnEditor/index.js +3 -3
  82. package/dist/SheetGrid/index.js +2 -2
  83. package/dist/Switcher/index.js +2 -2
  84. package/dist/ThemeGallery/ThemeGallery.d.ts +13 -2
  85. package/dist/ThemeGallery/index.js +3 -1
  86. package/dist/{ThemeGallery-X35Y25EX.css → ThemeGallery-UEFZRT6W.css} +21 -0
  87. package/dist/TimeWindowPicker/index.js +2 -2
  88. package/dist/TypeSpecimen/TypeSpecimen.d.ts +49 -0
  89. package/dist/TypeSpecimen/index.d.ts +3 -0
  90. package/dist/TypeSpecimen/index.js +3 -0
  91. package/dist/TypeSpecimen-WK6YNHL7.css +96 -0
  92. package/dist/chunk-5SGHW42B.js +23 -0
  93. package/dist/{chunk-ILDNJHRU.js → chunk-AVL52EME.js} +1 -1
  94. package/dist/chunk-B235ANDO.js +66 -0
  95. package/dist/{chunk-2MYSESZF.js → chunk-FB5CFQTG.js} +82 -12
  96. package/dist/{chunk-DY4DQ7EB.js → chunk-GP4YWZFO.js} +1 -1
  97. package/dist/{chunk-LIJQT74Y.js → chunk-H55D66IK.js} +1 -1
  98. package/dist/{chunk-6EBGPCAW.js → chunk-H7NMJ5AI.js} +1 -1
  99. package/dist/chunk-ITI2Z44C.js +139 -0
  100. package/dist/{chunk-P5VGSVWG.js → chunk-J24Q4HTD.js} +17 -8
  101. package/dist/{chunk-5EBDOE3C.js → chunk-JFDIMO3A.js} +1 -1
  102. package/dist/chunk-JKAFEFFC.js +44 -0
  103. package/dist/{chunk-32TGEMQQ.js → chunk-KHZYAEGZ.js} +1 -1
  104. package/dist/chunk-M4QM477B.js +80 -0
  105. package/dist/{chunk-TWZEWXNW.js → chunk-MIEBOO7Y.js} +2 -2
  106. package/dist/{chunk-SMOFYZJ5.js → chunk-NAWUXCBC.js} +3 -3
  107. package/dist/{chunk-F57N6ZJG.js → chunk-NCHKKYPQ.js} +5 -2
  108. package/dist/chunk-OCRVY42T.js +50 -0
  109. package/dist/chunk-OEEYL2CM.js +73 -0
  110. package/dist/chunk-P3OIM6OC.js +38 -0
  111. package/dist/{chunk-FWBKMPNR.js → chunk-P3QWT5VR.js} +1 -1
  112. package/dist/chunk-P5JBDHWC.js +206 -0
  113. package/dist/{chunk-OKE5YSLD.js → chunk-Q44X36QC.js} +79 -35
  114. package/dist/{chunk-R2IBCEU6.js → chunk-R3BA3C4Y.js} +2 -2
  115. package/dist/{chunk-CE2THTQR.js → chunk-RSKW25Y5.js} +4 -3
  116. package/dist/{chunk-UBZDYOCA.js → chunk-RV6XB5UV.js} +12 -1
  117. package/dist/{chunk-E4BOVKNJ.js → chunk-UTESMBPL.js} +5 -3
  118. package/dist/chunk-UZMNR366.js +9 -0
  119. package/dist/{chunk-CWKWMIIJ.js → chunk-V7GOOXPK.js} +1 -1
  120. package/dist/{chunk-7JED2NYP.js → chunk-VBIM6HFC.js} +1 -1
  121. package/dist/{chunk-U4HOKU6P.js → chunk-VN47PYUF.js} +5 -5
  122. package/dist/{chunk-MUQJCH2Y.js → chunk-VTSJMDGP.js} +2 -2
  123. package/dist/chunk-W6FOEBIL.js +119 -0
  124. package/dist/chunk-WLSEAIVC.js +48 -0
  125. package/dist/{chunk-AS2BMY3E.js → chunk-WQ7S7CKZ.js} +2 -2
  126. package/dist/{chunk-6AKG2VLR.js → chunk-YCC2S7DF.js} +4 -1
  127. package/dist/chunk-ZH77BXMA.js +14 -0
  128. package/dist/generated/index.d.ts +10 -0
  129. package/dist/generated/index.js +80 -68
  130. package/dist/index.js +80 -68
  131. package/dist/styles.css +1414 -85
  132. package/dist/utils/fontFamily.d.ts +29 -0
  133. package/dist/utils/hexColour.d.ts +12 -0
  134. package/package.json +3 -3
  135. package/scripts/check-css-variables.mjs +18 -2
  136. package/dist/Combobox-YDONYDTM.css +0 -81
  137. package/dist/chunk-OOJTPR7N.js +0 -137
  138. package/dist/{chunk-245IXG5P.js → chunk-3WMOEGEL.js} +0 -0
  139. package/dist/{chunk-ISDEXIXH.js → chunk-E6HXFFWO.js} +1 -1
  140. package/dist/{chunk-6R5BSA36.js → chunk-GHY63X4C.js} +1 -1
  141. package/dist/{chunk-ICVS3U4S.js → chunk-PGR2PKH6.js} +1 -1
  142. package/dist/{chunk-VKFG4FLE.js → chunk-R6R2UHVG.js} +1 -1
  143. package/dist/{chunk-OO7QJCJQ.js → chunk-WXOYHVWG.js} +1 -1
  144. package/dist/{chunk-UFXLNC2N.js → chunk-ZFM5L7M4.js} +1 -1
@@ -1,6 +1,6 @@
1
- export { PresenterView, formatStopwatch } from '../chunk-ISDEXIXH.js';
2
- import '../chunk-RMEBFYL7.js';
1
+ export { PresenterView, formatStopwatch } from '../chunk-E6HXFFWO.js';
3
2
  import '../chunk-RRO7UEYU.js';
3
+ import '../chunk-RMEBFYL7.js';
4
4
  import '../chunk-RK4XPHVG.js';
5
5
  import '../chunk-OMV5W53A.js';
6
6
  import '../chunk-OG6CL3EB.js';
@@ -1,5 +1,5 @@
1
- export { PrincipalPicker } from '../chunk-32TGEMQQ.js';
2
- import '../chunk-OOJTPR7N.js';
1
+ export { PrincipalPicker } from '../chunk-KHZYAEGZ.js';
2
+ import '../chunk-P5JBDHWC.js';
3
3
  import '../chunk-7KHM2FZH.js';
4
4
  import '../chunk-CI3VPIJN.js';
5
5
  import '../chunk-5AQBPHZD.js';
@@ -0,0 +1,50 @@
1
+ import { type ReactNode, type RefObject } from 'react';
2
+ export interface SelectionBarLabels {
3
+ /** The count, printed and said: "3 selected". */
4
+ count: (count: number) => string;
5
+ /** Said once the last pick is cleared, since the bar it was printed in goes. */
6
+ cleared: string;
7
+ /** The control that clears every pick. */
8
+ clear: string;
9
+ /** Names the bar: a toolbar is announced by its name. */
10
+ label: string;
11
+ }
12
+ export interface SelectionBarProps {
13
+ /** How many items are picked. At zero the bar draws nothing. */
14
+ count: number;
15
+ /** Clears every pick. */
16
+ onClear: () => void;
17
+ /**
18
+ * The bulk actions, as `Button`s ("Move to…"). An action only some of the
19
+ * picks allow is drawn with `disabledReason` ("You own 2 of 3"), never
20
+ * applied to the part it can be applied to without saying so.
21
+ */
22
+ children?: ReactNode;
23
+ /**
24
+ * Where focus goes once Clear has emptied the selection and the bar has
25
+ * gone with it: the gallery's Select toggle, or the list. Without it focus
26
+ * would fall to the page body with the button that held it.
27
+ */
28
+ returnFocusRef?: RefObject<HTMLElement | null> | undefined;
29
+ className?: string | undefined;
30
+ labels?: Partial<SelectionBarLabels> | undefined;
31
+ }
32
+ /**
33
+ * What is picked, and what can be done to all of it: the count, the bulk
34
+ * actions, and Clear.
35
+ *
36
+ * STICKY OVER THE LIST, DOCKED TO THE FOOT ON A PHONE. Over a long gallery the
37
+ * bar stays under the top of the scroller (`--crewlet-selection-bar-top` for a
38
+ * scroller that carries a bar of its own); under the phone breakpoint it
39
+ * floats at the bottom edge, where a thumb reaches it and the list it acts on
40
+ * stays in view; the host keeps the list's last row clear of it.
41
+ *
42
+ * THE COUNT IS SAID, POLITELY, AS IT CHANGES, through the shell's one polite
43
+ * region (`Announcer`): ticking a box changes nothing a screen reader reads on
44
+ * its own, and the bar appearing is not news a reader hears unless something
45
+ * says it. Clearing the last pick says so, since the bar goes with it.
46
+ *
47
+ * ONE STOP IN THE TAB ORDER: the actions and Clear are a `Toolbar`, walked
48
+ * with the arrows.
49
+ */
50
+ export declare function SelectionBar({ count, onClear, children, returnFocusRef, className, labels }: SelectionBarProps): import("react").JSX.Element | null;
@@ -0,0 +1,3 @@
1
+ import './SelectionBar.css';
2
+ export { SelectionBar } from './SelectionBar.js';
3
+ export type { SelectionBarLabels, SelectionBarProps } from './SelectionBar.js';
@@ -0,0 +1,9 @@
1
+ export { SelectionBar } from '../chunk-OCRVY42T.js';
2
+ import '../chunk-NR4CPM4T.js';
3
+ import '../chunk-RSAQOKH3.js';
4
+ import '../chunk-OMV5W53A.js';
5
+ import '../chunk-OG6CL3EB.js';
6
+ import '../chunk-H5XTJ7GJ.js';
7
+ import '../chunk-NUZHC6MM.js';
8
+ import '../chunk-BZFWDIV6.js';
9
+ import '../chunk-ODEQTPFM.js';
@@ -0,0 +1,61 @@
1
+ /*
2
+ * What is picked and what can be done to it: the count, the bulk actions and
3
+ * Clear, on the raised rung inside the strong hairline so it reads as a bar
4
+ * laid over the list rather than a row of it.
5
+ *
6
+ * ON TOP OF TOOLBAR, so the rules that change Toolbar's own layout carry
7
+ * Toolbar's class too: the bundle orders the two sheets by file name.
8
+ */
9
+ .crewlet-toolbar.crewlet-selection-bar {
10
+ position: sticky;
11
+ top: var(--crewlet-selection-bar-top, var(--spacing-0));
12
+ z-index: var(--z-index-sticky);
13
+ flex-wrap: nowrap;
14
+ gap: var(--spacing-3);
15
+ min-height: var(--size-row-lg);
16
+ padding: var(--spacing-1) var(--spacing-2) var(--spacing-1) var(--spacing-4);
17
+ border: 1px solid var(--color-border-strong);
18
+ border-radius: var(--radius-lg);
19
+ background: var(--color-surface-elevated);
20
+ box-shadow: var(--shadow-sm);
21
+ }
22
+
23
+ .crewlet-selection-bar__count {
24
+ flex: none;
25
+ color: var(--color-text-primary);
26
+ font-size: var(--font-size-sm);
27
+ font-weight: var(--font-weight-medium);
28
+ font-variant-numeric: tabular-nums;
29
+ white-space: nowrap;
30
+ }
31
+
32
+ .crewlet-selection-bar__actions {
33
+ display: flex;
34
+ align-items: center;
35
+ flex-wrap: wrap;
36
+ gap: var(--spacing-2);
37
+ min-width: 0;
38
+ }
39
+
40
+ .crewlet-selection-bar__spacer {
41
+ flex: 1 1 auto;
42
+ }
43
+
44
+ /*
45
+ * DOCKED TO THE FOOT ON A PHONE, strictly under the phone breakpoint: over the
46
+ * list at the bottom edge, inside the safe area, where a thumb reaches it and
47
+ * the picks it acts on stay in view above it.
48
+ */
49
+ @media (width < 640px) {
50
+ .crewlet-toolbar.crewlet-selection-bar {
51
+ position: fixed;
52
+ top: auto;
53
+ right: var(--spacing-3);
54
+ bottom: calc(var(--spacing-3) + env(safe-area-inset-bottom, var(--spacing-0)));
55
+ left: var(--spacing-3);
56
+ z-index: var(--z-index-overlay);
57
+ gap: var(--spacing-2);
58
+ padding-inline-start: var(--spacing-3);
59
+ box-shadow: var(--shadow-lg);
60
+ }
61
+ }
@@ -1,10 +1,10 @@
1
- export { ARTIFACT_ROLES, SHAREABLE_ROLES, ShareDialog, roleAtLeast } from '../chunk-5EBDOE3C.js';
1
+ export { ARTIFACT_ROLES, SHAREABLE_ROLES, ShareDialog, roleAtLeast } from '../chunk-JFDIMO3A.js';
2
2
  import '../chunk-XQZ6EWOE.js';
3
+ import '../chunk-YCC2S7DF.js';
4
+ import '../chunk-7KHM2FZH.js';
3
5
  import '../chunk-7SHAFLEX.js';
4
6
  import '../chunk-STJ7QBC3.js';
5
7
  import '../chunk-DTIW4CHZ.js';
6
- import '../chunk-6AKG2VLR.js';
7
- import '../chunk-7KHM2FZH.js';
8
8
  import '../chunk-SZZRIHGT.js';
9
9
  import '../chunk-CI3VPIJN.js';
10
10
  import '../chunk-5AQBPHZD.js';
@@ -1,4 +1,4 @@
1
- export { SHEET_COLUMN_EDITOR_LABELS, SheetColumnEditor, SheetColumnTypeGlyph } from '../chunk-MUQJCH2Y.js';
1
+ export { SHEET_COLUMN_EDITOR_LABELS, SheetColumnEditor, SheetColumnTypeGlyph } from '../chunk-VTSJMDGP.js';
2
2
  import '../chunk-XQZ6EWOE.js';
3
3
  import '../chunk-FFMCMSJB.js';
4
4
  import '../chunk-7KHM2FZH.js';
@@ -6,14 +6,14 @@ import '../chunk-LFSIKGRQ.js';
6
6
  import '../chunk-Z7JYG5TF.js';
7
7
  import '../chunk-34RMTXDZ.js';
8
8
  import '../chunk-AYKXMIOR.js';
9
- import '../chunk-F57N6ZJG.js';
10
9
  import '../chunk-6FVGSWLS.js';
11
10
  import '../chunk-ILFEWRLG.js';
12
11
  import '../chunk-WIATRXEJ.js';
13
12
  import '../chunk-EGMQURBR.js';
13
+ import '../chunk-NCHKKYPQ.js';
14
+ import '../chunk-SMBKXWML.js';
14
15
  import '../chunk-EXRRTKWT.js';
15
16
  import '../chunk-XCUUI7E7.js';
16
- import '../chunk-SMBKXWML.js';
17
17
  import '../chunk-BHHIIK3M.js';
18
18
  import '../chunk-PQADV6P6.js';
19
19
  import '../chunk-RSAQOKH3.js';
@@ -1,4 +1,4 @@
1
- export { CellDisplay, CellEditor, CheckboxCell, DateCell, LongTextCell, MultiSelectCell, NumberCell, PersonCell, RatingCell, SelectCell, SheetCell, SheetGrid, StatusCell, TextCell, UrlCell } from '../chunk-OO7QJCJQ.js';
1
+ export { CellDisplay, CellEditor, CheckboxCell, DateCell, LongTextCell, MultiSelectCell, NumberCell, PersonCell, RatingCell, SelectCell, SheetCell, SheetGrid, StatusCell, TextCell, UrlCell } from '../chunk-WXOYHVWG.js';
2
2
  import '../chunk-O2EGEONV.js';
3
3
  import '../chunk-CENOOTAV.js';
4
4
  import '../chunk-KYIAFNU7.js';
@@ -9,8 +9,8 @@ import '../chunk-LFSIKGRQ.js';
9
9
  import '../chunk-Z7JYG5TF.js';
10
10
  import '../chunk-KHJIEPZV.js';
11
11
  import '../chunk-AYKXMIOR.js';
12
- import '../chunk-WIATRXEJ.js';
13
12
  import '../chunk-I33UIUZD.js';
13
+ import '../chunk-WIATRXEJ.js';
14
14
  import '../chunk-5AQBPHZD.js';
15
15
  import '../chunk-PZKHBB7D.js';
16
16
  import '../chunk-RSAQOKH3.js';
@@ -1,5 +1,5 @@
1
- export { Switcher } from '../chunk-7JED2NYP.js';
2
- import '../chunk-6AKG2VLR.js';
1
+ export { Switcher } from '../chunk-VBIM6HFC.js';
2
+ import '../chunk-YCC2S7DF.js';
3
3
  import '../chunk-7KHM2FZH.js';
4
4
  import '../chunk-KHJIEPZV.js';
5
5
  import '../chunk-FYTIJM2T.js';
@@ -5,8 +5,19 @@ import { type ThemeSwatchPair } from '../ThemeSwatch/index.js';
5
5
  export interface ThemeGalleryTheme<T extends string = string> {
6
6
  id: T;
7
7
  name: string;
8
- /** A few words on what sets it apart, said with its name. */
9
- tag: string;
8
+ /**
9
+ * A few words on what sets it apart, said with its name. Drawn only when
10
+ * the theme also sets `tagTone`; left out, the card is its name alone.
11
+ */
12
+ tag?: string | undefined;
13
+ /**
14
+ * Draws the tag on the card as well as saying it: `quiet` as a caption
15
+ * under the name, `brand` as the accent's pill, for the company's own theme
16
+ * among the product's ("Your company brand"). Left out, the tag is said
17
+ * with the name and nothing is drawn, which is how the product's own theme
18
+ * picker lists its themes.
19
+ */
20
+ tagTone?: 'quiet' | 'brand' | undefined;
10
21
  /** The id of the group it is listed under. */
11
22
  group: string;
12
23
  /** Its two palettes, drawn as the card's thumbnail unless `renderPreview` draws one. */
@@ -1,6 +1,8 @@
1
- export { ThemeGallery } from '../chunk-E4BOVKNJ.js';
1
+ export { ThemeGallery } from '../chunk-UTESMBPL.js';
2
2
  import '../chunk-MNFU2RNT.js';
3
+ import '../chunk-KYIAFNU7.js';
3
4
  import '../chunk-7KHM2FZH.js';
5
+ import '../chunk-WIATRXEJ.js';
4
6
  import '../chunk-EGMQURBR.js';
5
7
  import '../chunk-H5XTJ7GJ.js';
6
8
  import '../chunk-NUZHC6MM.js';
@@ -102,6 +102,27 @@
102
102
  white-space: nowrap;
103
103
  }
104
104
 
105
+ /*
106
+ * THE TAG, DRAWN WHERE A THEME ASKS (`tagTone`), under the name: `quiet` on
107
+ * the tertiary step and a step smaller, cut to one line with the whole of it
108
+ * on hover, and `brand` as the accent's pill, so a reader picking a deck's
109
+ * theme finds their brand among the product's at a glance. A theme that sets
110
+ * no tone has its tag said with its name and nothing drawn.
111
+ */
112
+ .crewlet-theme-gallery__tag {
113
+ overflow: hidden;
114
+ color: var(--color-text-tertiary);
115
+ font-size: var(--font-size-2xs);
116
+ line-height: var(--font-line-height-tight);
117
+ text-overflow: ellipsis;
118
+ white-space: nowrap;
119
+ }
120
+
121
+ .crewlet-theme-gallery__tag--brand {
122
+ display: flex;
123
+ min-width: 0;
124
+ }
125
+
105
126
  /*
106
127
  * FORCED COLORS keeps the border and drops the accent, so the chosen card
107
128
  * would look like every other; the system's own selected colour says it.
@@ -1,8 +1,8 @@
1
- export { DEFAULT_TIME_WINDOW_LABELS, TIME_WINDOW_SPANS, TimeWindowPicker, describeTimeWindow, isTimeWindowSet, parseTimeWindowDuration, resolveTimeWindow, timeWindowMatchesPreset } from '../chunk-VKFG4FLE.js';
1
+ export { DEFAULT_TIME_WINDOW_LABELS, TIME_WINDOW_SPANS, TimeWindowPicker, describeTimeWindow, isTimeWindowSet, parseTimeWindowDuration, resolveTimeWindow, timeWindowMatchesPreset } from '../chunk-R6R2UHVG.js';
2
2
  import '../chunk-XQZ6EWOE.js';
3
3
  import '../chunk-7KHM2FZH.js';
4
- import '../chunk-KHJIEPZV.js';
5
4
  import '../chunk-GXQ3B46I.js';
5
+ import '../chunk-KHJIEPZV.js';
6
6
  import '../chunk-EXRRTKWT.js';
7
7
  import '../chunk-XCUUI7E7.js';
8
8
  import '../chunk-PQADV6P6.js';
@@ -0,0 +1,49 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface TypeSpecimenLabels {
3
+ /** The large letters the face is shown in. */
4
+ glyphs: string;
5
+ /** The line the face is read in, when the host gives none. */
6
+ sample: string;
7
+ }
8
+ export type TypeSpecimenSize = 'md' | 'sm';
9
+ export interface TypeSpecimenProps {
10
+ /** The face's name, as a reader knows it: "Geist", "Inter Display". */
11
+ family: string;
12
+ /**
13
+ * What the face is for, printed over its name: "Heading", "Body". Named
14
+ * `label` rather than `role`, which is the ARIA attribute's name.
15
+ */
16
+ label: string;
17
+ /**
18
+ * The CSS family list to draw it in, when it is not the face's name alone:
19
+ * a system stack, or the family an uploaded face was declared under. Left
20
+ * out, or not a list of family names, the name is drawn in quotes before the
21
+ * package's own sans, so a face this page has not loaded falls back to a
22
+ * face it has.
23
+ */
24
+ fontFamily?: string | undefined;
25
+ /** The line the face is read in. */
26
+ sample?: string | undefined;
27
+ /** One fact under the name: "Uploaded, 4 files", "System stack". */
28
+ detail?: ReactNode;
29
+ /** The weight the specimen draws: a heading's face is shown at a heading's weight. */
30
+ weight?: 'regular' | 'medium' | 'semibold' | 'bold' | undefined;
31
+ size?: TypeSpecimenSize | undefined;
32
+ className?: string | undefined;
33
+ labels?: Partial<TypeSpecimenLabels> | undefined;
34
+ }
35
+ /**
36
+ * A face, shown: what it is for, "Aa" large in it, its name, and a line read
37
+ * in it.
38
+ *
39
+ * THE FACE IS DRAWN, NOT DESCRIBED. The letters and the line are set in the
40
+ * face itself (through `--crewlet-type-specimen-family`), so choosing a face
41
+ * is choosing what it looks like rather than a name. The name and the role
42
+ * are set in the interface's own type, so they read the same whatever the face
43
+ * is.
44
+ *
45
+ * A FACE THE PAGE CANNOT DRAW FALLS BACK TO ONE IT CAN: the family list ends
46
+ * in the package's sans, so a face still loading (or never uploaded) shows as
47
+ * the interface's type rather than as the browser's default serif.
48
+ */
49
+ export declare function TypeSpecimen({ family, label, fontFamily, sample, detail, weight, size, className, labels, }: TypeSpecimenProps): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import './TypeSpecimen.css';
2
+ export { TypeSpecimen } from './TypeSpecimen.js';
3
+ export type { TypeSpecimenLabels, TypeSpecimenProps, TypeSpecimenSize } from './TypeSpecimen.js';
@@ -0,0 +1,3 @@
1
+ export { TypeSpecimen } from '../chunk-JKAFEFFC.js';
2
+ import '../chunk-5SGHW42B.js';
3
+ import '../chunk-ODEQTPFM.js';
@@ -0,0 +1,96 @@
1
+ /*
2
+ * A face, shown: its role and name in the interface's own type, then "Aa" and
3
+ * a line set in the face itself (`--crewlet-type-specimen-family`, which
4
+ * always ends in the package's sans).
5
+ */
6
+ .crewlet-type-specimen {
7
+ display: grid;
8
+ grid-template-columns: auto minmax(0, 1fr);
9
+ grid-template-areas:
10
+ 'glyphs caption'
11
+ 'sample sample';
12
+ align-items: center;
13
+ gap: var(--spacing-2) var(--spacing-4);
14
+ min-width: 0;
15
+ margin: 0;
16
+ }
17
+
18
+ .crewlet-type-specimen__caption {
19
+ grid-area: caption;
20
+ display: flex;
21
+ flex-direction: column;
22
+ gap: 2px;
23
+ min-width: 0;
24
+ }
25
+
26
+ .crewlet-type-specimen__label {
27
+ color: var(--color-text-tertiary);
28
+ font-size: var(--font-size-2xs);
29
+ font-weight: var(--font-weight-medium);
30
+ letter-spacing: var(--font-letter-spacing-wide);
31
+ text-transform: uppercase;
32
+ }
33
+
34
+ .crewlet-type-specimen__family {
35
+ overflow: hidden;
36
+ color: var(--color-text-primary);
37
+ font-size: var(--font-size-sm);
38
+ font-weight: var(--font-weight-medium);
39
+ text-overflow: ellipsis;
40
+ white-space: nowrap;
41
+ }
42
+
43
+ .crewlet-type-specimen__detail {
44
+ color: var(--color-text-tertiary);
45
+ font-size: var(--font-size-xs);
46
+ }
47
+
48
+ .crewlet-type-specimen__glyphs {
49
+ grid-area: glyphs;
50
+ color: var(--color-text-primary);
51
+ font-family: var(--crewlet-type-specimen-family);
52
+ font-size: var(--font-size-4xl);
53
+ line-height: 1;
54
+ }
55
+
56
+ .crewlet-type-specimen__sample {
57
+ grid-area: sample;
58
+ overflow: hidden;
59
+ color: var(--color-text-secondary);
60
+ font-family: var(--crewlet-type-specimen-family);
61
+ font-size: var(--font-size-md);
62
+ line-height: var(--font-line-height-snug);
63
+ text-overflow: ellipsis;
64
+ white-space: nowrap;
65
+ }
66
+
67
+ .crewlet-type-specimen--regular :is(.crewlet-type-specimen__glyphs, .crewlet-type-specimen__sample) {
68
+ font-weight: var(--font-weight-regular);
69
+ }
70
+
71
+ .crewlet-type-specimen--medium :is(.crewlet-type-specimen__glyphs, .crewlet-type-specimen__sample) {
72
+ font-weight: var(--font-weight-medium);
73
+ }
74
+
75
+ .crewlet-type-specimen--semibold :is(.crewlet-type-specimen__glyphs, .crewlet-type-specimen__sample) {
76
+ font-weight: var(--font-weight-semibold);
77
+ }
78
+
79
+ .crewlet-type-specimen--bold :is(.crewlet-type-specimen__glyphs, .crewlet-type-specimen__sample) {
80
+ font-weight: var(--font-weight-bold);
81
+ }
82
+
83
+ /* ---- sm: a select option's lead, the letters smaller and the line gone ---- */
84
+
85
+ .crewlet-type-specimen--sm {
86
+ grid-template-areas: 'glyphs caption';
87
+ gap: var(--spacing-3);
88
+ }
89
+
90
+ .crewlet-type-specimen--sm .crewlet-type-specimen__glyphs {
91
+ font-size: var(--font-size-2xl);
92
+ }
93
+
94
+ .crewlet-type-specimen--sm .crewlet-type-specimen__sample {
95
+ display: none;
96
+ }
@@ -0,0 +1,23 @@
1
+ // src/utils/fontFamily.ts
2
+ var QUOTED = String.raw`"[^"\\\r\n]{1,80}"|'[^'\\\r\n]{1,80}'`;
3
+ var IDENTIFIER = String.raw`-?[A-Za-z][A-Za-z0-9_-]*`;
4
+ var WORDS = `${IDENTIFIER}(?: ${IDENTIFIER}){0,5}`;
5
+ var TOKEN = String.raw`var\(--font-family-(?:sans|mono|display)\)`;
6
+ var NAME = `(?:${QUOTED}|${TOKEN}|${WORDS})`;
7
+ var MAX_NAMES = 11;
8
+ var LIST = new RegExp(`^${NAME}(?:\\s*,\\s*${NAME}){0,${MAX_NAMES - 1}}$`);
9
+ var KEYWORDS = /* @__PURE__ */ new Set(["inherit", "initial", "unset", "revert", "revert-layer", "default"]);
10
+ var MAX_LENGTH = 400;
11
+ function safeFontFamily(value) {
12
+ if (typeof value !== "string") return null;
13
+ const list = value.trim();
14
+ if (list === "" || list.length > MAX_LENGTH || !LIST.test(list)) return null;
15
+ const keyword = list.split(",").some((name) => KEYWORDS.has(name.trim().toLowerCase()));
16
+ return keyword ? null : list;
17
+ }
18
+ function fontStack(value, fallback) {
19
+ const list = safeFontFamily(value);
20
+ return list ? `${list}, ${fallback}` : fallback;
21
+ }
22
+
23
+ export { fontStack, safeFontFamily };
@@ -1,4 +1,4 @@
1
- import { ArtifactKindGlyph } from './chunk-CE2THTQR.js';
1
+ import { ArtifactKindGlyph } from './chunk-RSKW25Y5.js';
2
2
  import { ShieldGlyph, ActivityGlyph, GaugeGlyph, PackageGlyph, FolderGlyph, ClockGlyph, DatabaseGlyph, Settings2Glyph, BookOpenGlyph, FlagGlyph, StarGlyph, WandSparklesGlyph, BugGlyph, TargetGlyph, ImageGlyph, CodeGlyph, CoinsGlyph, UserGlyph, UsersGlyph, ChartNoAxesGanttGlyph, SquareKanbanGlyph, ListChecksGlyph, ListGlyph, GlobeGlyph, CompassGlyph, FileTextGlyph, TableGlyph, CalendarGlyph, LayoutDashboardGlyph, ChartPieGlyph, ChartColumnGlyph } from '@crewlethq/icons/glyphs';
3
3
  import { jsx } from 'react/jsx-runtime';
4
4
 
@@ -0,0 +1,66 @@
1
+ import { Tag } from './chunk-KYIAFNU7.js';
2
+ import { normalizeHex } from './chunk-UZMNR366.js';
3
+ import { VisuallyHidden } from './chunk-BZFWDIV6.js';
4
+ import { cx } from './chunk-ODEQTPFM.js';
5
+ import './ContrastBadge-CBZPGG3G.css';
6
+ import { CircleAlertGlyph, TriangleAlertGlyph, CircleCheckGlyph } from '@crewlethq/icons/glyphs';
7
+ import { WCAG_CONTRAST, parseHex, contrast } from '@crewlethq/tokens';
8
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
9
+
10
+ function contrastLevel(ratio, scale = "body") {
11
+ if (scale === "large") {
12
+ if (ratio >= WCAG_CONTRAST.aaaLarge) return "aaa";
13
+ if (ratio >= WCAG_CONTRAST.aaLarge) return "aa";
14
+ return "fail";
15
+ }
16
+ if (ratio >= WCAG_CONTRAST.aaa) return "aaa";
17
+ if (ratio >= WCAG_CONTRAST.aa) return "aa";
18
+ if (ratio >= WCAG_CONTRAST.aaLarge) return "aa-large";
19
+ return "fail";
20
+ }
21
+ function contrastRatio(foreground, background) {
22
+ const a = parseHex(foreground);
23
+ const b = parseHex(background);
24
+ return a && b ? contrast(a, b) : null;
25
+ }
26
+ function formatContrastRatio(ratio) {
27
+ const cut = Math.floor(ratio * 100) / 100;
28
+ return String(Number(cut.toFixed(2)));
29
+ }
30
+ var LABELS = {
31
+ levels: { aaa: "AAA", aa: "AA", "aa-large": "AA large text", fail: "Fails" },
32
+ unmeasured: "Not measured",
33
+ ratio: (ratio) => `${ratio} to 1`,
34
+ sample: "Aa"
35
+ };
36
+ var TONE = { aaa: "success", aa: "success", "aa-large": "warning", fail: "danger" };
37
+ function ContrastBadge({ foreground, background, label, scale = "body", className, labels }) {
38
+ const text = { ...LABELS, ...labels, levels: { ...LABELS.levels, ...labels?.levels } };
39
+ const ink = normalizeHex(foreground);
40
+ const ground = normalizeHex(background);
41
+ const ratio = ink && ground ? contrastRatio(ink, ground) : null;
42
+ const level = ratio === null ? null : contrastLevel(ratio, scale);
43
+ const printed = ratio === null ? null : formatContrastRatio(ratio);
44
+ const sample = ink && ground ? { "--crewlet-contrast-badge-ink": ink, "--crewlet-contrast-badge-ground": ground } : void 0;
45
+ return /* @__PURE__ */ jsxs("span", { className: cx("crewlet-contrast-badge", level && `crewlet-contrast-badge--${level}`, className), children: [
46
+ /* @__PURE__ */ jsx("span", { className: cx("crewlet-contrast-badge__sample", ratio === null && "is-empty"), style: sample, "aria-hidden": "true", children: text.sample }),
47
+ label ? /* @__PURE__ */ jsx("span", { className: "crewlet-contrast-badge__label", children: label }) : null,
48
+ printed !== null && level !== null ? /* @__PURE__ */ jsxs(Fragment, { children: [
49
+ /* @__PURE__ */ jsxs("span", { className: "crewlet-contrast-badge__ratio", children: [
50
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: `${printed}:1` }),
51
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: text.ratio(printed) })
52
+ ] }),
53
+ /* @__PURE__ */ jsx(
54
+ Tag,
55
+ {
56
+ size: "xs",
57
+ variant: TONE[level],
58
+ leadingIcon: level === "fail" ? /* @__PURE__ */ jsx(CircleAlertGlyph, { size: "xs" }) : level === "aa-large" ? /* @__PURE__ */ jsx(TriangleAlertGlyph, { size: "xs" }) : /* @__PURE__ */ jsx(CircleCheckGlyph, { size: "xs" }),
59
+ children: text.levels[level]
60
+ }
61
+ )
62
+ ] }) : /* @__PURE__ */ jsx("span", { className: "crewlet-contrast-badge__unmeasured", children: text.unmeasured })
63
+ ] });
64
+ }
65
+
66
+ export { ContrastBadge, contrastLevel, contrastRatio, formatContrastRatio };