@morlay/dsh-client-ui-primitives 0.0.8 → 0.0.9

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.
Files changed (44) hide show
  1. package/README.md +17 -18
  2. package/dist/client-DYp99CgT.mjs +3730 -0
  3. package/dist/client-uyVkC7mu.cjs +17197 -0
  4. package/dist/client.cjs +54 -0
  5. package/dist/client.d.cts +4 -0
  6. package/dist/client.d.mts +2 -664
  7. package/dist/client.mjs +2 -3728
  8. package/dist/index-AMHtcyMt.d.mts +647 -0
  9. package/dist/index.cjs +54 -0
  10. package/dist/index.d.mts +4 -5
  11. package/dist/index.mjs +4 -5
  12. package/dist/reference-hchCWm3z.cjs +482 -0
  13. package/dist/reference.cjs +4 -0
  14. package/dist/reference.d.mts +3 -0
  15. package/dist/reference.mjs +1 -0
  16. package/package.json +28 -30
  17. package/src/client/controls/IconButton.tsx +4 -2
  18. package/src/client/controls/ModelRouteList.module.css +1 -1
  19. package/src/client/controls/SeatButton.module.css +1 -1
  20. package/src/client/controls/SeatButton.tsx +1 -2
  21. package/src/client/controls/classes.ts +1 -3
  22. package/src/client/controls/index.ts +1 -7
  23. package/src/client/index.ts +7 -1
  24. package/src/client/layout/Row.tsx +20 -17
  25. package/src/client/layout/Stack.tsx +19 -16
  26. package/src/client/layout/Text.tsx +8 -1
  27. package/src/client/schema-form/Editor.tsx +26 -9
  28. package/src/client/schema-form/SchemaForm.tsx +6 -1
  29. package/src/client/schema-form/index.ts +5 -0
  30. package/src/client/schema-form/schema-form.module.css +16 -16
  31. package/src/client/schema-form/testing/fake-scope.ts +0 -1
  32. package/src/client/schema-form/value.tsx +8 -3
  33. package/src/client/settings-form/SettingsFieldRow.module.css +1 -1
  34. package/src/client/settings-form/SettingsFieldRow.tsx +4 -2
  35. package/src/index.ts +6 -2
  36. package/src/reference-markdown.tsx +2 -6
  37. package/dist/rolldown-runtime-EAsCxrDo.mjs +0 -14
  38. package/locale/en.json +0 -6
  39. package/locale/zh.json +0 -6
  40. package/src/client/controls/SearchInput.module.css +0 -11
  41. package/src/client/controls/SearchInput.tsx +0 -22
  42. package/src/client/controls/Tabs.module.css +0 -48
  43. package/src/client/controls/Tabs.tsx +0 -57
  44. /package/src/{client/markdown-text.ts → markdown-text.ts} +0 -0
package/dist/client.mjs CHANGED
@@ -1,3730 +1,4 @@
1
- import { n as __exportAll, t as __commonJSMin } from "./rolldown-runtime-EAsCxrDo.mjs";
1
+ import { A as failureOf, C as markdownLabels, D as SchemaFormHints, E as rowRegistrations, O as SchemaFormController, S as Row, T as schema_form_exports, _ as Button, a as TagInput, b as Text, c as SearchSelect, d as IconButton, f as VisuallyHidden, g as DisclosureRow, h as SeatButton, i as referenceMentions, j as walkFields, k as projectRoot, l as MultilineField, m as Spinner, n as inject, o as mergeTags, p as TimeLabel, r as ReferenceMarkdown, s as parseTagList, t as apply, u as ModelRouteList, v as Bubble, w as NS, x as Stack, y as SettingsFieldRow } from "./client-DYp99CgT.mjs";
2
2
  import { a as parseReference, i as isLocalReference, n as formatReference, o as parseReferenceToken, r as formatReferenceMention, t as findReferences } from "./reference-Cjcn21uW.mjs";
