@bendyline/squisq-react 2.2.0 → 2.3.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/NOTICE.md +6 -7
- package/dist/AudioController-DwMsPe38.d.ts +48 -0
- package/dist/chunk-7FVQ7T3I.js +2529 -0
- package/dist/chunk-D7KN4CRG.js +396 -0
- package/dist/chunk-LR3AIGDD.js +58 -0
- package/dist/chunk-NANF7REM.js +330 -0
- package/dist/chunk-NWZQGZIJ.js +675 -0
- package/dist/chunk-TQH6RTTV.js +789 -0
- package/dist/chunk-TT6ENR6T.js +26 -0
- package/dist/chunk-WLUZTUNZ.js +111 -0
- package/dist/chunk-XYS7HMP4.js +1604 -0
- package/dist/chunk-YQC3AXXU.js +92 -0
- package/dist/hooks/index.d.ts +187 -0
- package/dist/hooks/index.js +32 -0
- package/dist/index.d.ts +14 -904
- package/dist/index.js +53 -6440
- package/dist/json-view/index.d.ts +21 -0
- package/dist/json-view/index.js +10 -0
- package/dist/layers/index.d.ts +124 -0
- package/dist/layers/index.js +24 -0
- package/dist/markdown/index.d.ts +44 -0
- package/dist/markdown/index.js +11 -0
- package/dist/page/index.d.ts +105 -0
- package/dist/page/index.js +19 -0
- package/dist/player/index.d.ts +410 -0
- package/dist/player/index.js +41 -0
- package/dist/squisq-player.full.global.js +361 -361
- package/dist/squisq-player.global.js +57 -57
- package/dist/standalone-source.js +1 -1
- package/package.json +30 -3
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useAutoSurface
|
|
3
|
+
} from "./chunk-TT6ENR6T.js";
|
|
4
|
+
import {
|
|
5
|
+
MarkdownRenderer
|
|
6
|
+
} from "./chunk-D7KN4CRG.js";
|
|
7
|
+
|
|
8
|
+
// src/jsonView/useJsonViewTokens.ts
|
|
9
|
+
import { useMemo } from "react";
|
|
10
|
+
import { buildJsonFormTokens, resolveJsonFormTheme } from "@bendyline/squisq/jsonForm";
|
|
11
|
+
function useJsonViewTokens(theme, surface) {
|
|
12
|
+
const auto = useAutoSurface(surface === "auto");
|
|
13
|
+
const effectiveSurface = surface === "auto" ? auto : surface ?? void 0;
|
|
14
|
+
return useMemo(() => {
|
|
15
|
+
const style = buildJsonFormTokens(theme, effectiveSurface, {
|
|
16
|
+
prefix: "--squisq-json"
|
|
17
|
+
});
|
|
18
|
+
return { style, theme: resolveJsonFormTheme(theme, effectiveSurface) };
|
|
19
|
+
}, [theme, effectiveSurface]);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// src/jsonView/RenderNode.tsx
|
|
23
|
+
import {
|
|
24
|
+
chooseControl,
|
|
25
|
+
resolveFlag,
|
|
26
|
+
resolveRef
|
|
27
|
+
} from "@bendyline/squisq/jsonForm";
|
|
28
|
+
|
|
29
|
+
// src/jsonView/viewers.tsx
|
|
30
|
+
import { Fragment, useMemo as useMemo2 } from "react";
|
|
31
|
+
import {
|
|
32
|
+
arrayItemKind
|
|
33
|
+
} from "@bendyline/squisq/jsonForm";
|
|
34
|
+
import { parseMarkdown } from "@bendyline/squisq/markdown";
|
|
35
|
+
import { Fragment as Fragment2, jsx, jsxs } from "react/jsx-runtime";
|
|
36
|
+
function TextViewer({ value }) {
|
|
37
|
+
if (value === void 0 || value === null || value === "") {
|
|
38
|
+
return /* @__PURE__ */ jsx("span", { className: "squisq-jv-empty", children: "\u2014" });
|
|
39
|
+
}
|
|
40
|
+
return /* @__PURE__ */ jsx("span", { className: "squisq-jv-value", children: String(value) });
|
|
41
|
+
}
|
|
42
|
+
function MultilineViewer({ value }) {
|
|
43
|
+
if (value === void 0 || value === null || value === "") {
|
|
44
|
+
return /* @__PURE__ */ jsx("span", { className: "squisq-jv-empty", children: "\u2014" });
|
|
45
|
+
}
|
|
46
|
+
return /* @__PURE__ */ jsx("span", { className: "squisq-jv-value squisq-jv-value--multiline", children: String(value) });
|
|
47
|
+
}
|
|
48
|
+
function RichTextViewer({ value }) {
|
|
49
|
+
const nodes = useMemo2(() => {
|
|
50
|
+
if (typeof value !== "string" || value === "") return null;
|
|
51
|
+
try {
|
|
52
|
+
const doc = parseMarkdown(value);
|
|
53
|
+
return doc.children;
|
|
54
|
+
} catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}, [value]);
|
|
58
|
+
if (!nodes) return /* @__PURE__ */ jsx("span", { className: "squisq-jv-empty", children: "\u2014" });
|
|
59
|
+
return /* @__PURE__ */ jsx("div", { className: "squisq-jv-richtext", children: /* @__PURE__ */ jsx(MarkdownRenderer, { nodes }) });
|
|
60
|
+
}
|
|
61
|
+
function NumberViewer({ value }) {
|
|
62
|
+
if (value === void 0 || value === null) {
|
|
63
|
+
return /* @__PURE__ */ jsx("span", { className: "squisq-jv-empty", children: "\u2014" });
|
|
64
|
+
}
|
|
65
|
+
return /* @__PURE__ */ jsx("span", { className: "squisq-jv-value", children: String(value) });
|
|
66
|
+
}
|
|
67
|
+
function BooleanViewer({ value }) {
|
|
68
|
+
const on = Boolean(value);
|
|
69
|
+
return /* @__PURE__ */ jsx("span", { className: `squisq-jv-toggle squisq-jv-toggle--${on ? "on" : "off"}`, children: on ? "On" : "Off" });
|
|
70
|
+
}
|
|
71
|
+
function EnumViewer({ value, schema }) {
|
|
72
|
+
if (value === void 0 || value === null || value === "") {
|
|
73
|
+
return /* @__PURE__ */ jsx("span", { className: "squisq-jv-empty", children: "\u2014" });
|
|
74
|
+
}
|
|
75
|
+
const labels = schema.squisq?.enumLabels;
|
|
76
|
+
const display = labels && typeof value === "string" ? labels[value] ?? value : String(value);
|
|
77
|
+
return /* @__PURE__ */ jsx("span", { className: "squisq-jv-value", children: display });
|
|
78
|
+
}
|
|
79
|
+
function ColorViewer({ value }) {
|
|
80
|
+
if (typeof value !== "string" || value === "") {
|
|
81
|
+
return /* @__PURE__ */ jsx("span", { className: "squisq-jv-empty", children: "\u2014" });
|
|
82
|
+
}
|
|
83
|
+
return /* @__PURE__ */ jsxs("span", { className: "squisq-jv-color", children: [
|
|
84
|
+
/* @__PURE__ */ jsx("span", { className: "squisq-jv-color__swatch", style: { background: value }, "aria-hidden": true }),
|
|
85
|
+
/* @__PURE__ */ jsx("span", { className: "squisq-jv-color__hex", children: value })
|
|
86
|
+
] });
|
|
87
|
+
}
|
|
88
|
+
function DateViewer({ value, schema }) {
|
|
89
|
+
if (typeof value !== "string" || value === "") {
|
|
90
|
+
return /* @__PURE__ */ jsx("span", { className: "squisq-jv-empty", children: "\u2014" });
|
|
91
|
+
}
|
|
92
|
+
const fmt = schema.format;
|
|
93
|
+
let display = value;
|
|
94
|
+
try {
|
|
95
|
+
const date = new Date(value);
|
|
96
|
+
if (!Number.isNaN(date.getTime())) {
|
|
97
|
+
if (fmt === "time") {
|
|
98
|
+
display = date.toLocaleTimeString();
|
|
99
|
+
} else if (fmt === "date") {
|
|
100
|
+
display = date.toLocaleDateString();
|
|
101
|
+
} else {
|
|
102
|
+
display = date.toLocaleString();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
} catch {
|
|
106
|
+
}
|
|
107
|
+
return /* @__PURE__ */ jsx("span", { className: "squisq-jv-value", children: display });
|
|
108
|
+
}
|
|
109
|
+
function ChipBinViewer({ value, schema }) {
|
|
110
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
111
|
+
return /* @__PURE__ */ jsx("span", { className: "squisq-jv-empty", children: "\u2014" });
|
|
112
|
+
}
|
|
113
|
+
const itemSchema = Array.isArray(schema.items) ? schema.items[0] : schema.items;
|
|
114
|
+
const labels = itemSchema?.squisq?.enumLabels;
|
|
115
|
+
return /* @__PURE__ */ jsx("div", { className: "squisq-jv-chip-bin", children: value.map((item, i) => {
|
|
116
|
+
const label = labels && typeof item === "string" ? labels[item] ?? String(item) : String(item);
|
|
117
|
+
return /* @__PURE__ */ jsx("span", { className: "squisq-jv-chip", children: label }, i);
|
|
118
|
+
}) });
|
|
119
|
+
}
|
|
120
|
+
function CardStackViewer(props) {
|
|
121
|
+
const { value, schema, rootSchema, rootData, pointer, density } = props;
|
|
122
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
123
|
+
return /* @__PURE__ */ jsx("span", { className: "squisq-jv-empty", children: "No items" });
|
|
124
|
+
}
|
|
125
|
+
const itemSchema = (Array.isArray(schema.items) ? schema.items[0] : schema.items) ?? {};
|
|
126
|
+
const itemLabel = itemSchema.squisq?.itemLabel;
|
|
127
|
+
return /* @__PURE__ */ jsx("div", { className: "squisq-jv-card-stack", children: value.map((item, i) => {
|
|
128
|
+
const title = resolveItemTitle(itemLabel, item, i);
|
|
129
|
+
return /* @__PURE__ */ jsxs("div", { className: "squisq-jv-card", children: [
|
|
130
|
+
title ? /* @__PURE__ */ jsx("h4", { className: "squisq-jv-card__title", children: title }) : null,
|
|
131
|
+
/* @__PURE__ */ jsx(
|
|
132
|
+
RenderNode,
|
|
133
|
+
{
|
|
134
|
+
value: item,
|
|
135
|
+
schema: itemSchema,
|
|
136
|
+
rootSchema,
|
|
137
|
+
rootData,
|
|
138
|
+
pointer: `${pointer}/${i}`,
|
|
139
|
+
density,
|
|
140
|
+
suppressTopGroupTitle: true
|
|
141
|
+
}
|
|
142
|
+
)
|
|
143
|
+
] }, i);
|
|
144
|
+
}) });
|
|
145
|
+
}
|
|
146
|
+
function resolveItemTitle(spec, item, index) {
|
|
147
|
+
if (!spec) return `Item ${index + 1}`;
|
|
148
|
+
if (typeof spec === "string") return spec;
|
|
149
|
+
if (item && typeof item === "object") {
|
|
150
|
+
const v = item[spec.fromField];
|
|
151
|
+
if (typeof v === "string" && v !== "") return v;
|
|
152
|
+
if (typeof v === "number") return String(v);
|
|
153
|
+
}
|
|
154
|
+
return `Item ${index + 1}`;
|
|
155
|
+
}
|
|
156
|
+
function GroupViewer(props) {
|
|
157
|
+
const { value, schema, rootSchema, rootData, pointer, density, suppressTitle } = props;
|
|
158
|
+
const title = !suppressTitle ? schema.squisq?.label ?? schema.title : void 0;
|
|
159
|
+
const help = schema.squisq?.help ?? schema.description;
|
|
160
|
+
const obj = (value && typeof value === "object" ? value : {}) ?? {};
|
|
161
|
+
const propEntries = Object.entries(schema.properties ?? {});
|
|
162
|
+
return /* @__PURE__ */ jsxs("section", { className: "squisq-jv-group", children: [
|
|
163
|
+
title ? /* @__PURE__ */ jsx("h3", { className: "squisq-jv-group__title", children: title }) : null,
|
|
164
|
+
help ? /* @__PURE__ */ jsx("p", { className: "squisq-jv-group__help", children: help }) : null,
|
|
165
|
+
propEntries.map(([key, propSchema]) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
166
|
+
RowOrSection,
|
|
167
|
+
{
|
|
168
|
+
label: propSchema.squisq?.label ?? propSchema.title ?? key,
|
|
169
|
+
help: propSchema.squisq?.help ?? propSchema.description,
|
|
170
|
+
kindHint: propSchema,
|
|
171
|
+
children: /* @__PURE__ */ jsx(
|
|
172
|
+
RenderNode,
|
|
173
|
+
{
|
|
174
|
+
value: obj[key],
|
|
175
|
+
schema: propSchema,
|
|
176
|
+
rootSchema,
|
|
177
|
+
rootData,
|
|
178
|
+
pointer: `${pointer}/${key}`,
|
|
179
|
+
density,
|
|
180
|
+
suppressTopGroupTitle: true
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
) }, key))
|
|
185
|
+
] });
|
|
186
|
+
}
|
|
187
|
+
function RowOrSection({
|
|
188
|
+
label,
|
|
189
|
+
help,
|
|
190
|
+
kindHint,
|
|
191
|
+
children
|
|
192
|
+
}) {
|
|
193
|
+
const composite = isCompositeKind(kindHint);
|
|
194
|
+
if (composite) {
|
|
195
|
+
return /* @__PURE__ */ jsx(Fragment2, { children });
|
|
196
|
+
}
|
|
197
|
+
return /* @__PURE__ */ jsxs("div", { className: "squisq-jv-row", children: [
|
|
198
|
+
/* @__PURE__ */ jsx("div", { className: "squisq-jv-label", title: help, children: label }),
|
|
199
|
+
/* @__PURE__ */ jsx("div", { children })
|
|
200
|
+
] });
|
|
201
|
+
}
|
|
202
|
+
function isCompositeKind(schema) {
|
|
203
|
+
const t = schema.type;
|
|
204
|
+
const arrayLike = t === "array" || Array.isArray(t) && t.includes("array");
|
|
205
|
+
if (arrayLike) {
|
|
206
|
+
return arrayItemKind(schema) === "object";
|
|
207
|
+
}
|
|
208
|
+
const objectLike = t === "object" || Array.isArray(t) && t.includes("object");
|
|
209
|
+
if (objectLike) return true;
|
|
210
|
+
if (schema.oneOf || schema.anyOf) return true;
|
|
211
|
+
if (schema.format === "markdown" || schema.squisq?.control === "richtext") return true;
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
function TabsViewer(props) {
|
|
215
|
+
const { value, schema, rootSchema, rootData, pointer, density } = props;
|
|
216
|
+
const branches = (schema.oneOf ?? schema.anyOf ?? []).slice();
|
|
217
|
+
const matchedIndex = pickMatchingBranch(branches, value);
|
|
218
|
+
const branch = branches[matchedIndex];
|
|
219
|
+
if (!branch) {
|
|
220
|
+
return /* @__PURE__ */ jsx(TextViewer, { ...props });
|
|
221
|
+
}
|
|
222
|
+
return /* @__PURE__ */ jsxs("div", { className: "squisq-jv-tabs", children: [
|
|
223
|
+
/* @__PURE__ */ jsx("span", { className: "squisq-jv-tabs__discriminator", children: branch.squisq?.label ?? branch.title ?? `Option ${matchedIndex + 1}` }),
|
|
224
|
+
/* @__PURE__ */ jsx(
|
|
225
|
+
RenderNode,
|
|
226
|
+
{
|
|
227
|
+
value,
|
|
228
|
+
schema: branch,
|
|
229
|
+
rootSchema,
|
|
230
|
+
rootData,
|
|
231
|
+
pointer,
|
|
232
|
+
density
|
|
233
|
+
}
|
|
234
|
+
)
|
|
235
|
+
] });
|
|
236
|
+
}
|
|
237
|
+
function pickMatchingBranch(branches, value) {
|
|
238
|
+
for (let i = 0; i < branches.length; i++) {
|
|
239
|
+
if (matchesShape(branches[i], value)) return i;
|
|
240
|
+
}
|
|
241
|
+
return 0;
|
|
242
|
+
}
|
|
243
|
+
function matchesShape(schema, value) {
|
|
244
|
+
const t = schema.type;
|
|
245
|
+
const target = Array.isArray(t) ? t.find((x) => x !== "null") : t;
|
|
246
|
+
if (!target) return true;
|
|
247
|
+
switch (target) {
|
|
248
|
+
case "string":
|
|
249
|
+
return typeof value === "string";
|
|
250
|
+
case "number":
|
|
251
|
+
case "integer":
|
|
252
|
+
return typeof value === "number";
|
|
253
|
+
case "boolean":
|
|
254
|
+
return typeof value === "boolean";
|
|
255
|
+
case "null":
|
|
256
|
+
return value === null;
|
|
257
|
+
case "array":
|
|
258
|
+
return Array.isArray(value);
|
|
259
|
+
case "object":
|
|
260
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
261
|
+
default:
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
var VIEWERS = {
|
|
266
|
+
text: TextViewer,
|
|
267
|
+
multiline: MultilineViewer,
|
|
268
|
+
richtext: RichTextViewer,
|
|
269
|
+
color: ColorViewer,
|
|
270
|
+
date: DateViewer,
|
|
271
|
+
time: DateViewer,
|
|
272
|
+
datetime: DateViewer,
|
|
273
|
+
slider: NumberViewer,
|
|
274
|
+
stepper: NumberViewer,
|
|
275
|
+
segmented: EnumViewer,
|
|
276
|
+
radio: EnumViewer,
|
|
277
|
+
combobox: EnumViewer,
|
|
278
|
+
toggle: BooleanViewer,
|
|
279
|
+
checkbox: BooleanViewer,
|
|
280
|
+
card: GroupViewer,
|
|
281
|
+
group: GroupViewer,
|
|
282
|
+
"card-stack": CardStackViewer,
|
|
283
|
+
"chip-bin": ChipBinViewer,
|
|
284
|
+
tabs: TabsViewer
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
// src/jsonView/RenderNode.tsx
|
|
288
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
289
|
+
function RenderNode(props) {
|
|
290
|
+
const resolved = resolveRef(props.schema, props.rootSchema) ?? props.schema;
|
|
291
|
+
if (resolveFlag(resolved.squisq?.hidden, props.rootData)) return null;
|
|
292
|
+
const kind = chooseControl(resolved);
|
|
293
|
+
const Viewer = VIEWERS[kind];
|
|
294
|
+
const viewerProps = {
|
|
295
|
+
value: props.value,
|
|
296
|
+
schema: resolved,
|
|
297
|
+
rootSchema: props.rootSchema,
|
|
298
|
+
rootData: props.rootData,
|
|
299
|
+
pointer: props.pointer,
|
|
300
|
+
density: props.density
|
|
301
|
+
};
|
|
302
|
+
if (kind === "group" || kind === "card") {
|
|
303
|
+
const Group = Viewer;
|
|
304
|
+
return /* @__PURE__ */ jsx2(Group, { ...viewerProps, suppressTitle: props.suppressTopGroupTitle });
|
|
305
|
+
}
|
|
306
|
+
return /* @__PURE__ */ jsx2(Viewer, { ...viewerProps });
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// src/jsonView/JsonView.tsx
|
|
310
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
311
|
+
function JsonView(props) {
|
|
312
|
+
const { schema, value, theme, surface, density = "comfortable", className } = props;
|
|
313
|
+
const { style } = useJsonViewTokens(theme, surface);
|
|
314
|
+
const cls = "squisq-json-view" + (density === "compact" ? " squisq-json-view--compact" : "") + (className ? ` ${className}` : "");
|
|
315
|
+
return /* @__PURE__ */ jsx3("div", { className: cls, style, children: /* @__PURE__ */ jsx3(
|
|
316
|
+
RenderNode,
|
|
317
|
+
{
|
|
318
|
+
value,
|
|
319
|
+
schema,
|
|
320
|
+
rootSchema: schema,
|
|
321
|
+
rootData: value,
|
|
322
|
+
pointer: "",
|
|
323
|
+
density
|
|
324
|
+
}
|
|
325
|
+
) });
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export {
|
|
329
|
+
JsonView
|
|
330
|
+
};
|