@crewlethq/ui 0.15.1 → 0.17.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 (111) hide show
  1. package/README.md +36 -6
  2. package/dist/AppShell/AccountRow.d.ts +40 -0
  3. package/dist/AppShell/AppShell.d.ts +1 -0
  4. package/dist/AppShell/index.d.ts +2 -0
  5. package/dist/AppShell/index.js +1 -1
  6. package/dist/{AppShell-6QUD7NWM.css → AppShell-RUNVM4WH.css} +93 -0
  7. package/dist/AuthLayout/AuthLayout.d.ts +35 -0
  8. package/dist/AuthLayout/index.d.ts +3 -0
  9. package/dist/AuthLayout/index.js +8 -0
  10. package/dist/AuthLayout-ODHBUPHQ.css +54 -0
  11. package/dist/Avatar/Avatar.d.ts +37 -2
  12. package/dist/Avatar/index.d.ts +1 -1
  13. package/dist/Avatar/index.js +2 -2
  14. package/dist/{Avatar-I4NFP3WQ.css → Avatar-3C2H2WA4.css} +34 -0
  15. package/dist/AvatarPicker/index.js +4 -4
  16. package/dist/Callout/Callout.d.ts +7 -1
  17. package/dist/Callout/index.js +1 -1
  18. package/dist/{Callout-S7QDWHDL.css → Callout-SXXK4B5R.css} +3 -1
  19. package/dist/CharacterPicker/index.js +2 -2
  20. package/dist/Checkbox/CheckboxGroup.d.ts +30 -0
  21. package/dist/Checkbox/index.d.ts +2 -0
  22. package/dist/Checkbox/index.js +5 -1
  23. package/dist/{Checkbox-UE7TEPAM.css → Checkbox-KT7RS6QQ.css} +16 -0
  24. package/dist/CodeBlock/index.js +4 -3
  25. package/dist/Combobox/index.js +3 -3
  26. package/dist/CommandPalette/index.js +5 -5
  27. package/dist/Composer/index.js +3 -3
  28. package/dist/ConfirmField/ConfirmField.d.ts +43 -0
  29. package/dist/ConfirmField/index.d.ts +2 -0
  30. package/dist/ConfirmField/index.js +7 -0
  31. package/dist/Copyable/CopyButton.d.ts +13 -6
  32. package/dist/Copyable/index.js +3 -2
  33. package/dist/DataTable/index.js +7 -5
  34. package/dist/DataView/index.js +12 -11
  35. package/dist/DateTimePicker/index.js +2 -2
  36. package/dist/DownloadButton/DownloadButton.d.ts +52 -0
  37. package/dist/DownloadButton/index.d.ts +2 -0
  38. package/dist/DownloadButton/index.js +6 -0
  39. package/dist/EntityChip/index.js +3 -3
  40. package/dist/ImageUpload/index.js +3 -3
  41. package/dist/InlineCode/InlineCode.d.ts +8 -1
  42. package/dist/InlineCode/index.js +1 -1
  43. package/dist/{InlineCode-6WSR5COL.css → InlineCode-ASYHLN3E.css} +9 -0
  44. package/dist/Input/index.js +2 -2
  45. package/dist/{Input-RAKNQJCV.css → Input-3KVSNUO5.css} +11 -0
  46. package/dist/ListInput/index.js +3 -3
  47. package/dist/MarkdownEditor/index.js +1 -1
  48. package/dist/Modal/index.js +2 -2
  49. package/dist/ObjectHeader/ObjectHeader.d.ts +138 -0
  50. package/dist/ObjectHeader/index.d.ts +3 -0
  51. package/dist/ObjectHeader/index.js +4 -0
  52. package/dist/ObjectHeader-UNVYM2KD.css +174 -0
  53. package/dist/OrgLabel/index.js +3 -3
  54. package/dist/OrgNode/index.js +4 -4
  55. package/dist/OrgTable/index.js +4 -4
  56. package/dist/QrCode/QrCode.d.ts +58 -0
  57. package/dist/QrCode/index.d.ts +3 -0
  58. package/dist/QrCode/index.js +2 -0
  59. package/dist/QrCode-JWJTWMU5.css +19 -0
  60. package/dist/Switcher/index.js +4 -4
  61. package/dist/Text/Text.d.ts +7 -1
  62. package/dist/Text/index.js +1 -1
  63. package/dist/{Text-XIPYYZX2.css → Text-S3Q4O3IG.css} +11 -0
  64. package/dist/TimeWindowPicker/index.js +4 -4
  65. package/dist/{chunk-FTEJPHBI.js → chunk-4GB57WIT.js} +2 -2
  66. package/dist/{chunk-DDTDN5L2.js → chunk-4KWOKX2B.js} +1 -1
  67. package/dist/{chunk-NN62JQLR.js → chunk-5CLW2CXT.js} +3 -1
  68. package/dist/{chunk-HI6Q2UXQ.js → chunk-5OM447RW.js} +19 -7
  69. package/dist/{chunk-YXMCUKFI.js → chunk-5PSXBL73.js} +1 -1
  70. package/dist/{chunk-QSLIN64M.js → chunk-6NIMZ5XC.js} +1 -1
  71. package/dist/{chunk-YCTMKKRA.js → chunk-75CLJNDQ.js} +12 -2
  72. package/dist/chunk-7QFAORCY.js +37 -0
  73. package/dist/{chunk-22M7OXKW.js → chunk-AKEZ3G5V.js} +1 -1
  74. package/dist/chunk-BJCFNRGH.js +53 -0
  75. package/dist/chunk-CXBAIVYZ.js +39 -0
  76. package/dist/chunk-DTIW4CHZ.js +37 -0
  77. package/dist/chunk-F6NZOVWL.js +68 -0
  78. package/dist/{chunk-LCF4WPYS.js → chunk-FA2V2VT6.js} +2 -2
  79. package/dist/{chunk-KGTQ5CVD.js → chunk-GDDE4UM7.js} +1 -1
  80. package/dist/{chunk-EFNHOVC2.js → chunk-HENOTGUV.js} +2 -2
  81. package/dist/chunk-I7WXZOWA.js +90 -0
  82. package/dist/{chunk-23DHIMJA.js → chunk-IKBK4A5O.js} +1 -1
  83. package/dist/{chunk-DY77H372.js → chunk-JF7X673Z.js} +2 -2
  84. package/dist/{chunk-YYBD73OI.js → chunk-L4ZLXYPO.js} +1 -1
  85. package/dist/{chunk-H3XOMT7W.js → chunk-OYOQU7O5.js} +44 -3
  86. package/dist/{chunk-IYZZL3MZ.js → chunk-PQ63NLFC.js} +3 -3
  87. package/dist/{chunk-TK6YC5QT.js → chunk-RF5O4FYL.js} +4 -4
  88. package/dist/{chunk-5VNUYO76.js → chunk-STJ7QBC3.js} +8 -25
  89. package/dist/{chunk-R6FBDTP3.js → chunk-SVSCLHHI.js} +1 -1
  90. package/dist/{chunk-GARACZAH.js → chunk-T3ZWBZ65.js} +1 -1
  91. package/dist/{chunk-FY2R4U4Q.js → chunk-TBMDMXEX.js} +1 -1
  92. package/dist/{chunk-ZPWUVVIB.js → chunk-UAN5NE7M.js} +2 -2
  93. package/dist/{chunk-YACKC3K2.js → chunk-W46LPU4R.js} +8 -8
  94. package/dist/{chunk-4EOJR52M.js → chunk-XU4H6JQB.js} +4 -4
  95. package/dist/chunk-Y56FM3K4.js +57 -0
  96. package/dist/{chunk-DJMLHCLD.js → chunk-YDBC4DNW.js} +1 -1
  97. package/dist/{chunk-4Y7WKXAW.js → chunk-ZFH7H7GS.js} +1 -1
  98. package/dist/generated/index.d.ts +5 -0
  99. package/dist/generated/index.js +67 -60
  100. package/dist/index.js +67 -60
  101. package/dist/styles.css +440 -8
  102. package/dist/utils/index.d.ts +4 -0
  103. package/dist/utils/index.js +4 -2
  104. package/dist/utils/useClipboard.d.ts +6 -3
  105. package/dist/utils/useDownload.d.ts +63 -0
  106. package/dist/utils/useOutcome.d.ts +44 -0
  107. package/package.json +4 -3
  108. package/dist/{chunk-GUHP5JHC.js → chunk-2UU5IGZI.js} +1 -1
  109. package/dist/{chunk-6AR2T5Y4.js → chunk-CRVETI5L.js} +0 -0
  110. package/dist/{chunk-K4VORB64.js → chunk-DEEVA6TV.js} +1 -1
  111. /package/dist/{chunk-AER7UDD4.js → chunk-U5LQ2AS5.js} +0 -0
