@wssto2/vue-core 0.1.0 → 0.2.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 +20 -9
- package/dist/{AdaptivePageShell.vue_vue_type_script_setup_true_lang-CKghARkW.js → AdaptivePageShell.vue_vue_type_script_setup_true_lang-CeKK8_g5.js} +2 -2
- package/dist/{AlertDialog.vue_vue_type_script_setup_true_lang-BZb4qKXo.js → AlertDialog.vue_vue_type_script_setup_true_lang-e4hzkzg3.js} +1 -1
- package/dist/{AsyncSection.vue_vue_type_script_setup_true_lang-B82bl36A.js → AsyncSection.vue_vue_type_script_setup_true_lang-CWLB3xsR.js} +1 -1
- package/dist/Badge.vue_vue_type_script_setup_true_lang-DJyZc0C7.js +51 -0
- package/dist/Button.vue_vue_type_script_setup_true_lang-B1eZgLae.js +182 -0
- package/dist/CountryFlag.vue_vue_type_script_setup_true_lang-Kry_vPPZ.js +299 -0
- package/dist/{DiscardChangesModal.vue_vue_type_script_setup_true_lang-Bx5O1RZJ.js → DiscardChangesModal.vue_vue_type_script_setup_true_lang-DyhYHRyz.js} +1 -1
- package/dist/{LeaveGuardRoot.vue_vue_type_script_setup_true_lang-DH6EB8br.js → LeaveGuardRoot.vue_vue_type_script_setup_true_lang-CvwoT1JF.js} +1 -1
- package/dist/{Menu.vue_vue_type_script_setup_true_lang-D44EHXQZ.js → Menu.vue_vue_type_script_setup_true_lang-CrMj6KPD.js} +1 -1
- package/dist/{Modal.vue_vue_type_script_setup_true_lang-DYQgaUtj.js → Modal.vue_vue_type_script_setup_true_lang-BQZM49gC.js} +138 -128
- package/dist/{PhotoViewer.vue_vue_type_script_setup_true_lang-DDVQXJRB.js → PhotoViewer.vue_vue_type_script_setup_true_lang-ElDizaW2.js} +1 -1
- package/dist/{SectionList.vue_vue_type_script_setup_true_lang-DGcKX_OJ.js → SectionList.vue_vue_type_script_setup_true_lang-L9ita_Kx.js} +2 -2
- package/dist/SelectField.vue_vue_type_script_setup_true_lang-DZTrU8NJ.js +661 -0
- package/dist/{Sheet.vue_vue_type_script_setup_true_lang-BLBD5ps8.js → Sheet.vue_vue_type_script_setup_true_lang-CtkJ-4e3.js} +1 -1
- package/dist/{Tooltip.vue_vue_type_script_setup_true_lang-BJWPVyfT.js → Tooltip.vue_vue_type_script_setup_true_lang-OOD_XNWx.js} +1 -1
- package/dist/app/application.d.ts +5 -0
- package/dist/app/environment.d.ts +2 -0
- package/dist/app/index.js +75 -72
- package/dist/button/index.d.ts +1 -1
- package/dist/button/index.js +5 -3
- package/dist/button/shortcut.d.ts +28 -2
- package/dist/collection/CollectionPage.vue.d.ts +1 -0
- package/dist/collection/CollectionRows.vue.d.ts +59 -0
- package/dist/collection/CollectionTable.vue.d.ts +1 -1
- package/dist/collection/DataTable.vue.d.ts +47 -0
- package/dist/collection/RowActions.vue.d.ts +19 -0
- package/dist/collection/columns.d.ts +2 -0
- package/dist/collection/index.d.ts +4 -2
- package/dist/collection/index.js +1752 -1610
- package/dist/collection/rowLayout.d.ts +10 -0
- package/dist/collection/slots.d.ts +6 -3
- package/dist/describeError-l5T9b8Uv.js +41 -0
- package/dist/dialogStack-DZZg55w0.js +31 -0
- package/dist/form/CommandDialog.vue.d.ts +12 -1
- package/dist/form/FormGroup.vue.d.ts +1 -1
- package/dist/form/MultiSelectField.vue.d.ts +4 -1
- package/dist/form/NumberField.vue.d.ts +6 -0
- package/dist/form/OptionList.vue.d.ts +6 -2
- package/dist/form/SelectField.vue.d.ts +4 -1
- package/dist/form/index.d.ts +2 -0
- package/dist/form/index.js +1940 -2008
- package/dist/form/suggestions.d.ts +11 -0
- package/dist/form/useOptions.d.ts +60 -0
- package/dist/i18n/describeError.d.ts +31 -0
- package/dist/i18n/index.d.ts +26 -0
- package/dist/i18n/index.js +22 -20
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/CountryFlag.vue.d.ts +10 -0
- package/dist/modal/Modal.vue.d.ts +4 -0
- package/dist/modal/ShortcutHelp.vue.d.ts +2 -0
- package/dist/modal/index.d.ts +2 -0
- package/dist/modal/index.js +64 -6
- package/dist/modal/placement.d.ts +22 -0
- package/dist/{options-CjSz2dQK.js → options-DAkBtYkI.js} +3 -3
- package/dist/overlay/Popover.vue.d.ts +3 -0
- package/dist/overlay/dialogStack.d.ts +9 -0
- package/dist/overlay/index.d.ts +1 -1
- package/dist/overlay/index.js +18 -17
- package/dist/page/index.js +4 -4
- package/dist/phone/index.js +247 -540
- package/dist/platform/AccessGate.vue.d.ts +50 -0
- package/dist/platform/index.d.ts +2 -0
- package/dist/platform/index.js +86 -66
- package/dist/resource/index.js +42 -42
- package/dist/shell/AccountMenuItem.vue.d.ts +3 -0
- package/dist/shell/NavigationList.vue.d.ts +1 -1
- package/dist/shell/index.js +406 -394
- package/dist/state/Badge.vue.d.ts +17 -10
- package/dist/state/hue.d.ts +8 -0
- package/dist/state/index.d.ts +2 -0
- package/dist/state/index.js +92 -56
- package/dist/state/useLoad.d.ts +41 -0
- package/dist/styles.css +1 -1
- package/dist/testing/app.d.ts +61 -0
- package/dist/testing/async.d.ts +12 -0
- package/dist/testing/collection.d.ts +18 -0
- package/dist/testing/format.d.ts +9 -0
- package/dist/testing/i18n.d.ts +16 -0
- package/dist/testing/index.d.ts +14 -0
- package/dist/testing/index.js +178 -0
- package/dist/testing/media.d.ts +23 -0
- package/dist/testing/platform.d.ts +40 -0
- package/dist/testing/transport.d.ts +40 -0
- package/dist/{toast-BTeX0r66.js → toast-DvrHQ6Ag.js} +45 -43
- package/dist/{useDialog-wmyNx2j_.js → useDialog-CXR3hN0G.js} +1 -1
- package/package.json +5 -1
- package/src/styles/theme.css +60 -0
- package/dist/Badge.vue_vue_type_script_setup_true_lang-DKc6ugmr.js +0 -31
- package/dist/Button.vue_vue_type_script_setup_true_lang-3f0emVNU.js +0 -141
- package/dist/SelectField.vue_vue_type_script_setup_true_lang-SyFWE33A.js +0 -422
- package/dist/dialogStack-DiTG1rZc.js +0 -26
- package/dist/phone/CountryFlag.vue.d.ts +0 -10
- /package/dist/{phone → internal}/flagLoaders.d.ts +0 -0
|
@@ -59,6 +59,11 @@ export interface ApplicationLocaleOptions {
|
|
|
59
59
|
fallback?: string;
|
|
60
60
|
/** The locales the application offers. Default: the library's (`en`, `hr`, `bs`, `sl`). */
|
|
61
61
|
supported?: readonly string[];
|
|
62
|
+
/**
|
|
63
|
+
* The flag shown beside each locale's name in the language menu, as an ISO 3166-1 country code: `{ en: "GB", sl: "SI" }`.
|
|
64
|
+
* A flag stands for a language here, so the app chooses (English is not one country). No entry: the name alone.
|
|
65
|
+
*/
|
|
66
|
+
flags?: Readonly<Record<string, string>>;
|
|
62
67
|
/**
|
|
63
68
|
* Called after a switch to another locale committed (not for the start locale, a switch to the locale already active, or a
|
|
64
69
|
* switch a later one superseded), so the application can save the choice on the user. Not awaited: the page has already
|
|
@@ -22,6 +22,8 @@ export interface ApplicationEnvironment {
|
|
|
22
22
|
/** The active locale. */
|
|
23
23
|
readonly locale: Readonly<Ref<string>>;
|
|
24
24
|
readonly locales: readonly string[];
|
|
25
|
+
/** The flag country of each locale that has one (`{ en: "GB" }`); a locale without one shows no flag. */
|
|
26
|
+
readonly localeFlags: Readonly<Record<string, string>>;
|
|
25
27
|
/** Switches the locale once the texts in use exist in it; see `MessageRuntime.setLocale`. */
|
|
26
28
|
setLocale(locale: string): Promise<boolean>;
|
|
27
29
|
/** Tries the start again after a failed one. */
|
package/dist/app/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var Y = (e, a, n) =>
|
|
4
|
-
import { effectScope as D, watch as P, defineComponent as ue, openBlock as Se, createElementBlock as Le, createVNode as Z, unref as _, withCtx as ee, createTextVNode as xe, toDisplayString as Ae, shallowRef as Me, computed as Re, h as te, createApp as
|
|
5
|
-
import { useI18n as
|
|
1
|
+
var ke = Object.defineProperty;
|
|
2
|
+
var Ee = (e, a, n) => a in e ? ke(e, a, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[a] = n;
|
|
3
|
+
var Y = (e, a, n) => Ee(e, typeof a != "symbol" ? a + "" : a, n);
|
|
4
|
+
import { effectScope as D, watch as P, defineComponent as ue, openBlock as Se, createElementBlock as Le, createVNode as Z, unref as _, withCtx as ee, createTextVNode as xe, toDisplayString as Ae, shallowRef as Me, computed as Re, h as te, createApp as je } from "vue";
|
|
5
|
+
import { useI18n as Ne, createI18n as Oe } from "vue-i18n";
|
|
6
6
|
import { createRouter as Te, isNavigationFailure as _e } from "vue-router";
|
|
7
7
|
import { i as Ce, a as se } from "../environment-D3nozt9a.js";
|
|
8
8
|
import { b as Ct } from "../environment-D3nozt9a.js";
|
|
@@ -16,23 +16,23 @@ import { c as Ue, _ as Xe, i as Ye } from "../NoAccess.vue_vue_type_script_setup
|
|
|
16
16
|
import { b as Ze, c as et, n as re } from "../navigation-B33ikiCS.js";
|
|
17
17
|
import { i as tt, c as st, s as ae } from "../feature-DyDtyMLU.js";
|
|
18
18
|
import { S as It, d as Ft, p as Wt } from "../feature-DyDtyMLU.js";
|
|
19
|
-
import { _ as ot } from "../Button.vue_vue_type_script_setup_true_lang-
|
|
19
|
+
import { _ as ot } from "../Button.vue_vue_type_script_setup_true_lang-B1eZgLae.js";
|
|
20
20
|
import { _ as nt } from "../EmptyState.vue_vue_type_script_setup_true_lang-BeGpHMUP.js";
|
|
21
21
|
function rt(e) {
|
|
22
22
|
const { platform: a } = e, n = D();
|
|
23
23
|
let i = null, h = null, y = !1;
|
|
24
|
-
function
|
|
24
|
+
function $(l, d) {
|
|
25
25
|
const g = new AbortController(), u = { controller: g, stops: [] };
|
|
26
26
|
for (const p of l)
|
|
27
27
|
try {
|
|
28
|
-
const
|
|
29
|
-
typeof
|
|
30
|
-
} catch (
|
|
31
|
-
e.onError(
|
|
28
|
+
const b = d(p, g.signal);
|
|
29
|
+
typeof b == "function" && u.stops.push({ owned: p, stop: b });
|
|
30
|
+
} catch (b) {
|
|
31
|
+
e.onError(b, p);
|
|
32
32
|
}
|
|
33
33
|
return u;
|
|
34
34
|
}
|
|
35
|
-
function
|
|
35
|
+
function k(l) {
|
|
36
36
|
if (l) {
|
|
37
37
|
l.controller.abort();
|
|
38
38
|
for (const { owned: d, stop: g } of l.stops.reverse())
|
|
@@ -43,24 +43,24 @@ function rt(e) {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
-
const
|
|
46
|
+
const E = (l) => e.effects.filter((d) => d.effect.scope === l), x = (l) => l.status !== "authenticated" ? null : e.sessionKey ? e.sessionKey(l) : String(l.user.id);
|
|
47
47
|
return {
|
|
48
48
|
start() {
|
|
49
49
|
if (y || i) return;
|
|
50
|
-
i =
|
|
51
|
-
|
|
50
|
+
i = $(
|
|
51
|
+
E("app"),
|
|
52
52
|
(d, g) => d.effect.start({ signal: g, platform: a, report: (u) => e.onError(u, d) })
|
|
53
53
|
);
|
|
54
|
-
const l =
|
|
54
|
+
const l = E("session");
|
|
55
55
|
n.run(
|
|
56
56
|
() => P(
|
|
57
57
|
() => x(a.session.state.value),
|
|
58
58
|
(d) => {
|
|
59
|
-
|
|
59
|
+
k(h), h = null;
|
|
60
60
|
const g = a.session.state.value;
|
|
61
|
-
d === null || g.status !== "authenticated" || (h =
|
|
61
|
+
d === null || g.status !== "authenticated" || (h = $(
|
|
62
62
|
l,
|
|
63
|
-
(u, p) => u.effect.start({ signal: p, platform: a, user: g.user, report: (
|
|
63
|
+
(u, p) => u.effect.start({ signal: p, platform: a, user: g.user, report: (b) => e.onError(b, u) })
|
|
64
64
|
));
|
|
65
65
|
},
|
|
66
66
|
{ immediate: !0, flush: "sync" }
|
|
@@ -68,7 +68,7 @@ function rt(e) {
|
|
|
68
68
|
);
|
|
69
69
|
},
|
|
70
70
|
dispose() {
|
|
71
|
-
y || (y = !0, n.stop(),
|
|
71
|
+
y || (y = !0, n.stop(), k(h), k(i), h = i = null);
|
|
72
72
|
}
|
|
73
73
|
};
|
|
74
74
|
}
|
|
@@ -79,7 +79,7 @@ const at = { class: "mx-auto flex min-h-screen max-w-content items-center justif
|
|
|
79
79
|
},
|
|
80
80
|
emits: ["retry"],
|
|
81
81
|
setup(e) {
|
|
82
|
-
const { t: a } =
|
|
82
|
+
const { t: a } = Ne();
|
|
83
83
|
return (n, i) => (Se(), Le("div", at, [
|
|
84
84
|
Z(_(nt), {
|
|
85
85
|
title: _(a)("core.startup.title"),
|
|
@@ -130,25 +130,25 @@ function ct(e) {
|
|
|
130
130
|
for (const o of i)
|
|
131
131
|
for (const s of o.requires)
|
|
132
132
|
h.has(s) || n(w(o), `requires the feature "${s}", which is not in the features list.`);
|
|
133
|
-
const y = [],
|
|
134
|
-
if (
|
|
133
|
+
const y = [], $ = /* @__PURE__ */ new Set(), k = (o) => {
|
|
134
|
+
if ($.has(o.id)) return;
|
|
135
135
|
const s = y.indexOf(o.id);
|
|
136
136
|
if (s !== -1) {
|
|
137
|
-
n(w(o), `requirements form a cycle: ${[...y.slice(s), o.id].join(" -> ")}.`),
|
|
137
|
+
n(w(o), `requirements form a cycle: ${[...y.slice(s), o.id].join(" -> ")}.`), $.add(o.id);
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
140
140
|
y.push(o.id);
|
|
141
141
|
for (const c of o.requires) {
|
|
142
142
|
const m = h.get(c);
|
|
143
|
-
m &&
|
|
143
|
+
m && k(m);
|
|
144
144
|
}
|
|
145
|
-
y.pop(),
|
|
145
|
+
y.pop(), $.add(o.id);
|
|
146
146
|
};
|
|
147
|
-
i.forEach(
|
|
148
|
-
const
|
|
147
|
+
i.forEach(k);
|
|
148
|
+
const E = new Set(e.platform.config.capabilities);
|
|
149
149
|
for (const o of i)
|
|
150
150
|
for (const s of o.backend)
|
|
151
|
-
|
|
151
|
+
E.has(s) || n(w(o), `needs the backend capability "${s}", which the server does not report.`);
|
|
152
152
|
const x = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map();
|
|
153
153
|
for (const o of i) {
|
|
154
154
|
for (const s of o.routes) {
|
|
@@ -173,24 +173,24 @@ function ct(e) {
|
|
|
173
173
|
for (const c of s) {
|
|
174
174
|
const m = u.get(c.namespace);
|
|
175
175
|
m ? n(o, `declares the message namespace "${c.namespace}", which ${m} declares too.`) : u.set(c.namespace, o);
|
|
176
|
-
for (const
|
|
177
|
-
e.supportedLocales.includes(
|
|
176
|
+
for (const j of Object.keys(c.loaders))
|
|
177
|
+
e.supportedLocales.includes(j) || n(o, `the namespace "${c.namespace}" has a loader for "${j}", which is not a supported locale (${e.supportedLocales.join(", ")}).`);
|
|
178
178
|
}
|
|
179
179
|
};
|
|
180
180
|
for (const o of i) p(w(o), o.messages);
|
|
181
181
|
p(ce, e.messages);
|
|
182
|
-
const
|
|
182
|
+
const b = (o) => u.has(o);
|
|
183
183
|
for (const o of i)
|
|
184
184
|
for (const { record: s } of B(o.routes))
|
|
185
185
|
for (const c of s.meta?.messages ?? [])
|
|
186
|
-
|
|
186
|
+
b(c) || n(w(o), `the route "${String(s.name ?? s.path)}" needs the message namespace "${c}", which nobody declares.`);
|
|
187
187
|
const A = /* @__PURE__ */ new Map();
|
|
188
188
|
for (const o of i)
|
|
189
189
|
for (const s of o.contributions) {
|
|
190
190
|
const c = A.get(s.id);
|
|
191
191
|
c ? n(w(o), `declares the shell contribution "${s.id}", which feature "${c.id}" declares too.`) : A.set(s.id, o), e.shellSlots && !s.optional && !e.shellSlots.includes(s.slot) && n(w(o), `contributes "${s.id}" to the slot "${s.slot}", which the shell does not render (it renders ${e.shellSlots.join(", ") || "none"}). Mark it optional to leave it out instead.`);
|
|
192
192
|
for (const m of s.messages ?? [])
|
|
193
|
-
|
|
193
|
+
b(m) || n(w(o), `the contribution "${s.id}" needs the message namespace "${m}", which nobody declares.`);
|
|
194
194
|
}
|
|
195
195
|
const R = /* @__PURE__ */ new Map();
|
|
196
196
|
for (const o of i)
|
|
@@ -218,30 +218,32 @@ function fe(e, a) {
|
|
|
218
218
|
}));
|
|
219
219
|
}
|
|
220
220
|
const le = (e) => [...new Set(e)];
|
|
221
|
-
function
|
|
221
|
+
function Nt(e) {
|
|
222
222
|
const { platform: a } = e, n = e.locale?.supported ?? Object.keys(oe), i = e.locale?.fallback ?? "en", h = e.shell === void 0 ? void 0 : ut(e.shell) ? e.shell : { component: e.shell, slots: void 0, progress: void 0 }, y = [];
|
|
223
223
|
n.includes(i) || y.push({ owner: "application", message: `the fallback locale "${i}" is not among the supported locales (${n.join(", ")}).` });
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
const
|
|
224
|
+
for (const t of Object.keys(e.locale?.flags ?? {}))
|
|
225
|
+
n.includes(t) || y.push({ owner: "application", message: `locale.flags names the locale "${t}", which is not among the supported locales (${n.join(", ")}).` });
|
|
226
|
+
const $ = e.locale?.initial ?? (n.includes(a.config.locale) ? a.config.locale : i);
|
|
227
|
+
n.includes($) || y.push({ owner: "application", message: `the initial locale "${$}" is not among the supported locales (${n.join(", ")}).` });
|
|
228
|
+
const k = [Je, Fe, He, Ve, De, re, ae, ne, se], E = ct({
|
|
227
229
|
features: e.features,
|
|
228
230
|
platform: a,
|
|
229
231
|
messages: e.messages ?? [],
|
|
230
|
-
reservedContexts:
|
|
232
|
+
reservedContexts: k,
|
|
231
233
|
supportedLocales: n,
|
|
232
234
|
shellSlots: h?.slots
|
|
233
|
-
}), x = [...y, ...
|
|
235
|
+
}), x = [...y, ...E.issues], l = E.features, d = Ze(
|
|
234
236
|
l.flatMap((t) => t.navigation.map((r) => ({ feature: t.id, binding: r }))),
|
|
235
237
|
e.navigation
|
|
236
238
|
);
|
|
237
239
|
for (const t of d.issues) x.push({ owner: "navigation", message: t });
|
|
238
240
|
if (x.length > 0) throw new ie(x);
|
|
239
|
-
const g = lt(
|
|
241
|
+
const g = lt($, i, e.i18n), u = g.global;
|
|
240
242
|
for (const [t, r] of Object.entries(oe)) u.mergeLocaleMessage(t, r);
|
|
241
243
|
for (const [t, r] of Object.entries(e.i18n?.messages ?? {})) u.mergeLocaleMessage(t, r);
|
|
242
|
-
const p = Ke({ locale: () => u.locale.value, formatters: e.formatting }),
|
|
244
|
+
const p = Ke({ locale: () => u.locale.value, formatters: e.formatting }), b = [...l.flatMap((t) => t.messages), ...e.messages ?? []], A = (t) => (e.onError ?? ft)({ ...t, route: s.currentRoute.value.matched.length > 0 ? s.currentRoute.value.fullPath : null }), R = We({
|
|
243
245
|
target: u,
|
|
244
|
-
namespaces:
|
|
246
|
+
namespaces: b,
|
|
245
247
|
fallback: i,
|
|
246
248
|
supported: n,
|
|
247
249
|
onFailure: (t) => A({ source: "messages", error: t.error, detail: `${t.namespace} (${t.locale})`, feature: o.get(t.namespace) })
|
|
@@ -249,7 +251,7 @@ function jt(e) {
|
|
|
249
251
|
history: e.router?.history ?? Ue(),
|
|
250
252
|
routes: l.flatMap((t) => fe(t.routes, t.id)),
|
|
251
253
|
scrollBehavior: e.router?.scrollBehavior ?? ((t, r) => t.name === r.name ? !1 : { top: 0 })
|
|
252
|
-
}), c = e.router?.login ?? { name: "login" }, m = e.router?.home ?? { path: "/" },
|
|
254
|
+
}), c = e.router?.login ?? { name: "login" }, m = e.router?.home ?? { path: "/" }, j = [], H = (t) => {
|
|
253
255
|
try {
|
|
254
256
|
return s.resolve(t).matched.length > 0 ? null : "matches no route";
|
|
255
257
|
} catch (r) {
|
|
@@ -259,17 +261,18 @@ function jt(e) {
|
|
|
259
261
|
};
|
|
260
262
|
if (l.some((t) => t.routes.some((r) => r.meta?.public !== !0))) {
|
|
261
263
|
const t = H(c) ?? (s.resolve(c).meta.public === !0 ? null : "is not public (meta.public: true)");
|
|
262
|
-
t &&
|
|
264
|
+
t && j.push({ owner: "application", message: `the login route ${JSON.stringify(c)} ${t.replace("matches no route", "does not exist")}, but protected routes are installed: an anonymous visitor would have nowhere to go. Install a feature with the login route or set router.login.` });
|
|
263
265
|
}
|
|
264
266
|
for (const { feature: t, binding: r } of d.destinations.values()) {
|
|
265
267
|
const f = H(r.to);
|
|
266
|
-
f &&
|
|
268
|
+
f && j.push({ owner: `feature "${t}"`, message: `the destination "${r.destination}" is bound to ${JSON.stringify(r.to)}, which ${f}.` });
|
|
267
269
|
}
|
|
268
|
-
if (
|
|
269
|
-
const
|
|
270
|
-
state:
|
|
270
|
+
if (j.length > 0) throw new ie(j);
|
|
271
|
+
const N = Me({ status: "idle" }), K = {
|
|
272
|
+
state: N,
|
|
271
273
|
locale: Re(() => u.locale.value),
|
|
272
274
|
locales: n,
|
|
275
|
+
localeFlags: e.locale?.flags ?? {},
|
|
273
276
|
setLocale: async (t) => {
|
|
274
277
|
const r = u.locale.value, f = await R.setLocale(t);
|
|
275
278
|
if (f && u.locale.value !== r) {
|
|
@@ -305,19 +308,19 @@ function jt(e) {
|
|
|
305
308
|
name: "ApplicationRoot",
|
|
306
309
|
setup() {
|
|
307
310
|
return () => {
|
|
308
|
-
const t =
|
|
311
|
+
const t = N.value;
|
|
309
312
|
return t.status === "failed" ? te(it, { kind: t.kind, onRetry: () => void q() }) : t.status !== "ready" ? null : te(h?.component ?? Qe);
|
|
310
313
|
};
|
|
311
314
|
}
|
|
312
|
-
}), v =
|
|
315
|
+
}), v = je(ye);
|
|
313
316
|
Ge(v, a), v.use(g), Ie(v, p), F = Pe(v), Be(v), Ce(v), e.icons && qe(v, ...Array.isArray(e.icons) ? e.icons : [e.icons]), v.provide(se, K), v.provide(re, ge), v.provide(ae, ve), v.provide(ne, we);
|
|
314
317
|
for (const t of l) for (const { key: r, value: f } of t.contexts) v.provide(r, f);
|
|
315
318
|
let M = !1, J = !1, z = !1, Q = !1;
|
|
316
319
|
const T = [];
|
|
317
|
-
function
|
|
320
|
+
function $e() {
|
|
318
321
|
const t = v.config.errorHandler;
|
|
319
|
-
v.config.errorHandler = (L,
|
|
320
|
-
A({ source: "vue", error: L, detail: X }), t?.(L,
|
|
322
|
+
v.config.errorHandler = (L, be, X) => {
|
|
323
|
+
A({ source: "vue", error: L, detail: X }), t?.(L, be, X);
|
|
321
324
|
};
|
|
322
325
|
const r = (L) => A({ source: "unhandledrejection", error: L.reason }), f = (L) => {
|
|
323
326
|
L.error && A({ source: "window", error: L.error });
|
|
@@ -350,10 +353,10 @@ function jt(e) {
|
|
|
350
353
|
), T.push(() => O.stop());
|
|
351
354
|
}
|
|
352
355
|
const C = (t, r) => {
|
|
353
|
-
|
|
356
|
+
N.value = { status: "failed", kind: t, error: r };
|
|
354
357
|
};
|
|
355
358
|
async function U() {
|
|
356
|
-
|
|
359
|
+
N.value = { status: "starting" };
|
|
357
360
|
const t = await a.session.restore();
|
|
358
361
|
if (M) return;
|
|
359
362
|
if (t.status === "failed") return C("session", t.error);
|
|
@@ -368,23 +371,23 @@ function jt(e) {
|
|
|
368
371
|
M || C("startup", f);
|
|
369
372
|
return;
|
|
370
373
|
}
|
|
371
|
-
Q || (v.use(s), Q = !0),
|
|
374
|
+
Q || (v.use(s), Q = !0), N.value = { status: "ready" }, V.start();
|
|
372
375
|
}
|
|
373
376
|
}
|
|
374
377
|
async function q() {
|
|
375
|
-
M ||
|
|
378
|
+
M || N.value.status !== "failed" || (await R.retry(), await U());
|
|
376
379
|
}
|
|
377
380
|
return {
|
|
378
381
|
app: v,
|
|
379
382
|
router: s,
|
|
380
383
|
i18n: g,
|
|
381
|
-
state:
|
|
384
|
+
state: N,
|
|
382
385
|
locale: K.locale,
|
|
383
386
|
setLocale: K.setLocale,
|
|
384
387
|
async mount(t) {
|
|
385
388
|
if (M) throw new Error("This application was disposed; create a new one with createApplication().");
|
|
386
389
|
if (J) throw new Error("This application is already mounted.");
|
|
387
|
-
J = !0,
|
|
390
|
+
J = !0, $e(), await U(), !M && (v.mount(t), z = !0);
|
|
388
391
|
},
|
|
389
392
|
retry: q,
|
|
390
393
|
dispose() {
|
|
@@ -409,31 +412,31 @@ function Ot(e = {}) {
|
|
|
409
412
|
id: "vue-core.keep-session-alive",
|
|
410
413
|
scope: "session",
|
|
411
414
|
start({ signal: i, platform: h, report: y }) {
|
|
412
|
-
let
|
|
413
|
-
const
|
|
415
|
+
let $, k = null;
|
|
416
|
+
const E = () => {
|
|
414
417
|
const p = h.session.state.value;
|
|
415
418
|
return p.status === "authenticated" && p.expiresAt ? p.expiresAt.getTime() - Date.now() - a : null;
|
|
416
|
-
}, x = () => (
|
|
419
|
+
}, x = () => (k ?? (k = (async () => {
|
|
417
420
|
try {
|
|
418
421
|
await e.renew?.(h), await h.session.refresh();
|
|
419
422
|
} catch (p) {
|
|
420
423
|
y(p);
|
|
421
424
|
} finally {
|
|
422
|
-
|
|
425
|
+
k = null;
|
|
423
426
|
}
|
|
424
|
-
})()),
|
|
427
|
+
})()), k);
|
|
425
428
|
function l(p = 0) {
|
|
426
|
-
clearTimeout(
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
+
clearTimeout($);
|
|
430
|
+
const b = E();
|
|
431
|
+
b !== null && !i.aborted && ($ = setTimeout(() => void d(), Math.min(Math.max(b, p), pt)));
|
|
429
432
|
}
|
|
430
433
|
async function d() {
|
|
431
434
|
if (i.aborted || !navigator.onLine) return;
|
|
432
|
-
const p =
|
|
435
|
+
const p = E();
|
|
433
436
|
if (p !== null) {
|
|
434
437
|
if (p <= 0) {
|
|
435
438
|
if (await x(), i.aborted) return;
|
|
436
|
-
l((
|
|
439
|
+
l((E() ?? 1) <= 0 ? n : 0);
|
|
437
440
|
return;
|
|
438
441
|
}
|
|
439
442
|
l();
|
|
@@ -443,7 +446,7 @@ function Ot(e = {}) {
|
|
|
443
446
|
document.visibilityState === "visible" && d();
|
|
444
447
|
}, u = () => void d();
|
|
445
448
|
return document.addEventListener("visibilitychange", g), window.addEventListener("online", u), d(), () => {
|
|
446
|
-
clearTimeout(
|
|
449
|
+
clearTimeout($), document.removeEventListener("visibilitychange", g), window.removeEventListener("online", u);
|
|
447
450
|
};
|
|
448
451
|
}
|
|
449
452
|
};
|
|
@@ -452,7 +455,7 @@ export {
|
|
|
452
455
|
ie as ApplicationError,
|
|
453
456
|
It as ShellOutlet,
|
|
454
457
|
se as applicationKey,
|
|
455
|
-
|
|
458
|
+
Nt as createApplication,
|
|
456
459
|
Ft as defineFeature,
|
|
457
460
|
Ot as keepSessionAlive,
|
|
458
461
|
Wt as provideContext,
|
package/dist/button/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default as Button } from "./Button.vue";
|
|
2
|
-
export { useKeyboardShortcut, matchesShortcut, type KeyboardShortcut } from "./shortcut";
|
|
2
|
+
export { useKeyboardShortcut, matchesShortcut, shortcutKeys, useShortcutRegistry, type KeyboardShortcut, type ShortcutListing } from "./shortcut";
|
package/dist/button/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { _ as a, m as r, u as
|
|
1
|
+
import { _ as a, m as o, s as r, u, a as e } from "../Button.vue_vue_type_script_setup_true_lang-B1eZgLae.js";
|
|
2
2
|
export {
|
|
3
3
|
a as Button,
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
o as matchesShortcut,
|
|
5
|
+
r as shortcutKeys,
|
|
6
|
+
u as useKeyboardShortcut,
|
|
7
|
+
e as useShortcutRegistry
|
|
6
8
|
};
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import { type MaybeRefOrGetter } from "vue";
|
|
2
|
-
/**
|
|
1
|
+
import { type ComputedRef, type MaybeRefOrGetter } from "vue";
|
|
2
|
+
/**
|
|
3
|
+
* A keyboard shortcut: the key (case-insensitive, as `KeyboardEvent.key`) and exactly the modifiers listed.
|
|
4
|
+
* With a `label` it is listed by `useShortcutRegistry()` (a help dialog) for as long as its owner is mounted.
|
|
5
|
+
*/
|
|
3
6
|
export interface KeyboardShortcut {
|
|
4
7
|
key: string;
|
|
5
8
|
ctrlKey?: boolean;
|
|
6
9
|
shiftKey?: boolean;
|
|
7
10
|
altKey?: boolean;
|
|
8
11
|
metaKey?: boolean;
|
|
12
|
+
/** What it does, in the app's language ("Search the list"); a function is read when the list is read, so it follows the locale. An empty text is not listed. */
|
|
13
|
+
label?: string | (() => string);
|
|
14
|
+
/** The heading it is listed under; any name the app has a heading for. The library's own use `"list"` and `"record"`. */
|
|
15
|
+
group?: string;
|
|
9
16
|
}
|
|
10
17
|
export declare function matchesShortcut(event: KeyboardEvent, shortcut: KeyboardShortcut): boolean;
|
|
11
18
|
/**
|
|
@@ -15,3 +22,22 @@ export declare function matchesShortcut(event: KeyboardEvent, shortcut: Keyboard
|
|
|
15
22
|
* scope. A shortcut without Ctrl, Alt or Meta never fires while the user is typing in a field.
|
|
16
23
|
*/
|
|
17
24
|
export declare function useKeyboardShortcut(shortcut: MaybeRefOrGetter<KeyboardShortcut | undefined>, run: (event: KeyboardEvent) => void | false): void;
|
|
25
|
+
/** The key and modifiers as keycap texts: `["Ctrl", "S"]`, or `["⌘", "K"]` on Apple platforms; arrows as arrows. */
|
|
26
|
+
export declare function shortcutKeys(shortcut: KeyboardShortcut): string[];
|
|
27
|
+
/** One row of a shortcut help list: what it does and every way of doing it (`/`, or `J` and `→`). */
|
|
28
|
+
export interface ShortcutListing {
|
|
29
|
+
readonly group: string | null;
|
|
30
|
+
readonly label: string;
|
|
31
|
+
/** Each alternative as keycap texts, see `shortcutKeys`. */
|
|
32
|
+
readonly keys: readonly (readonly string[])[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The shortcuts that exist on the page right now, for a help dialog: every `useKeyboardShortcut`
|
|
36
|
+
* with a `label` whose owner is mounted, the library's own included (list search and filters, the
|
|
37
|
+
* record pager). Rows with the same group and label are one row (two lists on a page share "/");
|
|
38
|
+
* reactive, so the dialog follows pages and locale.
|
|
39
|
+
*
|
|
40
|
+
* const rows = useShortcutRegistry();
|
|
41
|
+
* <dl v-for="row in rows"><dt>{{ row.label }}</dt><dd><kbd v-for="key in row.keys[0]">{{ key }}</kbd></dd></dl>
|
|
42
|
+
*/
|
|
43
|
+
export declare function useShortcutRegistry(): ComputedRef<ShortcutListing[]>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type RouteLocationRaw } from "vue-router";
|
|
2
|
+
import { type Column, type RowAction } from "./columns";
|
|
3
|
+
import type { CollectionDisplay } from "./useCollection";
|
|
4
|
+
import type { SortDirection } from "./types";
|
|
5
|
+
declare const _default: <Row extends object, Col extends Column<Row>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
6
|
+
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
|
|
7
|
+
readonly onSort?: ((key: string) => any) | undefined;
|
|
8
|
+
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onSort"> & {
|
|
9
|
+
columns: readonly Col[];
|
|
10
|
+
rows: readonly Row[];
|
|
11
|
+
rowKey: (row: Row) => string | number;
|
|
12
|
+
display: CollectionDisplay;
|
|
13
|
+
/** Phone rows instead of a table (see `useRowLayout`). */
|
|
14
|
+
phone: boolean;
|
|
15
|
+
/** Where a click on the row goes; null for a row that is not a link. */
|
|
16
|
+
link: (row: Row) => RouteLocationRaw | null;
|
|
17
|
+
/** Text to mark in an identity cell. */
|
|
18
|
+
search?: string;
|
|
19
|
+
/** The sort the header shows; a header sorts (`sort`) only when the column has a `sort` key. */
|
|
20
|
+
sorted?: {
|
|
21
|
+
key: string;
|
|
22
|
+
direction: SortDirection;
|
|
23
|
+
} | null;
|
|
24
|
+
rowActions?: (row: Row) => RowAction[];
|
|
25
|
+
rowLabel?: (row: Row) => string;
|
|
26
|
+
/** Pixels. */
|
|
27
|
+
rowHeight?: number;
|
|
28
|
+
density?: "regular" | "condensed";
|
|
29
|
+
actionsVisible?: boolean;
|
|
30
|
+
skeletonRows: number;
|
|
31
|
+
/** Rows to reserve the height of while loading, so the card does not jump when they land. */
|
|
32
|
+
reserveRows?: number;
|
|
33
|
+
rowClass?: (row: Row) => string | undefined;
|
|
34
|
+
} & Partial<{}>> & import("vue").PublicProps;
|
|
35
|
+
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
|
|
36
|
+
attrs: any;
|
|
37
|
+
slots: import("./slots").CellSlots<Row, Col> & {
|
|
38
|
+
leading?: ((scope: {
|
|
39
|
+
item: Row;
|
|
40
|
+
compact: boolean;
|
|
41
|
+
}) => unknown) | undefined;
|
|
42
|
+
actions?: ((scope: {
|
|
43
|
+
item: Row;
|
|
44
|
+
}) => unknown) | undefined;
|
|
45
|
+
} & {
|
|
46
|
+
toolbar?: () => unknown;
|
|
47
|
+
empty?: () => unknown;
|
|
48
|
+
} & {
|
|
49
|
+
/** What a failed load shows. */
|
|
50
|
+
failed?: () => unknown;
|
|
51
|
+
};
|
|
52
|
+
emit: (evt: "sort", key: string) => void;
|
|
53
|
+
}>) => import("vue").VNode & {
|
|
54
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
55
|
+
};
|
|
56
|
+
export default _default;
|
|
57
|
+
type __VLS_PrettifyLocal<T> = {
|
|
58
|
+
[K in keyof T]: T[K];
|
|
59
|
+
} & {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Column, RowAction } from "./columns";
|
|
2
2
|
import type { CollectionSlots } from "./slots";
|
|
3
3
|
import type { Collection } from "./useCollection";
|
|
4
4
|
declare const _default: <Row extends object, Col extends Column<Row>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { RouteLocationRaw } from "vue-router";
|
|
2
|
+
import type { Column, RowAction } from "./columns";
|
|
3
|
+
declare const _default: <Row extends object, const Col extends Column<Row, never>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
4
|
+
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, never> & {
|
|
5
|
+
rows: readonly Row[];
|
|
6
|
+
columns: readonly Col[];
|
|
7
|
+
rowKey: (row: Row) => string | number;
|
|
8
|
+
/** Skeleton rows instead of the rows (and instead of the empty state). */
|
|
9
|
+
loading?: boolean;
|
|
10
|
+
/** How many skeleton rows `loading` shows. */
|
|
11
|
+
skeletonRows?: number;
|
|
12
|
+
/** Where a row's record lives: the row opens it on click, and an identity column links to it. */
|
|
13
|
+
recordRoute?: (row: Row) => RouteLocationRaw;
|
|
14
|
+
/** Quick actions per row: swiped in on phones (links), and the row's context menu (long press, right click). */
|
|
15
|
+
rowActions?: (row: Row) => RowAction[];
|
|
16
|
+
/** The accessible name of a row's menu and More button, e.g. the record's name. */
|
|
17
|
+
rowLabel?: (row: Row) => string;
|
|
18
|
+
/** Pixels. */
|
|
19
|
+
rowHeight?: number;
|
|
20
|
+
density?: "regular" | "condensed";
|
|
21
|
+
/** The row's actions are the only way to perform them, so the More button shows in the row. */
|
|
22
|
+
actionsVisible?: boolean;
|
|
23
|
+
/** Extra classes for a row, e.g. to set apart a total or the newest row. */
|
|
24
|
+
rowClass?: (row: Row) => string | undefined;
|
|
25
|
+
} & Partial<{}>> & import("vue").PublicProps;
|
|
26
|
+
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
|
|
27
|
+
attrs: any;
|
|
28
|
+
slots: import("./slots").CellSlots<Row, Col> & {
|
|
29
|
+
leading?: ((scope: {
|
|
30
|
+
item: Row;
|
|
31
|
+
compact: boolean;
|
|
32
|
+
}) => unknown) | undefined;
|
|
33
|
+
actions?: ((scope: {
|
|
34
|
+
item: Row;
|
|
35
|
+
}) => unknown) | undefined;
|
|
36
|
+
} & {
|
|
37
|
+
/** What shows when there are no rows; "No data" by default. */
|
|
38
|
+
empty?: () => unknown;
|
|
39
|
+
};
|
|
40
|
+
emit: {};
|
|
41
|
+
}>) => import("vue").VNode & {
|
|
42
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
43
|
+
};
|
|
44
|
+
export default _default;
|
|
45
|
+
type __VLS_PrettifyLocal<T> = {
|
|
46
|
+
[K in keyof T]: T[K];
|
|
47
|
+
} & {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { RowAction } from "./columns";
|
|
2
|
+
/**
|
|
3
|
+
* The actions of a row as icon buttons in its actions cell: view, edit, delete, download. The same
|
|
4
|
+
* `RowAction[]` a table gives its swipe and context menu, so a row's actions are written once; the
|
|
5
|
+
* page builds the array from what the user may do (`access.can(...)`), so there is nothing to hide
|
|
6
|
+
* here. A link (`href`) is an anchor, a command (`onSelect`) a button; `critical` is red.
|
|
7
|
+
*
|
|
8
|
+
* <template #actions="{ item }"><RowActions :actions="rowActions(item)" :disabled="item.locked" /></template>
|
|
9
|
+
*
|
|
10
|
+
* `disabled` greys out every button (a locked row); it does not hide them.
|
|
11
|
+
*/
|
|
12
|
+
type __VLS_Props = {
|
|
13
|
+
actions: readonly RowAction[];
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
};
|
|
16
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
17
|
+
disabled: boolean;
|
|
18
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
19
|
+
export default _default;
|
|
@@ -84,6 +84,8 @@ export type Column<Row, Sort extends string = string> = ColumnCommon<Row, Sort>
|
|
|
84
84
|
* const columns = [{ key: "title", label: t("title"), kind: "identity", mobile: "primary" }] satisfies CollectionColumns<Ticket>;
|
|
85
85
|
*/
|
|
86
86
|
export type CollectionColumns<Row, Sort extends string = string> = readonly Column<Row, Sort>[];
|
|
87
|
+
/** The columns of a `DataTable`: the collection's, without a `sort` key (a table over an array keeps its order). */
|
|
88
|
+
export type TableColumns<Row> = readonly Column<Row, never>[];
|
|
87
89
|
/** A quick action of a row: swiped in on phones (links only) and listed in the row's context menu. */
|
|
88
90
|
export interface RowAction {
|
|
89
91
|
key: string;
|
|
@@ -5,7 +5,7 @@ export type { Collection, CollectionDisplay, LinkedQuery, SavedViewsHandle, UseC
|
|
|
5
5
|
export type { CollectionLoader, ListPage, CollectionQuery, CollectionStateSource, LoadContext, SortDirection } from "./types";
|
|
6
6
|
export { httpList, listParams, readListPage } from "./http";
|
|
7
7
|
export { LIST_CONTEXT_PARAM } from "./location";
|
|
8
|
-
export type { CollectionColumns, Column, ColumnKey, ColumnKind, ColumnValue, MobileRole, RowAction, SlotKey } from "./columns";
|
|
8
|
+
export type { CollectionColumns, Column, ColumnKey, ColumnKind, ColumnValue, MobileRole, RowAction, SlotKey, TableColumns } from "./columns";
|
|
9
9
|
export type { FilterDescriptor, FilterOption, ViewDescriptor } from "./filters";
|
|
10
10
|
export { useCollectionNeighbors } from "./neighbors";
|
|
11
11
|
export type { CollectionNeighbors, Neighbor, NeighborOptions } from "./neighbors";
|
|
@@ -14,6 +14,8 @@ export type { SavedView, SavedViews, SavedViewState } from "./savedViews";
|
|
|
14
14
|
export { default as CollectionPage } from "./CollectionPage.vue";
|
|
15
15
|
export { default as CollectionTable } from "./CollectionTable.vue";
|
|
16
16
|
export { default as CollectionCell } from "./CollectionCell.vue";
|
|
17
|
+
export { default as DataTable } from "./DataTable.vue";
|
|
18
|
+
export { default as RowActions } from "./RowActions.vue";
|
|
17
19
|
export { default as RecordIdentity } from "./RecordIdentity.vue";
|
|
18
20
|
export { DATE_PRESETS, useDatePresetFilter } from "./datePresets";
|
|
19
|
-
export type { CellSlots, CollectionSlots } from "./slots";
|
|
21
|
+
export type { CellSlots, CollectionSlots, RowsSlots } from "./slots";
|