3
- import { createSnapshotStore } from "@deepseek-ai/dsh-client-store";
4
- import { Service } from "@deepseek-ai/cordis";
5
- import { cloneElement, forwardRef, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
6
- import { Button as Button$1, DisclosureRow as DisclosureRow$1, IconCheckOutlineRegular, IconChevronDownOutlineRegular, IconChevronRightOutlineRegular, IconCloseOutlineRegular, IconCopyOutlineRegular, IconRefreshOutlineRegular, IconTrashOutlineRegular, Input, MarkdownText, Menu, MenuItemButton, SettingsForm, Tooltip, rankByName } from "@deepseek-ai/dsh-client-ui-primitives";
7
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
3
  export * from "@deepseek-ai/dsh-client-ui-primitives";
9
- function emptyMeta() {
10
- return {
11
- description: void 0,
12
- comment: void 0,
13
- link: void 0,
14
- role: void 0,
15
- secret: false,
16
- required: false,
17
- disabled: false,
18
- collapse: false,
19
- badges: [],
20
- pattern: void 0,
21
- min: void 0,
22
- max: void 0,
23
- step: void 0,
24
- hasDefault: false,
25
- defaultValue: void 0,
26
- extra: void 0
27
- };
28
- }
29
- function badgesOf(meta) {
30
- return (meta.badges ?? []).map((badge) => badge.text);
31
- }
32
- function metaOf(schema) {
33
- const meta = schema.meta ?? {};
34
- return {
35
- description: meta.description,
36
- comment: meta.comment,
37
- link: meta.link,
38
- role: meta.role,
39
- secret: meta.role === "secret",
40
- required: meta.required === true,
41
- disabled: meta.disabled === true,
42
- collapse: meta.collapse === true,
43
- badges: badgesOf(meta),
44
- pattern: typeof meta.pattern === "string" ? meta.pattern : meta.pattern?.source ?? void 0,
45
- min: meta.min,
46
- max: meta.max,
47
- step: meta.step,
48
- hasDefault: meta.default !== void 0,
49
- defaultValue: meta.default,
50
- extra: meta.extra
51
- };
52
- }
53
- function mergeMeta(inner, outer) {
54
- const merged = { ...inner };
55
- for (const [key, value] of Object.entries(outer)) if (value !== void 0) merged[key] = value;
56
- return merged;
57
- }
58
- function keyOf(path) {
59
- return path[path.length - 1] ?? "";
60
- }
61
- function stringLeaf(path, meta) {
62
- return {
63
- key: keyOf(path),
64
- path,
65
- label: void 0,
66
- meta,
67
- readOnly: null,
68
- type: "string"
69
- };
70
- }
71
- function leafTypeOf(type) {
72
- switch (type) {
73
- case "string": return "string";
74
- case "number": return "number";
75
- case "boolean": return "boolean";
76
- case "function": return "function";
77
- case "never": return "never";
78
- default: return "any";
79
- }
80
- }
81
- function projectNode(schema, path = []) {
82
- return project(schema, path, []);
83
- }
84
- function project(schema, path, ancestors) {
85
- const base = {
86
- key: keyOf(path),
87
- path,
88
- label: void 0,
89
- meta: metaOf(schema),
90
- readOnly: null
91
- };
92
- if (ancestors.includes(schema)) return {
93
- ...base,
94
- type: "recursive",
95
- origin: schema.type
96
- };
97
- const chain = [...ancestors, schema];
98
- switch (schema.type) {
99
- case "object": {
100
- const fields = Object.entries(schema.dict ?? {}).filter(([, child]) => child.meta?.hidden !== true).map(([key, child]) => project(child, [...path, key], chain));
101
- return {
102
- ...base,
103
- type: "object",
104
- fields
105
- };
106
- }
107
- case "dict": {
108
- const segment = [...path, "*"];
109
- const keyNode = schema.sKey === void 0 ? stringLeaf(segment, emptyMeta()) : project(schema.sKey, segment, chain);
110
- return {
111
- ...base,
112
- type: "dict",
113
- keyNode,
114
- valueNode: project(schema.inner ?? schema, segment, chain)
115
- };
116
- }
117
- case "array": {
118
- const item = project(schema.inner ?? schema, [...path, "*"], chain);
119
- return {
120
- ...base,
121
- type: "array",
122
- item,
123
- mergeKey: mergeKeyOf(schema, item)
124
- };
125
- }
126
- case "tuple": {
127
- const items = (schema.list ?? []).map((child, index) => project(child, [...path, String(index)], chain));
128
- return {
129
- ...base,
130
- type: "tuple",
131
- items
132
- };
133
- }
134
- case "union": {
135
- const members = schema.list ?? [];
136
- const variants = members.map((child) => project(child, path, chain));
137
- const literals = members.every((child) => child.type === "const") ? members.map((child) => child.value) : void 0;
138
- return {
139
- ...base,
140
- type: "union",
141
- choices: literals,
142
- variants,
143
- tagKey: tagKeyOf(schema, variants)
144
- };
145
- }
146
- case "intersect": return {
147
- ...base,
148
- type: "intersect",
149
- members: (schema.list ?? []).map((child) => project(child, path, chain))
150
- };
151
- case "bitset": {
152
- const bits = Object.entries(schema.bits ?? {}).map(([name, bit]) => ({
153
- name,
154
- bit
155
- }));
156
- return {
157
- ...base,
158
- type: "bitset",
159
- bits
160
- };
161
- }
162
- case "const": return {
163
- ...base,
164
- type: "const",
165
- value: schema.value
166
- };
167
- case "transform": {
168
- const projected = project(schema.inner ?? schema, path, chain);
169
- return {
170
- ...projected,
171
- meta: mergeMeta(projected.meta, base.meta),
172
- readOnly: "transform"
173
- };
174
- }
175
- case "lazy": {
176
- const inner = schema.inner;
177
- return inner === void 0 ? {
178
- ...base,
179
- type: "any"
180
- } : {
181
- ...base,
182
- type: "lazy",
183
- inner: project(inner, path, chain)
184
- };
185
- }
186
- case "is": return {
187
- ...base,
188
- type: "any",
189
- readOnly: "constructor"
190
- };
191
- default: return {
192
- ...base,
193
- type: leafTypeOf(schema.type),
194
- readOnly: schema.type === "function" ? "function" : null
195
- };
196
- }
197
- }
198
- function unwrapLazy(node) {
199
- let current = node;
200
- while (current?.type === "lazy") current = current.inner;
201
- return current;
202
- }
203
- function fieldsOf(node) {
204
- const current = unwrapLazy(node);
205
- switch (current?.type) {
206
- case "object": return current.fields;
207
- case "union": return current.variants.flatMap((variant) => fieldsOf(variant));
208
- case "intersect": return current.members.flatMap((member) => fieldsOf(member));
209
- default: return [];
210
- }
211
- }
212
- function seekNode(root, path) {
213
- let current = root;
214
- for (const segment of path) {
215
- const node = unwrapLazy(current);
216
- if (node === void 0) return void 0;
217
- switch (node.type) {
218
- case "object":
219
- case "union":
220
- case "intersect":
221
- current = fieldsOf(node).find((field) => field.key === segment);
222
- break;
223
- case "dict":
224
- current = node.valueNode;
225
- break;
226
- case "array":
227
- current = node.item;
228
- break;
229
- case "tuple":
230
- current = node.items[Number(segment)];
231
- break;
232
- default: return;
233
- }
234
- }
235
- return unwrapLazy(current);
236
- }
237
- function walkFields(root, value) {
238
- const out = [];
239
- visit(root, root.path, value, out, true, void 0, /* @__PURE__ */ new Set(), void 0);
240
- return out;
241
- }
242
- function visit(node, path, value, out, emit, label, emitted, member) {
243
- const current = unwrapLazy(node);
244
- if (current === void 0) return;
245
- const positioned = {
246
- ...current,
247
- path,
248
- ...member === void 0 ? {} : { key: member.key },
249
- ...label === void 0 ? {} : { label }
250
- };
251
- const key = JSON.stringify(path);
252
- if (emit && !emitted.has(key)) {
253
- emitted.add(key);
254
- out.push({
255
- path,
256
- node: positioned,
257
- ...member === void 0 ? {} : { member }
258
- });
259
- }
260
- switch (positioned.type) {
261
- case "object":
262
- for (const field of positioned.fields) {
263
- const child = memberOf(value, field.key);
264
- if (child === void 0 && field.meta.required !== true) continue;
265
- visit(field, [...path, field.key], child, out, true, void 0, emitted, void 0);
266
- }
267
- return;
268
- case "dict":
269
- for (const [key, child] of entriesOf(value)) visit(positioned.valueNode, [...path, key], child, out, true, void 0, emitted, {
270
- parent: path,
271
- key,
272
- index: void 0
273
- });
274
- return;
275
- case "array":
276
- for (const [key, child] of entriesOf(value)) {
277
- const label = positioned.mergeKey === void 0 ? void 0 : memberLabel(child, positioned.mergeKey);
278
- visit(positioned.item, [...path, key], child, out, true, label, emitted, {
279
- parent: path,
280
- key,
281
- index: Number(key)
282
- });
283
- }
284
- return;
285
- case "tuple":
286
- positioned.items.forEach((item, index) => {
287
- visit(item, [...path, String(index)], memberOf(value, index), out, true, void 0, emitted, void 0);
288
- });
289
- return;
290
- case "union": {
291
- if (positioned.choices !== void 0) return;
292
- const variant = pickVariant(positioned, value);
293
- if (variant !== void 0) visit(variant, path, value, out, false, void 0, emitted, member);
294
- return;
295
- }
296
- case "intersect":
297
- for (const part of positioned.members) visit(part, path, value, out, false, void 0, emitted, member);
298
- return;
299
- default: return;
300
- }
301
- }
302
- function mergeKeyOf(schema, item) {
303
- const declared = declaredExtra(schema, "mergeKey");
304
- if (declared !== void 0) return declared;
305
- const current = unwrapLazy(item);
306
- return current?.type === "object" && current.fields.some((field) => field.key === "id") ? "id" : void 0;
307
- }
308
- function tagKeyOf(schema, variants) {
309
- const declared = declaredExtra(schema, "tag");
310
- if (declared !== void 0) return declared;
311
- const members = variants.map((variant) => unwrapLazy(variant));
312
- if (members.length === 0 || members.some((member) => member?.type !== "object")) return void 0;
313
- const objects = members;
314
- const candidates = (objects[0]?.fields ?? []).map((field) => unwrapLazy(field)).filter((field) => field?.type === "const").map((field) => field.key).filter((key) => objects.every((object) => unwrapLazy(object.fields.find((field) => field.key === key))?.type === "const"));
315
- return candidates.length === 1 ? candidates[0] : void 0;
316
- }
317
- function declaredExtra(schema, name) {
318
- const extra = schema.meta?.extra;
319
- if (typeof extra !== "object" || extra === null) return void 0;
320
- const value = Reflect.get(extra, name);
321
- return typeof value === "string" && value.length > 0 ? value : void 0;
322
- }
323
- function memberLabel(value, mergeKey) {
324
- if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
325
- const member = Reflect.get(value, mergeKey);
326
- if (typeof member === "string") return member;
327
- if (typeof member === "number" && Number.isFinite(member)) return String(member);
328
- }
329
- function mergeKeyConflict(root, value) {
330
- return scanConflict(root, root.path, value);
331
- }
332
- function scanConflict(node, path, value) {
333
- const current = unwrapLazy(node);
334
- if (current === void 0) return void 0;
335
- switch (current.type) {
336
- case "object":
337
- for (const field of current.fields) {
338
- const conflict = scanConflict(field, [...path, field.key], memberOf(value, field.key));
339
- if (conflict !== void 0) return conflict;
340
- }
341
- return;
342
- case "dict":
343
- for (const [key, child] of entriesOf(value)) {
344
- const conflict = scanConflict(current.valueNode, [...path, key], child);
345
- if (conflict !== void 0) return conflict;
346
- }
347
- return;
348
- case "array": {
349
- const names = /* @__PURE__ */ new Set();
350
- for (const [key, child] of entriesOf(value)) {
351
- const itemPath = [...path, key];
352
- if (current.mergeKey !== void 0) {
353
- const label = memberLabel(child, current.mergeKey);
354
- if (label === void 0 || label.trim() === "") return {
355
- kind: "missing",
356
- path: itemPath,
357
- mergeKey: current.mergeKey,
358
- value: ""
359
- };
360
- if (names.has(label)) return {
361
- kind: "duplicate",
362
- path: itemPath,
363
- mergeKey: current.mergeKey,
364
- value: label
365
- };
366
- names.add(label);
367
- }
368
- const conflict = scanConflict(current.item, itemPath, child);
369
- if (conflict !== void 0) return conflict;
370
- }
371
- return;
372
- }
373
- case "tuple":
374
- for (const [index, item] of current.items.entries()) {
375
- const conflict = scanConflict(item, [...path, String(index)], memberOf(value, index));
376
- if (conflict !== void 0) return conflict;
377
- }
378
- return;
379
- case "union": {
380
- if (current.choices !== void 0) return void 0;
381
- const variant = pickVariant(current, value);
382
- return variant === void 0 ? void 0 : scanConflict(variant, path, value);
383
- }
384
- case "intersect":
385
- for (const member of current.members) {
386
- const conflict = scanConflict(member, path, value);
387
- if (conflict !== void 0) return conflict;
388
- }
389
- return;
390
- default: return;
391
- }
392
- }
393
- function entriesOf(value) {
394
- if (Array.isArray(value)) return value.map((item, index) => [String(index), item]);
395
- if (typeof value === "object" && value !== null) return Object.entries(value);
396
- return [];
397
- }
398
- function memberOf(value, key) {
399
- if (Array.isArray(value)) return value[Number(key)];
400
- if (typeof value === "object" && value !== null) return value[String(key)];
401
- }
402
- function unionOf(node) {
403
- const current = unwrapLazy(node);
404
- return current?.type === "union" ? current : void 0;
405
- }
406
- function variantOf(node, value) {
407
- const union = unionOf(node);
408
- if (union === void 0) return unwrapLazy(node) ?? node;
409
- return pickVariant(union, value) ?? union;
410
- }
411
- function tagValueOf(variant, tagKey) {
412
- const current = unwrapLazy(variant);
413
- if (current?.type !== "object" && current?.type !== "intersect") return {
414
- found: false,
415
- value: void 0
416
- };
417
- for (const field of fieldsOf(current)) {
418
- if (field.key !== tagKey) continue;
419
- const candidate = unwrapLazy(field);
420
- if (candidate?.type === "const") return {
421
- found: true,
422
- value: candidate.value
423
- };
424
- }
425
- return {
426
- found: false,
427
- value: void 0
428
- };
429
- }
430
- function variantLabel(variant, tag) {
431
- if (tag.found) return JSON.stringify(tag.value);
432
- switch (unwrapLazy(variant)?.type) {
433
- case "string": return "\"\"";
434
- case "number": return "0";
435
- case "boolean": return "true";
436
- case "array":
437
- case "tuple": return "[ ]";
438
- case "object":
439
- case "dict":
440
- case "intersect": return "{ }";
441
- default: return unwrapLazy(variant)?.type ?? "any";
442
- }
443
- }
444
- function variantChoices(union) {
445
- return union.variants.map((variant) => {
446
- const tag = union.tagKey === void 0 ? {
447
- found: false,
448
- value: void 0
449
- } : tagValueOf(variant, union.tagKey);
450
- return {
451
- label: variantLabel(variant, tag),
452
- value: tag.found ? tag.value : emptyValueOf(variant)
453
- };
454
- });
455
- }
456
- function readPath(root, path) {
457
- return path.reduce((node, segment) => {
458
- if (Array.isArray(node)) return node[Number(segment)];
459
- if (typeof node !== "object" || node === null) return void 0;
460
- return node[segment];
461
- }, root);
462
- }
463
- function isBlankDefault(node) {
464
- const value = node.meta.defaultValue;
465
- if (value === null) return true;
466
- if (node.type !== "object" && node.type !== "intersect") return false;
467
- return typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0;
468
- }
469
- function emptyValueOf(node) {
470
- if (node.meta.hasDefault && !isBlankDefault(node)) return structuredClone(node.meta.defaultValue);
471
- switch (node.type) {
472
- case "array": return [];
473
- case "tuple": return node.items.map((item) => emptyValueOf(item));
474
- case "dict": return {};
475
- case "object":
476
- case "intersect": return Object.fromEntries(fieldsOf(node).map((field) => [field.key, emptyValueOf(field)]));
477
- case "const": return node.value;
478
- case "bitset": return 0;
479
- case "lazy": return emptyValueOf(node.inner);
480
- default: return null;
481
- }
482
- }
483
- function pickVariant(node, value) {
484
- if (node.tagKey !== void 0 && typeof value === "object" && value !== null && !Array.isArray(value)) {
485
- const tagValue = Reflect.get(value, node.tagKey);
486
- for (const variant of node.variants) {
487
- const current = unwrapLazy(variant);
488
- if (current?.type !== "object") continue;
489
- const field = unwrapLazy(current.fields.find((candidate) => candidate.key === node.tagKey));
490
- if (field?.type === "const" && field.value === tagValue) return variant;
491
- }
492
- }
493
- for (const variant of node.variants) {
494
- const current = unwrapLazy(variant);
495
- if (current?.type === "string" && typeof value === "string") return variant;
496
- if (current?.type === "number" && typeof value === "number") return variant;
497
- if (current?.type === "boolean" && typeof value === "boolean") return variant;
498
- if (current?.type === "array" && Array.isArray(value)) return variant;
499
- }
500
- return node.variants[0];
501
- }
502
- //#endregion
503
- //#region src/client/schema-form/draft.ts
504
- function failureOf(error) {
505
- const raw = error instanceof Error ? error.message : String(error);
506
- const path = (error.options?.path ?? []).filter((segment) => typeof segment === "string" || typeof segment === "number").map(String);
507
- const message = raw.replace(/^\$\S*\s/, "").trim();
508
- return {
509
- message: message === "" ? raw : message,
510
- path
511
- };
512
- }
513
- var SchemaDraftModel = class {
514
- #scope;
515
- #root;
516
- #validate;
517
- #staged = /* @__PURE__ */ new Map();
518
- #listeners = /* @__PURE__ */ new Set();
519
- #unsubscribe;
520
- #baseline;
521
- #saving = false;
522
- #failed = false;
523
- #violation;
524
- constructor(options) {
525
- this.#scope = options.scope;
526
- this.#root = options.root;
527
- this.#validate = options.validate;
528
- this.#unsubscribe = this.#scope.subscribe(() => {
529
- this.#publish();
530
- });
531
- }
532
- setRoot(root) {
533
- this.#root = root;
534
- }
535
- subscribe(listener) {
536
- this.#listeners.add(listener);
537
- return () => {
538
- this.#listeners.delete(listener);
539
- };
540
- }
541
- bind(project) {
542
- const store = createSnapshotStore(project());
543
- this.subscribe(() => {
544
- store.set(project());
545
- });
546
- return store;
547
- }
548
- shell() {
549
- const { writes, blocked } = this.#plan();
550
- return {
551
- available: this.#scope.getSnapshot().status === "ready",
552
- writable: this.#scope.getSnapshot().writable,
553
- dirty: writes.some((item) => item.op !== void 0) || blocked,
554
- invalid: blocked || this.#violation !== void 0,
555
- saving: this.#saving,
556
- failed: this.#failed
557
- };
558
- }
559
- violation() {
560
- return this.#violation;
561
- }
562
- field(path, preview) {
563
- const snapshot = this.#scope.getSnapshot();
564
- const staged = this.#staged.get(pathKey(path));
565
- const stored = hasPath(snapshot.user, path);
566
- if (staged === void 0) return {
567
- value: readPath(preview ?? snapshot.value, path),
568
- text: void 0,
569
- invalid: void 0,
570
- overridden: stored,
571
- staged: false
572
- };
573
- switch (staged.edit.kind) {
574
- case "value": return {
575
- value: staged.edit.value,
576
- text: void 0,
577
- invalid: void 0,
578
- overridden: true,
579
- staged: true
580
- };
581
- case "text": {
582
- const parsed = staged.edit.parse(staged.edit.text);
583
- return {
584
- value: parsed.kind === "value" ? parsed.value : readPath(snapshot.value, path),
585
- text: staged.edit.text,
586
- invalid: parsed.kind === "invalid" ? parsed.message : void 0,
587
- overridden: true,
588
- staged: true
589
- };
590
- }
591
- case "clear": return {
592
- value: readPath(snapshot.base, path),
593
- text: void 0,
594
- invalid: void 0,
595
- overridden: false,
596
- staged: true
597
- };
598
- case "drop": return {
599
- value: void 0,
600
- text: void 0,
601
- invalid: void 0,
602
- overridden: false,
603
- staged: true
604
- };
605
- }
606
- }
607
- set(path, value) {
608
- this.#stage(path, {
609
- kind: "value",
610
- value
611
- });
612
- }
613
- setText(path, text, parse) {
614
- this.#stage(path, {
615
- kind: "text",
616
- text,
617
- parse
618
- });
619
- }
620
- clear(path) {
621
- this.#stage(path, { kind: "clear" });
622
- }
623
- appendItem(path) {
624
- const node = seekNode(this.#root, path);
625
- if (node?.type !== "array") return;
626
- const current = readPath(this.preview(), path);
627
- const index = Array.isArray(current) ? current.length : 0;
628
- this.set([...path, String(index)], emptyValueOf(node.item));
629
- }
630
- removeItem(path, index) {
631
- this.#stage([...path, String(index)], { kind: "drop" });
632
- }
633
- addKey(path, key) {
634
- const node = seekNode(this.#root, path);
635
- if (node === void 0) return;
636
- if (node.type === "dict") {
637
- this.set([...path, key], emptyValueOf(node.valueNode));
638
- return;
639
- }
640
- const field = fieldsOf(node).find((candidate) => candidate.key === key);
641
- if (field === void 0) return;
642
- this.set([...path, key], emptyValueOf(field));
643
- }
644
- removeKey(path, key) {
645
- this.#stage([...path, key], { kind: "drop" });
646
- }
647
- revert(path) {
648
- if (!this.#staged.delete(pathKey(path))) return;
649
- this.#failed = false;
650
- this.#violation = void 0;
651
- this.#publish();
652
- }
653
- discard() {
654
- if (this.#staged.size === 0 && !this.#failed && this.#violation === void 0) return;
655
- this.#staged.clear();
656
- this.#baseline = void 0;
657
- this.#failed = false;
658
- this.#violation = void 0;
659
- this.#publish();
660
- }
661
- async save() {
662
- const snapshot = this.#scope.getSnapshot();
663
- if (this.#saving || !snapshot.writable) return;
664
- const { writes, blocked } = this.#plan();
665
- if (blocked) return;
666
- const ops = writes.flatMap((item) => item.op === void 0 ? [] : [item.op]);
667
- if (ops.length === 0) {
668
- this.#violation = void 0;
669
- this.#publish();
670
- return;
671
- }
672
- const failure = this.#validate(applyOps(snapshot.value ?? {}, ops));
673
- if (failure !== void 0) {
674
- this.#violation = failure;
675
- this.#publish();
676
- return;
677
- }
678
- this.#violation = void 0;
679
- this.#saving = true;
680
- this.#failed = false;
681
- this.#publish();
682
- try {
683
- const landed = await this.#scope.mutate(ops, this.#baseline?.revision);
684
- if (landed) {
685
- this.#staged.clear();
686
- this.#baseline = void 0;
687
- }
688
- this.#failed = !landed;
689
- } catch {
690
- this.#failed = true;
691
- } finally {
692
- this.#saving = false;
693
- this.#publish();
694
- }
695
- }
696
- dispose() {
697
- this.#unsubscribe();
698
- this.#listeners.clear();
699
- }
700
- #plan() {
701
- const snapshot = this.#scope.getSnapshot();
702
- const writes = [];
703
- let blocked = false;
704
- for (const { path, edit } of this.#staged.values()) {
705
- if (edit.kind === "drop") {
706
- writes.push({ op: {
707
- op: "unset",
708
- path: [...path]
709
- } });
710
- continue;
711
- }
712
- if (edit.kind === "clear") {
713
- if (hasPath(snapshot.user, path)) writes.push({ op: {
714
- op: "unset",
715
- path: [...path]
716
- } });
717
- continue;
718
- }
719
- const parsed = edit.kind === "value" ? {
720
- kind: "value",
721
- value: edit.value
722
- } : edit.parse(edit.text);
723
- if (parsed.kind === "invalid") {
724
- blocked = true;
725
- continue;
726
- }
727
- if (parsed.kind === "skip") continue;
728
- if (sameValue$1(readPath(snapshot.value, path), parsed.value)) continue;
729
- writes.push({ op: {
730
- op: "set",
731
- path: [...path],
732
- value: parsed.value
733
- } });
734
- }
735
- return {
736
- writes,
737
- blocked
738
- };
739
- }
740
- preview() {
741
- const ops = this.#plan().writes.flatMap((item) => item.op === void 0 ? [] : [item.op]);
742
- return applyOps(this.#scope.getSnapshot().value ?? {}, ops);
743
- }
744
- #stage(path, edit) {
745
- this.#baseline ??= this.#scope.getSnapshot();
746
- this.#staged.set(pathKey(path), {
747
- path: [...path],
748
- edit
749
- });
750
- this.#failed = false;
751
- this.#violation = void 0;
752
- this.#publish();
753
- }
754
- #publish() {
755
- for (const listener of this.#listeners) listener();
756
- }
757
- };
758
- function sameValue$1(left, right) {
759
- if (Object.is(left, right)) return true;
760
- if (typeof left !== "object" || typeof right !== "object" || left === null || right === null) return false;
761
- return JSON.stringify(left) === JSON.stringify(right);
762
- }
763
- function pathKey(path) {
764
- return JSON.stringify(path);
765
- }
766
- function hasPath(root, path) {
767
- if (path.length === 0) return root !== void 0;
768
- const parent = readPath(root, path.slice(0, -1));
769
- const leaf = path[path.length - 1] ?? "";
770
- if (Array.isArray(parent)) return Number(leaf) < parent.length;
771
- if (typeof parent !== "object" || parent === null) return false;
772
- return leaf in parent;
773
- }
774
- function applyOps(section, ops) {
775
- const next = structuredClone(section);
776
- for (const op of ops) {
777
- const parent = readPath(next, op.path.slice(0, -1));
778
- const leaf = op.path[op.path.length - 1] ?? "";
779
- if (Array.isArray(parent)) {
780
- if (op.op === "set") parent[Number(leaf)] = op.value;
781
- else parent.splice(Number(leaf), 1);
782
- continue;
783
- }
784
- if (typeof parent !== "object" || parent === null) continue;
785
- if (op.op === "set") parent[leaf] = op.value;
786
- else Reflect.deleteProperty(parent, leaf);
787
- }
788
- return next;
789
- }
790
- //#endregion
791
- //#region src/client/schema-form/controller.ts
792
- function declaredSource(node) {
793
- const extra = node?.meta.extra;
794
- if (typeof extra !== "object" || extra === null) return void 0;
795
- const name = Reflect.get(extra, "source");
796
- return typeof name === "string" && name.length > 0 ? name : void 0;
797
- }
798
- function fieldKey(path) {
799
- return JSON.stringify(path);
800
- }
801
- function projectRoot(serialized, rehydrate) {
802
- try {
803
- const schema = rehydrate(serialized);
804
- const root = projectNode(schema);
805
- if (root.type === "object" || root.type === "intersect") return {
806
- schema,
807
- root
808
- };
809
- if (root.type === "union" && root.tagKey !== void 0 && root.choices === void 0) return {
810
- schema,
811
- root
812
- };
813
- return;
814
- } catch {
815
- return;
816
- }
817
- }
818
- function canRender(view, rehydrate) {
819
- return view !== void 0 && projectRoot(view.schema, rehydrate) !== void 0;
820
- }
821
- const NO_FIELDS = {
822
- key: "",
823
- path: [],
824
- label: void 0,
825
- meta: emptyMeta(),
826
- readOnly: null,
827
- type: "object",
828
- fields: []
829
- };
830
- function keysOf(value) {
831
- if (Array.isArray(value)) return value.map((_item, index) => String(index));
832
- if (typeof value === "object" && value !== null) return Object.keys(value);
833
- return [];
834
- }
835
- function addableAt(node, path, value, hints) {
836
- const current = variantOf(node, value);
837
- if (current.type === "dict") {
838
- const present = new Set(keysOf(value));
839
- return (hints?.keysFor(path) ?? []).flatMap((key) => present.has(key) ? [] : [{
840
- key,
841
- description: void 0
842
- }]);
843
- }
844
- if (current.type !== "object" && current.type !== "intersect") return [];
845
- return fieldsOf(current).flatMap((field) => field.meta.required !== true && readPath(value, [field.key]) === void 0 ? [{
846
- key: field.key,
847
- description: field.meta.description ?? field.meta.comment
848
- }] : []);
849
- }
850
- function optionsFor(node, path, value, hints) {
851
- const current = unwrapLazy(node);
852
- if (current?.type === "union" && current.choices !== void 0) return current.choices.map((choice) => ({ value: choice }));
853
- const source = declaredSource(current);
854
- const spec = source === void 0 ? hints?.selectFor?.(path) : hints?.sourceFor?.(source);
855
- if (spec === void 0) return void 0;
856
- const parent = path.slice(0, -1);
857
- const options = spec.options((relative) => readPath(value, [...parent, ...relative]));
858
- return options.length === 0 ? void 0 : options;
859
- }
860
- var SchemaFormController = class {
861
- #ns;
862
- #deps;
863
- #model;
864
- #store;
865
- #disposers = [];
866
- #view;
867
- #schema;
868
- #root;
869
- constructor(ns, deps) {
870
- this.#ns = ns;
871
- this.#deps = deps;
872
- this.#model = new SchemaDraftModel({
873
- scope: deps.form,
874
- root: NO_FIELDS,
875
- validate: (value) => this.#validate(deps, value)
876
- });
877
- this.#store = createSnapshotStore(this.#project());
878
- this.#disposers.push(this.#model.subscribe(() => {
879
- this.#store.set(this.#project());
880
- }));
881
- this.#disposers.push(deps.describe.subscribe(() => {
882
- this.#sync();
883
- }));
884
- deps.describe.ensure();
885
- this.#sync();
886
- }
887
- face() {
888
- return {
889
- hooks: { schemaForm: this.#store },
890
- set: (path, value) => {
891
- this.#model.set(path, value);
892
- },
893
- setText: (path, text, parse) => {
894
- this.#model.setText(path, text, parse);
895
- },
896
- clear: (path) => {
897
- this.#model.clear(path);
898
- },
899
- appendItem: (path) => {
900
- this.#model.appendItem(path);
901
- },
902
- removeItem: (path, index) => {
903
- this.#model.removeItem(path, index);
904
- },
905
- addKey: (path, key) => {
906
- this.#model.addKey(path, key);
907
- },
908
- removeKey: (path, key) => {
909
- this.#model.removeKey(path, key);
910
- },
911
- save: () => {
912
- this.#model.save();
913
- },
914
- revert: (path) => {
915
- this.#model.revert(path);
916
- },
917
- discard: () => {
918
- this.#model.discard();
919
- }
920
- };
921
- }
922
- namespace() {
923
- return this.#ns;
924
- }
925
- refresh() {
926
- this.#sync();
927
- }
928
- dispose() {
929
- for (const dispose of this.#disposers.splice(0)) dispose();
930
- this.#model.dispose();
931
- }
932
- #sync() {
933
- const view = this.#deps.describe.getSnapshot().view?.namespaces.find((row) => row.ns === this.#ns);
934
- this.#view = view;
935
- const projected = view === void 0 ? void 0 : projectRoot(view.schema, this.#deps.rehydrate);
936
- this.#schema = projected?.schema;
937
- this.#root = projected?.root;
938
- this.#model.setRoot(projected?.root ?? NO_FIELDS);
939
- this.#store.set(this.#project());
940
- }
941
- #validate(deps, value) {
942
- if (this.#schema !== void 0) {
943
- const failure = deps.validate(this.#schema, value);
944
- if (failure !== void 0) return failure;
945
- }
946
- if (this.#root === void 0) return void 0;
947
- const conflict = mergeKeyConflict(this.#root, value);
948
- if (conflict === void 0) return void 0;
949
- return {
950
- message: conflict.kind === "duplicate" ? deps.t("duplicateItem", {
951
- key: conflict.mergeKey,
952
- value: conflict.value
953
- }) : deps.t("missingItem", { key: conflict.mergeKey }),
954
- path: conflict.path
955
- };
956
- }
957
- #project() {
958
- const fields = /* @__PURE__ */ new Map();
959
- const root = this.#root;
960
- const preview = this.#model.preview();
961
- const walked = root === void 0 ? [] : walkFields(root, preview);
962
- for (const item of walked) fields.set(fieldKey(item.path), this.#model.field(item.path, preview));
963
- const secrets = /* @__PURE__ */ new Map();
964
- for (const secret of this.#view?.secrets ?? []) secrets.set(fieldKey(secret.path), secret.set);
965
- const texts = /* @__PURE__ */ new Map();
966
- const options = /* @__PURE__ */ new Map();
967
- const addable = /* @__PURE__ */ new Map();
968
- for (const item of walked) {
969
- const text = this.#deps.hints?.textFor(item.path);
970
- if (text !== void 0) texts.set(fieldKey(item.path), text);
971
- const candidates = optionsFor(item.node, item.path, preview, this.#deps.hints);
972
- if (candidates !== void 0) options.set(fieldKey(item.path), candidates);
973
- const addableHere = addableAt(item.node, item.path, readPath(preview, item.path), this.#deps.hints);
974
- if (addableHere.length > 0) addable.set(fieldKey(item.path), addableHere);
975
- }
976
- const violation = this.#model.violation();
977
- const invalidAt = /* @__PURE__ */ new Map();
978
- if (violation !== void 0 && violation.path.length > 0) invalidAt.set(fieldKey(violation.path), violation.message);
979
- return {
980
- ...this.#model.shell(),
981
- configured: root !== void 0,
982
- root: root ?? NO_FIELDS,
983
- walked,
984
- fields,
985
- secrets,
986
- texts,
987
- options,
988
- addable,
989
- violation,
990
- invalidAt
991
- };
992
- }
993
- };
994
- //#endregion
995
- //#region src/client/schema-form/hints.ts
996
- var SchemaFormHints = class extends Service {
997
- #readers = /* @__PURE__ */ new Map();
998
- #texts = /* @__PURE__ */ new Map();
999
- #selects = /* @__PURE__ */ new Map();
1000
- #sources = /* @__PURE__ */ new Map();
1001
- #listeners = /* @__PURE__ */ new Set();
1002
- constructor(ctx) {
1003
- super(ctx, "schemaFormHints");
1004
- }
1005
- keysFor(ns, path) {
1006
- return lookup(this.#readers, ns, path)?.() ?? [];
1007
- }
1008
- textFor(ns, path) {
1009
- return lookup(this.#texts, ns, path)?.() ?? {};
1010
- }
1011
- select(ns, path, spec) {
1012
- const key = locationKey(ns, path);
1013
- this.#selects.set(key, spec);
1014
- this.#publish();
1015
- return () => {
1016
- if (this.#selects.get(key) !== spec) return;
1017
- this.#selects.delete(key);
1018
- this.#publish();
1019
- };
1020
- }
1021
- selectFor(ns, path) {
1022
- return lookup(this.#selects, ns, path);
1023
- }
1024
- source(name, spec) {
1025
- this.#sources.set(name, spec);
1026
- this.#publish();
1027
- return () => {
1028
- if (this.#sources.get(name) !== spec) return;
1029
- this.#sources.delete(name);
1030
- this.#publish();
1031
- };
1032
- }
1033
- sourceFor(name) {
1034
- return this.#sources.get(name);
1035
- }
1036
- describe(ns, path, read) {
1037
- const key = locationKey(ns, path);
1038
- this.#texts.set(key, read);
1039
- this.#publish();
1040
- return () => {
1041
- if (this.#texts.get(key) !== read) return;
1042
- this.#texts.delete(key);
1043
- this.#publish();
1044
- };
1045
- }
1046
- suggestKeys(ns, path, read) {
1047
- const key = locationKey(ns, path);
1048
- this.#readers.set(key, read);
1049
- this.#publish();
1050
- return () => {
1051
- if (this.#readers.get(key) !== read) return;
1052
- this.#readers.delete(key);
1053
- this.#publish();
1054
- };
1055
- }
1056
- subscribe(listener) {
1057
- this.#listeners.add(listener);
1058
- return () => {
1059
- this.#listeners.delete(listener);
1060
- };
1061
- }
1062
- refresh() {
1063
- this.#publish();
1064
- }
1065
- #publish() {
1066
- for (const listener of this.#listeners) listener();
1067
- }
1068
- };
1069
- function locationKey(ns, path) {
1070
- return `${ns}\u0000${path.join("\0")}`;
1071
- }
1072
- function lookup(map, ns, path) {
1073
- const exact = map.get(locationKey(ns, path));
1074
- if (exact !== void 0) return exact;
1075
- for (const masked of templates(path)) {
1076
- const hit = map.get(locationKey(ns, masked));
1077
- if (hit !== void 0) return hit;
1078
- }
1079
- }
1080
- function* templates(path) {
1081
- const wildcardable = Math.max(0, path.length - 1);
1082
- for (let bits = (1 << wildcardable) - 1; bits > 0; bits--) yield path.map((segment, index) => index > 0 && (bits & 1 << index - 1) !== 0 ? "*" : segment);
1083
- }
1084
- //#endregion
1085
- //#region src/client/schema-form/locales.ts
1086
- const zh = {
1087
- unavailable: "该插件当前未加载,暂时无法配置。",
1088
- readOnly: "本部署的设置为只读。",
1089
- save: "保存",
1090
- confirmEdit: "确认",
1091
- cancelEdit: "取消",
1092
- saving: "保存中…",
1093
- saveFailed: "本部署没有接受这些值,已保留供你修改。",
1094
- notSaved: "没有保存:{message}",
1095
- noSchema: "这一行没有可自动生成的配置项。",
1096
- reset: "恢复默认",
1097
- revert: "撤回",
1098
- invalid: "这个值不被接受。",
1099
- invalidNumber: "需要一个数字。",
1100
- invalidInteger: "需要一个整数。",
1101
- invalidJson: "需要一段合法的 JSON。",
1102
- invalidBoolean: "需要 true 或 false。",
1103
- invalidConst: "这个字段只接受固定值。",
1104
- invalidPattern: "要匹配 {pattern}。",
1105
- invalidRange: "要在 {min} 与 {max} 之间。",
1106
- invalidMin: "不能小于 {min}。",
1107
- invalidMax: "不能大于 {max}。",
1108
- invalidChoice: "只能是 {choices} 之一。",
1109
- unknownProperty: "这一层没有这个字段:从上面的候选里选,或换个键名。",
1110
- empty: "(空)",
1111
- toggleGroup: "展开 / 收起这一层",
1112
- switchVariant: "切换这一层的形状或分支",
1113
- copyValue: "复制值",
1114
- copied: "已复制",
1115
- addProperty: "添加属性",
1116
- addItemPaste: "添加数组项(可粘贴 JSON 字符串)",
1117
- addItem: "添加一项",
1118
- removeItem: "移除",
1119
- addKey: "添加键(可粘贴 JSON 字符串)",
1120
- keyName: "键名",
1121
- noKeys: "还没有键。",
1122
- noItems: "还没有项。",
1123
- deprecated: "已废弃",
1124
- experimental: "试验中",
1125
- secretSet: "已配置",
1126
- secretUnset: "未配置",
1127
- secretHint: "留空即保留已存的值。",
1128
- constValue: "固定值",
1129
- notEditable: "这一项由插件在运行时提供,不能在页面上编辑。",
1130
- recursive: "递归结构:展开到这一层为止。",
1131
- fixedLength: "固定长度",
1132
- bitsetHint: "可多选。",
1133
- unconfigured: "未配置",
1134
- readOnlyField: "只读",
1135
- noDescription: "(无说明)",
1136
- required: "必填",
1137
- duplicateItem: "重复的 {key}:{value}",
1138
- missingItem: "每一项都需要一个 {key}"
1139
- };
1140
- const en = {
1141
- unavailable: "This plugin is not loaded, so it cannot be configured right now.",
1142
- readOnly: "This deployment stores settings read-only.",
1143
- save: "Save",
1144
- confirmEdit: "Confirm",
1145
- cancelEdit: "Cancel",
1146
- saving: "Saving…",
1147
- saveFailed: "This deployment did not accept these values; they are kept for you to fix.",
1148
- notSaved: "Not saved: {message}",
1149
- noSchema: "This row has no configuration to generate.",
1150
- reset: "Reset",
1151
- revert: "Revert",
1152
- invalid: "This value is not accepted.",
1153
- invalidNumber: "Enter a number.",
1154
- invalidInteger: "Enter a whole number.",
1155
- invalidJson: "Enter valid JSON.",
1156
- invalidBoolean: "Enter true or false.",
1157
- invalidConst: "This field only accepts its fixed value.",
1158
- invalidPattern: "Must match {pattern}.",
1159
- invalidRange: "Must be between {min} and {max}.",
1160
- invalidMin: "Must not be less than {min}.",
1161
- invalidMax: "Must not be greater than {max}.",
1162
- invalidChoice: "Must be one of {choices}.",
1163
- unknownProperty: "No such field at this level: pick one of the candidates above.",
1164
- empty: "(empty)",
1165
- toggleGroup: "Expand or collapse this level",
1166
- switchVariant: "Switch this level's shape or branch",
1167
- copyValue: "Copy value",
1168
- copied: "Copied",
1169
- addProperty: "Add property",
1170
- addItemPaste: "Add item (a JSON string can be pasted)",
1171
- addItem: "Add item",
1172
- removeItem: "Remove",
1173
- addKey: "Add key (a JSON string can be pasted)",
1174
- keyName: "Key",
1175
- noKeys: "No keys yet.",
1176
- noItems: "No items yet.",
1177
- deprecated: "deprecated",
1178
- experimental: "experimental",
1179
- secretSet: "configured",
1180
- secretUnset: "not set",
1181
- secretHint: "Leave blank to keep the stored value.",
1182
- constValue: "fixed",
1183
- notEditable: "This entry is provided by the plugin at runtime and cannot be edited here.",
1184
- recursive: "Recursive structure: expanded down to this level.",
1185
- fixedLength: "fixed length",
1186
- bitsetHint: "Multiple choices.",
1187
- unconfigured: "not configured",
1188
- readOnlyField: "read-only",
1189
- noDescription: "(no description)",
1190
- required: "required",
1191
- duplicateItem: "Duplicate {key}: {value}",
1192
- missingItem: "Every item needs a {key}"
1193
- };
1194
- //#endregion
1195
- //#region src/client/schema-form/rows.ts
1196
- function rowRegistrations(namespaces, bundles) {
1197
- const owners = /* @__PURE__ */ new Map();
1198
- for (const bundle of bundles) for (const row of bundle.rows) owners.set(row.rowId, bundle.name);
1199
- const plans = [];
1200
- for (const view of namespaces) {
1201
- if (view.autoGenerate !== true) continue;
1202
- const owner = owners.get(view.ns);
1203
- if (owner === void 0) continue;
1204
- plans.push({
1205
- key: `${owner}#${view.ns}`,
1206
- ns: view.ns
1207
- });
1208
- }
1209
- return plans;
1210
- }
1211
- const FALLBACK_PRIORITY = 100;
1212
- var RowRegistration = class {
1213
- #deps;
1214
- #live = /* @__PURE__ */ new Map();
1215
- #pending;
1216
- #disposed = false;
1217
- constructor(deps) {
1218
- this.#deps = deps;
1219
- }
1220
- sync() {
1221
- if (this.#disposed) return Promise.resolve();
1222
- this.#pending ??= this.#run().finally(() => {
1223
- this.#pending = void 0;
1224
- });
1225
- return this.#pending;
1226
- }
1227
- dispose() {
1228
- this.#disposed = true;
1229
- this.#release();
1230
- }
1231
- async #run() {
1232
- const bundles = await this.#deps.bundles();
1233
- if (this.#disposed) return;
1234
- const namespaces = this.#deps.describe.getSnapshot().view?.namespaces ?? [];
1235
- const wanted = /* @__PURE__ */ new Map();
1236
- for (const plan of rowRegistrations(namespaces, bundles)) {
1237
- if (this.#deps.entryFor(plan.ns) === void 0) continue;
1238
- wanted.set(plan.ns, plan);
1239
- }
1240
- for (const [ns, dispose] of this.#live) {
1241
- if (wanted.has(ns)) continue;
1242
- dispose();
1243
- this.#live.delete(ns);
1244
- this.#deps.release(ns);
1245
- }
1246
- for (const [ns, plan] of wanted) {
1247
- if (this.#live.has(ns)) continue;
1248
- const entry = this.#deps.entryFor(ns);
1249
- if (entry === void 0) continue;
1250
- const dispose = this.#deps.slots.register({
1251
- name: "plugins.row.config",
1252
- key: plan.key,
1253
- priority: FALLBACK_PRIORITY,
1254
- locale: this.#deps.locale
1255
- }, entry.component);
1256
- this.#live.set(ns, dispose);
1257
- }
1258
- }
1259
- #release() {
1260
- for (const [ns, dispose] of this.#live) {
1261
- dispose();
1262
- this.#live.delete(ns);
1263
- this.#deps.release(ns);
1264
- }
1265
- }
1266
- };
1267
- //#endregion
1268
- //#region src/client/schema-form/labels.ts
1269
- function fieldHint(node, resolveText) {
1270
- const parts = [];
1271
- if (node.meta.description !== void 0) parts.push(resolveText(node.meta.description));
1272
- if (node.meta.comment !== void 0) parts.push(node.meta.comment);
1273
- return parts.length === 0 ? void 0 : parts.join(" ");
1274
- }
1275
- //#endregion
1276
- //#region src/client/schema-form/lines.ts
1277
- function containerShape(node, value) {
1278
- switch (variantOf(node, value).type) {
1279
- case "object":
1280
- case "dict":
1281
- case "intersect": return "object";
1282
- case "array":
1283
- case "tuple": return "array";
1284
- default: return;
1285
- }
1286
- }
1287
- function visibleFields(state, fold) {
1288
- const containers = new Set(state.walked.filter((item) => containerShape(item.node, valueAt(state, item.path)) !== void 0).map((item) => fieldKey(item.path)));
1289
- return state.walked.filter((item) => {
1290
- for (let depth = 1; depth < item.path.length; depth++) {
1291
- const ancestor = item.path.slice(0, depth);
1292
- if (containers.has(fieldKey(ancestor)) && fold.collapsed(ancestor)) return false;
1293
- }
1294
- return true;
1295
- });
1296
- }
1297
- function valueAt(state, path) {
1298
- return state.fields.get(fieldKey(path))?.value;
1299
- }
1300
- function addOf(node, shape, options) {
1301
- if (shape === "array") return { kind: "item" };
1302
- if (unwrapLazy(node)?.type === "dict") return {
1303
- kind: "key",
1304
- options
1305
- };
1306
- return options.length === 0 ? void 0 : {
1307
- kind: "prop",
1308
- options
1309
- };
1310
- }
1311
- function variantsOf(node, value) {
1312
- const union = unionOf(node);
1313
- if (union === void 0 || union.choices !== void 0 || union.variants.length < 2) return void 0;
1314
- return {
1315
- choices: variantChoices(union),
1316
- selected: union.variants.indexOf(variantOf(union, value))
1317
- };
1318
- }
1319
- function editorLines(state, fold, resolveText, t) {
1320
- const lines = [];
1321
- const open = [];
1322
- const closeOpenUntil = (path) => {
1323
- while (open.length > 0) {
1324
- const top = open[open.length - 1];
1325
- if (isPrefix(top.path, path)) return;
1326
- open.pop();
1327
- lines.push({
1328
- kind: "close",
1329
- path: top.path,
1330
- node: top.node,
1331
- shape: top.shape,
1332
- depth: top.depth,
1333
- add: top.add,
1334
- member: top.member
1335
- });
1336
- }
1337
- };
1338
- for (const item of visibleFields(state, fold)) {
1339
- closeOpenUntil(item.path);
1340
- const node = unwrapLazy(item.node) ?? item.node;
1341
- const value = valueAt(state, item.path);
1342
- const depth = item.path.length;
1343
- const comment = commentFor(state, item, resolveText, t);
1344
- if (comment !== void 0) lines.push({
1345
- kind: "comment",
1346
- path: item.path,
1347
- depth,
1348
- text: comment.text,
1349
- invalid: comment.invalid
1350
- });
1351
- const variants = variantsOf(node, value);
1352
- const shape = containerShape(node, value);
1353
- if (shape !== void 0) {
1354
- const collapsed = fold.collapsed(item.path);
1355
- const add = addOf(node, shape, state.addable.get(fieldKey(item.path)) ?? []);
1356
- lines.push({
1357
- kind: "open",
1358
- path: item.path,
1359
- node,
1360
- shape,
1361
- depth,
1362
- collapsed,
1363
- member: item.member,
1364
- variants
1365
- });
1366
- if (!collapsed) open.push({
1367
- path: item.path,
1368
- node,
1369
- shape,
1370
- depth,
1371
- add,
1372
- member: item.member
1373
- });
1374
- continue;
1375
- }
1376
- lines.push({
1377
- kind: "field",
1378
- path: item.path,
1379
- node,
1380
- depth,
1381
- field: state.fields.get(fieldKey(item.path)) ?? {
1382
- value: void 0,
1383
- text: void 0,
1384
- invalid: void 0,
1385
- overridden: false,
1386
- staged: false
1387
- },
1388
- member: item.member,
1389
- variants,
1390
- variantsStandIn: false
1391
- });
1392
- }
1393
- while (open.length > 0) {
1394
- const top = open.pop();
1395
- lines.push({
1396
- kind: "close",
1397
- path: top.path,
1398
- node: top.node,
1399
- shape: top.shape,
1400
- depth: top.depth,
1401
- add: top.add,
1402
- member: top.member
1403
- });
1404
- }
1405
- return moveVariantControlToTag(lines);
1406
- }
1407
- function moveVariantControlToTag(lines) {
1408
- for (const line of lines) {
1409
- if (line.kind === "comment" || line.kind === "close") continue;
1410
- if (line.variants === void 0) continue;
1411
- const tagKey = unionOf(line.node)?.tagKey;
1412
- if (tagKey === void 0) continue;
1413
- const tagPath = [...line.path, tagKey];
1414
- const tagLine = lines.find((candidate) => candidate.kind === "field" && candidate.path.length === tagPath.length && candidate.path.every((segment, index) => segment === tagPath[index]));
1415
- if (tagLine === void 0 || tagLine.kind !== "field") continue;
1416
- tagLine.variants = line.variants;
1417
- tagLine.variantsStandIn = true;
1418
- line.variants = void 0;
1419
- }
1420
- return lines;
1421
- }
1422
- function commentFor(state, item, resolveText, t) {
1423
- const key = fieldKey(item.path);
1424
- const failure = state.fields.get(key)?.invalid ?? state.invalidAt.get(key);
1425
- if (failure !== void 0) return {
1426
- text: failure,
1427
- invalid: true
1428
- };
1429
- const node = unwrapLazy(item.node) ?? item.node;
1430
- const parts = [];
1431
- const text = state.texts.get(fieldKey(item.path));
1432
- const hint = [text?.label, text?.hint].filter((part) => part !== void 0 && part !== "").join(":") || fieldHint(node, resolveText);
1433
- if (hint !== void 0 && hint !== "") parts.push(hint);
1434
- if (node.meta.disabled) parts.push(t("readOnlyField"));
1435
- if (node.meta.badges.length > 0) parts.push(node.meta.badges.join(" / "));
1436
- return parts.length === 0 ? void 0 : {
1437
- text: parts.join(" · "),
1438
- invalid: false
1439
- };
1440
- }
1441
- function isPrefix(prefix, path) {
1442
- if (prefix.length > path.length) return false;
1443
- return prefix.every((segment, index) => path[index] === segment);
1444
- }
1445
- //#endregion
1446
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/schema-form/schema-form.module.css.mjs
1447
- const css$16 = ".B1Faoa_editorRoot{width:100%;color:var(--dsw-alias-label-primary);flex-direction:column;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,monospace;font-size:14px;line-height:22px;display:flex}.B1Faoa_lineRow{white-space:nowrap;align-items:flex-start;gap:6px;min-height:22px;padding-right:8px;display:flex}.B1Faoa_lineRow:hover{background:var(--dsw-alias-bg-layer-2)}.B1Faoa_lineRow[data-selected=true]{background:var(--dsw-alias-bg-layer-3)}.B1Faoa_lineRow[data-dirty=true]{box-shadow:inset 2px 0 0 var(--dsw-alias-brand-primary)}.B1Faoa_lineRow[data-overridden=true]{box-shadow:inset 2px 0 0 var(--dsw-elevation-stroke-color)}.B1Faoa_lineRow[data-dirty=true] [data-role=key],.B1Faoa_lineRow[data-overridden=true] [data-role=key]{color:var(--dsw-alias-brand-primary)}.B1Faoa_lineRow[data-invalid=true]{background:color-mix(in srgb, var(--dsw-alias-state-error-secondary) 12%, transparent);box-shadow:inset 2px 0 0 var(--dsw-alias-state-error-primary)}.B1Faoa_lineRow[data-invalid=true] [data-role=key]{color:var(--dsw-alias-state-error-primary)}.B1Faoa_lineRow:hover [data-role=actions]{opacity:1}.B1Faoa_lineBody{flex:1;align-items:center;gap:6px;min-width:0;min-height:22px;display:flex}.B1Faoa_lineNumber{text-align:right;width:32px;color:var(--dsw-alias-label-caption);user-select:none;cursor:pointer;flex:none;line-height:22px}.B1Faoa_lineFold{width:14px;height:22px;color:var(--dsw-alias-label-caption);cursor:pointer;background:0 0;border:0;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.B1Faoa_lineFold:hover{color:var(--dsw-alias-label-secondary)}.B1Faoa_lineFoldSpacer{flex:none;width:14px}.B1Faoa_lineKey{color:var(--dsw-alias-label-primary);flex:none}.B1Faoa_lineKey[data-index=true]{color:var(--dsw-alias-label-caption)}.B1Faoa_lineToken{color:var(--dsw-alias-label-caption);flex:none}.B1Faoa_lineValue{text-overflow:ellipsis;cursor:text;min-width:0;color:var(--dsw-alias-state-business-primary);display:block;overflow:hidden}.B1Faoa_lineValue[data-tone=number]{color:var(--dsw-alias-state-warn-primary)}.B1Faoa_lineValue[data-tone=boolean]{color:var(--dsw-alias-state-success-primary)}.B1Faoa_lineValue[data-tone=empty]{color:var(--dsw-alias-label-caption)}.B1Faoa_valueSlot{flex:0 auto;min-width:0;display:block;overflow:hidden}.B1Faoa_valueTrigger{min-width:0;font:inherit;text-align:left;cursor:pointer;color:var(--dsw-alias-label-caption);background:0 0;border:0;align-items:center;gap:2px;padding:0;display:inline-flex}.B1Faoa_valueTrigger:disabled{cursor:default}.B1Faoa_valueTrigger:focus-visible{outline:none}.B1Faoa_compactInput{flex:auto;min-width:0;display:inline-flex}.B1Faoa_compactInput>span{border-radius:4px;width:100%;height:22px;padding:0 6px}.B1Faoa_compactInput input{font-size:14px;line-height:22px}.B1Faoa_compactTextField{background:var(--dsw-alias-bg-layer-1);min-width:0;box-shadow:0 0 0 .5px var(--dsw-elevation-stroke-color);border:0;border-radius:4px;flex:auto;padding:0 6px;display:inline-flex}.B1Faoa_compactTextField:focus-within{--dsw-elevation-stroke-color:var(--dsw-alias-brand-primary)}.B1Faoa_compactTextField>textarea{resize:none;field-sizing:content;width:100%;min-height:20px;max-height:240px;color:var(--dsw-alias-label-primary);background:0 0;border:0;outline:none;flex:1;padding:0;font-family:inherit;font-size:14px;line-height:22px}.B1Faoa_lineComment{text-overflow:ellipsis;min-width:0;color:var(--dsw-alias-label-tertiary);flex:auto;font-family:inherit;font-size:12px;overflow:hidden}.B1Faoa_lineInvalid{text-overflow:ellipsis;min-width:0;color:var(--dsw-alias-state-error-primary);flex:0 auto;font-family:inherit;font-size:12px;overflow:hidden}.B1Faoa_lineActions{opacity:0;flex:none;align-items:center;gap:4px;display:inline-flex}.B1Faoa_lineActions>button{width:20px;height:20px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:4px;justify-content:center;align-items:center;padding:0;display:inline-flex}.B1Faoa_lineActions>button:hover{background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary)}.B1Faoa_lineActions>button:disabled{cursor:not-allowed;color:var(--dsw-alias-label-dimmed)}.B1Faoa_hoverActions[data-editing=true]{opacity:1;gap:6px}.B1Faoa_hoverActions[data-editing=true]>button{box-shadow:0 0 0 .5px var(--dsw-elevation-stroke-color);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}.B1Faoa_hoverActions[data-editing=true]>button:first-of-type{color:var(--dsw-alias-state-success-primary)}.B1Faoa_addWrap{flex:auto;align-items:center;gap:6px;min-width:0;margin-left:6px;display:inline-flex;position:relative}.B1Faoa_addWrap[data-invalid=true] input{border-color:var(--dsw-alias-state-error-primary)}.B1Faoa_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}";
1448
- const tagId$16 = "@morlay/dsh-client-ui-primitives/schema-form.module.css";
1449
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/schema-form.module.css\"]") === null) {
1450
- const tag = document.createElement("style");
1451
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
1452
- tag.dataset.pluginCss = tagId$16;
1453
- tag.textContent = css$16;
1454
- document.head.appendChild(tag);
1455
- }
1456
- var schema_form_module_css_default = {
1457
- "compactTextField": "B1Faoa_compactTextField",
1458
- "editorRoot": "B1Faoa_editorRoot",
1459
- "lineRow": "B1Faoa_lineRow",
1460
- "lineActions": "B1Faoa_lineActions",
1461
- "lineInvalid": "B1Faoa_lineInvalid",
1462
- "hint": "B1Faoa_hint",
1463
- "lineKey": "B1Faoa_lineKey",
1464
- "lineNumber": "B1Faoa_lineNumber",
1465
- "lineToken": "B1Faoa_lineToken",
1466
- "valueTrigger": "B1Faoa_valueTrigger",
1467
- "lineFoldSpacer": "B1Faoa_lineFoldSpacer",
1468
- "lineComment": "B1Faoa_lineComment",
1469
- "compactInput": "B1Faoa_compactInput",
1470
- "addWrap": "B1Faoa_addWrap",
1471
- "lineFold": "B1Faoa_lineFold",
1472
- "hoverActions": "B1Faoa_hoverActions",
1473
- "valueSlot": "B1Faoa_valueSlot",
1474
- "lineValue": "B1Faoa_lineValue",
1475
- "lineBody": "B1Faoa_lineBody"
1476
- };
1477
- //#endregion
1478
- //#region src/client/schema-form/TruncatedTooltip.tsx
1479
- function TruncatedTooltip({ label, children }) {
1480
- const node = useRef(null);
1481
- const watch = useRef(null);
1482
- const [truncated, setTruncated] = useState(false);
1483
- const measure = useCallback(() => {
1484
- const el = node.current;
1485
- if (el === null) return;
1486
- setTruncated(el.scrollWidth > el.clientWidth);
1487
- }, []);
1488
- const anchor = useCallback((el) => {
1489
- watch.current?.disconnect();
1490
- watch.current = null;
1491
- node.current = el;
1492
- if (el === null) return;
1493
- const observer = new ResizeObserver(measure);
1494
- observer.observe(el);
1495
- watch.current = observer;
1496
- }, [measure]);
1497
- useLayoutEffect(measure);
1498
- return /* @__PURE__ */ jsx(Tooltip, {
1499
- label,
1500
- side: "bottom",
1501
- portal: true,
1502
- disabled: !truncated,
1503
- children: cloneElement(children, { ref: anchor })
1504
- });
1505
- }
1506
- //#endregion
1507
- //#region src/client/schema-form/value.tsx
1508
- function valueText(value) {
1509
- if (value === void 0 || value === null) return "";
1510
- if (typeof value === "string") return value;
1511
- if (typeof value === "number" || typeof value === "boolean") return String(value);
1512
- return JSON.stringify(value);
1513
- }
1514
- function isMultiline(value) {
1515
- return typeof value === "string" && /[\r\n]/.test(value);
1516
- }
1517
- function tokenText(value) {
1518
- if (value === void 0 || value === null) return "null";
1519
- if (typeof value === "string") return JSON.stringify(value);
1520
- if (typeof value === "number" || typeof value === "boolean") return String(value);
1521
- return JSON.stringify(value);
1522
- }
1523
- function tokenTone(value) {
1524
- if (value === void 0 || value === null) return "empty";
1525
- if (typeof value === "number") return "number";
1526
- if (typeof value === "boolean") return "boolean";
1527
- return "string";
1528
- }
1529
- function InlineValue({ owner }) {
1530
- if (owner.options !== void 0) return /* @__PURE__ */ jsx(OptionSelect, {
1531
- owner,
1532
- options: owner.options
1533
- });
1534
- if (owner.node.meta.secret) return /* @__PURE__ */ jsx("span", {
1535
- className: schema_form_module_css_default.lineValue,
1536
- "data-tone": "empty",
1537
- title: owner.hint,
1538
- children: owner.secretConfigured ? "••••••" : ""
1539
- });
1540
- const text = tokenText(owner.value);
1541
- return /* @__PURE__ */ jsx(TruncatedTooltip, {
1542
- label: text,
1543
- children: /* @__PURE__ */ jsx("span", {
1544
- className: schema_form_module_css_default.lineValue,
1545
- "data-tone": owner.node.readOnly === null ? tokenTone(owner.value) : "empty",
1546
- children: text
1547
- })
1548
- });
1549
- }
1550
- function OptionSelect({ owner, options }) {
1551
- const [open, setOpen] = useState(false);
1552
- const selected = options.findIndex((option) => sameValue(option.value, owner.value));
1553
- const current = selected < 0 ? void 0 : options[selected];
1554
- const label = current?.label ?? (owner.value === void 0 ? owner.t("unconfigured") : tokenText(current?.value ?? owner.value));
1555
- return /* @__PURE__ */ jsx(Menu, {
1556
- open,
1557
- dense: true,
1558
- compact: true,
1559
- portal: true,
1560
- align: "start",
1561
- items: options.map((option, index) => ({
1562
- id: String(index),
1563
- label: option.label ?? tokenText(option.value)
1564
- })),
1565
- selectedId: selected < 0 ? void 0 : String(selected),
1566
- onSelect: (id) => {
1567
- setOpen(false);
1568
- const option = options[Number(id)];
1569
- if (option !== void 0) owner.onChange(option.value);
1570
- },
1571
- onClose: () => {
1572
- setOpen(false);
1573
- },
1574
- anchor: /* @__PURE__ */ jsxs("button", {
1575
- className: schema_form_module_css_default.valueTrigger,
1576
- type: "button",
1577
- disabled: owner.disabled,
1578
- "aria-label": owner.label,
1579
- onClick: () => {
1580
- setOpen(true);
1581
- },
1582
- children: [/* @__PURE__ */ jsx("span", {
1583
- className: schema_form_module_css_default.lineValue,
1584
- "data-tone": current === void 0 ? tokenTone(owner.value) : tokenTone(current.value),
1585
- children: label
1586
- }), /* @__PURE__ */ jsx(IconChevronDownOutlineRegular, { size: 14 })]
1587
- })
1588
- });
1589
- }
1590
- function sameValue(left, right) {
1591
- if (Object.is(left, right)) return true;
1592
- if (typeof left !== "object" || typeof right !== "object" || left === null || right === null) return false;
1593
- return JSON.stringify(left) === JSON.stringify(right);
1594
- }
1595
- function SchemaFieldDefault({ owner }) {
1596
- return /* @__PURE__ */ jsx(InlineValue, { owner });
1597
- }
1598
- //#endregion
1599
- //#region src/client/schema-form/fields.tsx
1600
- function parseFor(node, t) {
1601
- switch (node.type) {
1602
- case "number": return (text) => {
1603
- const trimmed = text.trim();
1604
- const value = Number(trimmed);
1605
- if (trimmed === "" || !Number.isFinite(value)) return {
1606
- kind: "invalid",
1607
- message: t("invalidNumber")
1608
- };
1609
- if (node.meta.step === 1 && !Number.isInteger(value)) return {
1610
- kind: "invalid",
1611
- message: t("invalidInteger")
1612
- };
1613
- const { min, max } = node.meta;
1614
- if (min !== void 0 && max !== void 0 && (value < min || value > max)) return {
1615
- kind: "invalid",
1616
- message: t("invalidRange", {
1617
- min,
1618
- max
1619
- })
1620
- };
1621
- if (min !== void 0 && value < min) return {
1622
- kind: "invalid",
1623
- message: t("invalidMin", { min })
1624
- };
1625
- if (max !== void 0 && value > max) return {
1626
- kind: "invalid",
1627
- message: t("invalidMax", { max })
1628
- };
1629
- return {
1630
- kind: "value",
1631
- value
1632
- };
1633
- };
1634
- case "string": {
1635
- const pattern = node.meta.pattern;
1636
- if (pattern === void 0) return (text) => ({
1637
- kind: "value",
1638
- value: text
1639
- });
1640
- return (text) => new RegExp(pattern).test(text) ? {
1641
- kind: "value",
1642
- value: text
1643
- } : {
1644
- kind: "invalid",
1645
- message: t("invalidPattern", { pattern })
1646
- };
1647
- }
1648
- case "boolean": return (text) => {
1649
- const trimmed = text.trim();
1650
- if (trimmed === "true") return {
1651
- kind: "value",
1652
- value: true
1653
- };
1654
- if (trimmed === "false") return {
1655
- kind: "value",
1656
- value: false
1657
- };
1658
- return {
1659
- kind: "invalid",
1660
- message: t("invalidBoolean")
1661
- };
1662
- };
1663
- case "const": return (text) => text === String(node.type === "const" ? node.value : "") || text.trim() === JSON.stringify(node.value) ? {
1664
- kind: "value",
1665
- value: node.value
1666
- } : {
1667
- kind: "invalid",
1668
- message: t("invalidConst")
1669
- };
1670
- case "bitset": return (text) => {
1671
- const value = Number(text.trim());
1672
- return Number.isFinite(value) ? {
1673
- kind: "value",
1674
- value
1675
- } : {
1676
- kind: "invalid",
1677
- message: t("invalidNumber")
1678
- };
1679
- };
1680
- case "any": return (text) => {
1681
- try {
1682
- return {
1683
- kind: "value",
1684
- value: JSON.parse(text)
1685
- };
1686
- } catch {
1687
- return {
1688
- kind: "invalid",
1689
- message: t("invalidJson")
1690
- };
1691
- }
1692
- };
1693
- default:
1694
- if (node.type === "union" && node.choices !== void 0) {
1695
- const choices = node.choices;
1696
- const options = choices.map((choice) => String(choice)).join(" / ");
1697
- return (text) => choices.some((choice) => String(choice) === text) ? {
1698
- kind: "value",
1699
- value: text
1700
- } : {
1701
- kind: "invalid",
1702
- message: t("invalidChoice", { choices: options })
1703
- };
1704
- }
1705
- return (text) => ({
1706
- kind: "value",
1707
- value: text
1708
- });
1709
- }
1710
- }
1711
- //#endregion
1712
- //#region src/client/controls/classes.ts
1713
- function classes(...names) {
1714
- return names.filter((name) => typeof name === "string" && name !== "").join(" ");
1715
- }
1716
- //#endregion
1717
- //#region src/client/schema-form/Editor.tsx
1718
- function Editor(props) {
1719
- const { ns, state, face, t, resolveText, renderField } = props;
1720
- const [toggled, setToggled] = useState(() => /* @__PURE__ */ new Set());
1721
- const [editing, setEditing] = useState(void 0);
1722
- const [selected, setSelected] = useState(void 0);
1723
- const [dismissed, setDismissed] = useState(() => /* @__PURE__ */ new Set());
1724
- const fold = useFold(state, toggled, setToggled);
1725
- const lines = useMemo(() => editorLines(state, fold, resolveText, t), [
1726
- state,
1727
- fold,
1728
- resolveText,
1729
- t
1730
- ]);
1731
- const disabled = !state.writable || !state.available;
1732
- return /* @__PURE__ */ jsx("div", {
1733
- className: schema_form_module_css_default.editorRoot,
1734
- "data-editor": "schema-form",
1735
- children: lines.map((line, index) => /* @__PURE__ */ jsx(Row$1, {
1736
- line,
1737
- n: index + 1,
1738
- ns,
1739
- state,
1740
- face,
1741
- fold,
1742
- t,
1743
- resolveText,
1744
- disabled,
1745
- editing,
1746
- selected,
1747
- onEdit: (key) => {
1748
- setEditing(key);
1749
- if (key !== void 0) setDismissed((previous) => {
1750
- const next = new Set(previous);
1751
- next.delete(key);
1752
- return next;
1753
- });
1754
- },
1755
- onAdded: (path) => {
1756
- setEditing(fieldKey(path));
1757
- },
1758
- dismissed,
1759
- onDismiss: (key) => {
1760
- setDismissed((previous) => new Set(previous).add(key));
1761
- },
1762
- onSelect: (path) => {
1763
- setSelected(fieldKey(path));
1764
- },
1765
- renderField
1766
- }, `${line.kind}:${fieldKey(line.path)}:${String(index)}`))
1767
- });
1768
- }
1769
- function useFold(state, toggled, setToggled) {
1770
- const defaults = useMemo(() => {
1771
- const collapsed = /* @__PURE__ */ new Set();
1772
- for (const item of state.walked) {
1773
- const value = state.fields.get(fieldKey(item.path))?.value;
1774
- if (item.node.meta.collapse && containerShape(item.node, value) !== void 0) collapsed.add(fieldKey(item.path));
1775
- }
1776
- return collapsed;
1777
- }, [state.walked, state.fields]);
1778
- return useMemo(() => ({
1779
- collapsed: (path) => {
1780
- const key = fieldKey(path);
1781
- return toggled.has(key) !== defaults.has(key);
1782
- },
1783
- toggle: (path) => {
1784
- const key = fieldKey(path);
1785
- const next = new Set(toggled);
1786
- if (next.has(key)) next.delete(key);
1787
- else next.add(key);
1788
- setToggled(next);
1789
- }
1790
- }), [
1791
- defaults,
1792
- setToggled,
1793
- toggled
1794
- ]);
1795
- }
1796
- function Row$1({ line, n, ns, state, face, fold, t, resolveText, disabled, editing, selected, dismissed, onEdit, onAdded, onDismiss, onSelect, renderField }) {
1797
- const key = fieldKey(line.path);
1798
- const indent = { paddingLeft: `${String(line.depth * 14)}px` };
1799
- const body = line.kind === "comment" ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
1800
- className: schema_form_module_css_default.lineFoldSpacer,
1801
- "data-role": "fold"
1802
- }), /* @__PURE__ */ jsx(TruncatedTooltip, {
1803
- label: line.text,
1804
- children: line.invalid ? /* @__PURE__ */ jsx("span", {
1805
- className: schema_form_module_css_default.lineInvalid,
1806
- "data-role": "comment",
1807
- children: `// ${line.text}`
1808
- }) : /* @__PURE__ */ jsx("span", {
1809
- className: schema_form_module_css_default.lineComment,
1810
- "data-role": "comment",
1811
- children: `// ${line.text}`
1812
- })
1813
- })] }) : line.kind === "open" ? /* @__PURE__ */ jsxs(Fragment, { children: [
1814
- /* @__PURE__ */ jsx("button", {
1815
- className: schema_form_module_css_default.lineFold,
1816
- "data-role": "fold",
1817
- type: "button",
1818
- "aria-expanded": !line.collapsed,
1819
- "aria-label": t("toggleGroup"),
1820
- onClick: () => {
1821
- fold.toggle(line.path);
1822
- },
1823
- children: line.collapsed ? /* @__PURE__ */ jsx(IconChevronRightOutlineRegular, { size: 14 }) : /* @__PURE__ */ jsx(IconChevronDownOutlineRegular, { size: 14 })
1824
- }),
1825
- /* @__PURE__ */ jsx(LinePrefix, {
1826
- line,
1827
- face,
1828
- t,
1829
- disabled
1830
- }),
1831
- /* @__PURE__ */ jsx("span", {
1832
- className: schema_form_module_css_default.lineToken,
1833
- children: line.shape === "object" ? line.collapsed ? "{…}" : "{" : line.collapsed ? "[…]" : "["
1834
- }),
1835
- /* @__PURE__ */ jsx(VariantSelect, {
1836
- control: line.variants,
1837
- path: line.path,
1838
- face,
1839
- disabled,
1840
- t
1841
- })
1842
- ] }) : line.kind === "close" ? /* @__PURE__ */ jsxs(Fragment, { children: [
1843
- /* @__PURE__ */ jsx("span", {
1844
- className: schema_form_module_css_default.lineFoldSpacer,
1845
- "data-role": "fold"
1846
- }),
1847
- /* @__PURE__ */ jsx("span", {
1848
- className: schema_form_module_css_default.lineToken,
1849
- children: line.shape === "object" ? "}" : "]"
1850
- }),
1851
- /* @__PURE__ */ jsx(AddLine, {
1852
- line,
1853
- state,
1854
- face,
1855
- t,
1856
- resolveText,
1857
- disabled,
1858
- onAdded
1859
- })
1860
- ] }) : /* @__PURE__ */ jsx(FieldLine, {
1861
- line,
1862
- ns,
1863
- state,
1864
- face,
1865
- t,
1866
- disabled,
1867
- editing,
1868
- dismissed,
1869
- onEdit,
1870
- onDismiss,
1871
- renderField
1872
- });
1873
- return /* @__PURE__ */ jsxs("div", {
1874
- className: schema_form_module_css_default.lineRow,
1875
- "data-line": line.kind,
1876
- "data-field-path": line.path.join("."),
1877
- "data-selected": selected === key ? "true" : void 0,
1878
- "data-dirty": line.kind === "field" && line.field.staged ? "true" : void 0,
1879
- "data-overridden": line.kind === "field" && line.field.overridden && !line.field.staged ? "true" : void 0,
1880
- "data-invalid": line.kind === "field" && (line.field.invalid !== void 0 || state.invalidAt.has(key)) ? "true" : void 0,
1881
- children: [/* @__PURE__ */ jsx("span", {
1882
- className: schema_form_module_css_default.lineNumber,
1883
- "data-role": "number",
1884
- onClick: () => {
1885
- onSelect(line.path);
1886
- },
1887
- children: n
1888
- }), /* @__PURE__ */ jsx("div", {
1889
- className: schema_form_module_css_default.lineBody,
1890
- "data-role": "body",
1891
- style: indent,
1892
- children: body
1893
- })]
1894
- });
1895
- }
1896
- function FieldLine({ line, ns, state, face, t, disabled, editing, dismissed, onEdit, onDismiss, renderField }) {
1897
- const key = fieldKey(line.path);
1898
- const member = line.member;
1899
- const owner = {
1900
- ns,
1901
- path: line.path,
1902
- node: line.node,
1903
- label: line.node.label ?? member?.key ?? line.node.key,
1904
- hint: void 0,
1905
- value: line.field.value,
1906
- options: state.options.get(key),
1907
- text: line.field.text,
1908
- secretConfigured: state.secrets.get(key) === true,
1909
- depth: line.depth,
1910
- overridden: line.field.overridden,
1911
- invalid: line.field.invalid,
1912
- disabled,
1913
- t,
1914
- actions: face,
1915
- group: void 0,
1916
- member,
1917
- onChange: (value) => {
1918
- face.set(line.path, value);
1919
- },
1920
- onEditText: (text, parse) => {
1921
- face.setText(line.path, text, parse ?? parseFor(line.node, t));
1922
- },
1923
- onReset: () => {
1924
- face.clear(line.path);
1925
- }
1926
- };
1927
- const readOnly = line.node.meta.disabled || line.node.readOnly !== null;
1928
- const editable = !disabled && !readOnly && line.node.type !== "const" && owner.options === void 0 && !line.variantsStandIn;
1929
- const missing = line.field.value === null || line.field.value === void 0;
1930
- const isEditing = editable && (editing === key || missing && !dismissed.has(key));
1931
- const text = line.field.text ?? valueText(line.field.value);
1932
- const multiline = isMultiline(line.field.value) || /[\r\n]/.test(text);
1933
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1934
- /* @__PURE__ */ jsx("span", {
1935
- className: schema_form_module_css_default.lineFoldSpacer,
1936
- "data-role": "fold"
1937
- }),
1938
- /* @__PURE__ */ jsx("span", {
1939
- className: schema_form_module_css_default.lineKey,
1940
- "data-role": "key",
1941
- "data-index": member?.index === void 0 ? void 0 : "true",
1942
- title: member?.key ?? line.node.key,
1943
- children: member?.key ?? line.node.key
1944
- }),
1945
- /* @__PURE__ */ jsx("span", {
1946
- className: schema_form_module_css_default.lineToken,
1947
- children: member?.index === void 0 ? ": " : " "
1948
- }),
1949
- isEditing ? multiline ? /* @__PURE__ */ jsx("span", {
1950
- className: schema_form_module_css_default.compactTextField,
1951
- children: /* @__PURE__ */ jsx("textarea", {
1952
- autoFocus: !missing,
1953
- rows: 1,
1954
- "aria-label": owner.label,
1955
- value: text,
1956
- onChange: (event) => {
1957
- owner.onEditText(event.target.value);
1958
- },
1959
- onKeyDown: (event) => {
1960
- if (event.key === "Escape") {
1961
- face.revert(line.path);
1962
- onEdit(void 0);
1963
- }
1964
- }
1965
- })
1966
- }) : /* @__PURE__ */ jsx("span", {
1967
- className: schema_form_module_css_default.compactInput,
1968
- children: /* @__PURE__ */ jsx(Input, {
1969
- autoFocus: !missing,
1970
- type: "text",
1971
- "aria-label": owner.label,
1972
- placeholder: missing ? t("empty") : "",
1973
- value: text,
1974
- onBlur: () => {
1975
- if (!missing) onEdit(void 0);
1976
- },
1977
- onChange: (event) => {
1978
- owner.onEditText(event.target.value);
1979
- },
1980
- onKeyDown: (event) => {
1981
- if (event.key === "Enter" && !missing) onEdit(void 0);
1982
- if (event.key === "Escape") {
1983
- face.revert(line.path);
1984
- onEdit(void 0);
1985
- }
1986
- }
1987
- })
1988
- }) : null,
1989
- isEditing || line.variantsStandIn ? null : /* @__PURE__ */ jsx("span", {
1990
- className: schema_form_module_css_default.valueSlot,
1991
- "data-role": "value",
1992
- onClick: () => {
1993
- if (editable) onEdit(key);
1994
- },
1995
- children: renderField(owner)
1996
- }),
1997
- /* @__PURE__ */ jsx(VariantSelect, {
1998
- control: line.variants,
1999
- path: line.path,
2000
- face,
2001
- disabled,
2002
- t
2003
- }),
2004
- isEditing ? /* @__PURE__ */ jsxs("span", {
2005
- className: classes(schema_form_module_css_default.lineActions, schema_form_module_css_default.hoverActions),
2006
- "data-role": "actions",
2007
- "data-editing": "true",
2008
- children: [/* @__PURE__ */ jsx("button", {
2009
- type: "button",
2010
- "aria-label": t("confirmEdit"),
2011
- title: t("confirmEdit"),
2012
- onClick: () => {
2013
- onEdit(void 0);
2014
- },
2015
- children: /* @__PURE__ */ jsx(IconCheckOutlineRegular, { size: 14 })
2016
- }), /* @__PURE__ */ jsx("button", {
2017
- type: "button",
2018
- "aria-label": t("cancelEdit"),
2019
- title: t("cancelEdit"),
2020
- onClick: () => {
2021
- face.revert(line.path);
2022
- onEdit(void 0);
2023
- onDismiss(key);
2024
- },
2025
- children: /* @__PURE__ */ jsx(IconCloseOutlineRegular, { size: 14 })
2026
- })]
2027
- }) : null,
2028
- /* @__PURE__ */ jsxs("span", {
2029
- className: classes(schema_form_module_css_default.lineActions, schema_form_module_css_default.hoverActions),
2030
- "data-role": "actions",
2031
- children: [
2032
- line.field.staged && !disabled ? /* @__PURE__ */ jsx("button", {
2033
- type: "button",
2034
- "aria-label": t("revert"),
2035
- title: t("revert"),
2036
- onClick: () => {
2037
- face.revert(line.path);
2038
- },
2039
- children: /* @__PURE__ */ jsx(IconRefreshOutlineRegular, { size: 14 })
2040
- }) : null,
2041
- line.field.overridden && !line.field.staged && !disabled ? /* @__PURE__ */ jsx("button", {
2042
- type: "button",
2043
- "aria-label": t("reset"),
2044
- title: t("reset"),
2045
- onClick: () => {
2046
- face.clear(line.path);
2047
- },
2048
- children: /* @__PURE__ */ jsx(IconRefreshOutlineRegular, { size: 14 })
2049
- }) : null,
2050
- /* @__PURE__ */ jsx("button", {
2051
- type: "button",
2052
- "aria-label": t("copyValue"),
2053
- title: t("copyValue"),
2054
- onClick: () => {
2055
- navigator.clipboard?.writeText(line.field.text ?? tokenFor(line.field.value)).catch(() => {});
2056
- },
2057
- children: /* @__PURE__ */ jsx(IconCopyOutlineRegular, { size: 14 })
2058
- }),
2059
- member === void 0 ? null : /* @__PURE__ */ jsx(RemoveLineButton, {
2060
- member,
2061
- face,
2062
- t,
2063
- disabled
2064
- })
2065
- ]
2066
- })
2067
- ] });
2068
- }
2069
- function tokenFor(value) {
2070
- return typeof value === "string" ? JSON.stringify(value) : JSON.stringify(value ?? null);
2071
- }
2072
- function VariantSelect({ control, path, face, disabled, t }) {
2073
- const [open, setOpen] = useState(false);
2074
- if (control === void 0) return null;
2075
- const current = control.choices[control.selected];
2076
- return /* @__PURE__ */ jsx(Menu, {
2077
- open,
2078
- dense: true,
2079
- compact: true,
2080
- portal: true,
2081
- align: "start",
2082
- items: control.choices.map((choice, index) => ({
2083
- id: String(index),
2084
- label: choice.label
2085
- })),
2086
- selectedId: String(control.selected),
2087
- onSelect: (id) => {
2088
- setOpen(false);
2089
- const choice = control.choices[Number(id)];
2090
- if (choice !== void 0) face.set(path, choice.value);
2091
- },
2092
- onClose: () => {
2093
- setOpen(false);
2094
- },
2095
- anchor: /* @__PURE__ */ jsxs("button", {
2096
- className: schema_form_module_css_default.valueTrigger,
2097
- type: "button",
2098
- "data-role": "variant",
2099
- disabled,
2100
- "aria-label": t("switchVariant"),
2101
- onClick: () => {
2102
- setOpen(true);
2103
- },
2104
- children: [/* @__PURE__ */ jsx("span", {
2105
- className: schema_form_module_css_default.lineValue,
2106
- "data-tone": "empty",
2107
- children: current?.label ?? ""
2108
- }), /* @__PURE__ */ jsx(IconChevronDownOutlineRegular, { size: 14 })]
2109
- })
2110
- });
2111
- }
2112
- function LinePrefix({ line, face, t, disabled }) {
2113
- const member = line.member;
2114
- const key = member?.key ?? line.node.key;
2115
- if (key === "") return null;
2116
- const indexed = member !== void 0 && member.index !== void 0;
2117
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2118
- /* @__PURE__ */ jsx("span", {
2119
- className: schema_form_module_css_default.lineKey,
2120
- "data-role": "key",
2121
- "data-index": indexed ? "true" : void 0,
2122
- title: key,
2123
- children: key
2124
- }),
2125
- /* @__PURE__ */ jsx("span", {
2126
- className: schema_form_module_css_default.lineToken,
2127
- children: indexed ? " " : ": "
2128
- }),
2129
- member === void 0 ? null : /* @__PURE__ */ jsx("span", {
2130
- className: classes(schema_form_module_css_default.lineActions, schema_form_module_css_default.hoverActions),
2131
- "data-role": "actions",
2132
- children: /* @__PURE__ */ jsx(RemoveLineButton, {
2133
- member,
2134
- face,
2135
- t,
2136
- disabled
2137
- })
2138
- })
2139
- ] });
2140
- }
2141
- function RemoveLineButton({ member, face, t, disabled }) {
2142
- return /* @__PURE__ */ jsx("button", {
2143
- type: "button",
2144
- "aria-label": t("removeItem"),
2145
- title: t("removeItem"),
2146
- disabled,
2147
- onClick: () => {
2148
- if (member.index === void 0) face.removeKey(member.parent, member.key);
2149
- else face.removeItem(member.parent, member.index);
2150
- },
2151
- children: /* @__PURE__ */ jsx(IconTrashOutlineRegular, { size: 14 })
2152
- });
2153
- }
2154
- function AddLine({ line, state, face, t, resolveText, disabled, onAdded }) {
2155
- const spec = line.add;
2156
- const [text, setText] = useState("");
2157
- const [open, setOpen] = useState(false);
2158
- const [invalid, setInvalid] = useState(false);
2159
- if (spec === void 0 || disabled) return null;
2160
- const options = spec.kind === "item" ? [] : spec.options;
2161
- const query = text.trim().toLowerCase();
2162
- const matched = options.filter((option) => query === "" || option.key.toLowerCase().includes(query));
2163
- const label = spec.kind === "item" ? t("addItemPaste") : spec.kind === "key" ? t("addKey") : t("addProperty");
2164
- const commit = (picked) => {
2165
- const raw = (picked ?? text).trim();
2166
- if (raw === "") return;
2167
- setInvalid(false);
2168
- if (raw.startsWith("{") || raw.startsWith("[")) try {
2169
- face.set(line.path, JSON.parse(raw));
2170
- setText("");
2171
- setOpen(false);
2172
- return;
2173
- } catch {}
2174
- if (spec.kind === "key") {
2175
- face.addKey(line.path, raw);
2176
- onAdded([...line.path, raw]);
2177
- } else if (spec.kind === "item") {
2178
- const current = state.fields.get(fieldKey(line.path))?.value;
2179
- const index = Array.isArray(current) ? current.length : 0;
2180
- face.appendItem(line.path);
2181
- onAdded([...line.path, String(index)]);
2182
- } else {
2183
- if (!spec.options.some((option) => option.key === raw)) {
2184
- setInvalid(true);
2185
- return;
2186
- }
2187
- face.addKey(line.path, raw);
2188
- onAdded([...line.path, raw]);
2189
- }
2190
- setText("");
2191
- setOpen(false);
2192
- };
2193
- return /* @__PURE__ */ jsxs("span", {
2194
- className: schema_form_module_css_default.addWrap,
2195
- "data-add": spec.kind,
2196
- "data-invalid": invalid ? "true" : void 0,
2197
- children: [
2198
- /* @__PURE__ */ jsx(Menu, {
2199
- open: open && spec.kind !== "item" && matched.length > 0,
2200
- dense: true,
2201
- compact: true,
2202
- portal: true,
2203
- align: "start",
2204
- items: matched.map((option) => ({
2205
- id: option.key,
2206
- label: option.key
2207
- })),
2208
- onSelect: (key) => {
2209
- commit(key);
2210
- },
2211
- onClose: () => {
2212
- setOpen(false);
2213
- },
2214
- anchor: /* @__PURE__ */ jsx("span", {
2215
- className: schema_form_module_css_default.compactInput,
2216
- children: /* @__PURE__ */ jsx(Input, {
2217
- value: text,
2218
- placeholder: label,
2219
- "aria-label": label,
2220
- disabled,
2221
- onFocus: () => {
2222
- setOpen(true);
2223
- },
2224
- onChange: (event) => {
2225
- setText(event.target.value);
2226
- setInvalid(false);
2227
- setOpen(true);
2228
- },
2229
- onKeyDown: (event) => {
2230
- if (event.key === "Enter") {
2231
- event.preventDefault();
2232
- commit(matched.length === 1 && spec.kind === "prop" ? matched[0]?.key : void 0);
2233
- }
2234
- if (event.key === "Escape") {
2235
- setText("");
2236
- setOpen(false);
2237
- }
2238
- }
2239
- })
2240
- })
2241
- }),
2242
- invalid ? /* @__PURE__ */ jsx("span", {
2243
- className: schema_form_module_css_default.lineInvalid,
2244
- children: t("unknownProperty")
2245
- }) : null,
2246
- !invalid && matched.length === 1 && matched[0]?.description !== void 0 ? /* @__PURE__ */ jsx(TruncatedTooltip, {
2247
- label: resolveText(matched[0].description),
2248
- children: /* @__PURE__ */ jsx("span", {
2249
- className: schema_form_module_css_default.lineComment,
2250
- children: resolveText(matched[0].description)
2251
- })
2252
- }) : null
2253
- ]
2254
- });
2255
- }
2256
- //#endregion
2257
- //#region src/client/schema-form/SchemaForm.tsx
2258
- function SchemaForm(props) {
2259
- const { ns, face, t, resolveText, renderSlotChain } = props;
2260
- const store = face.hooks.schemaForm;
2261
- const state = useSyncExternalStore((listener) => store.subscribe(listener), () => store.getSnapshot());
2262
- const labels = {
2263
- unavailable: t("unavailable"),
2264
- readOnly: t("readOnly"),
2265
- saveFailed: t("saveFailed"),
2266
- save: t("save"),
2267
- saving: t("saving")
2268
- };
2269
- if (!state.configured) return /* @__PURE__ */ jsx("p", {
2270
- className: schema_form_module_css_default.hint,
2271
- role: "status",
2272
- children: t("noSchema")
2273
- });
2274
- return /* @__PURE__ */ jsxs(SettingsForm, {
2275
- labels,
2276
- state,
2277
- onSave: () => {
2278
- face.save();
2279
- },
2280
- onDiscard: () => {
2281
- face.discard();
2282
- },
2283
- children: [/* @__PURE__ */ jsx(Editor, {
2284
- ns,
2285
- state,
2286
- face,
2287
- t,
2288
- resolveText,
2289
- renderField: (owner) => renderSlotChain("settings.schema-form.field", owner, { fallback: /* @__PURE__ */ jsx(SchemaFieldDefault, { owner: {
2290
- ...owner,
2291
- onEditText: withParse(owner, t)
2292
- } }) })
2293
- }), state.violation === void 0 ? null : /* @__PURE__ */ jsx("p", {
2294
- className: schema_form_module_css_default.hint,
2295
- role: "alert",
2296
- "data-violation": "true",
2297
- children: t("notSaved", { message: state.violation.message })
2298
- })]
2299
- });
2300
- }
2301
- function withParse(owner, t) {
2302
- return (text, parse) => {
2303
- owner.onEditText(text, parse ?? parseFor(owner.node, t));
2304
- };
2305
- }
2306
- //#endregion
2307
- //#region src/client/schema-form/index.ts
2308
- var schema_form_exports = /* @__PURE__ */ __exportAll({
2309
- InlineValue: () => InlineValue,
2310
- NS: () => NS,
2311
- SchemaFieldDefault: () => SchemaFieldDefault,
2312
- SchemaFormController: () => SchemaFormController,
2313
- SchemaFormHints: () => SchemaFormHints,
2314
- apply: () => apply$1,
2315
- canRender: () => canRender,
2316
- containerShape: () => containerShape,
2317
- editorLines: () => editorLines,
2318
- failureOf: () => failureOf,
2319
- inject: () => inject$1,
2320
- optionsFor: () => optionsFor,
2321
- parseFor: () => parseFor,
2322
- projectNode: () => projectNode,
2323
- projectRoot: () => projectRoot,
2324
- rowRegistrations: () => rowRegistrations,
2325
- tokenText: () => tokenText,
2326
- tokenTone: () => tokenTone,
2327
- valueText: () => valueText,
2328
- visibleFields: () => visibleFields,
2329
- walkFields: () => walkFields
2330
- });
2331
- const NS = "settings.schema-form";
2332
- const inject$1 = [
2333
- "slots",
2334
- "locale",
2335
- "configForms",
2336
- "settingsSchema",
2337
- "remote",
2338
- "remote.pluginManager"
2339
- ];
2340
- function apply$1(ctx) {
2341
- ctx.inject([...inject$1], (scope) => {
2342
- if (scope.get("schemaFormHints") !== void 0) return;
2343
- install(scope);
2344
- });
2345
- }
2346
- function install(ctx) {
2347
- ctx.effect(() => ctx.locale.register(NS, {
2348
- zh,
2349
- en
2350
- }), "ui-schema-form: dictionaries");
2351
- const hints = new SchemaFormHints(ctx);
2352
- ctx.effect(() => ctx.slots.registerFactory({
2353
- name: "settings.schema-form.form",
2354
- scope: "root",
2355
- children: { "settings.schema-form.field": {
2356
- kind: "chain",
2357
- scope: "root"
2358
- } },
2359
- locale: NS
2360
- }, SchemaForm), "ui-schema-form: form factory");
2361
- const rehydrate = (serialized) => ctx.settingsSchema.rehydrate(serialized);
2362
- const validate = (schema, value) => {
2363
- try {
2364
- schema(value);
2365
- return;
2366
- } catch (error) {
2367
- return failureOf(error);
2368
- }
2369
- };
2370
- const resolveText = (text) => typeof text === "string" ? text : ctx.locale.resolveText(text);
2371
- const entries = /* @__PURE__ */ new Map();
2372
- const entryFor = (ns) => {
2373
- const describe = ctx.configForms.describe();
2374
- const view = describe.getSnapshot().view?.namespaces.find((row) => row.ns === ns);
2375
- if (!canRender(view, rehydrate)) return void 0;
2376
- const existing = entries.get(ns);
2377
- if (existing !== void 0) return existing;
2378
- const controller = new SchemaFormController(ns, {
2379
- form: ctx.configForms.get(ns),
2380
- describe,
2381
- rehydrate,
2382
- validate,
2383
- t: ctx.locale.bind(NS),
2384
- hints: {
2385
- keysFor: (path) => hints.keysFor(ns, path),
2386
- textFor: (path) => hints.textFor(ns, path),
2387
- selectFor: (path) => hints.selectFor(ns, path),
2388
- sourceFor: (name) => hints.sourceFor(name)
2389
- }
2390
- });
2391
- const face = controller.face();
2392
- const props = {
2393
- ns,
2394
- face,
2395
- resolveText
2396
- };
2397
- const component = (entryProps) => entryProps.view === "page" ? entryProps.renderFactorySlot("settings.schema-form.form", props) : null;
2398
- const entry = {
2399
- controller,
2400
- face,
2401
- component
2402
- };
2403
- entries.set(ns, entry);
2404
- return entry;
2405
- };
2406
- const registration = new RowRegistration({
2407
- slots: ctx.slots,
2408
- describe: ctx.configForms.describe(),
2409
- bundles: async () => {
2410
- const response = await ctx.remote.pluginManager.listBundles();
2411
- return response.ok ? response.value : [];
2412
- },
2413
- subscribeBundles: (listener) => ctx.remote.$on("plugin-manager/changed", listener),
2414
- entryFor,
2415
- locale: NS,
2416
- release: (ns) => {
2417
- const entry = entries.get(ns);
2418
- entries.delete(ns);
2419
- entry?.controller.dispose();
2420
- }
2421
- });
2422
- ctx.effect(() => {
2423
- const offDescribe = ctx.configForms.describe().subscribe(() => {
2424
- registration.sync();
2425
- });
2426
- const offHints = hints.subscribe(() => {
2427
- for (const entry of entries.values()) entry.controller.refresh();
2428
- });
2429
- registration.sync();
2430
- return () => {
2431
- offDescribe();
2432
- offHints();
2433
- registration.dispose();
2434
- for (const [ns, entry] of entries) {
2435
- entries.delete(ns);
2436
- entry.controller.dispose();
2437
- }
2438
- };
2439
- }, "ui-schema-form: row registrations");
2440
- }
2441
- //#endregion
2442
- //#region src/client/markdown-labels.ts
2443
- function markdownLabels(t) {
2444
- return {
2445
- code: {
2446
- copyLabel: t("copy"),
2447
- copiedLabel: t("copied")
2448
- },
2449
- footnotes: t("markdown.footnotes")
2450
- };
2451
- }
2452
- //#endregion
2453
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/layout/layout.module.css.mjs
2454
- const css$15 = ".e_G4ZW_stack{flex-direction:column;min-width:0;display:flex}.e_G4ZW_row{flex-direction:row;align-items:center;min-width:0;display:flex}.e_G4ZW_gap0{gap:0}.e_G4ZW_gap2{gap:2px}.e_G4ZW_gap4{gap:4px}.e_G4ZW_gap6{gap:6px}.e_G4ZW_gap8{gap:8px}.e_G4ZW_gap10{gap:10px}.e_G4ZW_gap12{gap:12px}.e_G4ZW_gap14{gap:14px}.e_G4ZW_gap16{gap:16px}.e_G4ZW_alignStart{align-items:flex-start}.e_G4ZW_alignCenter{align-items:center}.e_G4ZW_alignEnd{align-items:flex-end}.e_G4ZW_justifyBetween{justify-content:space-between}.e_G4ZW_justifyEnd{justify-content:flex-end}.e_G4ZW_justifyCenter{justify-content:center}.e_G4ZW_wrap{flex-wrap:wrap}.e_G4ZW_grow{flex:auto;min-width:0}.e_G4ZW_push{margin-left:auto}.e_G4ZW_fill{box-sizing:border-box;width:100%;height:100%;overflow:hidden}.e_G4ZW_scroll{flex:auto;min-height:0;overflow-y:auto}.e_G4ZW_plain{margin:0;padding:0;list-style:none}.e_G4ZW_padNone{padding:0}.e_G4ZW_padCard{padding:8px 12px}.e_G4ZW_padBody{padding:8px 0}.e_G4ZW_padPage{padding:24px 28px}.e_G4ZW_padRow{padding:10px 12px}.e_G4ZW_padBlocking{padding:32px 40px}.e_G4ZW_text{margin:0}.e_G4ZW_sizeXs{font-size:11px;line-height:1.5}.e_G4ZW_sizeSm{font-size:12px;line-height:18px}.e_G4ZW_sizeMd{font-size:13px;line-height:20px}.e_G4ZW_sizeBase{font-size:14px;line-height:24px}.e_G4ZW_sizeLg{font-size:16px;line-height:24px}.e_G4ZW_tonePrimary{color:var(--dsw-alias-label-primary)}.e_G4ZW_toneSecondary{color:var(--dsw-alias-label-secondary)}.e_G4ZW_toneTertiary{color:var(--dsw-alias-label-tertiary)}.e_G4ZW_toneDanger{color:var(--dsw-alias-label-error,var(--dsw-alias-label-primary))}.e_G4ZW_weightMedium{font-weight:500}.e_G4ZW_strong{font-weight:600}.e_G4ZW_mono{word-break:break-all;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,monospace}.e_G4ZW_truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.e_G4ZW_tabular{font-variant-numeric:tabular-nums}.e_G4ZW_boxed{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);border-radius:10px}.e_G4ZW_fixed{flex:none}.e_G4ZW_gapWide{gap:6px 20px}.e_G4ZW_narrow{min-width:0;max-width:min(calc(var(--dsh-chat-content-width,748px) * .702), 82%)}.e_G4ZW_wSearch{flex:none;width:360px;max-width:100%}";
2455
- const tagId$15 = "@morlay/dsh-client-ui-primitives/layout.module.css";
2456
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/layout.module.css\"]") === null) {
2457
- const tag = document.createElement("style");
2458
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
2459
- tag.dataset.pluginCss = tagId$15;
2460
- tag.textContent = css$15;
2461
- document.head.appendChild(tag);
2462
- }
2463
- var layout_module_css_default = {
2464
- "weightMedium": "e_G4ZW_weightMedium",
2465
- "gap16": "e_G4ZW_gap16",
2466
- "padBlocking": "e_G4ZW_padBlocking",
2467
- "wSearch": "e_G4ZW_wSearch",
2468
- "gapWide": "e_G4ZW_gapWide",
2469
- "alignEnd": "e_G4ZW_alignEnd",
2470
- "strong": "e_G4ZW_strong",
2471
- "toneSecondary": "e_G4ZW_toneSecondary",
2472
- "justifyCenter": "e_G4ZW_justifyCenter",
2473
- "justifyEnd": "e_G4ZW_justifyEnd",
2474
- "fill": "e_G4ZW_fill",
2475
- "padNone": "e_G4ZW_padNone",
2476
- "boxed": "e_G4ZW_boxed",
2477
- "justifyBetween": "e_G4ZW_justifyBetween",
2478
- "plain": "e_G4ZW_plain",
2479
- "grow": "e_G4ZW_grow",
2480
- "sizeBase": "e_G4ZW_sizeBase",
2481
- "gap14": "e_G4ZW_gap14",
2482
- "alignCenter": "e_G4ZW_alignCenter",
2483
- "sizeMd": "e_G4ZW_sizeMd",
2484
- "tonePrimary": "e_G4ZW_tonePrimary",
2485
- "stack": "e_G4ZW_stack",
2486
- "toneTertiary": "e_G4ZW_toneTertiary",
2487
- "mono": "e_G4ZW_mono",
2488
- "sizeLg": "e_G4ZW_sizeLg",
2489
- "gap0": "e_G4ZW_gap0",
2490
- "gap8": "e_G4ZW_gap8",
2491
- "gap6": "e_G4ZW_gap6",
2492
- "scroll": "e_G4ZW_scroll",
2493
- "sizeSm": "e_G4ZW_sizeSm",
2494
- "gap2": "e_G4ZW_gap2",
2495
- "gap4": "e_G4ZW_gap4",
2496
- "sizeXs": "e_G4ZW_sizeXs",
2497
- "padCard": "e_G4ZW_padCard",
2498
- "alignStart": "e_G4ZW_alignStart",
2499
- "padPage": "e_G4ZW_padPage",
2500
- "push": "e_G4ZW_push",
2501
- "truncate": "e_G4ZW_truncate",
2502
- "row": "e_G4ZW_row",
2503
- "toneDanger": "e_G4ZW_toneDanger",
2504
- "wrap": "e_G4ZW_wrap",
2505
- "padRow": "e_G4ZW_padRow",
2506
- "tabular": "e_G4ZW_tabular",
2507
- "fixed": "e_G4ZW_fixed",
2508
- "narrow": "e_G4ZW_narrow",
2509
- "gap10": "e_G4ZW_gap10",
2510
- "padBody": "e_G4ZW_padBody",
2511
- "text": "e_G4ZW_text",
2512
- "gap12": "e_G4ZW_gap12"
2513
- };
2514
- //#endregion
2515
- //#region src/client/layout/scales.ts
2516
- function gapClass(css, gap) {
2517
- if (gap === void 0) return void 0;
2518
- return gap === "wide" ? css.gapWide : css[`gap${gap}`];
2519
- }
2520
- function alignClass(css, align) {
2521
- if (align === void 0 || align === "stretch") return void 0;
2522
- if (align === "start") return css.alignStart;
2523
- return align === "center" ? css.alignCenter : css.alignEnd;
2524
- }
2525
- function justifyClass(css, justify) {
2526
- if (justify === void 0) return void 0;
2527
- if (justify === "between") return css.justifyBetween;
2528
- if (justify === "end") return css.justifyEnd;
2529
- return justify === "center" ? css.justifyCenter : void 0;
2530
- }
2531
- function padClass(css, pad) {
2532
- if (pad === void 0 || pad === "none") return void 0;
2533
- if (pad === "card") return css.padCard;
2534
- if (pad === "body") return css.padBody;
2535
- if (pad === "page") return css.padPage;
2536
- return pad === "row" ? css.padRow : css.padBlocking;
2537
- }
2538
- function sizeClass(css, size) {
2539
- if (size === void 0) return void 0;
2540
- if (size === "xs") return css.sizeXs;
2541
- if (size === "sm") return css.sizeSm;
2542
- if (size === "md") return css.sizeMd;
2543
- return size === "base" ? css.sizeBase : css.sizeLg;
2544
- }
2545
- function toneClass(css, tone) {
2546
- if (tone === void 0) return void 0;
2547
- if (tone === "primary") return css.tonePrimary;
2548
- if (tone === "secondary") return css.toneSecondary;
2549
- return tone === "tertiary" ? css.toneTertiary : css.toneDanger;
2550
- }
2551
- function weightClass(css, weight) {
2552
- if (weight === void 0) return void 0;
2553
- return weight === "medium" ? css.weightMedium : css.strong;
2554
- }
2555
- //#endregion
2556
- //#region src/client/layout/Row.tsx
2557
- const Row = forwardRef(function Row({ as: Element = "div", gap, align, justify, wrap = false, grow = false, boxed = false, fixed = false, narrow = false, push = false, plain = false, pad, className, children, ...rest }, ref) {
2558
- return /* @__PURE__ */ jsx(Element, {
2559
- ref,
2560
- className: classes(layout_module_css_default.row, gapClass(layout_module_css_default, gap), alignClass(layout_module_css_default, align), justifyClass(layout_module_css_default, justify), padClass(layout_module_css_default, pad), wrap ? layout_module_css_default.wrap : void 0, grow ? layout_module_css_default.grow : void 0, boxed ? layout_module_css_default.boxed : void 0, fixed ? layout_module_css_default.fixed : void 0, narrow ? layout_module_css_default.narrow : void 0, push ? layout_module_css_default.push : void 0, boxed ? layout_module_css_default.boxed : void 0, fixed ? layout_module_css_default.fixed : void 0, plain ? layout_module_css_default.plain : void 0, className),
2561
- ...rest,
2562
- children
2563
- });
2564
- });
2565
- //#endregion
2566
- //#region src/client/layout/Stack.tsx
2567
- const Stack = forwardRef(function Stack({ as: Element = "div", gap, align, pad, grow = false, boxed = false, fixed = false, narrow = false, fill = false, scroll = false, plain = false, className, children, ...rest }, ref) {
2568
- return /* @__PURE__ */ jsx(Element, {
2569
- ref,
2570
- className: classes(layout_module_css_default.stack, gapClass(layout_module_css_default, gap), alignClass(layout_module_css_default, align), padClass(layout_module_css_default, pad), grow ? layout_module_css_default.grow : void 0, boxed ? layout_module_css_default.boxed : void 0, fixed ? layout_module_css_default.fixed : void 0, narrow ? layout_module_css_default.narrow : void 0, fill ? layout_module_css_default.fill : void 0, scroll ? layout_module_css_default.scroll : void 0, plain ? layout_module_css_default.plain : void 0, className),
2571
- ...rest,
2572
- children
2573
- });
2574
- });
2575
- //#endregion
2576
- //#region src/client/layout/Text.tsx
2577
- function Text({ as: Element = "span", size, tone, weight, mono = false, truncate = false, tabular = false, className, children }) {
2578
- return /* @__PURE__ */ jsx(Element, {
2579
- className: classes(layout_module_css_default.text, sizeClass(layout_module_css_default, size), toneClass(layout_module_css_default, tone), weightClass(layout_module_css_default, weight), mono ? layout_module_css_default.mono : void 0, truncate ? layout_module_css_default.truncate : void 0, tabular ? layout_module_css_default.tabular : void 0, className),
2580
- children
2581
- });
2582
- }
2583
- //#endregion
2584
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/settings-form/SettingsFieldRow.module.css.mjs
2585
- const css$14 = "._72UBVa_row{flex-direction:column;display:flex}._72UBVa_row[data-divider=true]{border-top:.5px solid var(--dsw-alias-border-l2)}._72UBVa_body{flex-direction:column;gap:6px;padding:12px 0;display:flex}._72UBVa_inline{flex-direction:row;justify-content:space-between;align-items:center;gap:16px;padding:12px 0;display:flex}._72UBVa_text{flex-direction:column;gap:2px;min-width:0;display:flex}._72UBVa_label{color:var(--dsw-alias-label-primary);align-items:center;gap:8px;font-size:13px;font-weight:500;line-height:1.5;display:flex}._72UBVa_badge{corner-shape:round;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-module-platform);border-radius:999px;align-items:center;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px;display:inline-flex}._72UBVa_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}._72UBVa_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}._72UBVa_reset:disabled{cursor:default}._72UBVa_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}._72UBVa_invalid{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:1.5}";
2586
- const tagId$14 = "@morlay/dsh-client-ui-primitives/SettingsFieldRow.module.css";
2587
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/SettingsFieldRow.module.css\"]") === null) {
2588
- const tag = document.createElement("style");
2589
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
2590
- tag.dataset.pluginCss = tagId$14;
2591
- tag.textContent = css$14;
2592
- document.head.appendChild(tag);
2593
- }
2594
- var SettingsFieldRow_module_css_default = {
2595
- "inline": "_72UBVa_inline",
2596
- "row": "_72UBVa_row",
2597
- "reset": "_72UBVa_reset",
2598
- "hint": "_72UBVa_hint",
2599
- "badge": "_72UBVa_badge",
2600
- "body": "_72UBVa_body",
2601
- "text": "_72UBVa_text",
2602
- "label": "_72UBVa_label",
2603
- "invalid": "_72UBVa_invalid"
2604
- };
2605
- //#endregion
2606
- //#region src/client/settings-form/SettingsFieldRow.tsx
2607
- function SettingsFieldRow({ label, hint, layout = "stack", divider = false, overriddenLabel, resetLabel, onReset, invalid, children, className, ...rest }) {
2608
- const labelNode = /* @__PURE__ */ jsxs("span", {
2609
- className: SettingsFieldRow_module_css_default.label,
2610
- children: [label, overriddenLabel === void 0 ? null : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
2611
- className: SettingsFieldRow_module_css_default.badge,
2612
- children: overriddenLabel
2613
- }), resetLabel === void 0 || onReset === void 0 ? null : /* @__PURE__ */ jsx("button", {
2614
- type: "button",
2615
- className: SettingsFieldRow_module_css_default.reset,
2616
- onClick: () => {
2617
- onReset();
2618
- },
2619
- children: resetLabel
2620
- })] })]
2621
- });
2622
- const invalidNode = invalid === void 0 ? null : /* @__PURE__ */ jsx("p", {
2623
- className: SettingsFieldRow_module_css_default.invalid,
2624
- role: "alert",
2625
- children: invalid
2626
- });
2627
- if (layout === "inline") return /* @__PURE__ */ jsxs("div", {
2628
- className: classes(SettingsFieldRow_module_css_default.row, className),
2629
- "data-role": "field-row",
2630
- "data-divider": divider ? "true" : "false",
2631
- ...rest,
2632
- children: [/* @__PURE__ */ jsxs("div", {
2633
- className: SettingsFieldRow_module_css_default.inline,
2634
- children: [/* @__PURE__ */ jsxs("div", {
2635
- className: SettingsFieldRow_module_css_default.text,
2636
- children: [labelNode, /* @__PURE__ */ jsx("p", {
2637
- className: SettingsFieldRow_module_css_default.hint,
2638
- children: hint
2639
- })]
2640
- }), children]
2641
- }), invalidNode]
2642
- });
2643
- return /* @__PURE__ */ jsxs("div", {
2644
- className: classes(SettingsFieldRow_module_css_default.row, className),
2645
- "data-role": "field-row",
2646
- "data-divider": divider ? "true" : "false",
2647
- ...rest,
2648
- children: [/* @__PURE__ */ jsxs("div", {
2649
- className: SettingsFieldRow_module_css_default.body,
2650
- children: [
2651
- labelNode,
2652
- children,
2653
- /* @__PURE__ */ jsx("p", {
2654
- className: SettingsFieldRow_module_css_default.hint,
2655
- children: hint
2656
- })
2657
- ]
2658
- }), invalidNode]
2659
- });
2660
- }
2661
- //#endregion
2662
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/controls/Bubble.module.css.mjs
2663
- const css$13 = ".dtkLCG_bubble{background:var(--dsw-specific-bubble);border-radius:var(--dsw-radius-xl);max-width:100%;font-size:var(--dsh-content-font-size,14px);line-height:calc(22px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;padding:10px 16px}";
2664
- const tagId$13 = "@morlay/dsh-client-ui-primitives/Bubble.module.css";
2665
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/Bubble.module.css\"]") === null) {
2666
- const tag = document.createElement("style");
2667
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
2668
- tag.dataset.pluginCss = tagId$13;
2669
- tag.textContent = css$13;
2670
- document.head.appendChild(tag);
2671
- }
2672
- var Bubble_module_css_default = { "bubble": "dtkLCG_bubble" };
2673
- //#endregion
2674
- //#region src/client/controls/Bubble.tsx
2675
- function Bubble({ className, children, ...rest }) {
2676
- return /* @__PURE__ */ jsx("div", {
2677
- className: classes(Bubble_module_css_default.bubble, className),
2678
- ...rest,
2679
- children
2680
- });
2681
- }
2682
- //#endregion
2683
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/controls/Button.module.css.mjs
2684
- const css$12 = ".WFViLq_label{white-space:nowrap}.WFViLq_danger{--dsw-alias-button-primary-fill:var(--dsw-alias-state-error-primary)}";
2685
- const tagId$12 = "@morlay/dsh-client-ui-primitives/Button.module.css";
2686
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/Button.module.css\"]") === null) {
2687
- const tag = document.createElement("style");
2688
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
2689
- tag.dataset.pluginCss = tagId$12;
2690
- tag.textContent = css$12;
2691
- document.head.appendChild(tag);
2692
- }
2693
- var Button_module_css_default = {
2694
- "label": "WFViLq_label",
2695
- "danger": "WFViLq_danger"
2696
- };
2697
- //#endregion
2698
- //#region src/client/controls/Button.tsx
2699
- const Button = forwardRef(function Button({ className, tone, ...rest }, ref) {
2700
- return /* @__PURE__ */ jsx(Button$1, {
2701
- ref,
2702
- "data-role": "button",
2703
- className: classes(className, Button_module_css_default.label, tone === "danger" ? Button_module_css_default.danger : void 0),
2704
- ...rest
2705
- });
2706
- });
2707
- //#endregion
2708
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/controls/DisclosureRow.module.css.mjs
2709
- const css$11 = ".MBWCEG_content{flex:auto;min-width:0}.MBWCEG_contentLayout{align-items:center;gap:8px;width:100%;min-width:0;display:flex}";
2710
- const tagId$11 = "@morlay/dsh-client-ui-primitives/DisclosureRow.module.css";
2711
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/DisclosureRow.module.css\"]") === null) {
2712
- const tag = document.createElement("style");
2713
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
2714
- tag.dataset.pluginCss = tagId$11;
2715
- tag.textContent = css$11;
2716
- document.head.appendChild(tag);
2717
- }
2718
- var DisclosureRow_module_css_default = {
2719
- "content": "MBWCEG_content",
2720
- "contentLayout": "MBWCEG_contentLayout"
2721
- };
2722
- //#endregion
2723
- //#region src/client/controls/DisclosureRow.tsx
2724
- function DisclosureRow(props) {
2725
- return /* @__PURE__ */ jsx(DisclosureRow$1, {
2726
- contentClassName: DisclosureRow_module_css_default.content,
2727
- contentLayoutClassName: DisclosureRow_module_css_default.contentLayout,
2728
- ...props
2729
- });
2730
- }
2731
- //#endregion
2732
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/controls/SearchInput.module.css.mjs
2733
- const css$10 = ".KiR4MG_search{flex:none;width:360px;max-width:100%}.KiR4MG_full{flex:none;width:100%}";
2734
- const tagId$10 = "@morlay/dsh-client-ui-primitives/SearchInput.module.css";
2735
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/SearchInput.module.css\"]") === null) {
2736
- const tag = document.createElement("style");
2737
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
2738
- tag.dataset.pluginCss = tagId$10;
2739
- tag.textContent = css$10;
2740
- document.head.appendChild(tag);
2741
- }
2742
- var SearchInput_module_css_default = {
2743
- "search": "KiR4MG_search",
2744
- "full": "KiR4MG_full"
2745
- };
2746
- //#endregion
2747
- //#region src/client/controls/SearchInput.tsx
2748
- function SearchInput({ width = "search", className, ...rest }) {
2749
- return /* @__PURE__ */ jsx(Input, {
2750
- className: classes(className, width === "search" ? SearchInput_module_css_default.search : SearchInput_module_css_default.full),
2751
- ...rest
2752
- });
2753
- }
2754
- //#endregion
2755
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/controls/SeatButton.module.css.mjs
2756
- const css$9 = ".HcNbhG_seat{border-radius:var(--dsw-radius-sm);min-width:0;max-width:min(100%,240px);min-height:28px;color:var(--dsw-alias-label-primary);white-space:nowrap;cursor:pointer;background:0 0;border:none;align-items:center;gap:4px;padding:0 8px;font-size:13px;font-weight:500;line-height:20px;display:inline-flex}.HcNbhG_seat:not(:disabled):hover,.HcNbhG_seat[aria-expanded=true],.HcNbhG_expanded{background:var(--dsw-alias-interactive-bg-hover)}.HcNbhG_seat:disabled{cursor:default;color:var(--dsw-alias-label-quaternary)}.HcNbhG_icon{color:var(--dsw-alias-label-primary);flex:none;align-items:center;display:inline-flex}.HcNbhG_label{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.HcNbhG_chevron{color:var(--dsw-alias-label-caption);flex:none;display:inline-flex}";
2757
- const tagId$9 = "@morlay/dsh-client-ui-primitives/SeatButton.module.css";
2758
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/SeatButton.module.css\"]") === null) {
2759
- const tag = document.createElement("style");
2760
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
2761
- tag.dataset.pluginCss = tagId$9;
2762
- tag.textContent = css$9;
2763
- document.head.appendChild(tag);
2764
- }
2765
- var SeatButton_module_css_default = {
2766
- "chevron": "HcNbhG_chevron",
2767
- "expanded": "HcNbhG_expanded",
2768
- "icon": "HcNbhG_icon",
2769
- "seat": "HcNbhG_seat",
2770
- "label": "HcNbhG_label"
2771
- };
2772
- //#endregion
2773
- //#region src/client/controls/SeatButton.tsx
2774
- function SeatButton({ icon, label, expanded = false, chevron, type = "button", className, ...rest }) {
2775
- return /* @__PURE__ */ jsxs("button", {
2776
- type,
2777
- className: classes(SeatButton_module_css_default.seat, expanded ? SeatButton_module_css_default.expanded : void 0, className),
2778
- ...rest,
2779
- children: [
2780
- /* @__PURE__ */ jsx("span", {
2781
- className: SeatButton_module_css_default.icon,
2782
- children: icon
2783
- }),
2784
- /* @__PURE__ */ jsx("span", {
2785
- className: SeatButton_module_css_default.label,
2786
- children: label
2787
- }),
2788
- chevron === void 0 ? null : /* @__PURE__ */ jsx("span", {
2789
- className: SeatButton_module_css_default.chevron,
2790
- children: chevron
2791
- })
2792
- ]
2793
- });
2794
- }
2795
- //#endregion
2796
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/controls/Spinner.module.css.mjs
2797
- const css$8 = ".HGVDmW_spinner{border:2px solid var(--dsw-alias-border-l2);border-top-color:var(--dsw-alias-label-primary);border-radius:50%;width:28px;height:28px;animation:.9s linear infinite HGVDmW_spin}@keyframes HGVDmW_spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}";
2798
- const tagId$8 = "@morlay/dsh-client-ui-primitives/Spinner.module.css";
2799
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/Spinner.module.css\"]") === null) {
2800
- const tag = document.createElement("style");
2801
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
2802
- tag.dataset.pluginCss = tagId$8;
2803
- tag.textContent = css$8;
2804
- document.head.appendChild(tag);
2805
- }
2806
- var Spinner_module_css_default = {
2807
- "spin": "HGVDmW_spin",
2808
- "spinner": "HGVDmW_spinner"
2809
- };
2810
- //#endregion
2811
- //#region src/client/controls/Spinner.tsx
2812
- function Spinner({ label }) {
2813
- return /* @__PURE__ */ jsx("span", {
2814
- className: Spinner_module_css_default.spinner,
2815
- role: "status",
2816
- "aria-label": label
2817
- });
2818
- }
2819
- //#endregion
2820
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/controls/Tabs.module.css.mjs
2821
- const css$7 = ".GO-36q_tabs{z-index:1;flex:none;gap:36px;margin-top:10px;padding-left:8px;display:flex;position:relative}.GO-36q_tab{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;padding:0 0 9px;font-size:13px;font-weight:500;line-height:16px;position:relative}.GO-36q_tab:after{content:\"\";background:0 0;border-radius:2px;height:2px;position:absolute;bottom:-1px;left:0;right:0}.GO-36q_tabActive{color:var(--dsw-alias-state-business-primary)}.GO-36q_tabActive:after{background:var(--dsw-alias-state-business-primary)}.GO-36q_tab:disabled{cursor:not-allowed;opacity:.4}";
2822
- const tagId$7 = "@morlay/dsh-client-ui-primitives/Tabs.module.css";
2823
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/Tabs.module.css\"]") === null) {
2824
- const tag = document.createElement("style");
2825
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
2826
- tag.dataset.pluginCss = tagId$7;
2827
- tag.textContent = css$7;
2828
- document.head.appendChild(tag);
2829
- }
2830
- var Tabs_module_css_default = {
2831
- "tab": "GO-36q_tab",
2832
- "tabs": "GO-36q_tabs",
2833
- "tabActive": "GO-36q_tabActive"
2834
- };
2835
- //#endregion
2836
- //#region src/client/controls/Tabs.tsx
2837
- function Tabs({ label, items, value, onChange, role = "tablist", disabled = false }) {
2838
- return /* @__PURE__ */ jsx("div", {
2839
- className: Tabs_module_css_default.tabs,
2840
- role,
2841
- "aria-label": label,
2842
- children: items.map((item) => {
2843
- const active = item.value === value;
2844
- return /* @__PURE__ */ jsx("button", {
2845
- type: "button",
2846
- role: role === "tablist" ? "tab" : "radio",
2847
- "data-tab": item.value,
2848
- "aria-selected": role === "tablist" ? active : void 0,
2849
- "aria-checked": role === "tablist" ? void 0 : active,
2850
- disabled,
2851
- className: classes(Tabs_module_css_default.tab, active ? Tabs_module_css_default.tabActive : void 0),
2852
- onClick: () => {
2853
- onChange(item.value);
2854
- },
2855
- children: item.label
2856
- }, item.value);
2857
- })
2858
- });
2859
- }
2860
- //#endregion
2861
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/controls/TimeLabel.module.css.mjs
2862
- const css$6 = "._3IuWPG_label{color:var(--dsw-alias-label-tertiary);white-space:nowrap;opacity:0;padding:0;font-size:14px;line-height:24px;transition:opacity 80ms}[data-time-hover-root]:hover ._3IuWPG_label,[data-time-hover-root]:focus-within ._3IuWPG_label{opacity:1}";
2863
- const tagId$6 = "@morlay/dsh-client-ui-primitives/TimeLabel.module.css";
2864
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/TimeLabel.module.css\"]") === null) {
2865
- const tag = document.createElement("style");
2866
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
2867
- tag.dataset.pluginCss = tagId$6;
2868
- tag.textContent = css$6;
2869
- document.head.appendChild(tag);
2870
- }
2871
- var TimeLabel_module_css_default = { "label": "_3IuWPG_label" };
2872
- //#endregion
2873
- //#region src/client/controls/TimeLabel.tsx
2874
- function TimeLabel({ className, children, ...rest }) {
2875
- return /* @__PURE__ */ jsx("span", {
2876
- className: classes(TimeLabel_module_css_default.label, className),
2877
- ...rest,
2878
- children
2879
- });
2880
- }
2881
- //#endregion
2882
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/controls/VisuallyHidden.module.css.mjs
2883
- const css$5 = ".YAvv4W_hidden{clip-path:inset(50%);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}";
2884
- const tagId$5 = "@morlay/dsh-client-ui-primitives/VisuallyHidden.module.css";
2885
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/VisuallyHidden.module.css\"]") === null) {
2886
- const tag = document.createElement("style");
2887
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
2888
- tag.dataset.pluginCss = tagId$5;
2889
- tag.textContent = css$5;
2890
- document.head.appendChild(tag);
2891
- }
2892
- var VisuallyHidden_module_css_default = { "hidden": "YAvv4W_hidden" };
2893
- //#endregion
2894
- //#region src/client/controls/VisuallyHidden.tsx
2895
- function VisuallyHidden({ children, ...rest }) {
2896
- return /* @__PURE__ */ jsx("span", {
2897
- className: VisuallyHidden_module_css_default.hidden,
2898
- ...rest,
2899
- children
2900
- });
2901
- }
2902
- //#endregion
2903
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/controls/IconButton.module.css.mjs
2904
- const css$4 = ".I3t6Ga_iconButton{box-sizing:border-box;width:28px;height:28px;color:var(--dsw-alias-label-secondary);border-radius:var(--dsw-radius-sm);cursor:pointer;background:0 0;border:none;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.I3t6Ga_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.I3t6Ga_iconButton:disabled{cursor:not-allowed;opacity:.4}.I3t6Ga_iconButton:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:-2px}.I3t6Ga_sm{width:20px;height:20px;padding:0}.I3t6Ga_circle{color:var(--dsw-alias-label-tertiary);border-radius:28px;padding:6px}.I3t6Ga_circle:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}";
2905
- const tagId$4 = "@morlay/dsh-client-ui-primitives/IconButton.module.css";
2906
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/IconButton.module.css\"]") === null) {
2907
- const tag = document.createElement("style");
2908
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
2909
- tag.dataset.pluginCss = tagId$4;
2910
- tag.textContent = css$4;
2911
- document.head.appendChild(tag);
2912
- }
2913
- var IconButton_module_css_default = {
2914
- "sm": "I3t6Ga_sm",
2915
- "circle": "I3t6Ga_circle",
2916
- "iconButton": "I3t6Ga_iconButton"
2917
- };
2918
- //#endregion
2919
- //#region src/client/controls/IconButton.tsx
2920
- function IconButton({ label, children, type = "button", shape = "square", size = "md", className, ...rest }) {
2921
- return /* @__PURE__ */ jsx("button", {
2922
- type,
2923
- "data-role": "icon-button",
2924
- "aria-label": label,
2925
- className: classes(IconButton_module_css_default.iconButton, size === "sm" ? IconButton_module_css_default.sm : void 0, shape === "circle" ? IconButton_module_css_default.circle : void 0, className),
2926
- ...rest,
2927
- children
2928
- });
2929
- }
2930
- //#endregion
2931
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/controls/ModelRouteList.module.css.mjs
2932
- const css$3 = "._2eBkWq_list{border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-lg);gap:6px;min-width:0;max-height:280px;margin:0;padding:10px;display:grid;overflow:auto}._2eBkWq_group{gap:6px;display:grid}._2eBkWq_group+._2eBkWq_group{border-top:.5px solid var(--dsw-alias-border-l3);margin-top:4px;padding-top:10px}._2eBkWq_provider{color:var(--dsw-alias-label-tertiary);padding:0 6px;font-size:11px;font-weight:500}._2eBkWq_item{border-radius:var(--dsw-radius-md);cursor:pointer;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:8px;min-width:0;padding:6px;display:grid}._2eBkWq_item:hover{background:var(--dsw-alias-bg-layer-4)}._2eBkWq_item:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:-2px}._2eBkWq_item[aria-disabled=true]{cursor:not-allowed;opacity:.4}._2eBkWq_picked{background:var(--dsw-alias-interactive-bg-hover)}._2eBkWq_text{min-width:0}._2eBkWq_name{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-primary);font-size:13px;display:block;overflow:hidden}._2eBkWq_id{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-tertiary);margin-top:2px;font-size:11px;display:block;overflow:hidden}._2eBkWq_notice{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}._2eBkWq_error{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:1.5}";
2933
- const tagId$3 = "@morlay/dsh-client-ui-primitives/ModelRouteList.module.css";
2934
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/ModelRouteList.module.css\"]") === null) {
2935
- const tag = document.createElement("style");
2936
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
2937
- tag.dataset.pluginCss = tagId$3;
2938
- tag.textContent = css$3;
2939
- document.head.appendChild(tag);
2940
- }
2941
- var ModelRouteList_module_css_default = {
2942
- "id": "_2eBkWq_id",
2943
- "list": "_2eBkWq_list",
2944
- "group": "_2eBkWq_group",
2945
- "provider": "_2eBkWq_provider",
2946
- "name": "_2eBkWq_name",
2947
- "notice": "_2eBkWq_notice",
2948
- "error": "_2eBkWq_error",
2949
- "text": "_2eBkWq_text",
2950
- "item": "_2eBkWq_item",
2951
- "picked": "_2eBkWq_picked"
2952
- };
2953
- //#endregion
2954
- //#region src/client/controls/ModelRouteList.tsx
2955
- function ModelRouteList({ label, candidates, selectedKey, disabled = false, status, loadingLabel, errorLabel, emptyLabel, onSelect }) {
2956
- if (status === "loading") return /* @__PURE__ */ jsx("p", {
2957
- className: ModelRouteList_module_css_default.notice,
2958
- role: "status",
2959
- children: loadingLabel
2960
- });
2961
- if (status === "error") return /* @__PURE__ */ jsx("p", {
2962
- className: ModelRouteList_module_css_default.error,
2963
- role: "alert",
2964
- children: errorLabel
2965
- });
2966
- if (candidates.length === 0) return /* @__PURE__ */ jsx("p", {
2967
- className: ModelRouteList_module_css_default.notice,
2968
- children: emptyLabel
2969
- });
2970
- const groups = /* @__PURE__ */ new Map();
2971
- for (const candidate of candidates) {
2972
- const group = groups.get(candidate.provider);
2973
- if (group === void 0) groups.set(candidate.provider, {
2974
- name: candidate.providerName,
2975
- items: [candidate]
2976
- });
2977
- else group.items.push(candidate);
2978
- }
2979
- return /* @__PURE__ */ jsx("div", {
2980
- className: ModelRouteList_module_css_default.list,
2981
- "data-role": "model-route-list",
2982
- role: "radiogroup",
2983
- "aria-label": label,
2984
- "data-control": "model-routes",
2985
- children: [...groups].map(([provider, group]) => /* @__PURE__ */ jsxs("div", {
2986
- className: ModelRouteList_module_css_default.group,
2987
- "data-route-group": provider,
2988
- children: [/* @__PURE__ */ jsx("span", {
2989
- className: ModelRouteList_module_css_default.provider,
2990
- children: group.name
2991
- }), group.items.map((candidate) => {
2992
- const picked = candidate.key === selectedKey;
2993
- return /* @__PURE__ */ jsxs("div", {
2994
- className: classes(ModelRouteList_module_css_default.item, picked ? ModelRouteList_module_css_default.picked : void 0),
2995
- role: "radio",
2996
- "aria-checked": picked,
2997
- "aria-label": `${candidate.modelName} ${candidate.provider}/${candidate.model}`,
2998
- "aria-disabled": disabled ? true : void 0,
2999
- tabIndex: disabled ? -1 : 0,
3000
- "data-route": candidate.key,
3001
- onClick: () => {
3002
- if (!disabled) onSelect(candidate);
3003
- },
3004
- onKeyDown: (event) => {
3005
- if (event.key !== "Enter" && event.key !== " ") return;
3006
- event.preventDefault();
3007
- if (!disabled) onSelect(candidate);
3008
- },
3009
- children: [picked ? /* @__PURE__ */ jsx(IconCheckOutlineRegular, {}) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true" }), /* @__PURE__ */ jsxs("span", {
3010
- className: ModelRouteList_module_css_default.text,
3011
- children: [/* @__PURE__ */ jsx("span", {
3012
- className: ModelRouteList_module_css_default.name,
3013
- children: candidate.modelName
3014
- }), /* @__PURE__ */ jsx("span", {
3015
- className: ModelRouteList_module_css_default.id,
3016
- children: `${candidate.providerName} · ${candidate.provider}/${candidate.model}`
3017
- })]
3018
- })]
3019
- }, candidate.key);
3020
- })]
3021
- }, provider))
3022
- });
3023
- }
3024
- //#endregion
3025
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/controls/MultilineField.module.css.mjs
3026
- const css$2 = "._stHfW_multiline{box-sizing:border-box;width:100%;min-height:64px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3);border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);resize:vertical;padding:6px 12px;font-family:inherit;font-size:13px;line-height:1.5}._stHfW_multiline:disabled{cursor:not-allowed;opacity:.4}._stHfW_multiline:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:-2px}";
3027
- const tagId$2 = "@morlay/dsh-client-ui-primitives/MultilineField.module.css";
3028
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/MultilineField.module.css\"]") === null) {
3029
- const tag = document.createElement("style");
3030
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
3031
- tag.dataset.pluginCss = tagId$2;
3032
- tag.textContent = css$2;
3033
- document.head.appendChild(tag);
3034
- }
3035
- var MultilineField_module_css_default = { "multiline": "_stHfW_multiline" };
3036
- //#endregion
3037
- //#region src/client/controls/MultilineField.tsx
3038
- function MultilineField({ rows = 3, className, ...rest }) {
3039
- return /* @__PURE__ */ jsx("textarea", {
3040
- rows,
3041
- "data-role": "multiline-field",
3042
- className: classes(MultilineField_module_css_default.multiline, className),
3043
- ...rest
3044
- });
3045
- }
3046
- //#endregion
3047
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/controls/SearchSelect.module.css.mjs
3048
- const css$1 = ".BtUTmW_trigger{white-space:nowrap;height:32px}.BtUTmW_searchRow{border-bottom:.5px solid var(--dsw-alias-border-l2);align-items:center;padding:4px 8px 8px;display:flex}.BtUTmW_searchInput{width:100%;color:var(--dsw-alias-label-primary);background:0 0;border:none;outline:none;padding:2px 0;font-family:inherit;font-size:13px;line-height:1.5}.BtUTmW_empty{color:var(--dsw-alias-label-tertiary);margin:0;padding:8px;font-size:12px;line-height:1.5}";
3049
- const tagId$1 = "@morlay/dsh-client-ui-primitives/SearchSelect.module.css";
3050
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/SearchSelect.module.css\"]") === null) {
3051
- const tag = document.createElement("style");
3052
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
3053
- tag.dataset.pluginCss = tagId$1;
3054
- tag.textContent = css$1;
3055
- document.head.appendChild(tag);
3056
- }
3057
- var SearchSelect_module_css_default = {
3058
- "searchRow": "BtUTmW_searchRow",
3059
- "searchInput": "BtUTmW_searchInput",
3060
- "empty": "BtUTmW_empty",
3061
- "trigger": "BtUTmW_trigger"
3062
- };
3063
- //#endregion
3064
- //#region src/client/controls/SearchSelect.tsx
3065
- function SearchSelect({ label, value, emptyLabel, options, disabled = false, searchLabel, noMatchLabel, onSelect }) {
3066
- const [open, setOpen] = useState(false);
3067
- const [query, setQuery] = useState("");
3068
- const searchRef = useRef(null);
3069
- useEffect(() => {
3070
- if (open) searchRef.current?.focus();
3071
- }, [open]);
3072
- const matches = useMemo(() => rankByName(options.map((option) => ({
3073
- value: option.value,
3074
- name: option.label ?? option.value,
3075
- label: option.value
3076
- })), query), [options, query]);
3077
- const current = options.find((option) => option.value === value);
3078
- const close = () => {
3079
- setOpen(false);
3080
- setQuery("");
3081
- };
3082
- const pick = (next) => {
3083
- close();
3084
- onSelect(next);
3085
- };
3086
- return /* @__PURE__ */ jsxs(Menu, {
3087
- open,
3088
- anchor: /* @__PURE__ */ jsx(Button$1, {
3089
- variant: "outline",
3090
- size: "sm",
3091
- "data-role": "search-select",
3092
- className: classes(SearchSelect_module_css_default.trigger),
3093
- "data-action": "pick",
3094
- disabled,
3095
- "aria-haspopup": "menu",
3096
- "aria-label": label,
3097
- onClick: () => {
3098
- if (open) close();
3099
- else setOpen(true);
3100
- },
3101
- children: value === "" ? emptyLabel : current?.label ?? value
3102
- }),
3103
- selectedId: value,
3104
- onSelect: pick,
3105
- onClose: close,
3106
- children: [
3107
- /* @__PURE__ */ jsx("div", {
3108
- className: SearchSelect_module_css_default.searchRow,
3109
- children: /* @__PURE__ */ jsx("input", {
3110
- className: SearchSelect_module_css_default.searchInput,
3111
- ref: searchRef,
3112
- value: query,
3113
- "aria-label": searchLabel,
3114
- placeholder: searchLabel,
3115
- onChange: (event) => {
3116
- setQuery(event.currentTarget.value);
3117
- }
3118
- })
3119
- }),
3120
- /* @__PURE__ */ jsx(MenuItemButton, {
3121
- icon: value === "" ? /* @__PURE__ */ jsx(IconCheckOutlineRegular, {}) : void 0,
3122
- onSelect: () => {
3123
- pick("");
3124
- },
3125
- children: emptyLabel
3126
- }),
3127
- matches.map((option) => /* @__PURE__ */ jsx(MenuItemButton, {
3128
- icon: option.value === value ? /* @__PURE__ */ jsx(IconCheckOutlineRegular, {}) : void 0,
3129
- onSelect: () => {
3130
- pick(option.value);
3131
- },
3132
- children: option.name
3133
- }, option.value)),
3134
- matches.length === 0 ? /* @__PURE__ */ jsx("p", {
3135
- className: SearchSelect_module_css_default.empty,
3136
- children: noMatchLabel
3137
- }) : null
3138
- ]
3139
- });
3140
- }
3141
- //#endregion
3142
- //#region src/client/controls/tags.ts
3143
- function parseTagList(text) {
3144
- const seen = /* @__PURE__ */ new Set();
3145
- const names = [];
3146
- for (const raw of text.split(/[,,;;\t\n\r]+/u)) {
3147
- const name = raw.trim();
3148
- if (name === "" || seen.has(name)) continue;
3149
- seen.add(name);
3150
- names.push(name);
3151
- }
3152
- return names;
3153
- }
3154
- function mergeTags(current, incoming) {
3155
- const merged = [...current];
3156
- for (const name of incoming) {
3157
- if (name === "" || merged.includes(name)) continue;
3158
- merged.push(name);
3159
- }
3160
- return merged;
3161
- }
3162
- //#endregion
3163
- //#region \0dsh-css-modules:/Users/morlay/src/github.com/morlay/dsh-plugin/packages/client/ui-primitives/src/client/controls/TagInput.module.css.mjs
3164
- const css = ".Is5kta_row{align-items:flex-start;gap:8px;width:100%;display:flex}.Is5kta_anchor{flex:auto;width:100%;min-width:0;display:flex}.Is5kta_box{box-sizing:border-box;background:var(--dsw-alias-bg-layer-3);border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);flex-flow:wrap;align-items:center;gap:4px 6px;width:100%;min-height:32px;padding:4px 8px;display:flex}.Is5kta_input{min-width:120px;color:var(--dsw-alias-label-primary);background:0 0;border:none;outline:none;flex:120px;padding:2px 0;font-family:inherit;font-size:13px;line-height:1.5}.Is5kta_chip{corner-shape:round;white-space:nowrap;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-module-platform);border-radius:999px;align-items:center;gap:2px;padding:1px 4px 1px 8px;font-size:11px;font-weight:500;line-height:17px;display:inline-flex}.Is5kta_chipRemove{box-sizing:border-box;width:14px;height:14px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:999px;flex:none;justify-content:center;align-items:center;padding:0;line-height:1;display:inline-flex}.Is5kta_chipRemove:hover:not(:disabled){color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.Is5kta_chipRemove:disabled{cursor:not-allowed;opacity:.4}.Is5kta_chipRemove:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:0}.Is5kta_empty{color:var(--dsw-alias-label-tertiary);margin:0;padding:8px;font-size:12px;line-height:1.5}";
3165
- const tagId = "@morlay/dsh-client-ui-primitives/TagInput.module.css";
3166
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"@morlay/dsh-client-ui-primitives/TagInput.module.css\"]") === null) {
3167
- const tag = document.createElement("style");
3168
- tag.dataset.plugin = "@morlay/dsh-client-ui-primitives";
3169
- tag.dataset.pluginCss = tagId;
3170
- tag.textContent = css;
3171
- document.head.appendChild(tag);
3172
- }
3173
- var TagInput_module_css_default = {
3174
- "empty": "Is5kta_empty",
3175
- "anchor": "Is5kta_anchor",
3176
- "input": "Is5kta_input",
3177
- "chip": "Is5kta_chip",
3178
- "chipRemove": "Is5kta_chipRemove",
3179
- "box": "Is5kta_box",
3180
- "row": "Is5kta_row"
3181
- };
3182
- //#endregion
3183
- //#region src/client/controls/TagInput.tsx
3184
- function TagInput({ value, onChange, options, placeholder, label, disabled = false, noMatchLabel = "", removeLabel }) {
3185
- const [draft, setDraft] = useState("");
3186
- const [open, setOpen] = useState(false);
3187
- const commit = (text) => {
3188
- const names = parseTagList(text);
3189
- if (names.length === 0) return;
3190
- onChange(mergeTags(value, names));
3191
- setDraft("");
3192
- };
3193
- const remaining = useMemo(() => (options ?? []).filter((option) => !value.includes(option.value)).map((option) => ({
3194
- value: option.value,
3195
- name: option.label ?? option.value,
3196
- label: option.value
3197
- })), [options, value]);
3198
- const matches = useMemo(() => rankByName(remaining, draft), [remaining, draft]);
3199
- return /* @__PURE__ */ jsx("div", {
3200
- className: TagInput_module_css_default.row,
3201
- "data-role": "tag-input",
3202
- "data-control": "tags",
3203
- children: /* @__PURE__ */ jsxs(Menu, {
3204
- open: open && remaining.length > 0,
3205
- className: TagInput_module_css_default.anchor,
3206
- anchor: /* @__PURE__ */ jsxs("div", {
3207
- className: TagInput_module_css_default.box,
3208
- children: [value.map((name) => /* @__PURE__ */ jsxs("span", {
3209
- className: TagInput_module_css_default.chip,
3210
- "data-tag": name,
3211
- children: [name, /* @__PURE__ */ jsx("button", {
3212
- type: "button",
3213
- className: TagInput_module_css_default.chipRemove,
3214
- "data-action": "remove-tag",
3215
- disabled,
3216
- "aria-label": removeLabel(name),
3217
- onClick: () => {
3218
- onChange(value.filter((candidate) => candidate !== name));
3219
- },
3220
- children: /* @__PURE__ */ jsx(IconCloseOutlineRegular, { size: 10 })
3221
- })]
3222
- }, name)), /* @__PURE__ */ jsx("input", {
3223
- className: TagInput_module_css_default.input,
3224
- value: draft,
3225
- placeholder: value.length === 0 ? placeholder : "",
3226
- "aria-label": label,
3227
- disabled,
3228
- onFocus: () => {
3229
- setOpen(true);
3230
- },
3231
- onBlur: () => {
3232
- setOpen(false);
3233
- },
3234
- onChange: (event) => {
3235
- setDraft(event.currentTarget.value);
3236
- },
3237
- onKeyDown: (event) => {
3238
- if (event.key !== "Enter") return;
3239
- event.preventDefault();
3240
- commit(draft);
3241
- },
3242
- onPaste: (event) => {
3243
- const text = event.clipboardData.getData("text");
3244
- if (parseTagList(text).length < 2) return;
3245
- event.preventDefault();
3246
- commit(text);
3247
- }
3248
- })]
3249
- }),
3250
- onClose: () => {
3251
- setOpen(false);
3252
- },
3253
- children: [matches.map((candidate) => /* @__PURE__ */ jsx("span", {
3254
- onMouseDown: (event) => {
3255
- event.preventDefault();
3256
- },
3257
- children: /* @__PURE__ */ jsx(MenuItemButton, {
3258
- onSelect: () => {
3259
- commit(candidate.value);
3260
- },
3261
- children: candidate.name
3262
- })
3263
- }, candidate.value)), matches.length === 0 ? /* @__PURE__ */ jsx("p", {
3264
- className: TagInput_module_css_default.empty,
3265
- "data-role": "tag-input-empty",
3266
- children: noMatchLabel
3267
- }) : null]
3268
- })
3269
- });
3270
- }
3271
- //#endregion
3272
- //#region ../../../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js
3273
- /**
3274
- * @license React
3275
- * react.production.min.js
3276
- *
3277
- * Copyright (c) Facebook, Inc. and its affiliates.
3278
- *
3279
- * This source code is licensed under the MIT license found in the
3280
- * LICENSE file in the root directory of this source tree.
3281
- */
3282
- var require_react_production_min = /* @__PURE__ */ __commonJSMin(((exports) => {
3283
- var l = Symbol.for("react.element");
3284
- var n = Symbol.for("react.portal");
3285
- var p = Symbol.for("react.fragment");
3286
- var q = Symbol.for("react.strict_mode");
3287
- var r = Symbol.for("react.profiler");
3288
- var t = Symbol.for("react.provider");
3289
- var u = Symbol.for("react.context");
3290
- var v = Symbol.for("react.forward_ref");
3291
- var w = Symbol.for("react.suspense");
3292
- var x = Symbol.for("react.memo");
3293
- var y = Symbol.for("react.lazy");
3294
- var z = Symbol.iterator;
3295
- function A(a) {
3296
- if (null === a || "object" !== typeof a) return null;
3297
- a = z && a[z] || a["@@iterator"];
3298
- return "function" === typeof a ? a : null;
3299
- }
3300
- var B = {
3301
- isMounted: function() {
3302
- return !1;
3303
- },
3304
- enqueueForceUpdate: function() {},
3305
- enqueueReplaceState: function() {},
3306
- enqueueSetState: function() {}
3307
- };
3308
- var C = Object.assign;
3309
- var D = {};
3310
- function E(a, b, e) {
3311
- this.props = a;
3312
- this.context = b;
3313
- this.refs = D;
3314
- this.updater = e || B;
3315
- }
3316
- E.prototype.isReactComponent = {};
3317
- E.prototype.setState = function(a, b) {
3318
- if ("object" !== typeof a && "function" !== typeof a && null != a) throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");
3319
- this.updater.enqueueSetState(this, a, b, "setState");
3320
- };
3321
- E.prototype.forceUpdate = function(a) {
3322
- this.updater.enqueueForceUpdate(this, a, "forceUpdate");
3323
- };
3324
- function F() {}
3325
- F.prototype = E.prototype;
3326
- function G(a, b, e) {
3327
- this.props = a;
3328
- this.context = b;
3329
- this.refs = D;
3330
- this.updater = e || B;
3331
- }
3332
- var H = G.prototype = new F();
3333
- H.constructor = G;
3334
- C(H, E.prototype);
3335
- H.isPureReactComponent = !0;
3336
- var I = Array.isArray;
3337
- var J = Object.prototype.hasOwnProperty;
3338
- var K = { current: null };
3339
- var L = {
3340
- key: !0,
3341
- ref: !0,
3342
- __self: !0,
3343
- __source: !0
3344
- };
3345
- function M(a, b, e) {
3346
- var d, c = {}, k = null, h = null;
3347
- if (null != b) for (d in void 0 !== b.ref && (h = b.ref), void 0 !== b.key && (k = "" + b.key), b) J.call(b, d) && !L.hasOwnProperty(d) && (c[d] = b[d]);
3348
- var g = arguments.length - 2;
3349
- if (1 === g) c.children = e;
3350
- else if (1 < g) {
3351
- for (var f = Array(g), m = 0; m < g; m++) f[m] = arguments[m + 2];
3352
- c.children = f;
3353
- }
3354
- if (a && a.defaultProps) for (d in g = a.defaultProps, g) void 0 === c[d] && (c[d] = g[d]);
3355
- return {
3356
- $$typeof: l,
3357
- type: a,
3358
- key: k,
3359
- ref: h,
3360
- props: c,
3361
- _owner: K.current
3362
- };
3363
- }
3364
- function N(a, b) {
3365
- return {
3366
- $$typeof: l,
3367
- type: a.type,
3368
- key: b,
3369
- ref: a.ref,
3370
- props: a.props,
3371
- _owner: a._owner
3372
- };
3373
- }
3374
- function O(a) {
3375
- return "object" === typeof a && null !== a && a.$$typeof === l;
3376
- }
3377
- function escape(a) {
3378
- var b = {
3379
- "=": "=0",
3380
- ":": "=2"
3381
- };
3382
- return "$" + a.replace(/[=:]/g, function(a) {
3383
- return b[a];
3384
- });
3385
- }
3386
- var P = /\/+/g;
3387
- function Q(a, b) {
3388
- return "object" === typeof a && null !== a && null != a.key ? escape("" + a.key) : b.toString(36);
3389
- }
3390
- function R(a, b, e, d, c) {
3391
- var k = typeof a;
3392
- if ("undefined" === k || "boolean" === k) a = null;
3393
- var h = !1;
3394
- if (null === a) h = !0;
3395
- else switch (k) {
3396
- case "string":
3397
- case "number":
3398
- h = !0;
3399
- break;
3400
- case "object": switch (a.$$typeof) {
3401
- case l:
3402
- case n: h = !0;
3403
- }
3404
- }
3405
- if (h) return h = a, c = c(h), a = "" === d ? "." + Q(h, 0) : d, I(c) ? (e = "", null != a && (e = a.replace(P, "$&/") + "/"), R(c, b, e, "", function(a) {
3406
- return a;
3407
- })) : null != c && (O(c) && (c = N(c, e + (!c.key || h && h.key === c.key ? "" : ("" + c.key).replace(P, "$&/") + "/") + a)), b.push(c)), 1;
3408
- h = 0;
3409
- d = "" === d ? "." : d + ":";
3410
- if (I(a)) for (var g = 0; g < a.length; g++) {
3411
- k = a[g];
3412
- var f = d + Q(k, g);
3413
- h += R(k, b, e, f, c);
3414
- }
3415
- else if (f = A(a), "function" === typeof f) for (a = f.call(a), g = 0; !(k = a.next()).done;) k = k.value, f = d + Q(k, g++), h += R(k, b, e, f, c);
3416
- else if ("object" === k) throw b = String(a), Error("Objects are not valid as a React child (found: " + ("[object Object]" === b ? "object with keys {" + Object.keys(a).join(", ") + "}" : b) + "). If you meant to render a collection of children, use an array instead.");
3417
- return h;
3418
- }
3419
- function S(a, b, e) {
3420
- if (null == a) return a;
3421
- var d = [], c = 0;
3422
- R(a, d, "", "", function(a) {
3423
- return b.call(e, a, c++);
3424
- });
3425
- return d;
3426
- }
3427
- function T(a) {
3428
- if (-1 === a._status) {
3429
- var b = a._result;
3430
- b = b();
3431
- b.then(function(b) {
3432
- if (0 === a._status || -1 === a._status) a._status = 1, a._result = b;
3433
- }, function(b) {
3434
- if (0 === a._status || -1 === a._status) a._status = 2, a._result = b;
3435
- });
3436
- -1 === a._status && (a._status = 0, a._result = b);
3437
- }
3438
- if (1 === a._status) return a._result.default;
3439
- throw a._result;
3440
- }
3441
- var U = { current: null };
3442
- var V = { transition: null };
3443
- var W = {
3444
- ReactCurrentDispatcher: U,
3445
- ReactCurrentBatchConfig: V,
3446
- ReactCurrentOwner: K
3447
- };
3448
- function X() {
3449
- throw Error("act(...) is not supported in production builds of React.");
3450
- }
3451
- exports.Children = {
3452
- map: S,
3453
- forEach: function(a, b, e) {
3454
- S(a, function() {
3455
- b.apply(this, arguments);
3456
- }, e);
3457
- },
3458
- count: function(a) {
3459
- var b = 0;
3460
- S(a, function() {
3461
- b++;
3462
- });
3463
- return b;
3464
- },
3465
- toArray: function(a) {
3466
- return S(a, function(a) {
3467
- return a;
3468
- }) || [];
3469
- },
3470
- only: function(a) {
3471
- if (!O(a)) throw Error("React.Children.only expected to receive a single React element child.");
3472
- return a;
3473
- }
3474
- };
3475
- exports.Component = E;
3476
- exports.Fragment = p;
3477
- exports.Profiler = r;
3478
- exports.PureComponent = G;
3479
- exports.StrictMode = q;
3480
- exports.Suspense = w;
3481
- exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = W;
3482
- exports.act = X;
3483
- exports.cloneElement = function(a, b, e) {
3484
- if (null === a || void 0 === a) throw Error("React.cloneElement(...): The argument must be a React element, but you passed " + a + ".");
3485
- var d = C({}, a.props), c = a.key, k = a.ref, h = a._owner;
3486
- if (null != b) {
3487
- void 0 !== b.ref && (k = b.ref, h = K.current);
3488
- void 0 !== b.key && (c = "" + b.key);
3489
- if (a.type && a.type.defaultProps) var g = a.type.defaultProps;
3490
- for (f in b) J.call(b, f) && !L.hasOwnProperty(f) && (d[f] = void 0 === b[f] && void 0 !== g ? g[f] : b[f]);
3491
- }
3492
- var f = arguments.length - 2;
3493
- if (1 === f) d.children = e;
3494
- else if (1 < f) {
3495
- g = Array(f);
3496
- for (var m = 0; m < f; m++) g[m] = arguments[m + 2];
3497
- d.children = g;
3498
- }
3499
- return {
3500
- $$typeof: l,
3501
- type: a.type,
3502
- key: c,
3503
- ref: k,
3504
- props: d,
3505
- _owner: h
3506
- };
3507
- };
3508
- exports.createContext = function(a) {
3509
- a = {
3510
- $$typeof: u,
3511
- _currentValue: a,
3512
- _currentValue2: a,
3513
- _threadCount: 0,
3514
- Provider: null,
3515
- Consumer: null,
3516
- _defaultValue: null,
3517
- _globalName: null
3518
- };
3519
- a.Provider = {
3520
- $$typeof: t,
3521
- _context: a
3522
- };
3523
- return a.Consumer = a;
3524
- };
3525
- exports.createElement = M;
3526
- exports.createFactory = function(a) {
3527
- var b = M.bind(null, a);
3528
- b.type = a;
3529
- return b;
3530
- };
3531
- exports.createRef = function() {
3532
- return { current: null };
3533
- };
3534
- exports.forwardRef = function(a) {
3535
- return {
3536
- $$typeof: v,
3537
- render: a
3538
- };
3539
- };
3540
- exports.isValidElement = O;
3541
- exports.lazy = function(a) {
3542
- return {
3543
- $$typeof: y,
3544
- _payload: {
3545
- _status: -1,
3546
- _result: a
3547
- },
3548
- _init: T
3549
- };
3550
- };
3551
- exports.memo = function(a, b) {
3552
- return {
3553
- $$typeof: x,
3554
- type: a,
3555
- compare: void 0 === b ? null : b
3556
- };
3557
- };
3558
- exports.startTransition = function(a) {
3559
- var b = V.transition;
3560
- V.transition = {};
3561
- try {
3562
- a();
3563
- } finally {
3564
- V.transition = b;
3565
- }
3566
- };
3567
- exports.unstable_act = X;
3568
- exports.useCallback = function(a, b) {
3569
- return U.current.useCallback(a, b);
3570
- };
3571
- exports.useContext = function(a) {
3572
- return U.current.useContext(a);
3573
- };
3574
- exports.useDebugValue = function() {};
3575
- exports.useDeferredValue = function(a) {
3576
- return U.current.useDeferredValue(a);
3577
- };
3578
- exports.useEffect = function(a, b) {
3579
- return U.current.useEffect(a, b);
3580
- };
3581
- exports.useId = function() {
3582
- return U.current.useId();
3583
- };
3584
- exports.useImperativeHandle = function(a, b, e) {
3585
- return U.current.useImperativeHandle(a, b, e);
3586
- };
3587
- exports.useInsertionEffect = function(a, b) {
3588
- return U.current.useInsertionEffect(a, b);
3589
- };
3590
- exports.useLayoutEffect = function(a, b) {
3591
- return U.current.useLayoutEffect(a, b);
3592
- };
3593
- exports.useMemo = function(a, b) {
3594
- return U.current.useMemo(a, b);
3595
- };
3596
- exports.useReducer = function(a, b, e) {
3597
- return U.current.useReducer(a, b, e);
3598
- };
3599
- exports.useRef = function(a) {
3600
- return U.current.useRef(a);
3601
- };
3602
- exports.useState = function(a) {
3603
- return U.current.useState(a);
3604
- };
3605
- exports.useSyncExternalStore = function(a, b, e) {
3606
- return U.current.useSyncExternalStore(a, b, e);
3607
- };
3608
- exports.useTransition = function() {
3609
- return U.current.useTransition();
3610
- };
3611
- exports.version = "18.3.1";
3612
- }));
3613
- //#endregion
3614
- //#region ../../../node_modules/.pnpm/react@18.3.1/node_modules/react/index.js
3615
- var require_react = /* @__PURE__ */ __commonJSMin(((exports, module) => {
3616
- module.exports = require_react_production_min();
3617
- }));
3618
- //#endregion
3619
- //#region src/client/markdown-text.ts
3620
- var import_react = require_react();
3621
- //#endregion
3622
- //#region ../../../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-runtime.production.min.js
3623
- /**
3624
- * @license React
3625
- * react-jsx-runtime.production.min.js
3626
- *
3627
- * Copyright (c) Facebook, Inc. and its affiliates.
3628
- *
3629
- * This source code is licensed under the MIT license found in the
3630
- * LICENSE file in the root directory of this source tree.
3631
- */
3632
- var require_react_jsx_runtime_production_min = /* @__PURE__ */ __commonJSMin(((exports) => {
3633
- var f = require_react();
3634
- var k = Symbol.for("react.element");
3635
- var m = Object.prototype.hasOwnProperty;
3636
- var n = f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner;
3637
- var p = {
3638
- key: !0,
3639
- ref: !0,
3640
- __self: !0,
3641
- __source: !0
3642
- };
3643
- function q(c, a, g) {
3644
- var b, d = {}, e = null, h = null;
3645
- void 0 !== g && (e = "" + g);
3646
- void 0 !== a.key && (e = "" + a.key);
3647
- void 0 !== a.ref && (h = a.ref);
3648
- for (b in a) m.call(a, b) && !p.hasOwnProperty(b) && (d[b] = a[b]);
3649
- if (c && c.defaultProps) for (b in a = c.defaultProps, a) void 0 === d[b] && (d[b] = a[b]);
3650
- return {
3651
- $$typeof: k,
3652
- type: c,
3653
- key: e,
3654
- ref: h,
3655
- props: d,
3656
- _owner: n.current
3657
- };
3658
- }
3659
- exports.jsx = q;
3660
- }));
3661
- //#endregion
3662
- //#region src/reference-markdown.tsx
3663
- var import_jsx_runtime = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
3664
- module.exports = require_react_jsx_runtime_production_min();
3665
- })))();
3666
- function referenceMentions(actions, tokens) {
3667
- return { resolve: (value) => {
3668
- const reference = tokens?.get(value) ?? parseReferenceToken(value);
3669
- if (reference === void 0) return void 0;
3670
- return {
3671
- label: value,
3672
- title: formatReference(reference),
3673
- open: () => {
3674
- openReference(reference, actions);
3675
- }
3676
- };
3677
- } };
3678
- }
3679
- const ReferenceMarkdown = (0, import_react.memo)(function ReferenceMarkdown({ text, labels, actions, streaming = false, pathImages }) {
3680
- const { source, tokens } = (0, import_react.useMemo)(() => tokenizeReferences(text), [text]);
3681
- const mentions = (0, import_react.useMemo)(() => referenceMentions(actions, tokens), [actions, tokens]);
3682
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MarkdownText, {
3683
- text: source,
3684
- streaming,
3685
- labels,
3686
- fileMentions: mentions,
3687
- pathImages
3688
- });
3689
- });
3690
- function displayTextOf(reference) {
3691
- return (reference.title ?? `${reference.path ?? ""}${rangeOf(reference)}`).replaceAll("`", "'");
3692
- }
3693
- function rangeOf(reference) {
3694
- if (reference.lineStart === void 0) return "";
3695
- const column = reference.column === void 0 ? "" : `C${String(reference.column)}`;
3696
- return reference.lineEnd === void 0 ? `#L${String(reference.lineStart)}${column}` : `#L${String(reference.lineStart)}${column}-L${String(reference.lineEnd)}`;
3697
- }
3698
- function tokenizeReferences(text) {
3699
- const tokens = /* @__PURE__ */ new Map();
3700
- let out = "";
3701
- let cursor = 0;
3702
- for (const span of findReferences(text)) {
3703
- if (!isLocalReference(span.reference) || span.start < cursor) continue;
3704
- const display = displayTextOf(span.reference);
3705
- tokens.set(display, span.reference);
3706
- out += `${text.slice(cursor, span.start)}\`${display}\``;
3707
- cursor = span.end;
3708
- }
3709
- return {
3710
- source: cursor === 0 ? text : out + text.slice(cursor),
3711
- tokens
3712
- };
3713
- }
3714
- function openReference(reference, actions) {
3715
- const path = reference.path;
3716
- if (actions === void 0 || path === void 0) return;
3717
- if (reference.protocol === "skill") {
3718
- actions.openSkill(path);
3719
- return;
3720
- }
3721
- if (reference.protocol === "file") actions.openFile(path);
3722
- }
3723
- //#endregion
3724
- //#region src/client/index.ts
3725
- const inject = [...inject$1];
3726
- function apply(ctx) {
3727
- apply$1(ctx);
3728
- }
3729
- //#endregion
3730
- export { Bubble, Button, DisclosureRow, IconButton, ModelRouteList, MultilineField, ReferenceMarkdown, Row, NS as SCHEMA_FORM_NS, SchemaFormController, SchemaFormHints, SearchInput, SearchSelect, SeatButton, SettingsFieldRow, Spinner, Stack, Tabs, TagInput, Text, TimeLabel, VisuallyHidden, apply, failureOf, findReferences, formatReference, formatReferenceMention, inject, isLocalReference, markdownLabels, mergeTags, parseReference, parseReferenceToken, parseTagList, projectRoot, referenceMentions, rowRegistrations, schema_form_exports as schemaForm, walkFields };
4
+ export { Bubble, Button, DisclosureRow, IconButton, ModelRouteList, MultilineField, ReferenceMarkdown, Row, NS as SCHEMA_FORM_NS, SchemaFormController, SchemaFormHints, SearchSelect, SeatButton, SettingsFieldRow, Spinner, Stack, TagInput, Text, TimeLabel, VisuallyHidden, apply, failureOf, findReferences, formatReference, formatReferenceMention, inject, isLocalReference, markdownLabels, mergeTags, parseReference, parseReferenceToken, parseTagList, projectRoot, referenceMentions, rowRegistrations, schema_form_exports as schemaForm, walkFields };