@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.
- package/README.md +36 -6
- 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 +37 -2
- package/dist/Avatar/index.d.ts +1 -1
- package/dist/Avatar/index.js +2 -2
- package/dist/{Avatar-I4NFP3WQ.css → Avatar-3C2H2WA4.css} +34 -0
- 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 +12 -11
- package/dist/DateTimePicker/index.js +2 -2
- 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/OrgNode/index.js +4 -4
- package/dist/OrgTable/index.js +4 -4
- 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 +4 -4
- package/dist/{chunk-FTEJPHBI.js → chunk-4GB57WIT.js} +2 -2
- package/dist/{chunk-DDTDN5L2.js → chunk-4KWOKX2B.js} +1 -1
- package/dist/{chunk-NN62JQLR.js → chunk-5CLW2CXT.js} +3 -1
- package/dist/{chunk-HI6Q2UXQ.js → chunk-5OM447RW.js} +19 -7
- package/dist/{chunk-YXMCUKFI.js → chunk-5PSXBL73.js} +1 -1
- 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-22M7OXKW.js → chunk-AKEZ3G5V.js} +1 -1
- package/dist/chunk-BJCFNRGH.js +53 -0
- package/dist/chunk-CXBAIVYZ.js +39 -0
- package/dist/chunk-DTIW4CHZ.js +37 -0
- package/dist/chunk-F6NZOVWL.js +68 -0
- package/dist/{chunk-LCF4WPYS.js → chunk-FA2V2VT6.js} +2 -2
- package/dist/{chunk-KGTQ5CVD.js → chunk-GDDE4UM7.js} +1 -1
- package/dist/{chunk-EFNHOVC2.js → chunk-HENOTGUV.js} +2 -2
- package/dist/chunk-I7WXZOWA.js +90 -0
- package/dist/{chunk-23DHIMJA.js → chunk-IKBK4A5O.js} +1 -1
- package/dist/{chunk-DY77H372.js → chunk-JF7X673Z.js} +2 -2
- package/dist/{chunk-YYBD73OI.js → chunk-L4ZLXYPO.js} +1 -1
- package/dist/{chunk-H3XOMT7W.js → chunk-OYOQU7O5.js} +44 -3
- package/dist/{chunk-IYZZL3MZ.js → chunk-PQ63NLFC.js} +3 -3
- package/dist/{chunk-TK6YC5QT.js → chunk-RF5O4FYL.js} +4 -4
- 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-FY2R4U4Q.js → chunk-TBMDMXEX.js} +1 -1
- package/dist/{chunk-ZPWUVVIB.js → chunk-UAN5NE7M.js} +2 -2
- package/dist/{chunk-YACKC3K2.js → chunk-W46LPU4R.js} +8 -8
- package/dist/{chunk-4EOJR52M.js → chunk-XU4H6JQB.js} +4 -4
- package/dist/chunk-Y56FM3K4.js +57 -0
- package/dist/{chunk-DJMLHCLD.js → chunk-YDBC4DNW.js} +1 -1
- package/dist/{chunk-4Y7WKXAW.js → chunk-ZFH7H7GS.js} +1 -1
- package/dist/generated/index.d.ts +5 -0
- package/dist/generated/index.js +67 -60
- package/dist/index.js +67 -60
- package/dist/styles.css +440 -8
- 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-GUHP5JHC.js → chunk-2UU5IGZI.js} +1 -1
- 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
|
@@ -537,7 +537,7 @@
|
|
|
537
537
|
}
|
|
538
538
|
|
|
539
539
|
|
|
540
|
-
/* AppShell-
|
|
540
|
+
/* AppShell-RUNVM4WH.css */
|
|
541
541
|
/*
|
|
542
542
|
* The application frame: a rail on the FRAME, and the screen on a SHEET that
|
|
543
543
|
* floats beside it.
|
|
@@ -1162,8 +1162,158 @@
|
|
|
1162
1162
|
}
|
|
1163
1163
|
}
|
|
1164
1164
|
|
|
1165
|
+
/* ── the account row ───────────────────────────────────────────────────── */
|
|
1165
1166
|
|
|
1166
|
-
/*
|
|
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-3C2H2WA4.css */
|
|
1167
1317
|
/*
|
|
1168
1318
|
* The identity badge.
|
|
1169
1319
|
*
|
|
@@ -1292,6 +1442,25 @@
|
|
|
1292
1442
|
object-fit: cover;
|
|
1293
1443
|
}
|
|
1294
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
|
+
|
|
1295
1464
|
/* ── tones ─────────────────────────────────────────────────────────────── */
|
|
1296
1465
|
|
|
1297
1466
|
.crewlet-avatar--fallback {
|
|
@@ -1487,6 +1656,21 @@
|
|
|
1487
1656
|
background: var(--color-feedback-danger);
|
|
1488
1657
|
}
|
|
1489
1658
|
|
|
1659
|
+
/*
|
|
1660
|
+
* A MARK (`mark`): how a principal is present, not a state, so it is drawn
|
|
1661
|
+
* quiet rather than in a state's fill: the neutral badge's raised rung, its
|
|
1662
|
+
* strong hairline and its secondary ink. The hairline is the corner's own
|
|
1663
|
+
* outline, inset by its width, so it keeps the corner's size and survives
|
|
1664
|
+
* forced colours.
|
|
1665
|
+
*/
|
|
1666
|
+
.crewlet-avatar__status--mark {
|
|
1667
|
+
padding: 1px;
|
|
1668
|
+
background: var(--color-surface-elevated);
|
|
1669
|
+
outline-color: var(--color-border-strong);
|
|
1670
|
+
outline-offset: -1px;
|
|
1671
|
+
color: var(--color-text-secondary);
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1490
1674
|
|
|
1491
1675
|
/* AvatarPicker-PREY36MG.css */
|
|
1492
1676
|
/*
|
|
@@ -2418,7 +2602,7 @@ a.crewlet-breadcrumb__crumb:focus-visible {
|
|
|
2418
2602
|
}
|
|
2419
2603
|
|
|
2420
2604
|
|
|
2421
|
-
/* Callout-
|
|
2605
|
+
/* Callout-SXXK4B5R.css */
|
|
2422
2606
|
/*
|
|
2423
2607
|
* The callout: a status that stays in the content flow.
|
|
2424
2608
|
*
|
|
@@ -2473,8 +2657,10 @@ a.crewlet-breadcrumb__crumb:focus-visible {
|
|
|
2473
2657
|
}
|
|
2474
2658
|
|
|
2475
2659
|
.crewlet-callout__title {
|
|
2660
|
+
/* A LINE OF ITS OWN above the message, so the heading and the first
|
|
2661
|
+
sentence are never read as one run-on sentence. */
|
|
2662
|
+
display: block;
|
|
2476
2663
|
font-weight: var(--font-weight-semibold);
|
|
2477
|
-
margin-right: var(--spacing-2);
|
|
2478
2664
|
}
|
|
2479
2665
|
|
|
2480
2666
|
.crewlet-callout__action {
|
|
@@ -4219,7 +4405,7 @@ a.crewlet-breadcrumb__crumb:focus-visible {
|
|
|
4219
4405
|
}
|
|
4220
4406
|
|
|
4221
4407
|
|
|
4222
|
-
/* Checkbox-
|
|
4408
|
+
/* Checkbox-KT7RS6QQ.css */
|
|
4223
4409
|
/*
|
|
4224
4410
|
* Checkbox: a box, its label and its consequence as one target.
|
|
4225
4411
|
*
|
|
@@ -4340,6 +4526,22 @@ a.crewlet-breadcrumb__crumb:focus-visible {
|
|
|
4340
4526
|
outline-offset: 0;
|
|
4341
4527
|
}
|
|
4342
4528
|
|
|
4529
|
+
/*
|
|
4530
|
+
* A group of boxes under one legend. The boxes keep a field's inner rhythm,
|
|
4531
|
+
* one step apart, so the group reads as one field and its boxes as its parts.
|
|
4532
|
+
*/
|
|
4533
|
+
.crewlet-checkbox-group__options {
|
|
4534
|
+
display: flex;
|
|
4535
|
+
flex-direction: column;
|
|
4536
|
+
gap: var(--spacing-1);
|
|
4537
|
+
}
|
|
4538
|
+
|
|
4539
|
+
.crewlet-checkbox-group__empty {
|
|
4540
|
+
margin: 0;
|
|
4541
|
+
font-size: var(--font-size-xs);
|
|
4542
|
+
color: var(--color-text-secondary);
|
|
4543
|
+
}
|
|
4544
|
+
|
|
4343
4545
|
|
|
4344
4546
|
/* ChoiceButtons-DJ5EOGUA.css */
|
|
4345
4547
|
/*
|
|
@@ -9953,7 +10155,7 @@ svg.crewlet-datetime__chevron {
|
|
|
9953
10155
|
}
|
|
9954
10156
|
|
|
9955
10157
|
|
|
9956
|
-
/* InlineCode-
|
|
10158
|
+
/* InlineCode-ASYHLN3E.css */
|
|
9957
10159
|
/*
|
|
9958
10160
|
* One identifier inside a sentence: a mono chip on the inset surface.
|
|
9959
10161
|
*
|
|
@@ -10011,6 +10213,15 @@ svg.crewlet-datetime__chevron {
|
|
|
10011
10213
|
color: inherit;
|
|
10012
10214
|
}
|
|
10013
10215
|
|
|
10216
|
+
/*
|
|
10217
|
+
* A short token read as one: it moves to the next line whole rather than
|
|
10218
|
+
* splitting, which `overflow-wrap: anywhere` would otherwise allow.
|
|
10219
|
+
*/
|
|
10220
|
+
.crewlet-inline-code--whole {
|
|
10221
|
+
overflow-wrap: normal;
|
|
10222
|
+
white-space: nowrap;
|
|
10223
|
+
}
|
|
10224
|
+
|
|
10014
10225
|
.crewlet-inline-code--truncate {
|
|
10015
10226
|
display: inline-block;
|
|
10016
10227
|
max-width: 100%;
|
|
@@ -10021,7 +10232,7 @@ svg.crewlet-datetime__chevron {
|
|
|
10021
10232
|
}
|
|
10022
10233
|
|
|
10023
10234
|
|
|
10024
|
-
/* Input-
|
|
10235
|
+
/* Input-3KVSNUO5.css */
|
|
10025
10236
|
/*
|
|
10026
10237
|
* The form row: Input, Textarea, Label, FormField, FormRow, FormSection and
|
|
10027
10238
|
* ReadOnlyField.
|
|
@@ -10459,6 +10670,17 @@ svg.crewlet-datetime__chevron {
|
|
|
10459
10670
|
color: var(--color-text-tertiary);
|
|
10460
10671
|
}
|
|
10461
10672
|
|
|
10673
|
+
/*
|
|
10674
|
+
* A LITERAL INSIDE A LABEL KEEPS ITS CASE. The label is set in capitals, and
|
|
10675
|
+
* a value a reader has to type back exactly ("Type jane.founder to confirm")
|
|
10676
|
+
* read as JANE.FOUNDER, which is not what the field accepts.
|
|
10677
|
+
*/
|
|
10678
|
+
.crewlet-label code,
|
|
10679
|
+
.crewlet-label__text code {
|
|
10680
|
+
text-transform: none;
|
|
10681
|
+
letter-spacing: normal;
|
|
10682
|
+
}
|
|
10683
|
+
|
|
10462
10684
|
.crewlet-label--with-action {
|
|
10463
10685
|
display: flex;
|
|
10464
10686
|
justify-content: space-between;
|
|
@@ -12755,6 +12977,183 @@ svg.crewlet-datetime__chevron {
|
|
|
12755
12977
|
}
|
|
12756
12978
|
|
|
12757
12979
|
|
|
12980
|
+
/* ObjectHeader-UNVYM2KD.css */
|
|
12981
|
+
/*
|
|
12982
|
+
* The header of an object: its eyebrow, its head row and its fact line.
|
|
12983
|
+
*/
|
|
12984
|
+
.crewlet-object-header {
|
|
12985
|
+
display: flex;
|
|
12986
|
+
flex-direction: column;
|
|
12987
|
+
gap: var(--spacing-1);
|
|
12988
|
+
min-width: 0;
|
|
12989
|
+
padding: var(--spacing-4) 0 var(--spacing-3);
|
|
12990
|
+
}
|
|
12991
|
+
|
|
12992
|
+
.crewlet-object-header--peek {
|
|
12993
|
+
padding: var(--spacing-3) 0 var(--spacing-2);
|
|
12994
|
+
}
|
|
12995
|
+
|
|
12996
|
+
.crewlet-object-header__eyebrow {
|
|
12997
|
+
display: flex;
|
|
12998
|
+
align-items: center;
|
|
12999
|
+
gap: var(--spacing-2);
|
|
13000
|
+
min-width: 0;
|
|
13001
|
+
font-size: var(--font-size-2xs);
|
|
13002
|
+
letter-spacing: var(--font-letter-spacing-wide);
|
|
13003
|
+
text-transform: uppercase;
|
|
13004
|
+
color: var(--color-text-tertiary);
|
|
13005
|
+
}
|
|
13006
|
+
|
|
13007
|
+
.crewlet-object-header__icon {
|
|
13008
|
+
display: inline-flex;
|
|
13009
|
+
flex: none;
|
|
13010
|
+
}
|
|
13011
|
+
|
|
13012
|
+
/* A key or a name keeps its own case: in capitals a name is a shout. */
|
|
13013
|
+
.crewlet-object-header__id {
|
|
13014
|
+
min-width: 0;
|
|
13015
|
+
overflow: hidden;
|
|
13016
|
+
text-overflow: ellipsis;
|
|
13017
|
+
white-space: nowrap;
|
|
13018
|
+
letter-spacing: normal;
|
|
13019
|
+
text-transform: none;
|
|
13020
|
+
}
|
|
13021
|
+
|
|
13022
|
+
.crewlet-object-header__id--mono {
|
|
13023
|
+
font-family: var(--font-family-mono);
|
|
13024
|
+
}
|
|
13025
|
+
|
|
13026
|
+
/* The head row wraps: the marks and the actions take a line under the title
|
|
13027
|
+
rather than every pill on the row giving up a few characters. */
|
|
13028
|
+
.crewlet-object-header__head {
|
|
13029
|
+
display: flex;
|
|
13030
|
+
flex-wrap: wrap;
|
|
13031
|
+
align-items: center;
|
|
13032
|
+
gap: var(--spacing-2);
|
|
13033
|
+
min-width: 0;
|
|
13034
|
+
}
|
|
13035
|
+
|
|
13036
|
+
/* TWO LINES, AND THAT IS THE CEILING, which catches a title written as a
|
|
13037
|
+
paragraph and holds every real one. */
|
|
13038
|
+
.crewlet-object-header__title {
|
|
13039
|
+
display: -webkit-box;
|
|
13040
|
+
-webkit-box-orient: vertical;
|
|
13041
|
+
-webkit-line-clamp: 2;
|
|
13042
|
+
line-clamp: 2;
|
|
13043
|
+
overflow: hidden;
|
|
13044
|
+
flex: 0 1 auto;
|
|
13045
|
+
min-width: 0;
|
|
13046
|
+
margin: 0;
|
|
13047
|
+
font-size: var(--font-size-xl);
|
|
13048
|
+
font-weight: var(--font-weight-semibold);
|
|
13049
|
+
line-height: var(--font-line-height-snug);
|
|
13050
|
+
color: var(--color-text-primary);
|
|
13051
|
+
}
|
|
13052
|
+
|
|
13053
|
+
.crewlet-object-header--peek .crewlet-object-header__title {
|
|
13054
|
+
font-size: var(--font-size-lg);
|
|
13055
|
+
}
|
|
13056
|
+
|
|
13057
|
+
/* The state keeps its width: a pill squeezed to "13 pro…" says something
|
|
13058
|
+
else. The marks travel together when the row wraps. */
|
|
13059
|
+
.crewlet-object-header__status,
|
|
13060
|
+
.crewlet-object-header__actions {
|
|
13061
|
+
display: flex;
|
|
13062
|
+
flex: 0 0 auto;
|
|
13063
|
+
flex-wrap: wrap;
|
|
13064
|
+
align-items: center;
|
|
13065
|
+
gap: var(--spacing-1);
|
|
13066
|
+
}
|
|
13067
|
+
|
|
13068
|
+
.crewlet-object-header__actions {
|
|
13069
|
+
margin-left: auto;
|
|
13070
|
+
}
|
|
13071
|
+
|
|
13072
|
+
/* ── the fact line ─────────────────────────────────────────────────────── */
|
|
13073
|
+
|
|
13074
|
+
/* THE TRACK FLOOR IS 7.5rem, which fits seven facts on one line at 1280px and
|
|
13075
|
+
still holds every label and a two-line value. */
|
|
13076
|
+
.crewlet-fact-line {
|
|
13077
|
+
display: grid;
|
|
13078
|
+
grid-template-columns: repeat(auto-fill, minmax(min(7.5rem, 100%), 1fr));
|
|
13079
|
+
column-gap: var(--spacing-4);
|
|
13080
|
+
row-gap: var(--spacing-3);
|
|
13081
|
+
padding-top: var(--spacing-1);
|
|
13082
|
+
}
|
|
13083
|
+
|
|
13084
|
+
/* Two bands: the label, then the value with its footnotes in one cell. */
|
|
13085
|
+
.crewlet-fact-line__fact {
|
|
13086
|
+
display: grid;
|
|
13087
|
+
grid-template-rows: subgrid;
|
|
13088
|
+
grid-row: span 2;
|
|
13089
|
+
row-gap: 0;
|
|
13090
|
+
min-width: 0;
|
|
13091
|
+
}
|
|
13092
|
+
|
|
13093
|
+
/* A token and a set of chips take two tracks. */
|
|
13094
|
+
.crewlet-fact-line__fact--token,
|
|
13095
|
+
.crewlet-fact-line__fact--set {
|
|
13096
|
+
grid-column: span 2;
|
|
13097
|
+
}
|
|
13098
|
+
|
|
13099
|
+
.crewlet-fact-line__body {
|
|
13100
|
+
display: flex;
|
|
13101
|
+
flex-direction: column;
|
|
13102
|
+
min-width: 0;
|
|
13103
|
+
}
|
|
13104
|
+
|
|
13105
|
+
.crewlet-fact-line__label {
|
|
13106
|
+
font-size: var(--font-size-2xs);
|
|
13107
|
+
letter-spacing: var(--font-letter-spacing-wide);
|
|
13108
|
+
text-transform: uppercase;
|
|
13109
|
+
color: var(--color-text-tertiary);
|
|
13110
|
+
}
|
|
13111
|
+
|
|
13112
|
+
.crewlet-fact-line__value {
|
|
13113
|
+
min-width: 0;
|
|
13114
|
+
font-size: var(--font-size-compact);
|
|
13115
|
+
color: var(--color-text-primary);
|
|
13116
|
+
overflow-wrap: anywhere;
|
|
13117
|
+
}
|
|
13118
|
+
|
|
13119
|
+
.crewlet-fact-line__value--clamp {
|
|
13120
|
+
display: -webkit-box;
|
|
13121
|
+
-webkit-box-orient: vertical;
|
|
13122
|
+
-webkit-line-clamp: 2;
|
|
13123
|
+
line-clamp: 2;
|
|
13124
|
+
overflow: hidden;
|
|
13125
|
+
}
|
|
13126
|
+
|
|
13127
|
+
/* One token, one line, cut with an ellipsis where two tracks are too narrow;
|
|
13128
|
+
its title carries the whole of it. */
|
|
13129
|
+
.crewlet-fact-line__value--token {
|
|
13130
|
+
display: block;
|
|
13131
|
+
overflow: hidden;
|
|
13132
|
+
text-overflow: ellipsis;
|
|
13133
|
+
white-space: nowrap;
|
|
13134
|
+
overflow-wrap: normal;
|
|
13135
|
+
}
|
|
13136
|
+
|
|
13137
|
+
/* A footnote may not set its column's width: the track does, and the note
|
|
13138
|
+
wraps inside it, balanced so the wrap reads as deliberate. */
|
|
13139
|
+
.crewlet-fact-line__note,
|
|
13140
|
+
.crewlet-fact-line__set-by {
|
|
13141
|
+
font-size: var(--font-size-2xs);
|
|
13142
|
+
color: var(--color-text-tertiary);
|
|
13143
|
+
text-wrap: balance;
|
|
13144
|
+
}
|
|
13145
|
+
|
|
13146
|
+
/* ── the by-line ───────────────────────────────────────────────────────── */
|
|
13147
|
+
|
|
13148
|
+
/* The word and its arrow are one atomic box, so the arrow never takes a line
|
|
13149
|
+
of its own. */
|
|
13150
|
+
.crewlet-set-by__turn {
|
|
13151
|
+
display: inline-flex;
|
|
13152
|
+
align-items: center;
|
|
13153
|
+
gap: 0.25em;
|
|
13154
|
+
}
|
|
13155
|
+
|
|
13156
|
+
|
|
12758
13157
|
/* OrgLabel-R5KY7C3W.css */
|
|
12759
13158
|
/*
|
|
12760
13159
|
* What a node of an org chart and a row of an org table both say
|
|
@@ -14482,6 +14881,28 @@ svg.crewlet-datetime__chevron {
|
|
|
14482
14881
|
}
|
|
14483
14882
|
|
|
14484
14883
|
|
|
14884
|
+
/* QrCode-JWJTWMU5.css */
|
|
14885
|
+
/*
|
|
14886
|
+
* A QR code on its own plate.
|
|
14887
|
+
*
|
|
14888
|
+
* A FIXED BOX, because a camera needs modules of a readable size: at 208px a
|
|
14889
|
+
* second factor's code (a version 7 symbol and its quiet zone) draws each
|
|
14890
|
+
* module at about 4.3px. A consumer that needs another size sets the variable.
|
|
14891
|
+
*
|
|
14892
|
+
* ITS INKS ARE KEPT UNDER FORCED COLOURS. A high-contrast mode repaints fills
|
|
14893
|
+
* to system colours, and a plate repainted dark is a code no scanner reads.
|
|
14894
|
+
*/
|
|
14895
|
+
.crewlet-qr-code {
|
|
14896
|
+
--crewlet-qr-code-size: 208px;
|
|
14897
|
+
display: block;
|
|
14898
|
+
flex: none;
|
|
14899
|
+
width: var(--crewlet-qr-code-size);
|
|
14900
|
+
height: var(--crewlet-qr-code-size);
|
|
14901
|
+
border-radius: var(--radius-sm);
|
|
14902
|
+
forced-color-adjust: none;
|
|
14903
|
+
}
|
|
14904
|
+
|
|
14905
|
+
|
|
14485
14906
|
/* ReadingPane-5UOLPWY5.css */
|
|
14486
14907
|
/*
|
|
14487
14908
|
* One item read in full, in one column.
|
|
@@ -18969,7 +19390,7 @@ b.crewlet-switcher__match {
|
|
|
18969
19390
|
}
|
|
18970
19391
|
|
|
18971
19392
|
|
|
18972
|
-
/* Text-
|
|
19393
|
+
/* Text-S3Q4O3IG.css */
|
|
18973
19394
|
/*
|
|
18974
19395
|
* The type registers, one rule each.
|
|
18975
19396
|
*
|
|
@@ -19021,6 +19442,17 @@ b.crewlet-switcher__match {
|
|
|
19021
19442
|
color: var(--color-text-primary);
|
|
19022
19443
|
}
|
|
19023
19444
|
|
|
19445
|
+
/*
|
|
19446
|
+
* The register around it: nothing is set, so the run keeps its sentence's
|
|
19447
|
+
* size, weight, tracking and ink, and only a modifier (mono, numeric) or a
|
|
19448
|
+
* tone changes it.
|
|
19449
|
+
*/
|
|
19450
|
+
.crewlet-text--inherit {
|
|
19451
|
+
font-size: inherit;
|
|
19452
|
+
line-height: inherit;
|
|
19453
|
+
color: inherit;
|
|
19454
|
+
}
|
|
19455
|
+
|
|
19024
19456
|
.crewlet-text--body {
|
|
19025
19457
|
font-size: var(--font-size-sm);
|
|
19026
19458
|
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;
|