rei-kit 2.7.0 → 2.8.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 +4 -4
- package/dist/BaseSkeleton-B-oo7JKE.js +43 -0
- package/dist/BaseSkeleton-B-oo7JKE.js.map +1 -0
- package/dist/{GoogleButton-nIRz9G8s.js → GoogleButton-DVro7xZH.js} +3 -33
- package/dist/GoogleButton-DVro7xZH.js.map +1 -0
- package/dist/app.js +2 -2
- package/dist/components/BaseListbox.vue.d.ts +38 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +287 -195
- package/dist/index.js.map +1 -1
- package/dist/{inert-B441LoCD.js → inert-TJG_g0d6.js} +32 -2
- package/dist/inert-TJG_g0d6.js.map +1 -0
- package/dist/styles.css +273 -28
- package/dist/web/CommandMenu.vue.d.ts +50 -0
- package/dist/web/DataTable.vue.d.ts +61 -0
- package/dist/web/index.d.ts +13 -0
- package/dist/web.js +438 -51
- package/dist/web.js.map +1 -1
- package/package.json +2 -2
- package/dist/GoogleButton-nIRz9G8s.js.map +0 -1
- package/dist/inert-B441LoCD.js.map +0 -1
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
//#region src/utils/sheet-root.ts
|
|
2
|
+
/** The node every sheet teleports into. */
|
|
3
|
+
var SHEET_ROOT_ID = "sheet-root";
|
|
4
|
+
/**
|
|
5
|
+
* Returns the sheet root, creating it if the page has none.
|
|
6
|
+
*
|
|
7
|
+
* `BaseSheet` teleports out of the app's tree so the app behind it can be
|
|
8
|
+
* marked `inert` — a sheet inside the element it is disabling would disable
|
|
9
|
+
* itself. That means it needs a mount point outside `#app`.
|
|
10
|
+
*
|
|
11
|
+
* It used to need the consuming app to put `<div id="sheet-root">` in its
|
|
12
|
+
* `index.html`, and nothing said so. A page without it got a sheet that opened,
|
|
13
|
+
* blocked the page, and rendered nothing: Vue warns to the console about a
|
|
14
|
+
* missing teleport target and carries on, so the build is green, the types are
|
|
15
|
+
* fine, and the screen is wrong. The kit's own showcase had exactly that bug,
|
|
16
|
+
* which is how it was found.
|
|
17
|
+
*
|
|
18
|
+
* So the node is made on demand. An app that already declares one keeps it —
|
|
19
|
+
* this only fills a gap, it never replaces.
|
|
20
|
+
*/
|
|
21
|
+
function ensureSheetRoot() {
|
|
22
|
+
const selector = `#${SHEET_ROOT_ID}`;
|
|
23
|
+
if (typeof document === "undefined") return selector;
|
|
24
|
+
if (document.getElementById("sheet-root")) return selector;
|
|
25
|
+
const root = document.createElement("div");
|
|
26
|
+
root.id = SHEET_ROOT_ID;
|
|
27
|
+
document.body.appendChild(root);
|
|
28
|
+
return selector;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
1
31
|
//#region src/utils/inert.ts
|
|
2
32
|
/**
|
|
3
33
|
* How many open layers hold each element inert. An element set inert by the
|
|
@@ -48,6 +78,6 @@ function inertOutside(keep) {
|
|
|
48
78
|
};
|
|
49
79
|
}
|
|
50
80
|
//#endregion
|
|
51
|
-
export { inertOutside as t };
|
|
81
|
+
export { SHEET_ROOT_ID as n, ensureSheetRoot as r, inertOutside as t };
|
|
52
82
|
|
|
53
|
-
//# sourceMappingURL=inert-
|
|
83
|
+
//# sourceMappingURL=inert-TJG_g0d6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inert-TJG_g0d6.js","names":[],"sources":["../src/utils/sheet-root.ts","../src/utils/inert.ts"],"sourcesContent":["/** The node every sheet teleports into. */\nexport const SHEET_ROOT_ID = 'sheet-root'\n\n/**\n * Returns the sheet root, creating it if the page has none.\n *\n * `BaseSheet` teleports out of the app's tree so the app behind it can be\n * marked `inert` — a sheet inside the element it is disabling would disable\n * itself. That means it needs a mount point outside `#app`.\n *\n * It used to need the consuming app to put `<div id=\"sheet-root\">` in its\n * `index.html`, and nothing said so. A page without it got a sheet that opened,\n * blocked the page, and rendered nothing: Vue warns to the console about a\n * missing teleport target and carries on, so the build is green, the types are\n * fine, and the screen is wrong. The kit's own showcase had exactly that bug,\n * which is how it was found.\n *\n * So the node is made on demand. An app that already declares one keeps it —\n * this only fills a gap, it never replaces.\n */\nexport function ensureSheetRoot(): string {\n const selector = `#${SHEET_ROOT_ID}`\n\n // Server-rendered: there is no document, and Teleport is skipped anyway.\n if (typeof document === 'undefined') return selector\n if (document.getElementById(SHEET_ROOT_ID)) return selector\n\n const root = document.createElement('div')\n root.id = SHEET_ROOT_ID\n document.body.appendChild(root)\n\n return selector\n}\n","/**\n * How many open layers hold each element inert. An element set inert by the\n * app itself is never in here, so releasing never undoes the app's own choice.\n */\nconst holds = new Map<Element, number>()\n\n/**\n * Takes everything on the page except the branch holding `keep` out of tab\n * order and pointer events, and returns the function that gives it back.\n *\n * `inert` is a real focus trap without keydown bookkeeping, and the only one\n * that also stops a screen reader's virtual cursor. It used to be applied to\n * `document.getElementById('app')` — the id Vite's template happens to use —\n * so an app mounted on `#root` got a dialog whose background was still\n * reachable with Tab, and nothing said so. Working from `<body>`'s children\n * instead holds whatever the app is mounted on, and anything else teleported\n * there too.\n *\n * Counted per element, so a sheet opened over a sheet, or a tour over either,\n * does not hand the page back when the inner one closes.\n */\nexport function inertOutside(keep: Element): () => void {\n if (typeof document === 'undefined') return () => {}\n\n const taken: Element[] = []\n\n for (const element of Array.from(document.body.children)) {\n if (element.contains(keep)) continue\n\n const count = holds.get(element)\n if (count === undefined) {\n if (element.hasAttribute('inert')) continue\n element.setAttribute('inert', '')\n }\n holds.set(element, (count ?? 0) + 1)\n taken.push(element)\n }\n\n let released = false\n\n return () => {\n if (released) return\n released = true\n\n for (const element of taken) {\n const count = (holds.get(element) ?? 1) - 1\n if (count > 0) {\n holds.set(element, count)\n continue\n }\n holds.delete(element)\n element.removeAttribute('inert')\n }\n }\n}\n"],"mappings":";;AACA,IAAa,gBAAgB;;;;;;;;;;;;;;;;;;AAmB7B,SAAgB,kBAA0B;CACxC,MAAM,WAAW,IAAI;CAGrB,IAAI,OAAO,aAAa,aAAa,OAAO;CAC5C,IAAI,SAAS,eAAA,YAA4B,GAAG,OAAO;CAEnD,MAAM,OAAO,SAAS,cAAc,KAAK;CACzC,KAAK,KAAK;CACV,SAAS,KAAK,YAAY,IAAI;CAE9B,OAAO;AACT;;;;;;;AC5BA,IAAM,wBAAQ,IAAI,IAAqB;;;;;;;;;;;;;;;;AAiBvC,SAAgB,aAAa,MAA2B;CACtD,IAAI,OAAO,aAAa,aAAa,aAAa,CAAC;CAEnD,MAAM,QAAmB,CAAC;CAE1B,KAAK,MAAM,WAAW,MAAM,KAAK,SAAS,KAAK,QAAQ,GAAG;EACxD,IAAI,QAAQ,SAAS,IAAI,GAAG;EAE5B,MAAM,QAAQ,MAAM,IAAI,OAAO;EAC/B,IAAI,UAAU,KAAA,GAAW;GACvB,IAAI,QAAQ,aAAa,OAAO,GAAG;GACnC,QAAQ,aAAa,SAAS,EAAE;EAClC;EACA,MAAM,IAAI,UAAU,SAAS,KAAK,CAAC;EACnC,MAAM,KAAK,OAAO;CACpB;CAEA,IAAI,WAAW;CAEf,aAAa;EACX,IAAI,UAAU;EACd,WAAW;EAEX,KAAK,MAAM,WAAW,OAAO;GAC3B,MAAM,SAAS,MAAM,IAAI,OAAO,KAAK,KAAK;GAC1C,IAAI,QAAQ,GAAG;IACb,MAAM,IAAI,SAAS,KAAK;IACxB;GACF;GACA,MAAM,OAAO,OAAO;GACpB,QAAQ,gBAAgB,OAAO;EACjC;CACF;AACF"}
|
package/dist/styles.css
CHANGED
|
@@ -218,6 +218,34 @@
|
|
|
218
218
|
opacity: 0;
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
+
.rk-skeleton[data-v-37327de6] {
|
|
222
|
+
display: block;
|
|
223
|
+
flex-shrink: 0;
|
|
224
|
+
background: var(--color-muted);
|
|
225
|
+
animation: rk-skeleton-pulse-37327de6 1.6s ease-in-out infinite;
|
|
226
|
+
}
|
|
227
|
+
.rk-skeleton.is-block[data-v-37327de6] {
|
|
228
|
+
border-radius: var(--radius-cell);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/* A line of text, rounded like one and a little short of its box. */
|
|
232
|
+
.rk-skeleton.is-text[data-v-37327de6] {
|
|
233
|
+
border-radius: 9999px;
|
|
234
|
+
}
|
|
235
|
+
.rk-skeleton.is-circle[data-v-37327de6] {
|
|
236
|
+
border-radius: 9999px;
|
|
237
|
+
}
|
|
238
|
+
@keyframes rk-skeleton-pulse-37327de6 {
|
|
239
|
+
50% {
|
|
240
|
+
opacity: 0.55;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
@media (prefers-reduced-motion: reduce) {
|
|
244
|
+
.rk-skeleton[data-v-37327de6] {
|
|
245
|
+
animation: none;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
221
249
|
.rk-avatar[data-v-47586bec] {
|
|
222
250
|
display: grid;
|
|
223
251
|
place-items: center;
|
|
@@ -1089,6 +1117,57 @@ to {
|
|
|
1089
1117
|
color: var(--color-ink-soft);
|
|
1090
1118
|
}
|
|
1091
1119
|
|
|
1120
|
+
.rk-listbox[data-v-95e230a5] {
|
|
1121
|
+
overflow-y: auto;
|
|
1122
|
+
border-radius: var(--radius-card);
|
|
1123
|
+
padding: 0.25rem;
|
|
1124
|
+
}
|
|
1125
|
+
.rk-listbox[data-v-95e230a5]:focus-visible {
|
|
1126
|
+
outline: 2px solid var(--color-primary);
|
|
1127
|
+
outline-offset: 1px;
|
|
1128
|
+
}
|
|
1129
|
+
.rk-listbox-option[data-v-95e230a5] {
|
|
1130
|
+
display: flex;
|
|
1131
|
+
cursor: pointer;
|
|
1132
|
+
align-items: center;
|
|
1133
|
+
gap: 0.625rem;
|
|
1134
|
+
border-radius: var(--radius-cell);
|
|
1135
|
+
padding: 0.5rem 0.625rem;
|
|
1136
|
+
font-size: 0.875rem;
|
|
1137
|
+
color: var(--color-ink);
|
|
1138
|
+
}
|
|
1139
|
+
.rk-listbox-option.is-active[data-v-95e230a5] {
|
|
1140
|
+
background: var(--color-muted);
|
|
1141
|
+
}
|
|
1142
|
+
.rk-listbox-option.is-chosen[data-v-95e230a5] {
|
|
1143
|
+
color: var(--color-primary);
|
|
1144
|
+
font-weight: 500;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
/* Both at once: the current option and the chosen one are different things,
|
|
1148
|
+
and a list that shows only one of them loses the reader's place. */
|
|
1149
|
+
.rk-listbox-option.is-chosen.is-active[data-v-95e230a5] {
|
|
1150
|
+
background: color-mix(in oklab, var(--color-primary) 12%, transparent);
|
|
1151
|
+
}
|
|
1152
|
+
.rk-listbox-option.is-disabled[data-v-95e230a5] {
|
|
1153
|
+
cursor: not-allowed;
|
|
1154
|
+
opacity: 0.45;
|
|
1155
|
+
}
|
|
1156
|
+
.rk-listbox-label[data-v-95e230a5] {
|
|
1157
|
+
display: block;
|
|
1158
|
+
overflow: hidden;
|
|
1159
|
+
text-overflow: ellipsis;
|
|
1160
|
+
white-space: nowrap;
|
|
1161
|
+
}
|
|
1162
|
+
.rk-listbox-description[data-v-95e230a5] {
|
|
1163
|
+
display: block;
|
|
1164
|
+
font-size: 0.75rem;
|
|
1165
|
+
color: var(--color-ink-soft);
|
|
1166
|
+
}
|
|
1167
|
+
.rk-listbox-empty[data-v-95e230a5] {
|
|
1168
|
+
padding: 1rem;
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1092
1171
|
.rk-link[data-v-88581007] {
|
|
1093
1172
|
display: inline;
|
|
1094
1173
|
border-radius: var(--radius-cell);
|
|
@@ -1221,34 +1300,6 @@ to {
|
|
|
1221
1300
|
color: var(--color-ink-soft);
|
|
1222
1301
|
}
|
|
1223
1302
|
|
|
1224
|
-
.rk-skeleton[data-v-37327de6] {
|
|
1225
|
-
display: block;
|
|
1226
|
-
flex-shrink: 0;
|
|
1227
|
-
background: var(--color-muted);
|
|
1228
|
-
animation: rk-skeleton-pulse-37327de6 1.6s ease-in-out infinite;
|
|
1229
|
-
}
|
|
1230
|
-
.rk-skeleton.is-block[data-v-37327de6] {
|
|
1231
|
-
border-radius: var(--radius-cell);
|
|
1232
|
-
}
|
|
1233
|
-
|
|
1234
|
-
/* A line of text, rounded like one and a little short of its box. */
|
|
1235
|
-
.rk-skeleton.is-text[data-v-37327de6] {
|
|
1236
|
-
border-radius: 9999px;
|
|
1237
|
-
}
|
|
1238
|
-
.rk-skeleton.is-circle[data-v-37327de6] {
|
|
1239
|
-
border-radius: 9999px;
|
|
1240
|
-
}
|
|
1241
|
-
@keyframes rk-skeleton-pulse-37327de6 {
|
|
1242
|
-
50% {
|
|
1243
|
-
opacity: 0.55;
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
@media (prefers-reduced-motion: reduce) {
|
|
1247
|
-
.rk-skeleton[data-v-37327de6] {
|
|
1248
|
-
animation: none;
|
|
1249
|
-
}
|
|
1250
|
-
}
|
|
1251
|
-
|
|
1252
1303
|
.rk-copy[data-v-c481e140] {
|
|
1253
1304
|
display: inline-flex;
|
|
1254
1305
|
height: 2.25rem;
|
|
@@ -2425,6 +2476,200 @@ to {
|
|
|
2425
2476
|
color: var(--color-ink-soft);
|
|
2426
2477
|
}
|
|
2427
2478
|
|
|
2479
|
+
.rk-command[data-v-cce1dd03] {
|
|
2480
|
+
position: fixed;
|
|
2481
|
+
inset: 0;
|
|
2482
|
+
z-index: 90;
|
|
2483
|
+
display: flex;
|
|
2484
|
+
justify-content: center;
|
|
2485
|
+
padding: 1rem;
|
|
2486
|
+
/* Near the top, not centred: the eye is already up there, and the list
|
|
2487
|
+
grows downwards into space rather than pushing itself off both edges. */
|
|
2488
|
+
padding-top: min(12vh, 6rem);
|
|
2489
|
+
}
|
|
2490
|
+
.rk-command-scrim[data-v-cce1dd03] {
|
|
2491
|
+
position: absolute;
|
|
2492
|
+
inset: 0;
|
|
2493
|
+
background: color-mix(in oklab, var(--color-ink) 45%, transparent);
|
|
2494
|
+
backdrop-filter: blur(2px);
|
|
2495
|
+
}
|
|
2496
|
+
.rk-command-panel[data-v-cce1dd03] {
|
|
2497
|
+
position: relative;
|
|
2498
|
+
display: flex;
|
|
2499
|
+
width: 100%;
|
|
2500
|
+
max-width: 34rem;
|
|
2501
|
+
max-height: min(28rem, 70vh);
|
|
2502
|
+
flex-direction: column;
|
|
2503
|
+
overflow: hidden;
|
|
2504
|
+
border-radius: var(--radius-card);
|
|
2505
|
+
}
|
|
2506
|
+
.rk-command-field[data-v-cce1dd03] {
|
|
2507
|
+
display: flex;
|
|
2508
|
+
align-items: center;
|
|
2509
|
+
gap: 0.625rem;
|
|
2510
|
+
border-bottom: 1px solid var(--surface-border-color);
|
|
2511
|
+
padding: 0.875rem 1rem;
|
|
2512
|
+
}
|
|
2513
|
+
.rk-command-input[data-v-cce1dd03] {
|
|
2514
|
+
min-width: 0;
|
|
2515
|
+
flex: 1;
|
|
2516
|
+
background: transparent;
|
|
2517
|
+
font-size: 1rem;
|
|
2518
|
+
color: var(--color-ink);
|
|
2519
|
+
outline: none;
|
|
2520
|
+
}
|
|
2521
|
+
|
|
2522
|
+
/* The field takes focus the moment this opens, so a full ring around it
|
|
2523
|
+
would be on the whole time. The rule under it turns instead: enough to
|
|
2524
|
+
say where the keyboard is, quiet enough to live with. */
|
|
2525
|
+
.rk-command-field[data-v-cce1dd03]:has(.rk-command-input:focus-visible) {
|
|
2526
|
+
border-bottom-color: var(--color-primary);
|
|
2527
|
+
box-shadow: inset 0 -1px 0 var(--color-primary);
|
|
2528
|
+
}
|
|
2529
|
+
.rk-command-list[data-v-cce1dd03] {
|
|
2530
|
+
overflow-y: auto;
|
|
2531
|
+
padding: 0.375rem;
|
|
2532
|
+
}
|
|
2533
|
+
.rk-command-group[data-v-cce1dd03] {
|
|
2534
|
+
padding: 0.5rem 0.625rem 0.25rem;
|
|
2535
|
+
font-size: 0.6875rem;
|
|
2536
|
+
font-weight: 600;
|
|
2537
|
+
letter-spacing: 0.04em;
|
|
2538
|
+
text-transform: uppercase;
|
|
2539
|
+
color: var(--color-ink-soft);
|
|
2540
|
+
}
|
|
2541
|
+
.rk-command-item[data-v-cce1dd03] {
|
|
2542
|
+
display: flex;
|
|
2543
|
+
cursor: pointer;
|
|
2544
|
+
align-items: center;
|
|
2545
|
+
gap: 0.625rem;
|
|
2546
|
+
border-radius: var(--radius-cell);
|
|
2547
|
+
padding: 0.5rem 0.625rem;
|
|
2548
|
+
font-size: 0.875rem;
|
|
2549
|
+
color: var(--color-ink);
|
|
2550
|
+
}
|
|
2551
|
+
.rk-command-item.is-active[data-v-cce1dd03] {
|
|
2552
|
+
background: var(--color-muted);
|
|
2553
|
+
}
|
|
2554
|
+
.rk-command-hint[data-v-cce1dd03] {
|
|
2555
|
+
margin-left: auto;
|
|
2556
|
+
flex-shrink: 0;
|
|
2557
|
+
font-size: 0.75rem;
|
|
2558
|
+
color: var(--color-ink-soft);
|
|
2559
|
+
}
|
|
2560
|
+
.rk-command-empty[data-v-cce1dd03] {
|
|
2561
|
+
padding: 1.5rem 0.625rem;
|
|
2562
|
+
text-align: center;
|
|
2563
|
+
font-size: 0.875rem;
|
|
2564
|
+
color: var(--color-ink-soft);
|
|
2565
|
+
}
|
|
2566
|
+
.rk-command-enter-active[data-v-cce1dd03],
|
|
2567
|
+
.rk-command-leave-active[data-v-cce1dd03] {
|
|
2568
|
+
transition: opacity var(--duration-fast) var(--ease-standard);
|
|
2569
|
+
}
|
|
2570
|
+
.rk-command-enter-active .rk-command-panel[data-v-cce1dd03],
|
|
2571
|
+
.rk-command-leave-active .rk-command-panel[data-v-cce1dd03] {
|
|
2572
|
+
transition: transform var(--duration-fast) var(--ease-standard);
|
|
2573
|
+
}
|
|
2574
|
+
.rk-command-enter-from[data-v-cce1dd03],
|
|
2575
|
+
.rk-command-leave-to[data-v-cce1dd03] {
|
|
2576
|
+
opacity: 0;
|
|
2577
|
+
}
|
|
2578
|
+
.rk-command-enter-from .rk-command-panel[data-v-cce1dd03],
|
|
2579
|
+
.rk-command-leave-to .rk-command-panel[data-v-cce1dd03] {
|
|
2580
|
+
transform: translateY(-0.5rem) scale(0.98);
|
|
2581
|
+
}
|
|
2582
|
+
|
|
2583
|
+
/* The scroller is focusable: a region only a drag can reach is a region a
|
|
2584
|
+
keyboard cannot read at all. */
|
|
2585
|
+
.rk-data-scroll[data-v-5920cac0] {
|
|
2586
|
+
overflow-x: auto;
|
|
2587
|
+
border-radius: var(--radius-card);
|
|
2588
|
+
}
|
|
2589
|
+
.rk-data-scroll[data-v-5920cac0]:focus-visible {
|
|
2590
|
+
outline: 2px solid var(--color-primary);
|
|
2591
|
+
outline-offset: 2px;
|
|
2592
|
+
}
|
|
2593
|
+
.rk-data[data-v-5920cac0] {
|
|
2594
|
+
width: 100%;
|
|
2595
|
+
border-collapse: collapse;
|
|
2596
|
+
font-size: 0.875rem;
|
|
2597
|
+
}
|
|
2598
|
+
.rk-data-caption[data-v-5920cac0] {
|
|
2599
|
+
padding-bottom: 0.5rem;
|
|
2600
|
+
text-align: left;
|
|
2601
|
+
font-size: 0.8125rem;
|
|
2602
|
+
color: var(--color-ink-soft);
|
|
2603
|
+
}
|
|
2604
|
+
.rk-data-caption-hidden[data-v-5920cac0] {
|
|
2605
|
+
position: absolute;
|
|
2606
|
+
width: 1px;
|
|
2607
|
+
height: 1px;
|
|
2608
|
+
overflow: hidden;
|
|
2609
|
+
clip-path: inset(50%);
|
|
2610
|
+
white-space: nowrap;
|
|
2611
|
+
}
|
|
2612
|
+
.rk-data th[data-v-5920cac0] {
|
|
2613
|
+
border-bottom: 1px solid var(--color-hair);
|
|
2614
|
+
padding: 0.625rem 0.75rem;
|
|
2615
|
+
text-align: left;
|
|
2616
|
+
font-size: 0.75rem;
|
|
2617
|
+
font-weight: 600;
|
|
2618
|
+
letter-spacing: 0.02em;
|
|
2619
|
+
color: var(--color-ink-soft);
|
|
2620
|
+
white-space: nowrap;
|
|
2621
|
+
}
|
|
2622
|
+
.rk-data.is-sticky thead th[data-v-5920cac0] {
|
|
2623
|
+
position: sticky;
|
|
2624
|
+
top: 0;
|
|
2625
|
+
z-index: 1;
|
|
2626
|
+
background: var(--color-surface);
|
|
2627
|
+
}
|
|
2628
|
+
.rk-data td[data-v-5920cac0] {
|
|
2629
|
+
border-bottom: 1px solid color-mix(in oklab, var(--color-hair) 60%, transparent);
|
|
2630
|
+
padding: 0.625rem 0.75rem;
|
|
2631
|
+
color: var(--color-ink);
|
|
2632
|
+
vertical-align: middle;
|
|
2633
|
+
}
|
|
2634
|
+
.rk-data tbody tr:last-child td[data-v-5920cac0] {
|
|
2635
|
+
border-bottom: 0;
|
|
2636
|
+
}
|
|
2637
|
+
.rk-data tbody tr.is-chosen td[data-v-5920cac0] {
|
|
2638
|
+
background: color-mix(in oklab, var(--color-primary) 8%, transparent);
|
|
2639
|
+
}
|
|
2640
|
+
.is-end[data-v-5920cac0] {
|
|
2641
|
+
text-align: right;
|
|
2642
|
+
font-variant-numeric: tabular-nums;
|
|
2643
|
+
}
|
|
2644
|
+
.is-nowrap[data-v-5920cac0] {
|
|
2645
|
+
white-space: nowrap;
|
|
2646
|
+
}
|
|
2647
|
+
.rk-data-sort[data-v-5920cac0] {
|
|
2648
|
+
display: inline-flex;
|
|
2649
|
+
align-items: center;
|
|
2650
|
+
gap: 0.25rem;
|
|
2651
|
+
border-radius: var(--radius-cell);
|
|
2652
|
+
color: inherit;
|
|
2653
|
+
transition: color var(--duration-fast) var(--ease-standard);
|
|
2654
|
+
}
|
|
2655
|
+
.rk-data-sort[data-v-5920cac0]:hover {
|
|
2656
|
+
color: var(--color-ink);
|
|
2657
|
+
}
|
|
2658
|
+
.rk-data-pick[data-v-5920cac0] {
|
|
2659
|
+
width: 2.75rem;
|
|
2660
|
+
padding-right: 0;
|
|
2661
|
+
}
|
|
2662
|
+
.rk-data-box[data-v-5920cac0] {
|
|
2663
|
+
width: 1rem;
|
|
2664
|
+
height: 1rem;
|
|
2665
|
+
accent-color: var(--color-primary);
|
|
2666
|
+
}
|
|
2667
|
+
.rk-data-empty[data-v-5920cac0] {
|
|
2668
|
+
padding: 2rem 0.75rem;
|
|
2669
|
+
text-align: center;
|
|
2670
|
+
color: var(--color-ink-soft);
|
|
2671
|
+
}
|
|
2672
|
+
|
|
2428
2673
|
.rk-tabs[data-v-8135ecab] {
|
|
2429
2674
|
display: flex;
|
|
2430
2675
|
align-items: center;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Component } from 'vue';
|
|
2
|
+
export interface CommandItem<Id extends string> {
|
|
3
|
+
id: Id;
|
|
4
|
+
/** Already translated. */
|
|
5
|
+
label: string;
|
|
6
|
+
/** A line under it, or a shortcut to show on the right. */
|
|
7
|
+
hint?: string | undefined;
|
|
8
|
+
icon?: Component | undefined;
|
|
9
|
+
/** Extra words that should find it — synonyms, the English name. */
|
|
10
|
+
keywords?: readonly string[] | undefined;
|
|
11
|
+
}
|
|
12
|
+
export interface CommandGroup<Id extends string> {
|
|
13
|
+
/** Already translated. Omitted, the items sit without a heading. */
|
|
14
|
+
label?: string | undefined;
|
|
15
|
+
items: readonly CommandItem<Id>[];
|
|
16
|
+
}
|
|
17
|
+
declare const __VLS_export: <Id extends string>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
18
|
+
props: import('vue').PublicProps & __VLS_PrettifyLocal<({
|
|
19
|
+
groups: readonly CommandGroup<Id>[];
|
|
20
|
+
/** The dialog's accessible name, e.g. "Commands". */
|
|
21
|
+
label: string;
|
|
22
|
+
/** The field's placeholder, e.g. "Type a command or search". */
|
|
23
|
+
placeholder: string;
|
|
24
|
+
/** Shown when nothing matches, e.g. "Nothing found". */
|
|
25
|
+
emptyLabel: string;
|
|
26
|
+
/** The letter that opens it with ⌘ or Ctrl. Unset, the app opens it itself. */
|
|
27
|
+
hotkey?: string | undefined;
|
|
28
|
+
} & {
|
|
29
|
+
/** Open or closed, with `v-model`. */
|
|
30
|
+
modelValue?: boolean;
|
|
31
|
+
}) & {
|
|
32
|
+
onSelect?: (id: Id) => any;
|
|
33
|
+
"onUpdate:modelValue"?: (value: boolean) => any;
|
|
34
|
+
}> & (typeof globalThis extends {
|
|
35
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
36
|
+
} ? P : {});
|
|
37
|
+
expose: (exposed: {}) => void;
|
|
38
|
+
attrs: any;
|
|
39
|
+
slots: {};
|
|
40
|
+
emit: ((evt: "select", id: Id) => void) & ((event: "update:modelValue", value: boolean) => void);
|
|
41
|
+
}>) => import('vue').VNode & {
|
|
42
|
+
__ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
|
|
43
|
+
};
|
|
44
|
+
declare const _default: typeof __VLS_export;
|
|
45
|
+
export default _default;
|
|
46
|
+
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
47
|
+
[K in keyof T]: T[K];
|
|
48
|
+
} : {
|
|
49
|
+
[K in keyof T as K]: T[K];
|
|
50
|
+
}) & {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Column } from '../components/BaseTable.vue';
|
|
2
|
+
export interface DataColumn<Row> extends Column<Row> {
|
|
3
|
+
/** Adds a button to the header that sorts by this column. */
|
|
4
|
+
sortable?: boolean | undefined;
|
|
5
|
+
}
|
|
6
|
+
export interface TableSort<Row> {
|
|
7
|
+
key: string & keyof Row;
|
|
8
|
+
direction: 'asc' | 'desc';
|
|
9
|
+
}
|
|
10
|
+
declare const __VLS_export: <Row extends Record<string, unknown>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
11
|
+
props: import('vue').PublicProps & __VLS_PrettifyLocal<({
|
|
12
|
+
columns: readonly DataColumn<Row>[];
|
|
13
|
+
rows: readonly Row[];
|
|
14
|
+
/** What this table is. Required — an unnamed table is a box of numbers. */
|
|
15
|
+
caption: string;
|
|
16
|
+
captionHidden?: boolean | undefined;
|
|
17
|
+
/** Which field identifies a row. Required for selection. */
|
|
18
|
+
rowKey?: (string & keyof Row) | undefined;
|
|
19
|
+
/** Given with `rowKey`, the table grows a checkbox column. Names the header one. */
|
|
20
|
+
selectAllLabel?: string | undefined;
|
|
21
|
+
/** Names each row's checkbox from the row: `(row) => \`Select ${row.name}\``. */
|
|
22
|
+
rowLabel?: ((row: Row) => string) | undefined;
|
|
23
|
+
/** Report the sort instead of doing it — for a server that pages the data. */
|
|
24
|
+
manualSort?: boolean | undefined;
|
|
25
|
+
/** Draws skeleton rows instead of the body. */
|
|
26
|
+
loading?: boolean | undefined;
|
|
27
|
+
loadingRows?: number | undefined;
|
|
28
|
+
/** Keeps the header on screen while the body scrolls under it. */
|
|
29
|
+
stickyHeader?: boolean | undefined;
|
|
30
|
+
} & {
|
|
31
|
+
/** Which column is sorted, and which way. `v-model:sort`. */
|
|
32
|
+
sort?: TableSort<Row> | undefined;
|
|
33
|
+
/** The chosen rows' keys. `v-model:selected`. */
|
|
34
|
+
selected?: string[];
|
|
35
|
+
}) & {
|
|
36
|
+
"onUpdate:sort"?: (value: TableSort<Row> | undefined) => any;
|
|
37
|
+
"onUpdate:selected"?: (value: string[]) => any;
|
|
38
|
+
}> & (typeof globalThis extends {
|
|
39
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
40
|
+
} ? P : {});
|
|
41
|
+
expose: (exposed: {}) => void;
|
|
42
|
+
attrs: any;
|
|
43
|
+
slots: {
|
|
44
|
+
[key: string]: (props: {
|
|
45
|
+
row: Row;
|
|
46
|
+
value: unknown;
|
|
47
|
+
}) => unknown;
|
|
48
|
+
/** Shown instead of the body when there are no rows. */
|
|
49
|
+
empty?: () => unknown;
|
|
50
|
+
};
|
|
51
|
+
emit: ((event: "update:sort", value: TableSort<Row> | undefined) => void) & ((event: "update:selected", value: string[]) => void);
|
|
52
|
+
}>) => import('vue').VNode & {
|
|
53
|
+
__ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
|
|
54
|
+
};
|
|
55
|
+
declare const _default: typeof __VLS_export;
|
|
56
|
+
export default _default;
|
|
57
|
+
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
58
|
+
[K in keyof T]: T[K];
|
|
59
|
+
} : {
|
|
60
|
+
[K in keyof T as K]: T[K];
|
|
61
|
+
}) & {};
|
package/dist/web/index.d.ts
CHANGED
|
@@ -34,6 +34,19 @@ export { default as BaseDisclosure } from './BaseDisclosure.vue';
|
|
|
34
34
|
*/
|
|
35
35
|
export { default as BaseModal } from './BaseModal.vue';
|
|
36
36
|
export { default as BasePagination } from './BasePagination.vue';
|
|
37
|
+
/**
|
|
38
|
+
* Everything the app can do, behind ⌘K. In the wide entry because it is a
|
|
39
|
+
* keyboard shortcut first: a phone has no ⌘, and an app that is only ever a
|
|
40
|
+
* phone should not download it.
|
|
41
|
+
*/
|
|
42
|
+
export { default as CommandMenu } from './CommandMenu.vue';
|
|
43
|
+
export type { CommandGroup, CommandItem } from './CommandMenu.vue';
|
|
44
|
+
/**
|
|
45
|
+
* `BaseTable` with a sort, a selection and a loading state. Wide because a
|
|
46
|
+
* table of nine columns is not a thing a phone shows; a phone shows a list.
|
|
47
|
+
*/
|
|
48
|
+
export { default as DataTable } from './DataTable.vue';
|
|
49
|
+
export type { DataColumn, TableSort } from './DataTable.vue';
|
|
37
50
|
export { default as BaseTabs } from './BaseTabs.vue';
|
|
38
51
|
export type { TabPanel } from './BaseTabs.vue';
|
|
39
52
|
export { default as BaseTooltip } from './BaseTooltip.vue';
|