@@ -0,0 +1,174 @@
1
+ /*
2
+ * The header of an object: its eyebrow, its head row and its fact line.
3
+ */
4
+ .crewlet-object-header {
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: var(--spacing-1);
8
+ min-width: 0;
9
+ padding: var(--spacing-4) 0 var(--spacing-3);
10
+ }
11
+
12
+ .crewlet-object-header--peek {
13
+ padding: var(--spacing-3) 0 var(--spacing-2);
14
+ }
15
+
16
+ .crewlet-object-header__eyebrow {
17
+ display: flex;
18
+ align-items: center;
19
+ gap: var(--spacing-2);
20
+ min-width: 0;
21
+ font-size: var(--font-size-2xs);
22
+ letter-spacing: var(--font-letter-spacing-wide);
23
+ text-transform: uppercase;
24
+ color: var(--color-text-tertiary);
25
+ }
26
+
27
+ .crewlet-object-header__icon {
28
+ display: inline-flex;
29
+ flex: none;
30
+ }
31
+
32
+ /* A key or a name keeps its own case: in capitals a name is a shout. */
33
+ .crewlet-object-header__id {
34
+ min-width: 0;
35
+ overflow: hidden;
36
+ text-overflow: ellipsis;
37
+ white-space: nowrap;
38
+ letter-spacing: normal;
39
+ text-transform: none;
40
+ }
41
+
42
+ .crewlet-object-header__id--mono {
43
+ font-family: var(--font-family-mono);
44
+ }
45
+
46
+ /* The head row wraps: the marks and the actions take a line under the title
47
+ rather than every pill on the row giving up a few characters. */
48
+ .crewlet-object-header__head {
49
+ display: flex;
50
+ flex-wrap: wrap;
51
+ align-items: center;
52
+ gap: var(--spacing-2);
53
+ min-width: 0;
54
+ }
55
+
56
+ /* TWO LINES, AND THAT IS THE CEILING, which catches a title written as a
57
+ paragraph and holds every real one. */
58
+ .crewlet-object-header__title {
59
+ display: -webkit-box;
60
+ -webkit-box-orient: vertical;
61
+ -webkit-line-clamp: 2;
62
+ line-clamp: 2;
63
+ overflow: hidden;
64
+ flex: 0 1 auto;
65
+ min-width: 0;
66
+ margin: 0;
67
+ font-size: var(--font-size-xl);
68
+ font-weight: var(--font-weight-semibold);
69
+ line-height: var(--font-line-height-snug);
70
+ color: var(--color-text-primary);
71
+ }
72
+
73
+ .crewlet-object-header--peek .crewlet-object-header__title {
74
+ font-size: var(--font-size-lg);
75
+ }
76
+
77
+ /* The state keeps its width: a pill squeezed to "13 pro…" says something
78
+ else. The marks travel together when the row wraps. */
79
+ .crewlet-object-header__status,
80
+ .crewlet-object-header__actions {
81
+ display: flex;
82
+ flex: 0 0 auto;
83
+ flex-wrap: wrap;
84
+ align-items: center;
85
+ gap: var(--spacing-1);
86
+ }
87
+
88
+ .crewlet-object-header__actions {
89
+ margin-left: auto;
90
+ }
91
+
92
+ /* ── the fact line ─────────────────────────────────────────────────────── */
93
+
94
+ /* THE TRACK FLOOR IS 7.5rem, which fits seven facts on one line at 1280px and
95
+ still holds every label and a two-line value. */
96
+ .crewlet-fact-line {
97
+ display: grid;
98
+ grid-template-columns: repeat(auto-fill, minmax(min(7.5rem, 100%), 1fr));
99
+ column-gap: var(--spacing-4);
100
+ row-gap: var(--spacing-3);
101
+ padding-top: var(--spacing-1);
102
+ }
103
+
104
+ /* Two bands: the label, then the value with its footnotes in one cell. */
105
+ .crewlet-fact-line__fact {
106
+ display: grid;
107
+ grid-template-rows: subgrid;
108
+ grid-row: span 2;
109
+ row-gap: 0;
110
+ min-width: 0;
111
+ }
112
+
113
+ /* A token and a set of chips take two tracks. */
114
+ .crewlet-fact-line__fact--token,
115
+ .crewlet-fact-line__fact--set {
116
+ grid-column: span 2;
117
+ }
118
+
119
+ .crewlet-fact-line__body {
120
+ display: flex;
121
+ flex-direction: column;
122
+ min-width: 0;
123
+ }
124
+
125
+ .crewlet-fact-line__label {
126
+ font-size: var(--font-size-2xs);
127
+ letter-spacing: var(--font-letter-spacing-wide);
128
+ text-transform: uppercase;
129
+ color: var(--color-text-tertiary);
130
+ }
131
+
132
+ .crewlet-fact-line__value {
133
+ min-width: 0;
134
+ font-size: var(--font-size-compact);
135
+ color: var(--color-text-primary);
136
+ overflow-wrap: anywhere;
137
+ }
138
+
139
+ .crewlet-fact-line__value--clamp {
140
+ display: -webkit-box;
141
+ -webkit-box-orient: vertical;
142
+ -webkit-line-clamp: 2;
143
+ line-clamp: 2;
144
+ overflow: hidden;
145
+ }
146
+
147
+ /* One token, one line, cut with an ellipsis where two tracks are too narrow;
148
+ its title carries the whole of it. */
149
+ .crewlet-fact-line__value--token {
150
+ display: block;
151
+ overflow: hidden;
152
+ text-overflow: ellipsis;
153
+ white-space: nowrap;
154
+ overflow-wrap: normal;
155
+ }
156
+
157
+ /* A footnote may not set its column's width: the track does, and the note
158
+ wraps inside it, balanced so the wrap reads as deliberate. */
159
+ .crewlet-fact-line__note,
160
+ .crewlet-fact-line__set-by {
161
+ font-size: var(--font-size-2xs);
162
+ color: var(--color-text-tertiary);
163
+ text-wrap: balance;
164
+ }
165
+
166
+ /* ── the by-line ───────────────────────────────────────────────────────── */
167
+
168
+ /* The word and its arrow are one atomic box, so the arrow never takes a line
169
+ of its own. */
170
+ .crewlet-set-by__turn {
171
+ display: inline-flex;
172
+ align-items: center;
173
+ gap: 0.25em;
174
+ }
@@ -1,4 +1,4 @@
1
- export { OrgLabel } from '../chunk-22M7OXKW.js';
2
- import '../chunk-ZPWUVVIB.js';
3
- import '../chunk-HI6Q2UXQ.js';
1
+ export { OrgLabel } from '../chunk-AKEZ3G5V.js';
2
+ import '../chunk-UAN5NE7M.js';
3
+ import '../chunk-5OM447RW.js';
4
4
  import '../chunk-ODEQTPFM.js';
