@synopackageland/ui 0.5.8 → 0.6.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/LICENSES/THIRD_PARTY.md +450 -0
- package/README.md +18 -10
- package/dist/cli.js +296 -0
- package/dist/components/app/app-layout/AppLayout.vue.d.ts +12 -5
- package/dist/components/app/page-content/PageContent.vue.d.ts +3 -0
- package/dist/components/app/responsive-view/ResponsiveView.vue.d.ts +24 -0
- package/dist/components/composite/data-table/DataTable.vue.d.ts +9 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4280 -4105
- package/dist/json/SynoJsonRenderer.vue.d.ts +21 -0
- package/dist/json/catalog.d.ts +910 -0
- package/dist/json/describe.d.ts +31 -0
- package/dist/json/registry.d.ts +13953 -0
- package/dist/json/schema.d.ts +9 -0
- package/dist/json/validate.d.ts +63 -0
- package/dist/json-ai-prompt.md +184 -0
- package/dist/json-catalog.schema.json +2723 -0
- package/dist/json-preview/preview.js +21657 -0
- package/dist/json.d.ts +10 -0
- package/dist/json.js +1117 -0
- package/dist/lib/adaptiveLayout.d.ts +9 -0
- package/dist/reka-runtime.json +1 -1
- package/dist/theme.css +1 -1
- package/dist/themes/dsm7-embedded-theme.css +1 -1
- package/dist/themes/dsm7-embedded.css +1 -1
- package/dist/themes/dsm7.css +1 -1
- package/docs/adaptive-layout.md +143 -0
- package/docs/app-local-modal.md +4 -3
- package/docs/component-defaults-0.5.7.md +90 -0
- package/docs/json-ui.md +154 -0
- package/package.json +15 -3
package/dist/cli.js
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFile as v, mkdtemp as E, mkdir as M, writeFile as D, rm as R } from "node:fs/promises";
|
|
3
|
+
import { createServer as F } from "node:http";
|
|
4
|
+
import { tmpdir as H } from "node:os";
|
|
5
|
+
import { join as w, win32 as U, posix as j } from "node:path";
|
|
6
|
+
import { spawn as I } from "node:child_process";
|
|
7
|
+
import { existsSync as g } from "node:fs";
|
|
8
|
+
import { setTimeout as L } from "node:timers/promises";
|
|
9
|
+
import { synoJsonAiPrompt as T, synoJsonSchema as W, describeSynoJsonComponent as _, closestSynoJsonComponent as V, listSynoJsonComponents as B, validateSynoJsonSpec as G } from "./json.js";
|
|
10
|
+
const K = [
|
|
11
|
+
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
12
|
+
"/Applications/Chromium.app/Contents/MacOS/Chromium"
|
|
13
|
+
], X = ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"], z = ["ProgramFiles", "ProgramFiles(x86)", "LOCALAPPDATA"];
|
|
14
|
+
function Q(e = process.env, t = process.platform, n = g) {
|
|
15
|
+
return e.CHROME ? e.CHROME : (t === "darwin" ? K : t === "win32" ? z.flatMap((o) => e[o] ? [U.join(e[o], "Google", "Chrome", "Application", "chrome.exe")] : []) : (e.PATH ?? "").split(j.delimiter).filter(Boolean).flatMap((o) => X.map((r) => j.join(o, r)))).find(n);
|
|
16
|
+
}
|
|
17
|
+
async function Y(e) {
|
|
18
|
+
const t = Q();
|
|
19
|
+
if (!t) throw new Error("Chrome or Chromium was not found; set CHROME to its executable path.");
|
|
20
|
+
const n = I(t, [
|
|
21
|
+
"--headless=new",
|
|
22
|
+
"--disable-gpu",
|
|
23
|
+
"--hide-scrollbars",
|
|
24
|
+
"--no-first-run",
|
|
25
|
+
// GitHub's Ubuntu AppArmor policy blocks the unprivileged Chromium sandbox.
|
|
26
|
+
// Match Playwright's CI launch defaults for these repository-only fixtures.
|
|
27
|
+
...process.env.CI ? ["--no-sandbox", "--disable-dev-shm-usage"] : [],
|
|
28
|
+
"--remote-debugging-port=0",
|
|
29
|
+
`--user-data-dir=${e}`,
|
|
30
|
+
"about:blank"
|
|
31
|
+
], { stdio: ["ignore", "ignore", "pipe"] });
|
|
32
|
+
let s, o = "";
|
|
33
|
+
n.once("error", (a) => {
|
|
34
|
+
s = a;
|
|
35
|
+
}), n.stderr.on("data", (a) => {
|
|
36
|
+
o = (o + a).slice(-4e3);
|
|
37
|
+
});
|
|
38
|
+
const r = w(e, "DevToolsActivePort");
|
|
39
|
+
for (let a = 0; a < 100 && !g(r) && !s && n.exitCode === null; a++) await L(100);
|
|
40
|
+
if (!g(r))
|
|
41
|
+
throw n.kill(), new Error(`Chrome failed to start: ${s?.message ?? (o || "no debugging port within 10 seconds")}`);
|
|
42
|
+
const [i] = (await v(r, "utf8")).split(`
|
|
43
|
+
`), c = await (await fetch(`http://127.0.0.1:${i}/json/new?about:blank`, { method: "PUT" })).json(), d = new WebSocket(c.webSocketDebuggerUrl);
|
|
44
|
+
await new Promise((a, m) => {
|
|
45
|
+
d.onopen = a, d.onerror = m;
|
|
46
|
+
});
|
|
47
|
+
let l = 1;
|
|
48
|
+
const u = /* @__PURE__ */ new Map();
|
|
49
|
+
d.onmessage = (a) => {
|
|
50
|
+
const m = JSON.parse(String(a.data));
|
|
51
|
+
u.get(m.id)?.(m), u.delete(m.id);
|
|
52
|
+
};
|
|
53
|
+
const b = (a, m = {}) => new Promise((P, A) => {
|
|
54
|
+
const O = l++;
|
|
55
|
+
u.set(O, (h) => h.error ? A(new Error(h.error.message)) : P(h.result)), d.send(JSON.stringify({ id: O, method: a, params: m }));
|
|
56
|
+
});
|
|
57
|
+
await b("Emulation.setDeviceMetricsOverride", { width: 1100, height: 720, deviceScaleFactor: 1, mobile: !1 });
|
|
58
|
+
const k = new Promise((a) => n.once("exit", a));
|
|
59
|
+
return { send: b, close: () => (d.close(), n.kill(), k) };
|
|
60
|
+
}
|
|
61
|
+
const Z = `<!doctype html>
|
|
62
|
+
<html><head><meta charset="utf-8"><link rel="stylesheet" href="/theme.css">
|
|
63
|
+
<style>html, body, #app { margin: 0; height: 100%; }</style></head>
|
|
64
|
+
<body><div id="app"></div><script type="module" src="/preview.js"><\/script></body></html>`;
|
|
65
|
+
function q(e, t) {
|
|
66
|
+
const n = {
|
|
67
|
+
"/theme.css": [new URL("theme.css", e), "text/css"],
|
|
68
|
+
"/preview.js": [new URL("json-preview/preview.js", e), "text/javascript"]
|
|
69
|
+
}, s = F(async (o, r) => {
|
|
70
|
+
const i = new URL(o.url ?? "/", "http://localhost").pathname;
|
|
71
|
+
try {
|
|
72
|
+
const [c, d] = i === "/" ? [Z, "text/html"] : i === "/config.json" ? [t, "application/json"] : [await v(n[i][0]), n[i][1]];
|
|
73
|
+
r.writeHead(200, { "content-type": d }).end(c);
|
|
74
|
+
} catch {
|
|
75
|
+
r.writeHead(404).end();
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return new Promise((o) => s.listen(0, "127.0.0.1", () => o(s)));
|
|
79
|
+
}
|
|
80
|
+
async function ee(e, t) {
|
|
81
|
+
await e.send("Page.navigate", { url: t });
|
|
82
|
+
const { result: n, exceptionDetails: s } = await e.send(
|
|
83
|
+
"Runtime.evaluate",
|
|
84
|
+
{
|
|
85
|
+
expression: `new Promise((done, fail) => {
|
|
86
|
+
const started = Date.now()
|
|
87
|
+
const tick = () => location.href === ${JSON.stringify(t)} && window.synoPreview
|
|
88
|
+
? window.synoPreview.then(preview => done(preview.issues()), fail)
|
|
89
|
+
: Date.now() - started > 30000 ? fail(new Error('preview did not render within 30 seconds')) : setTimeout(tick, 50)
|
|
90
|
+
tick()
|
|
91
|
+
})`,
|
|
92
|
+
awaitPromise: !0,
|
|
93
|
+
returnByValue: !0
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
if (s) throw new Error(`Rendering failed: ${s.exception?.description ?? "unknown error"}`);
|
|
97
|
+
return n.value;
|
|
98
|
+
}
|
|
99
|
+
function te(e) {
|
|
100
|
+
return async (t) => {
|
|
101
|
+
const n = await q(e, JSON.stringify({ spec: t.spec, state: t.state, messages: t.messages })), s = `http://127.0.0.1:${n.address().port}/`, o = await E(w(H(), "syno-ui-render-"));
|
|
102
|
+
let r;
|
|
103
|
+
try {
|
|
104
|
+
r = await Y(o), await M(t.out, { recursive: !0 });
|
|
105
|
+
const i = [];
|
|
106
|
+
for (const c of t.widths) {
|
|
107
|
+
await r.send("Emulation.setDeviceMetricsOverride", { width: c, height: t.height, deviceScaleFactor: 1, mobile: !1 });
|
|
108
|
+
const d = await ee(r, `${s}?width=${c}`), { data: l } = await r.send("Page.captureScreenshot", { format: "png" }), u = w(t.out, `${t.name}-${c}.png`);
|
|
109
|
+
await D(u, Buffer.from(l, "base64")), i.push({ width: c, screenshot: u, issues: d });
|
|
110
|
+
}
|
|
111
|
+
return i;
|
|
112
|
+
} finally {
|
|
113
|
+
await r?.close(), n.close(), await R(o, { recursive: !0, force: !0, maxRetries: 12, retryDelay: 250 });
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const S = `Usage: syno-ui <command> [options]
|
|
118
|
+
|
|
119
|
+
Commands:
|
|
120
|
+
catalog [--json] List the JSON UI components
|
|
121
|
+
describe <Component> [--json] Show one component's props, slots, events and an example
|
|
122
|
+
schema Print the spec JSON Schema (generated from the catalog)
|
|
123
|
+
prompt Print the AI system prompt, rules and self-check workflow
|
|
124
|
+
validate <file...> [options] Check specs; exit 1 on errors
|
|
125
|
+
--json Machine-readable output
|
|
126
|
+
--strict Also fail on warnings
|
|
127
|
+
--actions a,b Host action handlers
|
|
128
|
+
--functions f,g Host $computed functions
|
|
129
|
+
--state <file.json> Host-provided state
|
|
130
|
+
--messages <file.json> Message catalog (enables i18n checks)
|
|
131
|
+
render <file> [options] Validate, screenshot and report layout overflow (needs Chrome, Node 22+)
|
|
132
|
+
--out <dir> Screenshot directory (default syno-ui-render)
|
|
133
|
+
--widths 390,640,960,1350 Viewport widths: phone, narrow window, DSM window, wide
|
|
134
|
+
--height <px> Viewport height (default 800)
|
|
135
|
+
--state, --messages As for validate; messages also back $computed t()
|
|
136
|
+
`, ne = /* @__PURE__ */ new Set(["actions", "functions", "state", "messages", "out", "widths", "height", "wide"]);
|
|
137
|
+
function se(e) {
|
|
138
|
+
const t = [], n = {};
|
|
139
|
+
for (let s = 0; s < e.length; s++) {
|
|
140
|
+
const o = e[s];
|
|
141
|
+
if (!o.startsWith("--")) {
|
|
142
|
+
t.push(o);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const [r, i] = o.slice(2).split("=", 2);
|
|
146
|
+
n[r] = i ?? (ne.has(r) && e[s + 1] !== void 0 ? e[++s] : !0);
|
|
147
|
+
}
|
|
148
|
+
return { positional: t, flags: n };
|
|
149
|
+
}
|
|
150
|
+
const f = (e) => typeof e == "string" ? e.split(",").map((t) => t.trim()).filter(Boolean) : void 0;
|
|
151
|
+
function oe(e) {
|
|
152
|
+
return ` ${e.severity} ${e.code} ${e.path || "/"}: ${e.message}${e.hint ? `
|
|
153
|
+
hint: ${e.hint}` : ""}
|
|
154
|
+
`;
|
|
155
|
+
}
|
|
156
|
+
class p extends Error {
|
|
157
|
+
}
|
|
158
|
+
async function C(e, t) {
|
|
159
|
+
try {
|
|
160
|
+
return await e.readFile(t);
|
|
161
|
+
} catch (n) {
|
|
162
|
+
throw new p(`Cannot read ${t}: ${n instanceof Error ? n.message : String(n)}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async function y(e, t) {
|
|
166
|
+
const n = await C(e, t);
|
|
167
|
+
try {
|
|
168
|
+
return JSON.parse(n);
|
|
169
|
+
} catch (s) {
|
|
170
|
+
throw new p(`${t} is not valid JSON: ${s instanceof Error ? s.message : String(s)}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async function x(e, t, n) {
|
|
174
|
+
const s = await C(e, t);
|
|
175
|
+
let o;
|
|
176
|
+
try {
|
|
177
|
+
o = JSON.parse(s);
|
|
178
|
+
} catch (r) {
|
|
179
|
+
return { valid: !1, errors: [{ severity: "error", code: "invalid_json", path: "", message: r instanceof Error ? r.message : String(r), hint: "Return a single JSON object without comments or trailing commas." }], warnings: [] };
|
|
180
|
+
}
|
|
181
|
+
return G(o, n);
|
|
182
|
+
}
|
|
183
|
+
async function J(e, t) {
|
|
184
|
+
return {
|
|
185
|
+
actions: f(t.actions),
|
|
186
|
+
functions: f(t.functions),
|
|
187
|
+
state: typeof t.state == "string" ? await y(e, t.state) : void 0,
|
|
188
|
+
messages: typeof t.messages == "string" ? await y(e, t.messages) : void 0
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
const N = (e, t) => e.errors.length > 0 || !!t.strict && e.warnings.length > 0;
|
|
192
|
+
function $(e) {
|
|
193
|
+
return e.errors.length || e.warnings.length ? `${e.file}: ${e.errors.length} error(s), ${e.warnings.length} warning(s)
|
|
194
|
+
${[...e.errors, ...e.warnings].map(oe).join("")}` : `${e.file}: OK
|
|
195
|
+
`;
|
|
196
|
+
}
|
|
197
|
+
async function re(e, { positional: t, flags: n }) {
|
|
198
|
+
if (!t.length)
|
|
199
|
+
return e.stderr(S), 2;
|
|
200
|
+
const s = await J(e, n), o = [];
|
|
201
|
+
for (const r of t) o.push({ file: r, ...await x(e, r, s) });
|
|
202
|
+
return e.stdout(n.json ? JSON.stringify(o, null, 2) + `
|
|
203
|
+
` : o.map($).join("")), o.some((r) => N(r, n)) ? 1 : 0;
|
|
204
|
+
}
|
|
205
|
+
const ie = [390, 640, 960, 1350];
|
|
206
|
+
async function ae(e, { positional: [t], flags: n }) {
|
|
207
|
+
if (!t)
|
|
208
|
+
return e.stderr(S), 2;
|
|
209
|
+
if (!e.render)
|
|
210
|
+
return e.stderr(`render needs a local Chrome or Chromium (set CHROME to its path) and Node 22 or newer.
|
|
211
|
+
`), 2;
|
|
212
|
+
const s = await J(e, n), o = { file: t, ...await x(e, t, s) };
|
|
213
|
+
if (N(o, n))
|
|
214
|
+
return e.stdout(n.json ? JSON.stringify({ file: t, validation: o, renders: [] }, null, 2) + `
|
|
215
|
+
` : $(o)), 1;
|
|
216
|
+
const r = await e.render({
|
|
217
|
+
spec: await y(e, t),
|
|
218
|
+
state: s.state,
|
|
219
|
+
messages: s.messages,
|
|
220
|
+
widths: f(n.widths)?.map(Number) ?? ie,
|
|
221
|
+
height: typeof n.height == "string" ? Number(n.height) : 800,
|
|
222
|
+
out: typeof n.out == "string" ? n.out : "syno-ui-render",
|
|
223
|
+
name: t.split(/[\\/]/).pop().replace(/\.json$/i, "")
|
|
224
|
+
}).catch((i) => {
|
|
225
|
+
throw new p(`render failed: ${i instanceof Error ? i.message : String(i)}`);
|
|
226
|
+
});
|
|
227
|
+
if (n.json) e.stdout(JSON.stringify({ file: t, validation: o, renders: r }, null, 2) + `
|
|
228
|
+
`);
|
|
229
|
+
else {
|
|
230
|
+
e.stdout(o.warnings.length ? $(o) : "");
|
|
231
|
+
for (const { width: i, screenshot: c, issues: d } of r)
|
|
232
|
+
e.stdout(`${t} @${i}px: ${d.length ? `${d.length} layout issue(s)` : "OK"} ${c}
|
|
233
|
+
` + d.map((l) => ` ${l.kind} ${l.key ?? "(outside the spec)"}: ${l.detail}
|
|
234
|
+
`).join(""));
|
|
235
|
+
}
|
|
236
|
+
return r.some((i) => i.issues.length) ? 1 : 0;
|
|
237
|
+
}
|
|
238
|
+
async function ce(e, t) {
|
|
239
|
+
try {
|
|
240
|
+
return await de(se(e), t);
|
|
241
|
+
} catch (n) {
|
|
242
|
+
if (!(n instanceof p)) throw n;
|
|
243
|
+
return t.stderr(`${n.message}
|
|
244
|
+
`), 2;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
async function de(e, t) {
|
|
248
|
+
const [n, ...s] = e.positional, o = e.flags.json === !0;
|
|
249
|
+
switch (n) {
|
|
250
|
+
case "catalog": {
|
|
251
|
+
const r = B();
|
|
252
|
+
return t.stdout(o ? JSON.stringify({ components: r }, null, 2) + `
|
|
253
|
+
` : r.map((i) => `${i.name}${i.required.length ? ` (${i.required.join(", ")})` : ""}: ${i.description}
|
|
254
|
+
`).join("")), 0;
|
|
255
|
+
}
|
|
256
|
+
case "describe": {
|
|
257
|
+
const r = s[0] ?? "", i = _(r);
|
|
258
|
+
if (!i) {
|
|
259
|
+
const c = V(r);
|
|
260
|
+
return t.stderr(`Unknown component ${JSON.stringify(r)}.${c ? ` Did you mean "${c}"?` : ""} Run "syno-ui catalog".
|
|
261
|
+
`), 2;
|
|
262
|
+
}
|
|
263
|
+
return t.stdout(o ? JSON.stringify(i, null, 2) + `
|
|
264
|
+
` : le(i)), 0;
|
|
265
|
+
}
|
|
266
|
+
case "schema":
|
|
267
|
+
return t.stdout(JSON.stringify(W(), null, 2) + `
|
|
268
|
+
`), 0;
|
|
269
|
+
case "prompt":
|
|
270
|
+
return t.stdout(T()), 0;
|
|
271
|
+
case "validate":
|
|
272
|
+
return re(t, { positional: s, flags: e.flags });
|
|
273
|
+
case "render":
|
|
274
|
+
return ae(t, { positional: s, flags: e.flags });
|
|
275
|
+
default:
|
|
276
|
+
return t.stderr(S), 2;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
function le(e) {
|
|
280
|
+
const t = Object.entries(e.props).map(([n, s]) => ` ${n}${s.required ? "" : "?"}: ${JSON.stringify(s.schema)}
|
|
281
|
+
`).join("");
|
|
282
|
+
return `${e.name}: ${e.description}
|
|
283
|
+
props:
|
|
284
|
+
${t || ` (none)
|
|
285
|
+
`}slots: ${e.slots.join(", ") || "(none)"}
|
|
286
|
+
events: ${e.events.join(", ") || "(none)"}
|
|
287
|
+
example: ${JSON.stringify(e.example)}
|
|
288
|
+
`;
|
|
289
|
+
}
|
|
290
|
+
process.exitCode = await ce(process.argv.slice(2), {
|
|
291
|
+
stdout: (e) => process.stdout.write(e),
|
|
292
|
+
stderr: (e) => process.stderr.write(e),
|
|
293
|
+
readFile: (e) => v(e, "utf8"),
|
|
294
|
+
// The DevTools connection uses the WebSocket global of Node 22 and newer.
|
|
295
|
+
render: typeof WebSocket == "function" ? te(import.meta.url) : void 0
|
|
296
|
+
});
|
|
@@ -1,20 +1,27 @@
|
|
|
1
|
+
import { WideLayout } from '../../../lib/adaptiveLayout';
|
|
1
2
|
type __VLS_Props = {
|
|
2
3
|
sidebarWidth?: string;
|
|
3
4
|
minHeight?: string;
|
|
5
|
+
/** Disable responsive layout if an application deliberately manages it itself. */
|
|
6
|
+
responsive?: boolean;
|
|
7
|
+
/** `web` opts a full-page Portal into the spacious layout at 1200px or wider; DSM windows keep `window`. */
|
|
8
|
+
wideLayout?: WideLayout;
|
|
4
9
|
};
|
|
5
|
-
declare var
|
|
10
|
+
declare var __VLS_6: {}, __VLS_13: {}, __VLS_15: {}, __VLS_17: {};
|
|
6
11
|
type __VLS_Slots = {} & {
|
|
7
|
-
sidebar?: (props: typeof
|
|
12
|
+
sidebar?: (props: typeof __VLS_6) => any;
|
|
8
13
|
} & {
|
|
9
|
-
toolbar?: (props: typeof
|
|
14
|
+
toolbar?: (props: typeof __VLS_13) => any;
|
|
10
15
|
} & {
|
|
11
|
-
default?: (props: typeof
|
|
16
|
+
default?: (props: typeof __VLS_15) => any;
|
|
12
17
|
} & {
|
|
13
|
-
footer?: (props: typeof
|
|
18
|
+
footer?: (props: typeof __VLS_17) => any;
|
|
14
19
|
};
|
|
15
20
|
declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
16
21
|
minHeight: string;
|
|
17
22
|
sidebarWidth: string;
|
|
23
|
+
responsive: boolean;
|
|
24
|
+
wideLayout: WideLayout;
|
|
18
25
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
19
26
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
20
27
|
declare const _default: typeof __VLS_export;
|
|
@@ -4,6 +4,8 @@ type __VLS_Props = {
|
|
|
4
4
|
* `--ui-page-readable-width`; any other value is a CSS maximum width.
|
|
5
5
|
*/
|
|
6
6
|
width?: 'fill' | 'readable' | (string & {});
|
|
7
|
+
/** Web/portal mode uses a page surface by default. Set flat for card-based dashboards. */
|
|
8
|
+
surface?: 'auto' | 'flat' | 'card';
|
|
7
9
|
};
|
|
8
10
|
declare var __VLS_1: {};
|
|
9
11
|
type __VLS_Slots = {} & {
|
|
@@ -11,6 +13,7 @@ type __VLS_Slots = {} & {
|
|
|
11
13
|
};
|
|
12
14
|
declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
13
15
|
width: "fill" | "readable" | (string & {});
|
|
16
|
+
surface: "auto" | "flat" | "card";
|
|
14
17
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
15
18
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
16
19
|
declare const _default: typeof __VLS_export;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { AppPresentation } from '../../../lib/adaptiveLayout';
|
|
2
|
+
/**
|
|
3
|
+
* Optional alternate representations for specialized views.
|
|
4
|
+
* Never silently discard functionality: if a mode has no slot, retain
|
|
5
|
+
* the default content or reuse the closest supplied representation.
|
|
6
|
+
*/
|
|
7
|
+
type __VLS_Props = {
|
|
8
|
+
mode?: 'auto' | AppPresentation;
|
|
9
|
+
};
|
|
10
|
+
declare var __VLS_2: "default" | AppPresentation, __VLS_3: {};
|
|
11
|
+
type __VLS_Slots = {} & {
|
|
12
|
+
[K in NonNullable<typeof __VLS_2>]?: (props: typeof __VLS_3) => any;
|
|
13
|
+
};
|
|
14
|
+
declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
15
|
+
mode: "auto" | AppPresentation;
|
|
16
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
17
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
18
|
+
declare const _default: typeof __VLS_export;
|
|
19
|
+
export default _default;
|
|
20
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
21
|
+
new (): {
|
|
22
|
+
$slots: S;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -10,18 +10,27 @@ type __VLS_Props = {
|
|
|
10
10
|
rowKey?: string;
|
|
11
11
|
emptyText?: string;
|
|
12
12
|
compact?: boolean;
|
|
13
|
+
/** Simple tables become fully labeled cards in mobile mode unless set to table. */
|
|
14
|
+
mobileView?: 'auto' | 'cards' | 'table';
|
|
13
15
|
};
|
|
14
16
|
declare var __VLS_2: `cell-${string}`, __VLS_3: {
|
|
15
17
|
row: Record<string, unknown>;
|
|
16
18
|
value: unknown;
|
|
17
19
|
column: DataTableColumn;
|
|
20
|
+
}, __VLS_6: `cell-${string}`, __VLS_7: {
|
|
21
|
+
row: Record<string, unknown>;
|
|
22
|
+
value: unknown;
|
|
23
|
+
column: DataTableColumn;
|
|
18
24
|
};
|
|
19
25
|
type __VLS_Slots = {} & {
|
|
20
26
|
[K in NonNullable<typeof __VLS_2>]?: (props: typeof __VLS_3) => any;
|
|
27
|
+
} & {
|
|
28
|
+
[K in NonNullable<typeof __VLS_6>]?: (props: typeof __VLS_7) => any;
|
|
21
29
|
};
|
|
22
30
|
declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
23
31
|
compact: boolean;
|
|
24
32
|
rowKey: string;
|
|
33
|
+
mobileView: "auto" | "cards" | "table";
|
|
25
34
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
26
35
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
27
36
|
declare const _default: typeof __VLS_export;
|
package/dist/index.d.ts
CHANGED
|
@@ -153,6 +153,9 @@ export type { AboutCheckState, AboutVersionInfo } from './components/composite/a
|
|
|
153
153
|
export { default as AppRoot } from './components/app/app-root/AppRoot.vue';
|
|
154
154
|
export { APP_ROOT_ATTRIBUTE, APP_ROOT_SELECTOR } from './lib/appRoot';
|
|
155
155
|
export { default as AppLayout } from './components/app/app-layout/AppLayout.vue';
|
|
156
|
+
export { default as ResponsiveView } from './components/app/responsive-view/ResponsiveView.vue';
|
|
157
|
+
export { appPresentationForWidth, MOBILE_LAYOUT_MAX, WEB_LAYOUT_MIN } from './lib/adaptiveLayout';
|
|
158
|
+
export type { AppPresentation, WideLayout } from './lib/adaptiveLayout';
|
|
156
159
|
export { default as AppSidebar } from './components/app/app-sidebar/AppSidebar.vue';
|
|
157
160
|
export type { AppSidebarGroup, AppSidebarItem } from './components/app/app-sidebar/AppSidebar.vue';
|
|
158
161
|
export { default as AppToolbar } from './components/app/app-toolbar/AppToolbar.vue';
|