@crewlethq/ui 0.15.0 → 0.16.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.
- package/README.md +36 -6
- package/dist/AddPill/index.js +1 -1
- package/dist/{AddPill-V4TQXJ53.css → AddPill-RYCY56P4.css} +3 -1
- package/dist/AppShell/AccountRow.d.ts +40 -0
- package/dist/AppShell/AppShell.d.ts +1 -0
- package/dist/AppShell/index.d.ts +2 -0
- package/dist/AppShell/index.js +1 -1
- package/dist/{AppShell-6QUD7NWM.css → AppShell-RUNVM4WH.css} +93 -0
- package/dist/AuthLayout/AuthLayout.d.ts +35 -0
- package/dist/AuthLayout/index.d.ts +3 -0
- package/dist/AuthLayout/index.js +8 -0
- package/dist/AuthLayout-ODHBUPHQ.css +54 -0
- package/dist/Avatar/Avatar.d.ts +22 -2
- package/dist/Avatar/index.d.ts +1 -1
- package/dist/Avatar/index.js +2 -2
- package/dist/{Avatar-BPJ36QZR.css → Avatar-MBUPR5E5.css} +22 -3
- package/dist/AvatarPicker/index.js +4 -4
- package/dist/Callout/Callout.d.ts +7 -1
- package/dist/Callout/index.js +1 -1
- package/dist/{Callout-S7QDWHDL.css → Callout-SXXK4B5R.css} +3 -1
- package/dist/CharacterPicker/index.js +2 -2
- package/dist/Checkbox/CheckboxGroup.d.ts +30 -0
- package/dist/Checkbox/index.d.ts +2 -0
- package/dist/Checkbox/index.js +5 -1
- package/dist/{Checkbox-UE7TEPAM.css → Checkbox-KT7RS6QQ.css} +16 -0
- package/dist/CodeBlock/index.js +4 -3
- package/dist/Combobox/index.js +3 -3
- package/dist/CommandPalette/index.js +5 -5
- package/dist/Composer/index.js +3 -3
- package/dist/ConfirmField/ConfirmField.d.ts +43 -0
- package/dist/ConfirmField/index.d.ts +2 -0
- package/dist/ConfirmField/index.js +7 -0
- package/dist/Copyable/CopyButton.d.ts +13 -6
- package/dist/Copyable/index.js +3 -2
- package/dist/DataTable/index.js +7 -5
- package/dist/DataView/index.js +10 -9
- package/dist/DownloadButton/DownloadButton.d.ts +52 -0
- package/dist/DownloadButton/index.d.ts +2 -0
- package/dist/DownloadButton/index.js +6 -0
- package/dist/EntityChip/index.js +3 -3
- package/dist/ImageUpload/index.js +3 -3
- package/dist/InlineCode/InlineCode.d.ts +8 -1
- package/dist/InlineCode/index.js +1 -1
- package/dist/{InlineCode-6WSR5COL.css → InlineCode-ASYHLN3E.css} +9 -0
- package/dist/Input/index.js +2 -2
- package/dist/{Input-RAKNQJCV.css → Input-3KVSNUO5.css} +11 -0
- package/dist/ListInput/index.js +3 -3
- package/dist/MarkdownEditor/index.js +1 -1
- package/dist/Modal/index.js +2 -2
- package/dist/ObjectHeader/ObjectHeader.d.ts +138 -0
- package/dist/ObjectHeader/index.d.ts +3 -0
- package/dist/ObjectHeader/index.js +4 -0
- package/dist/ObjectHeader-UNVYM2KD.css +174 -0
- package/dist/OrgLabel/index.js +3 -3
- package/dist/{OrgLabel-6WSKJQOT.css → OrgLabel-R5KY7C3W.css} +6 -1
- package/dist/OrgNode/index.js +4 -4
- package/dist/OrgTable/index.js +5 -5
- package/dist/QrCode/QrCode.d.ts +58 -0
- package/dist/QrCode/index.d.ts +3 -0
- package/dist/QrCode/index.js +2 -0
- package/dist/QrCode-JWJTWMU5.css +19 -0
- package/dist/Switcher/index.js +4 -4
- package/dist/Text/Text.d.ts +7 -1
- package/dist/Text/index.js +1 -1
- package/dist/{Text-XIPYYZX2.css → Text-S3Q4O3IG.css} +11 -0
- package/dist/TimeWindowPicker/index.js +3 -3
- package/dist/{chunk-FTEJPHBI.js → chunk-4GB57WIT.js} +2 -2
- package/dist/{chunk-NN62JQLR.js → chunk-5CLW2CXT.js} +3 -1
- package/dist/{chunk-2GXTIK37.js → chunk-5EFRWWGX.js} +3 -3
- package/dist/{chunk-6OF2DBKY.js → chunk-6DQWF5Y4.js} +2 -2
- package/dist/{chunk-QSLIN64M.js → chunk-6NIMZ5XC.js} +1 -1
- package/dist/{chunk-YCTMKKRA.js → chunk-75CLJNDQ.js} +12 -2
- package/dist/chunk-7QFAORCY.js +37 -0
- package/dist/chunk-BJCFNRGH.js +53 -0
- package/dist/{chunk-IHGKPEEV.js → chunk-CGNQPGJL.js} +1 -1
- package/dist/{chunk-DDTDN5L2.js → chunk-CKB3OHL3.js} +1 -1
- package/dist/chunk-CXBAIVYZ.js +39 -0
- package/dist/chunk-DTIW4CHZ.js +37 -0
- package/dist/{chunk-YXMCUKFI.js → chunk-DZ2YR6MV.js} +1 -1
- package/dist/{chunk-QV266R6G.js → chunk-EIOTVNYX.js} +4 -4
- package/dist/chunk-F6NZOVWL.js +68 -0
- package/dist/{chunk-LCF4WPYS.js → chunk-FA2V2VT6.js} +2 -2
- package/dist/{chunk-EFNHOVC2.js → chunk-FAEN3HYI.js} +2 -2
- package/dist/{chunk-HI6Q2UXQ.js → chunk-FY4SP3HF.js} +11 -3
- package/dist/{chunk-KGTQ5CVD.js → chunk-GDDE4UM7.js} +1 -1
- package/dist/chunk-I7WXZOWA.js +90 -0
- package/dist/{chunk-23DHIMJA.js → chunk-IKBK4A5O.js} +1 -1
- package/dist/{chunk-7BZPYA5P.js → chunk-JF7X673Z.js} +1 -1
- package/dist/{chunk-DJMLHCLD.js → chunk-KLESCRTS.js} +1 -1
- package/dist/{chunk-DYHSQHAZ.js → chunk-OFMPIRGD.js} +2 -2
- package/dist/{chunk-H3XOMT7W.js → chunk-OYOQU7O5.js} +44 -3
- package/dist/{chunk-IYZZL3MZ.js → chunk-PQ63NLFC.js} +3 -3
- package/dist/{chunk-5VNUYO76.js → chunk-STJ7QBC3.js} +8 -25
- package/dist/{chunk-R6FBDTP3.js → chunk-SVSCLHHI.js} +1 -1
- package/dist/{chunk-GARACZAH.js → chunk-T3ZWBZ65.js} +1 -1
- package/dist/{chunk-74WGARJE.js → chunk-TROLVEZY.js} +1 -1
- package/dist/{chunk-6NIZCQUM.js → chunk-UAMDRJD6.js} +2 -2
- package/dist/{chunk-YACKC3K2.js → chunk-W46LPU4R.js} +8 -8
- package/dist/chunk-Y56FM3K4.js +57 -0
- package/dist/{chunk-4Y7WKXAW.js → chunk-ZFH7H7GS.js} +1 -1
- package/dist/generated/index.d.ts +5 -0
- package/dist/generated/index.js +66 -59
- package/dist/index.js +66 -59
- package/dist/styles.css +439 -15
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +4 -2
- package/dist/utils/useClipboard.d.ts +6 -3
- package/dist/utils/useDownload.d.ts +63 -0
- package/dist/utils/useOutcome.d.ts +44 -0
- package/package.json +4 -3
- package/dist/{chunk-6AR2T5Y4.js → chunk-CRVETI5L.js} +0 -0
- package/dist/{chunk-K4VORB64.js → chunk-DEEVA6TV.js} +1 -1
- /package/dist/{chunk-AER7UDD4.js → chunk-U5LQ2AS5.js} +0 -0
package/dist/styles.css
CHANGED
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
|
|
91
|
-
/* AddPill-
|
|
91
|
+
/* AddPill-RYCY56P4.css */
|
|
92
92
|
/*
|
|
93
93
|
* The control that adds a child (AddPill.tsx).
|
|
94
94
|
*
|
|
@@ -499,7 +499,9 @@
|
|
|
499
499
|
/* THE FILL IS FOR A FILLED DRAWING, and a glyph is a stroke. Painting the
|
|
500
500
|
inside of a Lucide glyph turns every closed shape in it solid and every
|
|
501
501
|
open one into a smear, so a `.crewlet-glyph` keeps the fill its own frame
|
|
502
|
-
decides and takes the ink through its stroke, which is `currentColor`.
|
|
502
|
+
decides and takes the ink through its stroke, which is `currentColor`.
|
|
503
|
+
A drawing here cuts its holes as geometry, never through a mask: this rule
|
|
504
|
+
repaints a mask's paths and groups as well, and fills its holes with ink. */
|
|
503
505
|
.crewlet-add-pill__section svg:not(.crewlet-glyph),
|
|
504
506
|
.crewlet-add-pill__section svg:not(.crewlet-glyph) g,
|
|
505
507
|
.crewlet-add-pill__section svg:not(.crewlet-glyph) path {
|
|
@@ -535,7 +537,7 @@
|
|
|
535
537
|
}
|
|
536
538
|
|
|
537
539
|
|
|
538
|
-
/* AppShell-
|
|
540
|
+
/* AppShell-RUNVM4WH.css */
|
|
539
541
|
/*
|
|
540
542
|
* The application frame: a rail on the FRAME, and the screen on a SHEET that
|
|
541
543
|
* floats beside it.
|
|
@@ -1160,8 +1162,158 @@
|
|
|
1160
1162
|
}
|
|
1161
1163
|
}
|
|
1162
1164
|
|
|
1165
|
+
/* ── the account row ───────────────────────────────────────────────────── */
|
|
1163
1166
|
|
|
1164
|
-
/*
|
|
1167
|
+
/*
|
|
1168
|
+
* The signed-in reader at the foot of the rail, with the row's controls at
|
|
1169
|
+
* its end. The link takes the room, so a long name is cut rather than pushing
|
|
1170
|
+
* the controls off the rail.
|
|
1171
|
+
*/
|
|
1172
|
+
.crewlet-account-row {
|
|
1173
|
+
display: flex;
|
|
1174
|
+
align-items: center;
|
|
1175
|
+
gap: var(--spacing-1);
|
|
1176
|
+
min-width: 0;
|
|
1177
|
+
padding: var(--spacing-1) 0;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
.crewlet-account-row__who {
|
|
1181
|
+
display: flex;
|
|
1182
|
+
flex: 1 1 auto;
|
|
1183
|
+
align-items: center;
|
|
1184
|
+
gap: var(--spacing-2);
|
|
1185
|
+
min-width: 0;
|
|
1186
|
+
padding: var(--spacing-1);
|
|
1187
|
+
border-radius: var(--radius-md);
|
|
1188
|
+
color: var(--color-text-primary);
|
|
1189
|
+
text-decoration: none;
|
|
1190
|
+
/* The fill eases under the pointer, as the rail's rows do. */
|
|
1191
|
+
transition: background var(--motion-duration-fast) var(--motion-easing-default);
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
a.crewlet-account-row__who:hover {
|
|
1195
|
+
background: var(--color-surface-hover);
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
/* After :hover, so the current row shows the lift rather than the overlay. */
|
|
1199
|
+
a.crewlet-account-row__who[aria-current='page'] {
|
|
1200
|
+
background: var(--color-surface-elevated);
|
|
1201
|
+
outline: 1px solid var(--color-border-default);
|
|
1202
|
+
outline-offset: -1px;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
a.crewlet-account-row__who:focus-visible {
|
|
1206
|
+
outline: 2px solid var(--color-focus);
|
|
1207
|
+
outline-offset: var(--size-focus-ring-inset-offset);
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
.crewlet-account-row__avatar {
|
|
1211
|
+
display: inline-flex;
|
|
1212
|
+
flex: none;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
.crewlet-account-row__text {
|
|
1216
|
+
display: flex;
|
|
1217
|
+
flex-direction: column;
|
|
1218
|
+
min-width: 0;
|
|
1219
|
+
line-height: var(--font-line-height-snug);
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
.crewlet-account-row__name,
|
|
1223
|
+
.crewlet-account-row__detail {
|
|
1224
|
+
overflow: hidden;
|
|
1225
|
+
text-overflow: ellipsis;
|
|
1226
|
+
white-space: nowrap;
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
.crewlet-account-row__name {
|
|
1230
|
+
font-size: var(--font-size-xs);
|
|
1231
|
+
font-weight: var(--font-weight-medium);
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
.crewlet-account-row__detail {
|
|
1235
|
+
font-size: var(--font-size-2xs);
|
|
1236
|
+
color: var(--color-text-tertiary);
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
.crewlet-account-row__go {
|
|
1240
|
+
flex: none;
|
|
1241
|
+
margin-left: auto;
|
|
1242
|
+
color: var(--color-text-tertiary);
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
.crewlet-account-row__actions {
|
|
1246
|
+
display: flex;
|
|
1247
|
+
flex: none;
|
|
1248
|
+
align-items: center;
|
|
1249
|
+
gap: var(--spacing-1);
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1253
|
+
.crewlet-account-row__who {
|
|
1254
|
+
transition: none;
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
|
|
1259
|
+
/* AuthLayout-ODHBUPHQ.css */
|
|
1260
|
+
/*
|
|
1261
|
+
* The sign-in page: one narrow column near the top of the window.
|
|
1262
|
+
*
|
|
1263
|
+
* THE PAGE SCROLLS ITSELF, at the viewport's dynamic height, because it is
|
|
1264
|
+
* drawn outside any shell that would: on a phone with the keyboard up, a form
|
|
1265
|
+
* taller than what is left of the window has to scroll, not be cut off.
|
|
1266
|
+
*/
|
|
1267
|
+
.crewlet-auth-layout {
|
|
1268
|
+
display: flex;
|
|
1269
|
+
justify-content: center;
|
|
1270
|
+
height: 100dvh;
|
|
1271
|
+
overflow-y: auto;
|
|
1272
|
+
padding: var(--spacing-8) var(--spacing-4);
|
|
1273
|
+
background: var(--color-surface-background);
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
/* A sentence's measure wide, and held at the top: the form does not jump when
|
|
1277
|
+
an error line appears under a field. */
|
|
1278
|
+
.crewlet-auth-layout__column {
|
|
1279
|
+
display: flex;
|
|
1280
|
+
flex-direction: column;
|
|
1281
|
+
gap: var(--spacing-5);
|
|
1282
|
+
width: 100%;
|
|
1283
|
+
max-width: 52ch;
|
|
1284
|
+
margin-block-end: auto;
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
/* The lockup is centred over the card, and takes none of the rail's inset,
|
|
1288
|
+
which is what its own padding is for. */
|
|
1289
|
+
.crewlet-auth-layout__brand {
|
|
1290
|
+
align-self: center;
|
|
1291
|
+
padding: 0;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
/* The form's parts stand one field step apart, under the title and lede. */
|
|
1295
|
+
.crewlet-auth-layout__body {
|
|
1296
|
+
display: flex;
|
|
1297
|
+
flex-direction: column;
|
|
1298
|
+
gap: var(--spacing-4);
|
|
1299
|
+
margin-top: var(--spacing-4);
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
/* A submit does not stretch: every button here states one gesture, and a
|
|
1303
|
+
full-width bar reads as the page's edge rather than a control. */
|
|
1304
|
+
.crewlet-auth-layout__body > form {
|
|
1305
|
+
display: flex;
|
|
1306
|
+
flex-direction: column;
|
|
1307
|
+
gap: var(--spacing-4);
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
.crewlet-auth-layout__body > form > button,
|
|
1311
|
+
.crewlet-auth-layout__body > button {
|
|
1312
|
+
align-self: flex-start;
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
|
|
1316
|
+
/* Avatar-MBUPR5E5.css */
|
|
1165
1317
|
/*
|
|
1166
1318
|
* The identity badge.
|
|
1167
1319
|
*
|
|
@@ -1290,6 +1442,25 @@
|
|
|
1290
1442
|
object-fit: cover;
|
|
1291
1443
|
}
|
|
1292
1444
|
|
|
1445
|
+
/*
|
|
1446
|
+
* A GLYPH IN PLACE OF THE INITIALS, for a principal whose name's initials
|
|
1447
|
+
* mean nothing (an API token, a service account). It takes a little over half
|
|
1448
|
+
* the box, the share the initials' cap height and width take, so a key badge
|
|
1449
|
+
* beside a person's badge reads as the same size of mark.
|
|
1450
|
+
*/
|
|
1451
|
+
.crewlet-avatar__icon {
|
|
1452
|
+
display: inline-flex;
|
|
1453
|
+
align-items: center;
|
|
1454
|
+
justify-content: center;
|
|
1455
|
+
width: 55%;
|
|
1456
|
+
height: 55%;
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
.crewlet-avatar__icon > * {
|
|
1460
|
+
width: 100%;
|
|
1461
|
+
height: 100%;
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1293
1464
|
/* ── tones ─────────────────────────────────────────────────────────────── */
|
|
1294
1465
|
|
|
1295
1466
|
.crewlet-avatar--fallback {
|
|
@@ -1324,9 +1495,9 @@
|
|
|
1324
1495
|
|
|
1325
1496
|
/*
|
|
1326
1497
|
* THE CHARACTER FILLS MOST OF THE PLATE, centred by its own frame (it frames
|
|
1327
|
-
* every silhouette square on
|
|
1328
|
-
* it: a wide character such as the original Crewlet reaches the
|
|
1329
|
-
* sides, a tall one its top and its foot, and none touches the curve.
|
|
1498
|
+
* every silhouette square on its optical centre), with the plate's corner
|
|
1499
|
+
* clear of it: a wide character such as the original Crewlet reaches the
|
|
1500
|
+
* plate's sides, a tall one its top and its foot, and none touches the curve.
|
|
1330
1501
|
*/
|
|
1331
1502
|
.crewlet-avatar--character {
|
|
1332
1503
|
border: 1px solid transparent;
|
|
@@ -2416,7 +2587,7 @@ a.crewlet-breadcrumb__crumb:focus-visible {
|
|
|
2416
2587
|
}
|
|
2417
2588
|
|
|
2418
2589
|
|
|
2419
|
-
/* Callout-
|
|
2590
|
+
/* Callout-SXXK4B5R.css */
|
|
2420
2591
|
/*
|
|
2421
2592
|
* The callout: a status that stays in the content flow.
|
|
2422
2593
|
*
|
|
@@ -2471,8 +2642,10 @@ a.crewlet-breadcrumb__crumb:focus-visible {
|
|
|
2471
2642
|
}
|
|
2472
2643
|
|
|
2473
2644
|
.crewlet-callout__title {
|
|
2645
|
+
/* A LINE OF ITS OWN above the message, so the heading and the first
|
|
2646
|
+
sentence are never read as one run-on sentence. */
|
|
2647
|
+
display: block;
|
|
2474
2648
|
font-weight: var(--font-weight-semibold);
|
|
2475
|
-
margin-right: var(--spacing-2);
|
|
2476
2649
|
}
|
|
2477
2650
|
|
|
2478
2651
|
.crewlet-callout__action {
|
|
@@ -4217,7 +4390,7 @@ a.crewlet-breadcrumb__crumb:focus-visible {
|
|
|
4217
4390
|
}
|
|
4218
4391
|
|
|
4219
4392
|
|
|
4220
|
-
/* Checkbox-
|
|
4393
|
+
/* Checkbox-KT7RS6QQ.css */
|
|
4221
4394
|
/*
|
|
4222
4395
|
* Checkbox: a box, its label and its consequence as one target.
|
|
4223
4396
|
*
|
|
@@ -4338,6 +4511,22 @@ a.crewlet-breadcrumb__crumb:focus-visible {
|
|
|
4338
4511
|
outline-offset: 0;
|
|
4339
4512
|
}
|
|
4340
4513
|
|
|
4514
|
+
/*
|
|
4515
|
+
* A group of boxes under one legend. The boxes keep a field's inner rhythm,
|
|
4516
|
+
* one step apart, so the group reads as one field and its boxes as its parts.
|
|
4517
|
+
*/
|
|
4518
|
+
.crewlet-checkbox-group__options {
|
|
4519
|
+
display: flex;
|
|
4520
|
+
flex-direction: column;
|
|
4521
|
+
gap: var(--spacing-1);
|
|
4522
|
+
}
|
|
4523
|
+
|
|
4524
|
+
.crewlet-checkbox-group__empty {
|
|
4525
|
+
margin: 0;
|
|
4526
|
+
font-size: var(--font-size-xs);
|
|
4527
|
+
color: var(--color-text-secondary);
|
|
4528
|
+
}
|
|
4529
|
+
|
|
4341
4530
|
|
|
4342
4531
|
/* ChoiceButtons-DJ5EOGUA.css */
|
|
4343
4532
|
/*
|
|
@@ -9951,7 +10140,7 @@ svg.crewlet-datetime__chevron {
|
|
|
9951
10140
|
}
|
|
9952
10141
|
|
|
9953
10142
|
|
|
9954
|
-
/* InlineCode-
|
|
10143
|
+
/* InlineCode-ASYHLN3E.css */
|
|
9955
10144
|
/*
|
|
9956
10145
|
* One identifier inside a sentence: a mono chip on the inset surface.
|
|
9957
10146
|
*
|
|
@@ -10009,6 +10198,15 @@ svg.crewlet-datetime__chevron {
|
|
|
10009
10198
|
color: inherit;
|
|
10010
10199
|
}
|
|
10011
10200
|
|
|
10201
|
+
/*
|
|
10202
|
+
* A short token read as one: it moves to the next line whole rather than
|
|
10203
|
+
* splitting, which `overflow-wrap: anywhere` would otherwise allow.
|
|
10204
|
+
*/
|
|
10205
|
+
.crewlet-inline-code--whole {
|
|
10206
|
+
overflow-wrap: normal;
|
|
10207
|
+
white-space: nowrap;
|
|
10208
|
+
}
|
|
10209
|
+
|
|
10012
10210
|
.crewlet-inline-code--truncate {
|
|
10013
10211
|
display: inline-block;
|
|
10014
10212
|
max-width: 100%;
|
|
@@ -10019,7 +10217,7 @@ svg.crewlet-datetime__chevron {
|
|
|
10019
10217
|
}
|
|
10020
10218
|
|
|
10021
10219
|
|
|
10022
|
-
/* Input-
|
|
10220
|
+
/* Input-3KVSNUO5.css */
|
|
10023
10221
|
/*
|
|
10024
10222
|
* The form row: Input, Textarea, Label, FormField, FormRow, FormSection and
|
|
10025
10223
|
* ReadOnlyField.
|
|
@@ -10457,6 +10655,17 @@ svg.crewlet-datetime__chevron {
|
|
|
10457
10655
|
color: var(--color-text-tertiary);
|
|
10458
10656
|
}
|
|
10459
10657
|
|
|
10658
|
+
/*
|
|
10659
|
+
* A LITERAL INSIDE A LABEL KEEPS ITS CASE. The label is set in capitals, and
|
|
10660
|
+
* a value a reader has to type back exactly ("Type jane.founder to confirm")
|
|
10661
|
+
* read as JANE.FOUNDER, which is not what the field accepts.
|
|
10662
|
+
*/
|
|
10663
|
+
.crewlet-label code,
|
|
10664
|
+
.crewlet-label__text code {
|
|
10665
|
+
text-transform: none;
|
|
10666
|
+
letter-spacing: normal;
|
|
10667
|
+
}
|
|
10668
|
+
|
|
10460
10669
|
.crewlet-label--with-action {
|
|
10461
10670
|
display: flex;
|
|
10462
10671
|
justify-content: space-between;
|
|
@@ -12753,7 +12962,184 @@ svg.crewlet-datetime__chevron {
|
|
|
12753
12962
|
}
|
|
12754
12963
|
|
|
12755
12964
|
|
|
12756
|
-
/*
|
|
12965
|
+
/* ObjectHeader-UNVYM2KD.css */
|
|
12966
|
+
/*
|
|
12967
|
+
* The header of an object: its eyebrow, its head row and its fact line.
|
|
12968
|
+
*/
|
|
12969
|
+
.crewlet-object-header {
|
|
12970
|
+
display: flex;
|
|
12971
|
+
flex-direction: column;
|
|
12972
|
+
gap: var(--spacing-1);
|
|
12973
|
+
min-width: 0;
|
|
12974
|
+
padding: var(--spacing-4) 0 var(--spacing-3);
|
|
12975
|
+
}
|
|
12976
|
+
|
|
12977
|
+
.crewlet-object-header--peek {
|
|
12978
|
+
padding: var(--spacing-3) 0 var(--spacing-2);
|
|
12979
|
+
}
|
|
12980
|
+
|
|
12981
|
+
.crewlet-object-header__eyebrow {
|
|
12982
|
+
display: flex;
|
|
12983
|
+
align-items: center;
|
|
12984
|
+
gap: var(--spacing-2);
|
|
12985
|
+
min-width: 0;
|
|
12986
|
+
font-size: var(--font-size-2xs);
|
|
12987
|
+
letter-spacing: var(--font-letter-spacing-wide);
|
|
12988
|
+
text-transform: uppercase;
|
|
12989
|
+
color: var(--color-text-tertiary);
|
|
12990
|
+
}
|
|
12991
|
+
|
|
12992
|
+
.crewlet-object-header__icon {
|
|
12993
|
+
display: inline-flex;
|
|
12994
|
+
flex: none;
|
|
12995
|
+
}
|
|
12996
|
+
|
|
12997
|
+
/* A key or a name keeps its own case: in capitals a name is a shout. */
|
|
12998
|
+
.crewlet-object-header__id {
|
|
12999
|
+
min-width: 0;
|
|
13000
|
+
overflow: hidden;
|
|
13001
|
+
text-overflow: ellipsis;
|
|
13002
|
+
white-space: nowrap;
|
|
13003
|
+
letter-spacing: normal;
|
|
13004
|
+
text-transform: none;
|
|
13005
|
+
}
|
|
13006
|
+
|
|
13007
|
+
.crewlet-object-header__id--mono {
|
|
13008
|
+
font-family: var(--font-family-mono);
|
|
13009
|
+
}
|
|
13010
|
+
|
|
13011
|
+
/* The head row wraps: the marks and the actions take a line under the title
|
|
13012
|
+
rather than every pill on the row giving up a few characters. */
|
|
13013
|
+
.crewlet-object-header__head {
|
|
13014
|
+
display: flex;
|
|
13015
|
+
flex-wrap: wrap;
|
|
13016
|
+
align-items: center;
|
|
13017
|
+
gap: var(--spacing-2);
|
|
13018
|
+
min-width: 0;
|
|
13019
|
+
}
|
|
13020
|
+
|
|
13021
|
+
/* TWO LINES, AND THAT IS THE CEILING, which catches a title written as a
|
|
13022
|
+
paragraph and holds every real one. */
|
|
13023
|
+
.crewlet-object-header__title {
|
|
13024
|
+
display: -webkit-box;
|
|
13025
|
+
-webkit-box-orient: vertical;
|
|
13026
|
+
-webkit-line-clamp: 2;
|
|
13027
|
+
line-clamp: 2;
|
|
13028
|
+
overflow: hidden;
|
|
13029
|
+
flex: 0 1 auto;
|
|
13030
|
+
min-width: 0;
|
|
13031
|
+
margin: 0;
|
|
13032
|
+
font-size: var(--font-size-xl);
|
|
13033
|
+
font-weight: var(--font-weight-semibold);
|
|
13034
|
+
line-height: var(--font-line-height-snug);
|
|
13035
|
+
color: var(--color-text-primary);
|
|
13036
|
+
}
|
|
13037
|
+
|
|
13038
|
+
.crewlet-object-header--peek .crewlet-object-header__title {
|
|
13039
|
+
font-size: var(--font-size-lg);
|
|
13040
|
+
}
|
|
13041
|
+
|
|
13042
|
+
/* The state keeps its width: a pill squeezed to "13 pro…" says something
|
|
13043
|
+
else. The marks travel together when the row wraps. */
|
|
13044
|
+
.crewlet-object-header__status,
|
|
13045
|
+
.crewlet-object-header__actions {
|
|
13046
|
+
display: flex;
|
|
13047
|
+
flex: 0 0 auto;
|
|
13048
|
+
flex-wrap: wrap;
|
|
13049
|
+
align-items: center;
|
|
13050
|
+
gap: var(--spacing-1);
|
|
13051
|
+
}
|
|
13052
|
+
|
|
13053
|
+
.crewlet-object-header__actions {
|
|
13054
|
+
margin-left: auto;
|
|
13055
|
+
}
|
|
13056
|
+
|
|
13057
|
+
/* ── the fact line ─────────────────────────────────────────────────────── */
|
|
13058
|
+
|
|
13059
|
+
/* THE TRACK FLOOR IS 7.5rem, which fits seven facts on one line at 1280px and
|
|
13060
|
+
still holds every label and a two-line value. */
|
|
13061
|
+
.crewlet-fact-line {
|
|
13062
|
+
display: grid;
|
|
13063
|
+
grid-template-columns: repeat(auto-fill, minmax(min(7.5rem, 100%), 1fr));
|
|
13064
|
+
column-gap: var(--spacing-4);
|
|
13065
|
+
row-gap: var(--spacing-3);
|
|
13066
|
+
padding-top: var(--spacing-1);
|
|
13067
|
+
}
|
|
13068
|
+
|
|
13069
|
+
/* Two bands: the label, then the value with its footnotes in one cell. */
|
|
13070
|
+
.crewlet-fact-line__fact {
|
|
13071
|
+
display: grid;
|
|
13072
|
+
grid-template-rows: subgrid;
|
|
13073
|
+
grid-row: span 2;
|
|
13074
|
+
row-gap: 0;
|
|
13075
|
+
min-width: 0;
|
|
13076
|
+
}
|
|
13077
|
+
|
|
13078
|
+
/* A token and a set of chips take two tracks. */
|
|
13079
|
+
.crewlet-fact-line__fact--token,
|
|
13080
|
+
.crewlet-fact-line__fact--set {
|
|
13081
|
+
grid-column: span 2;
|
|
13082
|
+
}
|
|
13083
|
+
|
|
13084
|
+
.crewlet-fact-line__body {
|
|
13085
|
+
display: flex;
|
|
13086
|
+
flex-direction: column;
|
|
13087
|
+
min-width: 0;
|
|
13088
|
+
}
|
|
13089
|
+
|
|
13090
|
+
.crewlet-fact-line__label {
|
|
13091
|
+
font-size: var(--font-size-2xs);
|
|
13092
|
+
letter-spacing: var(--font-letter-spacing-wide);
|
|
13093
|
+
text-transform: uppercase;
|
|
13094
|
+
color: var(--color-text-tertiary);
|
|
13095
|
+
}
|
|
13096
|
+
|
|
13097
|
+
.crewlet-fact-line__value {
|
|
13098
|
+
min-width: 0;
|
|
13099
|
+
font-size: var(--font-size-compact);
|
|
13100
|
+
color: var(--color-text-primary);
|
|
13101
|
+
overflow-wrap: anywhere;
|
|
13102
|
+
}
|
|
13103
|
+
|
|
13104
|
+
.crewlet-fact-line__value--clamp {
|
|
13105
|
+
display: -webkit-box;
|
|
13106
|
+
-webkit-box-orient: vertical;
|
|
13107
|
+
-webkit-line-clamp: 2;
|
|
13108
|
+
line-clamp: 2;
|
|
13109
|
+
overflow: hidden;
|
|
13110
|
+
}
|
|
13111
|
+
|
|
13112
|
+
/* One token, one line, cut with an ellipsis where two tracks are too narrow;
|
|
13113
|
+
its title carries the whole of it. */
|
|
13114
|
+
.crewlet-fact-line__value--token {
|
|
13115
|
+
display: block;
|
|
13116
|
+
overflow: hidden;
|
|
13117
|
+
text-overflow: ellipsis;
|
|
13118
|
+
white-space: nowrap;
|
|
13119
|
+
overflow-wrap: normal;
|
|
13120
|
+
}
|
|
13121
|
+
|
|
13122
|
+
/* A footnote may not set its column's width: the track does, and the note
|
|
13123
|
+
wraps inside it, balanced so the wrap reads as deliberate. */
|
|
13124
|
+
.crewlet-fact-line__note,
|
|
13125
|
+
.crewlet-fact-line__set-by {
|
|
13126
|
+
font-size: var(--font-size-2xs);
|
|
13127
|
+
color: var(--color-text-tertiary);
|
|
13128
|
+
text-wrap: balance;
|
|
13129
|
+
}
|
|
13130
|
+
|
|
13131
|
+
/* ── the by-line ───────────────────────────────────────────────────────── */
|
|
13132
|
+
|
|
13133
|
+
/* The word and its arrow are one atomic box, so the arrow never takes a line
|
|
13134
|
+
of its own. */
|
|
13135
|
+
.crewlet-set-by__turn {
|
|
13136
|
+
display: inline-flex;
|
|
13137
|
+
align-items: center;
|
|
13138
|
+
gap: 0.25em;
|
|
13139
|
+
}
|
|
13140
|
+
|
|
13141
|
+
|
|
13142
|
+
/* OrgLabel-R5KY7C3W.css */
|
|
12757
13143
|
/*
|
|
12758
13144
|
* What a node of an org chart and a row of an org table both say
|
|
12759
13145
|
* (OrgLabel.tsx).
|
|
@@ -12835,7 +13221,12 @@ svg.crewlet-datetime__chevron {
|
|
|
12835
13221
|
inside of a Lucide glyph turns every closed shape in it solid and every
|
|
12836
13222
|
open one into a smear (a person's head and shoulders, a unit's building, a
|
|
12837
13223
|
warning's triangle, each a blob), so a `.crewlet-glyph` keeps the fill its
|
|
12838
|
-
own frame decides and takes the ink through its stroke.
|
|
13224
|
+
own frame decides and takes the ink through its stroke.
|
|
13225
|
+
|
|
13226
|
+
A DRAWING HERE CUTS ITS HOLES AS GEOMETRY. This rule repaints every path and
|
|
13227
|
+
group in the zone, a mask's included, so a hole cut by a mask fills with a
|
|
13228
|
+
share of the ink that changes with the hue: every agent's eyes on the chart
|
|
13229
|
+
did, until the Crewlet characters cut their faces into their own paths. */
|
|
12839
13230
|
.crewlet-org-label__icon svg:not(.crewlet-glyph),
|
|
12840
13231
|
.crewlet-org-label__icon svg:not(.crewlet-glyph) g,
|
|
12841
13232
|
.crewlet-org-label__icon svg:not(.crewlet-glyph) path {
|
|
@@ -14475,6 +14866,28 @@ svg.crewlet-datetime__chevron {
|
|
|
14475
14866
|
}
|
|
14476
14867
|
|
|
14477
14868
|
|
|
14869
|
+
/* QrCode-JWJTWMU5.css */
|
|
14870
|
+
/*
|
|
14871
|
+
* A QR code on its own plate.
|
|
14872
|
+
*
|
|
14873
|
+
* A FIXED BOX, because a camera needs modules of a readable size: at 208px a
|
|
14874
|
+
* second factor's code (a version 7 symbol and its quiet zone) draws each
|
|
14875
|
+
* module at about 4.3px. A consumer that needs another size sets the variable.
|
|
14876
|
+
*
|
|
14877
|
+
* ITS INKS ARE KEPT UNDER FORCED COLOURS. A high-contrast mode repaints fills
|
|
14878
|
+
* to system colours, and a plate repainted dark is a code no scanner reads.
|
|
14879
|
+
*/
|
|
14880
|
+
.crewlet-qr-code {
|
|
14881
|
+
--crewlet-qr-code-size: 208px;
|
|
14882
|
+
display: block;
|
|
14883
|
+
flex: none;
|
|
14884
|
+
width: var(--crewlet-qr-code-size);
|
|
14885
|
+
height: var(--crewlet-qr-code-size);
|
|
14886
|
+
border-radius: var(--radius-sm);
|
|
14887
|
+
forced-color-adjust: none;
|
|
14888
|
+
}
|
|
14889
|
+
|
|
14890
|
+
|
|
14478
14891
|
/* ReadingPane-5UOLPWY5.css */
|
|
14479
14892
|
/*
|
|
14480
14893
|
* One item read in full, in one column.
|
|
@@ -18962,7 +19375,7 @@ b.crewlet-switcher__match {
|
|
|
18962
19375
|
}
|
|
18963
19376
|
|
|
18964
19377
|
|
|
18965
|
-
/* Text-
|
|
19378
|
+
/* Text-S3Q4O3IG.css */
|
|
18966
19379
|
/*
|
|
18967
19380
|
* The type registers, one rule each.
|
|
18968
19381
|
*
|
|
@@ -19014,6 +19427,17 @@ b.crewlet-switcher__match {
|
|
|
19014
19427
|
color: var(--color-text-primary);
|
|
19015
19428
|
}
|
|
19016
19429
|
|
|
19430
|
+
/*
|
|
19431
|
+
* The register around it: nothing is set, so the run keeps its sentence's
|
|
19432
|
+
* size, weight, tracking and ink, and only a modifier (mono, numeric) or a
|
|
19433
|
+
* tone changes it.
|
|
19434
|
+
*/
|
|
19435
|
+
.crewlet-text--inherit {
|
|
19436
|
+
font-size: inherit;
|
|
19437
|
+
line-height: inherit;
|
|
19438
|
+
color: inherit;
|
|
19439
|
+
}
|
|
19440
|
+
|
|
19017
19441
|
.crewlet-text--body {
|
|
19018
19442
|
font-size: var(--font-size-sm);
|
|
19019
19443
|
line-height: var(--font-line-height-normal);
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export { cx } from './cx.js';
|
|
2
2
|
export { useClipboard, writeClipboard } from './useClipboard.js';
|
|
3
3
|
export type { Clipboard, ClipboardOptions, ClipboardState } from './useClipboard.js';
|
|
4
|
+
export { useOutcome } from './useOutcome.js';
|
|
5
|
+
export type { Outcome, OutcomeOptions, OutcomeState } from './useOutcome.js';
|
|
6
|
+
export { downloadText, safeFilename, useDownload } from './useDownload.js';
|
|
7
|
+
export type { Download, DownloadState } from './useDownload.js';
|
|
4
8
|
export type { Tone } from './tone.js';
|
|
5
9
|
export { NODE_HUES, NODE_HUE_NAMES, isNodeHue } from './nodeHue.js';
|
|
6
10
|
export type { NodeHue } from './nodeHue.js';
|
package/dist/utils/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import '../chunk-
|
|
2
|
-
export {
|
|
1
|
+
import '../chunk-U5LQ2AS5.js';
|
|
2
|
+
export { downloadText, safeFilename, useDownload } from '../chunk-F6NZOVWL.js';
|
|
3
|
+
export { useClipboard, writeClipboard } from '../chunk-STJ7QBC3.js';
|
|
4
|
+
export { useOutcome } from '../chunk-DTIW4CHZ.js';
|
|
3
5
|
export { HeadingLevelProvider, headingTag, nextHeadingLevel, useHeadingLevel } from '../chunk-PQADV6P6.js';
|
|
4
6
|
export { NODE_HUES, NODE_HUE_NAMES, isNodeHue } from '../chunk-AYKXMIOR.js';
|
|
5
7
|
export { cx } from '../chunk-ODEQTPFM.js';
|
|
@@ -33,6 +33,8 @@ export interface ClipboardOptions {
|
|
|
33
33
|
}
|
|
34
34
|
export interface Clipboard {
|
|
35
35
|
state: ClipboardState;
|
|
36
|
+
/** How many copies have settled. See [Outcome.attempt]. */
|
|
37
|
+
attempt: number;
|
|
36
38
|
copy: (text: string | (() => string)) => Promise<boolean>;
|
|
37
39
|
}
|
|
38
40
|
/**
|
|
@@ -56,9 +58,10 @@ export interface Clipboard {
|
|
|
56
58
|
* timer exists AT THAT MOMENT, and for a write still in flight that is
|
|
57
59
|
* none: the settle then ran after the cleanup and armed a fresh timer with
|
|
58
60
|
* nothing left alive to clear it, so the hook leaked a timer per abandoned
|
|
59
|
-
* copy and wrote state to a component that was gone.
|
|
60
|
-
*
|
|
61
|
-
*
|
|
61
|
+
* copy and wrote state to a component that was gone. [useOutcome], the
|
|
62
|
+
* machine this and `useDownload` share, checks whether the component is
|
|
63
|
+
* still mounted AFTER the await rather than before, because the await is
|
|
64
|
+
* the whole of the gap.
|
|
62
65
|
*
|
|
63
66
|
* The text may be a THUNK, resolved on the press. On a live screen the thing
|
|
64
67
|
* worth copying is assembled from everything on it, so a string prop means
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { type OutcomeOptions } from './useOutcome.js';
|
|
2
|
+
/** Where a download stands: not tried, handed to the browser, or refused. */
|
|
3
|
+
export type DownloadState = 'idle' | 'started' | 'failed';
|
|
4
|
+
export interface Download {
|
|
5
|
+
state: DownloadState;
|
|
6
|
+
/** How many downloads have settled. See [Outcome.attempt]. */
|
|
7
|
+
attempt: number;
|
|
8
|
+
/**
|
|
9
|
+
* Offers `text` as a file, and answers whether the browser took it. The
|
|
10
|
+
* text may be a thunk, resolved on the press.
|
|
11
|
+
*/
|
|
12
|
+
download: (text: string | (() => string), filename: string, mime?: string) => Promise<boolean>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Handing text to the reader as a file, and saying whether it landed: the
|
|
16
|
+
* mirror of `useClipboard`, on the same state machine.
|
|
17
|
+
*
|
|
18
|
+
* "STARTED", NOT "SAVED". There is no completion event on an `<a download>`:
|
|
19
|
+
* the browser took the click, and a gate such as Chrome's automatic multiple
|
|
20
|
+
* download prompt can still stop it silently after that. What the control can
|
|
21
|
+
* honestly say is that the download was handed over, and under which name.
|
|
22
|
+
*/
|
|
23
|
+
export declare function useDownload(options?: OutcomeOptions): Download;
|
|
24
|
+
/**
|
|
25
|
+
* Saves `text` on the reader's machine and reports whether the browser took
|
|
26
|
+
* it, with the name it was offered under ([safeFilename] of `filename`).
|
|
27
|
+
*
|
|
28
|
+
* For a control that cannot say so on itself, such as a menu item that
|
|
29
|
+
* closes on the press: the caller raises a toast from the answer.
|
|
30
|
+
*
|
|
31
|
+
* TWO THINGS ARE CHECKED UP FRONT rather than assumed. Without
|
|
32
|
+
* `URL.createObjectURL` there is nothing to point a saveable link at, and a
|
|
33
|
+
* `data:` URL is the wrong fallback because several engines cap it near two
|
|
34
|
+
* megabytes, so it would fail silently on exactly the large files. Without the
|
|
35
|
+
* `download` attribute the click NAVIGATES to the text instead of saving it,
|
|
36
|
+
* which looks enough like something happening that nobody checks.
|
|
37
|
+
*
|
|
38
|
+
* The blob URL is revoked on the NEXT macrotask: the click only queues the
|
|
39
|
+
* download, and freeing the entry inside the same task races the fetch that is
|
|
40
|
+
* about to read it. Never revoking is the other failure, a second copy of the
|
|
41
|
+
* text held for the life of the tab.
|
|
42
|
+
*/
|
|
43
|
+
export declare function downloadText(text: string, filename: string, mime?: string): {
|
|
44
|
+
started: boolean;
|
|
45
|
+
name: string;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* A filename the reader will actually get, out of whatever the caller had.
|
|
49
|
+
*
|
|
50
|
+
* The `download` attribute is only a suggestion and each browser sanitises it
|
|
51
|
+
* its own way, so the name is decided here and every caller gets one
|
|
52
|
+
* predictable answer. A name composed from data (an id off the URL) that
|
|
53
|
+
* arrived as `../etc/passwd` or with a newline in it never reaches that guess.
|
|
54
|
+
*
|
|
55
|
+
* UNICODE-AWARE: letters, marks and numbers in every script are kept, and
|
|
56
|
+
* separators and invisibles (a slash, a colon, the fullwidth solidus, a
|
|
57
|
+
* right-to-left override) become a hyphen. An ASCII-only class turned
|
|
58
|
+
* `日本語.json` into a file called `json`. The EXTENSION is never what gets cut
|
|
59
|
+
* or stripped, because a name that loses it opens in the wrong application;
|
|
60
|
+
* leading dots, which make `..` a traversal and `.name` a hidden file, are
|
|
61
|
+
* stripped from the stem.
|
|
62
|
+
*/
|
|
63
|
+
export declare function safeFilename(name: string): string;
|