@@ -1,5 +1,5 @@
1
- export { OrgNodeDisclosure, OrgNodeLabel, OrgNodeLead } from '../chunk-FY2R4U4Q.js';
2
- import '../chunk-22M7OXKW.js';
3
- import '../chunk-ZPWUVVIB.js';
4
- import '../chunk-HI6Q2UXQ.js';
1
+ export { OrgNodeDisclosure, OrgNodeLabel, OrgNodeLead } from '../chunk-TBMDMXEX.js';
2
+ import '../chunk-AKEZ3G5V.js';
3
+ import '../chunk-UAN5NE7M.js';
4
+ import '../chunk-5OM447RW.js';
5
5
  import '../chunk-ODEQTPFM.js';
@@ -1,13 +1,13 @@
1
- export { OrgTable, OrgTableActions, OrgTableAdd, OrgTableName } from '../chunk-YYBD73OI.js';
1
+ export { OrgTable, OrgTableActions, OrgTableAdd, OrgTableName } from '../chunk-L4ZLXYPO.js';
2
2
  import '../chunk-B2Z2CDM5.js';
3
3
  import '../chunk-MY374UUD.js';
4
- import '../chunk-22M7OXKW.js';
4
+ import '../chunk-AKEZ3G5V.js';
5
5
  import '../chunk-VYOKRN2I.js';
6
6
  import '../chunk-TROLVEZY.js';
7
7
  import '../chunk-4FQT6ZAY.js';
8
- import '../chunk-ZPWUVVIB.js';
8
+ import '../chunk-UAN5NE7M.js';
9
9
  import '../chunk-HMPFGIWM.js';
10
10
  import '../chunk-R25RGPUB.js';
11
11
  import '../chunk-BZFWDIV6.js';
12
- import '../chunk-HI6Q2UXQ.js';
12
+ import '../chunk-5OM447RW.js';
13
13
  import '../chunk-ODEQTPFM.js';
@@ -0,0 +1,58 @@
1
+ /**
2
+ * A QR code, drawn as inline SVG from the encoder's module matrix.
3
+ *
4
+ * INLINE SVG AND NOTHING ELSE. The encoder answers a matrix of booleans and
5
+ * this draws it as one `<path>` on one `<rect>`: not an `<img>` with a `data:`
6
+ * URI, not markup set as HTML, and nothing fetched. A strict
7
+ * Content-Security-Policy admits each of those only by being widened, and the
8
+ * value a QR code carries is often a credential (a second factor's seed),
9
+ * which must not leave the DOM it is shown in.
10
+ *
11
+ * BLACK ON A WHITE PLATE, IN EVERY THEME. A QR code is a symbol a camera reads,
12
+ * and its two inks are part of the symbol rather than colours of the palette.
13
+ * A code is specified dark on light, and some authenticator apps do not read
14
+ * one inverted for a dark theme, so it is never inverted. The inks are the
15
+ * `color.qr` tokens, which are the same in every palette, and they are written
16
+ * as the SVG's own fill attributes so the code draws correctly with no
17
+ * stylesheet at all. The plate keeps its inks under forced colours too.
18
+ *
19
+ * FOUR MODULES OF QUIET ZONE, AND LEVEL M. The margin a reader needs to find
20
+ * the finder patterns is four light modules on every side, the standard's own
21
+ * figure. Error correction is M, which still reads with 15% of the symbol
22
+ * lost and is the level authenticator codes are conventionally drawn at.
23
+ */
24
+ /** Light modules around the symbol, on every side. */
25
+ export declare const QR_QUIET_ZONE = 4;
26
+ /** The dark modules' ink: the `color.qr.dark` token. */
27
+ export declare const QR_DARK: string;
28
+ /** The plate's ink, the quiet zone included: the `color.qr.light` token. */
29
+ export declare const QR_LIGHT: string;
30
+ /**
31
+ * The symbol's modules for `value`, `true` for dark, row by row, or null for
32
+ * a value too long for any QR code to hold.
33
+ *
34
+ * NULL RATHER THAN A THROW. The encoder refuses an oversized value with a
35
+ * `RangeError`, and a code that cannot be drawn is an aid missing rather than
36
+ * a screen that should fall over: whoever renders one keeps the value's other
37
+ * forms beside it. Any other error is a fault and is not caught.
38
+ */
39
+ export declare function qrModules(value: string): boolean[][] | null;
40
+ /**
41
+ * The dark modules as one SVG path in module units: one rectangle per
42
+ * horizontal run of dark modules, so adjacent modules share an edge rather
43
+ * than meeting at two anti-aliased ones.
44
+ */
45
+ export declare function qrModulePath(modules: readonly (readonly boolean[])[]): string;
46
+ export interface QrCodeProps {
47
+ /** What the code encodes, exactly. */
48
+ value: string;
49
+ /** The image's accessible name: what the code is for, never the value itself. */
50
+ label: string;
51
+ className?: string | undefined;
52
+ }
53
+ /**
54
+ * `value` as a QR code, named by `label`, or nothing for a value no QR code
55
+ * can hold. Keep the value's other forms (a key to type, a link to open)
56
+ * beside it: a code is an aid, and not every reader has a camera.
57
+ */
58
+ export declare function QrCode({ value, label, className }: QrCodeProps): import("react").JSX.Element | null;
@@ -0,0 +1,3 @@
1
+ import './QrCode.css';
2
+ export { QR_DARK, QR_LIGHT, QR_QUIET_ZONE, QrCode, qrModulePath, qrModules } from './QrCode.js';
3
+ export type { QrCodeProps } from './QrCode.js';
@@ -0,0 +1,2 @@
1
+ export { QR_DARK, QR_LIGHT, QR_QUIET_ZONE, QrCode, qrModulePath, qrModules } from '../chunk-Y56FM3K4.js';
2
+ import '../chunk-ODEQTPFM.js';
@@ -0,0 +1,19 @@
1
+ /*
2
+ * A QR code on its own plate.
3
+ *
4
+ * A FIXED BOX, because a camera needs modules of a readable size: at 208px a
5
+ * second factor's code (a version 7 symbol and its quiet zone) draws each
6
+ * module at about 4.3px. A consumer that needs another size sets the variable.
7
+ *
8
+ * ITS INKS ARE KEPT UNDER FORCED COLOURS. A high-contrast mode repaints fills
9
+ * to system colours, and a plate repainted dark is a code no scanner reads.
10
+ */
11
+ .crewlet-qr-code {
12
+ --crewlet-qr-code-size: 208px;
13
+ display: block;
14
+ flex: none;
15
+ width: var(--crewlet-qr-code-size);
16
+ height: var(--crewlet-qr-code-size);
17
+ border-radius: var(--radius-sm);
18
+ forced-color-adjust: none;
19
+ }
@@ -1,14 +1,14 @@
1
- export { Switcher } from '../chunk-LCF4WPYS.js';
1
+ export { Switcher } from '../chunk-FA2V2VT6.js';
2
2
  import '../chunk-W5J7R5EB.js';
3
- import '../chunk-K4VORB64.js';
3
+ import '../chunk-DEEVA6TV.js';
4
4
  import '../chunk-F73MC7EZ.js';
5
- import '../chunk-FTEJPHBI.js';
5
+ import '../chunk-4GB57WIT.js';
6
6
  import '../chunk-FYTIJM2T.js';
7
7
  import '../chunk-OG6CL3EB.js';
8
- import '../chunk-PQADV6P6.js';
9
8
  import '../chunk-RSAQOKH3.js';
10
9
  import '../chunk-IG75YMUN.js';
11
10
  import '../chunk-4FQT6ZAY.js';
11
+ import '../chunk-PQADV6P6.js';
12
12
  import '../chunk-BWRGFKJP.js';
13
13
  import '../chunk-HMPFGIWM.js';
14
14
  import '../chunk-R25RGPUB.js';
@@ -20,7 +20,13 @@ export type TextVariant =
20
20
  /** A page title. */
21
21
  | 'display'
22
22
  /** A single measured number, the size a stat card sets it at. */
23
- | 'stat';
23
+ | 'stat'
24
+ /**
25
+ * The register of the words around it: their size, weight and ink. For a
26
+ * run inside a sentence or a chip that changes one thing about it, with
27
+ * `mono` for a literal (a login, a header name) or `numeric` for a figure.
28
+ */
29
+ | 'inherit';
24
30
  /**
25
31
  * Which ink. There is deliberately no decoration step here: the decoration
26
32
  * ink is measured into the 2.8 to 4.5:1 band on purpose, so it carries a
@@ -1,2 +1,2 @@
1
- export { Text } from '../chunk-23DHIMJA.js';
1
+ export { Text } from '../chunk-IKBK4A5O.js';
2
2
  import '../chunk-ODEQTPFM.js';
@@ -49,6 +49,17 @@
49
49
  color: var(--color-text-primary);
50
50
  }
51
51
 
52
+ /*
53
+ * The register around it: nothing is set, so the run keeps its sentence's
54
+ * size, weight, tracking and ink, and only a modifier (mono, numeric) or a
55
+ * tone changes it.
56
+ */
57
+ .crewlet-text--inherit {
58
+ font-size: inherit;
59
+ line-height: inherit;
60
+ color: inherit;
61
+ }
62
+
52
63
  .crewlet-text--body {
53
64
  font-size: var(--font-size-sm);
54
65
  line-height: var(--font-line-height-normal);
@@ -1,11 +1,11 @@
1
- export { DEFAULT_TIME_WINDOW_LABELS, TIME_WINDOW_SPANS, TimeWindowPicker, describeTimeWindow, isTimeWindowSet, parseTimeWindowDuration, resolveTimeWindow, timeWindowMatchesPreset } from '../chunk-DY77H372.js';
1
+ export { DEFAULT_TIME_WINDOW_LABELS, TIME_WINDOW_SPANS, TimeWindowPicker, describeTimeWindow, isTimeWindowSet, parseTimeWindowDuration, resolveTimeWindow, timeWindowMatchesPreset } from '../chunk-JF7X673Z.js';
2
2
  import '../chunk-FC4YTTFJ.js';
3
3
  import '../chunk-F73MC7EZ.js';
4
- import '../chunk-FTEJPHBI.js';
5
- import '../chunk-OG6CL3EB.js';
4
+ import '../chunk-4GB57WIT.js';
6
5
  import '../chunk-GXQ3B46I.js';
7
- import '../chunk-PQADV6P6.js';
6
+ import '../chunk-OG6CL3EB.js';
8
7
  import '../chunk-4FQT6ZAY.js';
8
+ import '../chunk-PQADV6P6.js';
9
9
  import '../chunk-BWRGFKJP.js';
10
10
  import '../chunk-HMPFGIWM.js';
11
11
  import '../chunk-R25RGPUB.js';
@@ -1,8 +1,8 @@
1
- import { useHeadingLevel, headingTag, HeadingLevelProvider, nextHeadingLevel } from './chunk-PQADV6P6.js';
2
1
  import { IconButton } from './chunk-4FQT6ZAY.js';
2
+ import { useHeadingLevel, headingTag, HeadingLevelProvider, nextHeadingLevel } from './chunk-PQADV6P6.js';
3
3
  import { VisuallyHidden } from './chunk-BZFWDIV6.js';
4
4
  import { cx } from './chunk-ODEQTPFM.js';
5
- import './Input-RAKNQJCV.css';
5
+ import './Input-3KVSNUO5.css';
6
6
  import { forwardRef, useRef, useState, useImperativeHandle, useEffect, useId } from 'react';
7
7
  import { XGlyph } from '@crewlethq/icons/glyphs';
8
8
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
@@ -1,4 +1,4 @@
1
- import { Avatar } from './chunk-HI6Q2UXQ.js';
1
+ import { Avatar } from './chunk-5OM447RW.js';
2
2
  import { cx } from './chunk-ODEQTPFM.js';
3
3
  import './EntityChip-LUCPZBBG.css';
4
4
  import { Children, isValidElement, cloneElement } from 'react';
@@ -1,11 +1,12 @@
1
1
  import { cx } from './chunk-ODEQTPFM.js';
2
- import './InlineCode-6WSR5COL.css';
2
+ import './InlineCode-ASYHLN3E.css';
3
3
  import { jsx } from 'react/jsx-runtime';
4
4
 
5
5
  function InlineCode({
6
6
  variant = "default",
7
7
  tone = "default",
8
8
  truncate = false,
9
+ whole = false,
9
10
  className,
10
11
  children,
11
12
  ...rest
@@ -19,6 +20,7 @@ function InlineCode({
19
20
  `crewlet-inline-code--${variant}`,
20
21
  tone === "inherit" && "crewlet-inline-code--inherit",
21
22
  truncate && "crewlet-inline-code--truncate",
23
+ whole && "crewlet-inline-code--whole",
22
24
  className
23
25
  ),
24
26
  children
@@ -11,6 +11,12 @@ var AVATAR_STATUS_LABELS = {
11
11
  };
12
12
  var AVATAR_SIZES = { xs: 20, sm: 26, md: 32, lg: 40 };
13
13
  var AVATAR_CORNER_RATIO = 0.29;
14
+ var AGENT_WORD = /^agent(?:[\s._-]+)(?=\S)/i;
15
+ function avatarInitialsName(name, kind) {
16
+ if (name === void 0 || kind !== "agent") return name;
17
+ const rest = name.replace(AGENT_WORD, "");
18
+ return rest.trim() ? rest : name;
19
+ }
14
20
  var AVATAR_CHARACTER_FULL_DETAIL = 56;
15
21
  var getInitials = (name) => {
16
22
  if (!name) return "?";
@@ -45,10 +51,13 @@ var Avatar = ({
45
51
  tone = "neutral",
46
52
  ring,
47
53
  status,
54
+ mark,
55
+ markLabel,
48
56
  decorative = false,
49
57
  colorSeed,
50
58
  character,
51
59
  hue,
60
+ icon,
52
61
  className,
53
62
  style,
54
63
  ...rest
@@ -64,9 +73,11 @@ var Avatar = ({
64
73
  fontSize: Math.max(9, Math.round(pixels * 0.36))
65
74
  } : {};
66
75
  const seeded = tone === "seeded" ? avatarTint(colorSeed ?? name ?? "") : null;
67
- const framed = status !== void 0;
76
+ const marked = status === void 0 && mark !== void 0 && mark !== null;
77
+ const framed = status !== void 0 || marked;
78
+ const corner = status !== void 0 ? AVATAR_STATUS_LABELS[status] : marked ? markLabel : void 0;
68
79
  const label = name ? `${name} avatar` : "Avatar";
69
- const spoken = framed ? `${label}, ${AVATAR_STATUS_LABELS[status]}` : label;
80
+ const spoken = corner ? `${label}, ${corner}` : label;
70
81
  const classes = cx(
71
82
  "crewlet-avatar",
72
83
  `crewlet-avatar--${kind}`,
@@ -110,7 +121,7 @@ var Avatar = ({
110
121
  className: cx(classes, "crewlet-avatar--image"),
111
122
  style: faceStyle,
112
123
  src,
113
- alt: decorative ? "" : framed ? `${name ?? ""}, ${AVATAR_STATUS_LABELS[status]}` : name ?? "",
124
+ alt: decorative ? "" : corner ? `${name ?? ""}, ${corner}` : name ?? "",
114
125
  "aria-hidden": decorative ? true : void 0,
115
126
  onError: () => setImageFailed(true)
116
127
  }
@@ -124,13 +135,14 @@ var Avatar = ({
124
135
  classes,
125
136
  "crewlet-avatar--fallback",
126
137
  `crewlet-avatar--${tone}`,
127
- seeded === null ? null : `crewlet-avatar--tint-${seeded}`
138
+ seeded === null ? null : `crewlet-avatar--tint-${seeded}`,
139
+ icon === void 0 || icon === null ? null : "crewlet-avatar--icon"
128
140
  ),
129
141
  style: faceStyle,
130
142
  role: decorative ? void 0 : "img",
131
143
  "aria-hidden": decorative ? true : void 0,
132
144
  "aria-label": decorative ? void 0 : spoken,
133
- children: getInitials(name)
145
+ children: icon === void 0 || icon === null ? getInitials(avatarInitialsName(name, kind)) : /* @__PURE__ */ jsx("span", { className: "crewlet-avatar__icon", "aria-hidden": "true", children: icon })
134
146
  }
135
147
  );
136
148
  }
@@ -143,7 +155,7 @@ var Avatar = ({
143
155
  style: { "--crewlet-avatar-size": `${pixels}px`, ...style },
144
156
  children: [
145
157
  face,
146
- /* @__PURE__ */ jsx("span", { className: `crewlet-avatar__status crewlet-avatar__status--${status}`, "aria-hidden": "true", children: STATUS_GLYPHS[status] })
158
+ status !== void 0 ? /* @__PURE__ */ jsx("span", { className: `crewlet-avatar__status crewlet-avatar__status--${status}`, "aria-hidden": "true", children: STATUS_GLYPHS[status] }) : /* @__PURE__ */ jsx("span", { className: "crewlet-avatar__status crewlet-avatar__status--mark", "aria-hidden": "true", children: mark })
147
159
  ]
148
160
  }
149
161
  );
@@ -166,4 +178,4 @@ var STATUS_GLYPHS = {
166
178
  stopped: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 14 14", focusable: "false", children: /* @__PURE__ */ jsx("rect", { x: "4.6", y: "4.6", width: "4.8", height: "4.8", rx: ".7", fill: "currentColor" }) })
167
179
  };
168
180
 
169
- export { AVATAR_CHARACTER_FULL_DETAIL, AVATAR_CORNER_RATIO, AVATAR_SIZES, AVATAR_STATUSES, AVATAR_STATUS_LABELS, Avatar, avatarCorner, avatarPixels, avatarTint, getInitials };
181
+ export { AVATAR_CHARACTER_FULL_DETAIL, AVATAR_CORNER_RATIO, AVATAR_SIZES, AVATAR_STATUSES, AVATAR_STATUS_LABELS, Avatar, avatarCorner, avatarInitialsName, avatarPixels, avatarTint, getInitials };
@@ -1,5 +1,5 @@
1
1
  import { useRoving, tabStop } from './chunk-CBOICT64.js';
2
- import { Avatar } from './chunk-HI6Q2UXQ.js';
2
+ import { Avatar } from './chunk-5OM447RW.js';
3
3
  import { cx } from './chunk-ODEQTPFM.js';
4
4
  import { CREWLET_CHARACTERS, CREWLET_CHARACTER_GEOMETRY } from '@crewlethq/icons/characters';
5
5
  import { jsx } from 'react/jsx-runtime';
@@ -1,5 +1,5 @@
1
1
  import { Kbd } from './chunk-SMBKXWML.js';
2
- import { Textarea } from './chunk-FTEJPHBI.js';
2
+ import { Textarea } from './chunk-4GB57WIT.js';
3
3
  import { cx } from './chunk-ODEQTPFM.js';
4
4
  import './Composer-ABGJIAIR.css';
5
5
  import { forwardRef } from 'react';
@@ -1,5 +1,6 @@
1
+ import { FormField } from './chunk-4GB57WIT.js';
1
2
  import { cx } from './chunk-ODEQTPFM.js';
2
- import './Checkbox-UE7TEPAM.css';
3
+ import './Checkbox-KT7RS6QQ.css';
3
4
  import { forwardRef, useId, useRef, useCallback, useEffect } from 'react';
4
5
  import { jsxs, jsx } from 'react/jsx-runtime';
5
6
 
@@ -70,5 +71,14 @@ var Checkbox = forwardRef(function Checkbox2({
70
71
  }
71
72
  );
72
73
  });
74
+ function hasChildren(children) {
75
+ if (children === null || children === void 0 || children === false) return false;
76
+ if (Array.isArray(children)) return children.some(hasChildren);
77
+ return true;
78
+ }
79
+ function CheckboxGroup({ legend, helper, error, emptyMessage, children, className }) {
80
+ const empty = !hasChildren(children);
81
+ return /* @__PURE__ */ jsx(FormField, { as: "fieldset", label: legend, helper, error, className: cx("crewlet-checkbox-group", className), children: empty ? emptyMessage ? /* @__PURE__ */ jsx("p", { className: "crewlet-checkbox-group__empty", children: emptyMessage }) : null : /* @__PURE__ */ jsx("div", { className: "crewlet-checkbox-group__options", children }) });
82
+ }
73
83
 
74
- export { Checkbox };
84
+ export { Checkbox, CheckboxGroup };
@@ -0,0 +1,37 @@
1
+ import { BrandLockup } from './chunk-7KBNFFM3.js';
2
+ import { Card } from './chunk-EG6NYWVK.js';
3
+ import { cx } from './chunk-ODEQTPFM.js';
4
+ import './AuthLayout-ODHBUPHQ.css';
5
+ import { useId } from 'react';
6
+ import { CrewletIcon } from '@crewlethq/icons';
7
+ import { jsx, jsxs } from 'react/jsx-runtime';
8
+
9
+ function AuthLayout({
10
+ title,
11
+ description,
12
+ productName = "Crewlet",
13
+ mark,
14
+ homeHref,
15
+ children,
16
+ className
17
+ }) {
18
+ const heading = useId();
19
+ return /* @__PURE__ */ jsx("main", { className: cx("crewlet-auth-layout", className), children: /* @__PURE__ */ jsxs("div", { className: "crewlet-auth-layout__column", children: [
20
+ /* @__PURE__ */ jsx(
21
+ BrandLockup,
22
+ {
23
+ className: "crewlet-auth-layout__brand",
24
+ name: productName,
25
+ mark: mark ?? /* @__PURE__ */ jsx(CrewletIcon, {}),
26
+ href: homeHref
27
+ }
28
+ ),
29
+ /* @__PURE__ */ jsxs(Card, { as: "section", padding: "lg", "aria-labelledby": heading, children: [
30
+ /* @__PURE__ */ jsx(Card.Title, { as: "h1", id: heading, children: title }),
31
+ description ? /* @__PURE__ */ jsx(Card.Description, { children: description }) : null,
32
+ children === void 0 || children === null || children === false ? null : /* @__PURE__ */ jsx("div", { className: "crewlet-auth-layout__body", children })
33
+ ] })
34
+ ] }) });
35
+ }
36
+
37
+ export { AuthLayout };
@@ -1,4 +1,4 @@
1
- import { Avatar } from './chunk-HI6Q2UXQ.js';
1
+ import { Avatar } from './chunk-5OM447RW.js';
2
2
  import { cx } from './chunk-ODEQTPFM.js';
3
3
  import './OrgLabel-R5KY7C3W.css';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -0,0 +1,53 @@
1
+ import { useDownload, safeFilename } from './chunk-F6NZOVWL.js';
2
+ import { Button } from './chunk-OG6CL3EB.js';
3
+ import { VisuallyHidden } from './chunk-BZFWDIV6.js';
4
+ import { useMemo, useCallback } from 'react';
5
+ import { CheckGlyph, CircleAlertGlyph, SaveGlyph } from '@crewlethq/icons/glyphs';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ function downloadGlyph(state) {
9
+ if (state === "started") return /* @__PURE__ */ jsx(CheckGlyph, { size: "sm" });
10
+ if (state === "failed") return /* @__PURE__ */ jsx(CircleAlertGlyph, { size: "sm" });
11
+ return /* @__PURE__ */ jsx(SaveGlyph, { size: "sm" });
12
+ }
13
+ function DownloadButton({
14
+ text,
15
+ filename,
16
+ mime,
17
+ label = "Download",
18
+ startedLabel = "Downloading",
19
+ failedLabel = "Download failed",
20
+ startedMessage,
21
+ failedMessage = "the browser refused the download",
22
+ size = "small",
23
+ variant = "ghost",
24
+ title,
25
+ disabled,
26
+ resetMs,
27
+ failedResetMs = null,
28
+ className
29
+ }) {
30
+ const { state, attempt, download } = useDownload({ resetMs, failedResetMs });
31
+ const name = useMemo(() => safeFilename(filename), [filename]);
32
+ const onClick = useCallback(() => {
33
+ void download(text, filename, mime);
34
+ }, [download, text, filename, mime]);
35
+ const said = state === "started" ? startedMessage ?? `download started: ${name}` : state === "failed" ? failedMessage : "";
36
+ return /* @__PURE__ */ jsxs("span", { className, children: [
37
+ /* @__PURE__ */ jsx(
38
+ Button,
39
+ {
40
+ size,
41
+ variant,
42
+ leadingIcon: downloadGlyph(state),
43
+ onClick,
44
+ disabled,
45
+ title: state === "failed" ? failedMessage : title,
46
+ children: state === "started" ? startedLabel : state === "failed" ? failedLabel : label
47
+ }
48
+ ),
49
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: /* @__PURE__ */ jsx("span", { role: "status", children: /* @__PURE__ */ jsx("span", { children: said }, attempt) }) })
50
+ ] });
51
+ }
52
+
53
+ export { DownloadButton };