@structured-field/widget-editor 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +284 -0
- package/dist/structured-widget-editor.esm.js +621 -67
- package/dist/structured-widget-editor.esm.js.map +1 -1
- package/dist/structured-widget-editor.iife.js +4 -5
- package/dist/structured-widget-editor.js +4 -5
- package/dist/structured-widget-editor.js.map +1 -1
- package/package.json +1 -1
- package/src/BaseEditorElement.js +108 -0
- package/src/SchemaForm.vue +30 -0
- package/src/conditionals.js +248 -0
- package/src/editors/ArrayEditor.vue +1 -1
- package/src/editors/ObjectEditor.vue +24 -4
- package/src/editors/SchemaEditor.vue +25 -0
- package/src/editors/WebComponentWrapper.vue +55 -0
- package/src/index.js +3 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var script$
|
|
1
|
+
var script$d = {
|
|
2
2
|
name: 'StringEditor',
|
|
3
3
|
props: {
|
|
4
4
|
schema: { type: Object, required: true },
|
|
@@ -1583,6 +1583,44 @@ const toReadonly = (value) => isObject(value) ? /* @__PURE__ */ readonly(value)
|
|
|
1583
1583
|
function isRef(r) {
|
|
1584
1584
|
return r ? r["__v_isRef"] === true : false;
|
|
1585
1585
|
}
|
|
1586
|
+
// @__NO_SIDE_EFFECTS__
|
|
1587
|
+
function ref(value) {
|
|
1588
|
+
return createRef(value, false);
|
|
1589
|
+
}
|
|
1590
|
+
function createRef(rawValue, shallow) {
|
|
1591
|
+
if (/* @__PURE__ */ isRef(rawValue)) {
|
|
1592
|
+
return rawValue;
|
|
1593
|
+
}
|
|
1594
|
+
return new RefImpl(rawValue, shallow);
|
|
1595
|
+
}
|
|
1596
|
+
class RefImpl {
|
|
1597
|
+
constructor(value, isShallow2) {
|
|
1598
|
+
this.dep = new Dep();
|
|
1599
|
+
this["__v_isRef"] = true;
|
|
1600
|
+
this["__v_isShallow"] = false;
|
|
1601
|
+
this._rawValue = isShallow2 ? value : toRaw(value);
|
|
1602
|
+
this._value = isShallow2 ? value : toReactive(value);
|
|
1603
|
+
this["__v_isShallow"] = isShallow2;
|
|
1604
|
+
}
|
|
1605
|
+
get value() {
|
|
1606
|
+
{
|
|
1607
|
+
this.dep.track();
|
|
1608
|
+
}
|
|
1609
|
+
return this._value;
|
|
1610
|
+
}
|
|
1611
|
+
set value(newValue) {
|
|
1612
|
+
const oldValue = this._rawValue;
|
|
1613
|
+
const useDirectValue = this["__v_isShallow"] || isShallow(newValue) || isReadonly(newValue);
|
|
1614
|
+
newValue = useDirectValue ? newValue : toRaw(newValue);
|
|
1615
|
+
if (hasChanged(newValue, oldValue)) {
|
|
1616
|
+
this._rawValue = newValue;
|
|
1617
|
+
this._value = useDirectValue ? newValue : toReactive(newValue);
|
|
1618
|
+
{
|
|
1619
|
+
this.dep.trigger();
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1586
1624
|
function unref(ref2) {
|
|
1587
1625
|
return /* @__PURE__ */ isRef(ref2) ? ref2.value : ref2;
|
|
1588
1626
|
}
|
|
@@ -5974,6 +6012,32 @@ const computed = (getterOrOptions, debugOptions) => {
|
|
|
5974
6012
|
return c;
|
|
5975
6013
|
};
|
|
5976
6014
|
|
|
6015
|
+
function h(type, propsOrChildren, children) {
|
|
6016
|
+
try {
|
|
6017
|
+
setBlockTracking(-1);
|
|
6018
|
+
const l = arguments.length;
|
|
6019
|
+
if (l === 2) {
|
|
6020
|
+
if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
|
|
6021
|
+
if (isVNode(propsOrChildren)) {
|
|
6022
|
+
return createVNode(type, null, [propsOrChildren]);
|
|
6023
|
+
}
|
|
6024
|
+
return createVNode(type, propsOrChildren);
|
|
6025
|
+
} else {
|
|
6026
|
+
return createVNode(type, null, propsOrChildren);
|
|
6027
|
+
}
|
|
6028
|
+
} else {
|
|
6029
|
+
if (l > 3) {
|
|
6030
|
+
children = Array.prototype.slice.call(arguments, 2);
|
|
6031
|
+
} else if (l === 3 && isVNode(children)) {
|
|
6032
|
+
children = [children];
|
|
6033
|
+
}
|
|
6034
|
+
return createVNode(type, propsOrChildren, children);
|
|
6035
|
+
}
|
|
6036
|
+
} finally {
|
|
6037
|
+
setBlockTracking(1);
|
|
6038
|
+
}
|
|
6039
|
+
}
|
|
6040
|
+
|
|
5977
6041
|
const version = "3.5.30";
|
|
5978
6042
|
|
|
5979
6043
|
/**
|
|
@@ -7044,10 +7108,10 @@ function render$c(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7044
7108
|
], 2 /* CLASS */))
|
|
7045
7109
|
}
|
|
7046
7110
|
|
|
7047
|
-
script$
|
|
7048
|
-
script$
|
|
7111
|
+
script$d.render = render$c;
|
|
7112
|
+
script$d.__file = "src/editors/StringEditor.vue";
|
|
7049
7113
|
|
|
7050
|
-
var script$
|
|
7114
|
+
var script$c = {
|
|
7051
7115
|
name: 'NumberEditor',
|
|
7052
7116
|
props: {
|
|
7053
7117
|
schema: { type: Object, required: true },
|
|
@@ -7120,10 +7184,10 @@ function render$b(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7120
7184
|
], 2 /* CLASS */))
|
|
7121
7185
|
}
|
|
7122
7186
|
|
|
7123
|
-
script$
|
|
7124
|
-
script$
|
|
7187
|
+
script$c.render = render$b;
|
|
7188
|
+
script$c.__file = "src/editors/NumberEditor.vue";
|
|
7125
7189
|
|
|
7126
|
-
var script$
|
|
7190
|
+
var script$b = {
|
|
7127
7191
|
name: 'BooleanEditor',
|
|
7128
7192
|
props: {
|
|
7129
7193
|
schema: { type: Object, required: true },
|
|
@@ -7179,10 +7243,10 @@ function render$a(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7179
7243
|
], 2 /* CLASS */))
|
|
7180
7244
|
}
|
|
7181
7245
|
|
|
7182
|
-
script$
|
|
7183
|
-
script$
|
|
7246
|
+
script$b.render = render$a;
|
|
7247
|
+
script$b.__file = "src/editors/BooleanEditor.vue";
|
|
7184
7248
|
|
|
7185
|
-
var script$
|
|
7249
|
+
var script$a = {
|
|
7186
7250
|
name: 'SelectEditor',
|
|
7187
7251
|
props: {
|
|
7188
7252
|
schema: { type: Object, required: true },
|
|
@@ -7251,10 +7315,10 @@ function render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7251
7315
|
], 2 /* CLASS */))
|
|
7252
7316
|
}
|
|
7253
7317
|
|
|
7254
|
-
script$
|
|
7255
|
-
script$
|
|
7318
|
+
script$a.render = render$9;
|
|
7319
|
+
script$a.__file = "src/editors/SelectEditor.vue";
|
|
7256
7320
|
|
|
7257
|
-
var script$
|
|
7321
|
+
var script$9 = {
|
|
7258
7322
|
name: 'HiddenEditor',
|
|
7259
7323
|
props: {
|
|
7260
7324
|
schema: { type: Object, required: true },
|
|
@@ -7288,10 +7352,10 @@ function render$8(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7288
7352
|
return (openBlock(), createElementBlock("div", _hoisted_1$7))
|
|
7289
7353
|
}
|
|
7290
7354
|
|
|
7291
|
-
script$
|
|
7292
|
-
script$
|
|
7355
|
+
script$9.render = render$8;
|
|
7356
|
+
script$9.__file = "src/editors/HiddenEditor.vue";
|
|
7293
7357
|
|
|
7294
|
-
var script$
|
|
7358
|
+
var script$8 = {
|
|
7295
7359
|
name: 'SfIcon',
|
|
7296
7360
|
props: {
|
|
7297
7361
|
name: { type: String, required: true },
|
|
@@ -7383,15 +7447,264 @@ function render$7(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7383
7447
|
], 8 /* PROPS */, _hoisted_1$6))
|
|
7384
7448
|
}
|
|
7385
7449
|
|
|
7386
|
-
script$
|
|
7387
|
-
script$
|
|
7450
|
+
script$8.render = render$7;
|
|
7451
|
+
script$8.__file = "src/editors/SfIcon.vue";
|
|
7452
|
+
|
|
7453
|
+
// JSON Schema conditional evaluation for form rendering.
|
|
7454
|
+
//
|
|
7455
|
+
// Supports the standard keywords: `if`/`then`/`else`, `allOf` of those,
|
|
7456
|
+
// `dependentSchemas`, and `dependentRequired`. The matcher implements the
|
|
7457
|
+
// subset of JSON Schema validation that is meaningful for form-time
|
|
7458
|
+
// conditionals on object properties:
|
|
7459
|
+
//
|
|
7460
|
+
// - `properties: { field: { const, enum, type, not } }`
|
|
7461
|
+
// - `required: [...]` (treated as "key is present and not null/undefined")
|
|
7462
|
+
// - `not`, `allOf`, `anyOf`, `oneOf` (recursive)
|
|
7463
|
+
//
|
|
7464
|
+
// The functions are pure: they take a schema + value and return an
|
|
7465
|
+
// "effective schema" with `properties`/`required` merged from any matching
|
|
7466
|
+
// branches. The renderer uses that effective schema instead of the raw one.
|
|
7467
|
+
|
|
7468
|
+
function isPresent(value, key) {
|
|
7469
|
+
if (value == null || typeof value !== 'object') return false;
|
|
7470
|
+
if (!(key in value)) return false;
|
|
7471
|
+
const v = value[key];
|
|
7472
|
+
return v !== undefined && v !== null && v !== '';
|
|
7473
|
+
}
|
|
7474
|
+
|
|
7475
|
+
function matchesPropertyConstraint(value, constraint) {
|
|
7476
|
+
if (!constraint || typeof constraint !== 'object') return true;
|
|
7477
|
+
if ('const' in constraint) return value === constraint.const;
|
|
7478
|
+
if (Array.isArray(constraint.enum)) return constraint.enum.includes(value);
|
|
7479
|
+
if (constraint.type) {
|
|
7480
|
+
const t = constraint.type;
|
|
7481
|
+
if (t === 'string' && typeof value !== 'string') return false;
|
|
7482
|
+
if (t === 'number' && typeof value !== 'number') return false;
|
|
7483
|
+
if (t === 'integer' && (typeof value !== 'number' || !Number.isInteger(value))) return false;
|
|
7484
|
+
if (t === 'boolean' && typeof value !== 'boolean') return false;
|
|
7485
|
+
if (t === 'null' && value !== null) return false;
|
|
7486
|
+
if (t === 'array' && !Array.isArray(value)) return false;
|
|
7487
|
+
if (t === 'object' && (value == null || typeof value !== 'object' || Array.isArray(value))) return false;
|
|
7488
|
+
}
|
|
7489
|
+
// Numeric comparators
|
|
7490
|
+
if (typeof value === 'number') {
|
|
7491
|
+
if (typeof constraint.minimum === 'number' && value < constraint.minimum) return false;
|
|
7492
|
+
if (typeof constraint.maximum === 'number' && value > constraint.maximum) return false;
|
|
7493
|
+
if (typeof constraint.exclusiveMinimum === 'number' && value <= constraint.exclusiveMinimum) return false;
|
|
7494
|
+
if (typeof constraint.exclusiveMaximum === 'number' && value >= constraint.exclusiveMaximum) return false;
|
|
7495
|
+
if (typeof constraint.multipleOf === 'number' && constraint.multipleOf > 0) {
|
|
7496
|
+
const q = value / constraint.multipleOf;
|
|
7497
|
+
if (Math.abs(q - Math.round(q)) > 1e-9) return false;
|
|
7498
|
+
}
|
|
7499
|
+
}
|
|
7500
|
+
// String comparators
|
|
7501
|
+
if (typeof value === 'string') {
|
|
7502
|
+
if (typeof constraint.minLength === 'number' && value.length < constraint.minLength) return false;
|
|
7503
|
+
if (typeof constraint.maxLength === 'number' && value.length > constraint.maxLength) return false;
|
|
7504
|
+
if (typeof constraint.pattern === 'string') {
|
|
7505
|
+
try {
|
|
7506
|
+
if (!new RegExp(constraint.pattern).test(value)) return false;
|
|
7507
|
+
} catch (e) {
|
|
7508
|
+
// Invalid pattern — treat as non-match rather than throwing in render path.
|
|
7509
|
+
return false;
|
|
7510
|
+
}
|
|
7511
|
+
}
|
|
7512
|
+
}
|
|
7513
|
+
if (constraint.not) return !matchesSchema(value, constraint.not);
|
|
7514
|
+
return true;
|
|
7515
|
+
}
|
|
7388
7516
|
|
|
7389
|
-
|
|
7517
|
+
// Returns true if `value` (an object) satisfies the form-relevant subset of `schema`.
|
|
7518
|
+
function matchesSchema(value, schema) {
|
|
7519
|
+
if (!schema || typeof schema !== 'object') return true;
|
|
7520
|
+
|
|
7521
|
+
if (Array.isArray(schema.required)) {
|
|
7522
|
+
for (const k of schema.required) {
|
|
7523
|
+
if (!isPresent(value, k)) return false;
|
|
7524
|
+
}
|
|
7525
|
+
}
|
|
7526
|
+
|
|
7527
|
+
if (schema.properties && typeof schema.properties === 'object') {
|
|
7528
|
+
for (const [k, constraint] of Object.entries(schema.properties)) {
|
|
7529
|
+
// Standard JSON Schema: property constraints only apply if the key is present.
|
|
7530
|
+
if (value == null || !(k in value)) continue;
|
|
7531
|
+
if (!matchesPropertyConstraint(value[k], constraint)) return false;
|
|
7532
|
+
}
|
|
7533
|
+
}
|
|
7534
|
+
|
|
7535
|
+
if (schema.not && matchesSchema(value, schema.not)) return false;
|
|
7536
|
+
if (Array.isArray(schema.allOf) && !schema.allOf.every((s) => matchesSchema(value, s))) return false;
|
|
7537
|
+
if (Array.isArray(schema.anyOf) && !schema.anyOf.some((s) => matchesSchema(value, s))) return false;
|
|
7538
|
+
if (Array.isArray(schema.oneOf)) {
|
|
7539
|
+
const matched = schema.oneOf.filter((s) => matchesSchema(value, s)).length;
|
|
7540
|
+
if (matched !== 1) return false;
|
|
7541
|
+
}
|
|
7542
|
+
|
|
7543
|
+
return true;
|
|
7544
|
+
}
|
|
7545
|
+
|
|
7546
|
+
function insertAfter(properties, anchorKey, newEntries) {
|
|
7547
|
+
// Rebuild the property map so newly-added keys appear immediately after
|
|
7548
|
+
// their controlling field instead of being appended to the end.
|
|
7549
|
+
const existingKeys = Object.keys(properties);
|
|
7550
|
+
const anchorIdx = anchorKey ? existingKeys.indexOf(anchorKey) : -1;
|
|
7551
|
+
if (anchorIdx === -1) {
|
|
7552
|
+
const out = { ...properties };
|
|
7553
|
+
for (const [k, v] of newEntries) out[k] = v;
|
|
7554
|
+
return out;
|
|
7555
|
+
}
|
|
7556
|
+
const out = {};
|
|
7557
|
+
for (let i = 0; i < existingKeys.length; i++) {
|
|
7558
|
+
const key = existingKeys[i];
|
|
7559
|
+
out[key] = properties[key];
|
|
7560
|
+
if (i === anchorIdx) {
|
|
7561
|
+
for (const [k, v] of newEntries) {
|
|
7562
|
+
if (!(k in properties)) out[k] = v;
|
|
7563
|
+
}
|
|
7564
|
+
}
|
|
7565
|
+
}
|
|
7566
|
+
// Any new keys that already existed in properties have been kept in place;
|
|
7567
|
+
// overwrite their values with the merged versions.
|
|
7568
|
+
for (const [k, v] of newEntries) {
|
|
7569
|
+
if (k in properties) out[k] = v;
|
|
7570
|
+
}
|
|
7571
|
+
return out;
|
|
7572
|
+
}
|
|
7573
|
+
|
|
7574
|
+
function mergeBranch(target, branch, anchorKey) {
|
|
7575
|
+
if (!branch || typeof branch !== 'object') return target;
|
|
7576
|
+
|
|
7577
|
+
if (branch.properties) {
|
|
7578
|
+
const merged = [];
|
|
7579
|
+
for (const [k, v] of Object.entries(branch.properties)) {
|
|
7580
|
+
const existing = target.properties && target.properties[k];
|
|
7581
|
+
merged.push([k, existing ? { ...existing, ...v } : v]);
|
|
7582
|
+
}
|
|
7583
|
+
target.properties = insertAfter(target.properties || {}, anchorKey, merged);
|
|
7584
|
+
}
|
|
7585
|
+
|
|
7586
|
+
if (Array.isArray(branch.required)) {
|
|
7587
|
+
const set = new Set(target.required || []);
|
|
7588
|
+
for (const k of branch.required) set.add(k);
|
|
7589
|
+
target.required = Array.from(set);
|
|
7590
|
+
}
|
|
7591
|
+
|
|
7592
|
+
// Conditionals can also nest more conditionals — flatten them.
|
|
7593
|
+
if (branch.allOf) {
|
|
7594
|
+
target.allOf = [...(target.allOf || []), ...branch.allOf];
|
|
7595
|
+
}
|
|
7596
|
+
if (branch.if) {
|
|
7597
|
+
target.allOf = [...(target.allOf || []), { if: branch.if, then: branch.then, else: branch.else }];
|
|
7598
|
+
}
|
|
7599
|
+
if (branch.dependentSchemas) {
|
|
7600
|
+
target.dependentSchemas = { ...(target.dependentSchemas || {}), ...branch.dependentSchemas };
|
|
7601
|
+
}
|
|
7602
|
+
if (branch.dependentRequired) {
|
|
7603
|
+
target.dependentRequired = { ...(target.dependentRequired || {}), ...branch.dependentRequired };
|
|
7604
|
+
}
|
|
7605
|
+
|
|
7606
|
+
return target;
|
|
7607
|
+
}
|
|
7608
|
+
|
|
7609
|
+
// Returns an effective schema for an object schema given the current value.
|
|
7610
|
+
// Resolves `if/then/else`, `allOf` of those, `dependentSchemas`, and
|
|
7611
|
+
// `dependentRequired`. Idempotent and safe to call on every render.
|
|
7612
|
+
//
|
|
7613
|
+
// `resolver` (optional) is called on each `then`/`else`/`dependentSchemas`
|
|
7614
|
+
// branch before merging, so `$ref` inside conditional branches is followed.
|
|
7615
|
+
// Pass `form.resolveSchema` from the renderer.
|
|
7616
|
+
function applyConditionals(schema, value, resolver) {
|
|
7617
|
+
const resolve = typeof resolver === 'function' ? resolver : (s) => s;
|
|
7618
|
+
if (!schema || typeof schema !== 'object') return schema;
|
|
7619
|
+
if (schema.type !== 'object' && !schema.properties) return schema;
|
|
7620
|
+
|
|
7621
|
+
// Start with a shallow clone of the parts we may mutate.
|
|
7622
|
+
let effective = {
|
|
7623
|
+
...schema,
|
|
7624
|
+
properties: { ...(schema.properties || {}) },
|
|
7625
|
+
required: Array.isArray(schema.required) ? [...schema.required] : [],
|
|
7626
|
+
};
|
|
7627
|
+
|
|
7628
|
+
const safeValue = value && typeof value === 'object' ? value : {};
|
|
7629
|
+
|
|
7630
|
+
// Pick the controlling field of an `if` clause so newly-added properties
|
|
7631
|
+
// can be inserted right after it in render order.
|
|
7632
|
+
const anchorOf = (ifClause) => {
|
|
7633
|
+
if (!ifClause || typeof ifClause !== 'object') return null;
|
|
7634
|
+
const props = ifClause.properties && Object.keys(ifClause.properties);
|
|
7635
|
+
if (props && props.length) return props[0];
|
|
7636
|
+
if (Array.isArray(ifClause.required) && ifClause.required.length) return ifClause.required[0];
|
|
7637
|
+
return null;
|
|
7638
|
+
};
|
|
7639
|
+
|
|
7640
|
+
// Collect rules: top-level if/then/else + every entry in allOf that has one.
|
|
7641
|
+
const rules = [];
|
|
7642
|
+
if (effective.if) {
|
|
7643
|
+
rules.push({ if: effective.if, then: effective.then, else: effective.else, anchor: anchorOf(effective.if) });
|
|
7644
|
+
}
|
|
7645
|
+
if (Array.isArray(effective.allOf)) {
|
|
7646
|
+
for (const entry of effective.allOf) {
|
|
7647
|
+
if (entry && typeof entry === 'object' && entry.if) {
|
|
7648
|
+
rules.push({ if: entry.if, then: entry.then, else: entry.else, anchor: anchorOf(entry.if) });
|
|
7649
|
+
} else if (entry && typeof entry === 'object' && (entry.properties || entry.required)) {
|
|
7650
|
+
// Plain allOf branch (e.g. shared base) — always merge.
|
|
7651
|
+
mergeBranch(effective, entry);
|
|
7652
|
+
}
|
|
7653
|
+
}
|
|
7654
|
+
}
|
|
7655
|
+
|
|
7656
|
+
// Iterate to a fixed point so newly-merged rules can themselves trigger further rules.
|
|
7657
|
+
// Capped to avoid pathological loops.
|
|
7658
|
+
for (let i = 0; i < 8; i++) {
|
|
7659
|
+
let changed = false;
|
|
7660
|
+
const before = JSON.stringify({ p: effective.properties, r: effective.required });
|
|
7661
|
+
|
|
7662
|
+
for (const rule of rules) {
|
|
7663
|
+
const matched = matchesSchema(safeValue, rule.if);
|
|
7664
|
+
const branch = matched ? rule.then : rule.else;
|
|
7665
|
+
if (branch) mergeBranch(effective, resolve(branch), rule.anchor);
|
|
7666
|
+
}
|
|
7667
|
+
|
|
7668
|
+
if (effective.dependentSchemas) {
|
|
7669
|
+
for (const [key, branch] of Object.entries(effective.dependentSchemas)) {
|
|
7670
|
+
if (isPresent(safeValue, key)) mergeBranch(effective, resolve(branch), key);
|
|
7671
|
+
}
|
|
7672
|
+
}
|
|
7673
|
+
|
|
7674
|
+
if (effective.dependentRequired) {
|
|
7675
|
+
for (const [key, requiredKeys] of Object.entries(effective.dependentRequired)) {
|
|
7676
|
+
if (isPresent(safeValue, key) && Array.isArray(requiredKeys)) {
|
|
7677
|
+
const set = new Set(effective.required || []);
|
|
7678
|
+
for (const k of requiredKeys) set.add(k);
|
|
7679
|
+
effective.required = Array.from(set);
|
|
7680
|
+
}
|
|
7681
|
+
}
|
|
7682
|
+
}
|
|
7683
|
+
|
|
7684
|
+
const after = JSON.stringify({ p: effective.properties, r: effective.required });
|
|
7685
|
+
if (after !== before) changed = true;
|
|
7686
|
+
if (!changed) break;
|
|
7687
|
+
}
|
|
7688
|
+
|
|
7689
|
+
return effective;
|
|
7690
|
+
}
|
|
7691
|
+
|
|
7692
|
+
// Returns true if the schema declares any form-relevant conditional logic.
|
|
7693
|
+
function hasConditionals(schema) {
|
|
7694
|
+
if (!schema || typeof schema !== 'object') return false;
|
|
7695
|
+
if (schema.if || schema.dependentSchemas || schema.dependentRequired) return true;
|
|
7696
|
+
if (Array.isArray(schema.allOf)) {
|
|
7697
|
+
return schema.allOf.some((e) => e && typeof e === 'object' && (e.if || e.dependentSchemas));
|
|
7698
|
+
}
|
|
7699
|
+
return false;
|
|
7700
|
+
}
|
|
7701
|
+
|
|
7702
|
+
var script$7 = {
|
|
7390
7703
|
name: 'ObjectEditor',
|
|
7391
7704
|
beforeCreate() {
|
|
7392
7705
|
if (!this.$options.components) this.$options.components = {};
|
|
7393
7706
|
this.$options.components.SchemaEditor = script$1;
|
|
7394
|
-
this.$options.components.SfIcon = script$
|
|
7707
|
+
this.$options.components.SfIcon = script$8;
|
|
7395
7708
|
},
|
|
7396
7709
|
props: {
|
|
7397
7710
|
schema: { type: Object, required: true },
|
|
@@ -7412,10 +7725,14 @@ var script$6 = {
|
|
|
7412
7725
|
title() {
|
|
7413
7726
|
return this.schema.title || this.humanize(this.path[this.path.length - 1]) || '';
|
|
7414
7727
|
},
|
|
7728
|
+
effectiveSchema() {
|
|
7729
|
+
if (!hasConditionals(this.schema)) return this.schema;
|
|
7730
|
+
return applyConditionals(this.schema, this.modelValue || {}, this.form?.resolveSchema);
|
|
7731
|
+
},
|
|
7415
7732
|
summary() {
|
|
7416
7733
|
const val = this.modelValue || {};
|
|
7417
7734
|
const parts = [];
|
|
7418
|
-
for (const key of Object.keys(this.
|
|
7735
|
+
for (const key of Object.keys(this.effectiveSchema.properties || {})) {
|
|
7419
7736
|
if (parts.length >= 3) break;
|
|
7420
7737
|
const v = val[key];
|
|
7421
7738
|
if (v !== null && v !== undefined && v !== '' && typeof v !== 'object') {
|
|
@@ -7438,7 +7755,22 @@ var script$6 = {
|
|
|
7438
7755
|
},
|
|
7439
7756
|
onChildChange(key, value) {
|
|
7440
7757
|
const newVal = { ...(this.modelValue || {}), [key]: value };
|
|
7441
|
-
this.$emit('update:modelValue', newVal);
|
|
7758
|
+
this.$emit('update:modelValue', this.pruneInactive(newVal));
|
|
7759
|
+
},
|
|
7760
|
+
pruneInactive(value) {
|
|
7761
|
+
if (!hasConditionals(this.schema)) return value;
|
|
7762
|
+
const effective = applyConditionals(this.schema, value, this.form?.resolveSchema);
|
|
7763
|
+
const allowed = new Set(Object.keys(effective.properties || {}));
|
|
7764
|
+
let changed = false;
|
|
7765
|
+
const out = {};
|
|
7766
|
+
for (const k of Object.keys(value)) {
|
|
7767
|
+
if (allowed.has(k)) {
|
|
7768
|
+
out[k] = value[k];
|
|
7769
|
+
} else {
|
|
7770
|
+
changed = true;
|
|
7771
|
+
}
|
|
7772
|
+
}
|
|
7773
|
+
return changed ? out : value;
|
|
7442
7774
|
},
|
|
7443
7775
|
},
|
|
7444
7776
|
};
|
|
@@ -7464,7 +7796,7 @@ function render$6(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7464
7796
|
return ($options.isRoot)
|
|
7465
7797
|
? (openBlock(), createElementBlock("div", _hoisted_1$5, [
|
|
7466
7798
|
createBaseVNode("div", _hoisted_2$4, [
|
|
7467
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(($
|
|
7799
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(($options.effectiveSchema.properties || {}), (propSchema, key) => {
|
|
7468
7800
|
return (openBlock(), createBlock(_component_SchemaEditor, {
|
|
7469
7801
|
key: key,
|
|
7470
7802
|
schema: $props.form.resolveSchema(propSchema),
|
|
@@ -7498,7 +7830,7 @@ function render$6(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7498
7830
|
: createCommentVNode("v-if", true)
|
|
7499
7831
|
]),
|
|
7500
7832
|
withDirectives(createBaseVNode("div", _hoisted_7$2, [
|
|
7501
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(($
|
|
7833
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(($options.effectiveSchema.properties || {}), (propSchema, key) => {
|
|
7502
7834
|
return (openBlock(), createBlock(_component_SchemaEditor, {
|
|
7503
7835
|
key: key,
|
|
7504
7836
|
schema: $props.form.resolveSchema(propSchema),
|
|
@@ -7514,8 +7846,8 @@ function render$6(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7514
7846
|
], 2 /* CLASS */))
|
|
7515
7847
|
}
|
|
7516
7848
|
|
|
7517
|
-
script$
|
|
7518
|
-
script$
|
|
7849
|
+
script$7.render = render$6;
|
|
7850
|
+
script$7.__file = "src/editors/ObjectEditor.vue";
|
|
7519
7851
|
|
|
7520
7852
|
function debounce(fn, delay) {
|
|
7521
7853
|
let timer;
|
|
@@ -7558,12 +7890,12 @@ function getDefaultForSchema(schema) {
|
|
|
7558
7890
|
|
|
7559
7891
|
let keyCounter = 0;
|
|
7560
7892
|
|
|
7561
|
-
var script$
|
|
7893
|
+
var script$6 = {
|
|
7562
7894
|
name: 'ArrayEditor',
|
|
7563
7895
|
beforeCreate() {
|
|
7564
7896
|
if (!this.$options.components) this.$options.components = {};
|
|
7565
7897
|
this.$options.components.SchemaEditor = script$1;
|
|
7566
|
-
this.$options.components.SfIcon = script$
|
|
7898
|
+
this.$options.components.SfIcon = script$8;
|
|
7567
7899
|
},
|
|
7568
7900
|
props: {
|
|
7569
7901
|
schema: { type: Object, required: true },
|
|
@@ -7747,13 +8079,16 @@ function render$5(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7747
8079
|
createVNode(_component_SfIcon, { name: "arrow-up" })
|
|
7748
8080
|
], 8 /* PROPS */, _hoisted_12))
|
|
7749
8081
|
: createCommentVNode("v-if", true),
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
|
|
7753
|
-
|
|
7754
|
-
|
|
7755
|
-
|
|
7756
|
-
|
|
8082
|
+
(index < $data.items.length - 1)
|
|
8083
|
+
? (openBlock(), createElementBlock("button", {
|
|
8084
|
+
key: 1,
|
|
8085
|
+
type: "button",
|
|
8086
|
+
class: "sf-btn sf-btn-sm",
|
|
8087
|
+
onClick: $event => ($options.moveItem(index, 1))
|
|
8088
|
+
}, [
|
|
8089
|
+
createVNode(_component_SfIcon, { name: "arrow-down" })
|
|
8090
|
+
], 8 /* PROPS */, _hoisted_13))
|
|
8091
|
+
: createCommentVNode("v-if", true),
|
|
7757
8092
|
createBaseVNode("button", {
|
|
7758
8093
|
type: "button",
|
|
7759
8094
|
class: "sf-btn sf-btn-sm sf-btn-danger",
|
|
@@ -7791,15 +8126,15 @@ function render$5(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7791
8126
|
], 2 /* CLASS */))
|
|
7792
8127
|
}
|
|
7793
8128
|
|
|
7794
|
-
script$
|
|
7795
|
-
script$
|
|
8129
|
+
script$6.render = render$5;
|
|
8130
|
+
script$6.__file = "src/editors/ArrayEditor.vue";
|
|
7796
8131
|
|
|
7797
|
-
var script$
|
|
8132
|
+
var script$5 = {
|
|
7798
8133
|
name: 'NullableEditor',
|
|
7799
8134
|
beforeCreate() {
|
|
7800
8135
|
if (!this.$options.components) this.$options.components = {};
|
|
7801
8136
|
this.$options.components.SchemaEditor = script$1;
|
|
7802
|
-
this.$options.components.SfIcon = script$
|
|
8137
|
+
this.$options.components.SfIcon = script$8;
|
|
7803
8138
|
},
|
|
7804
8139
|
props: {
|
|
7805
8140
|
schema: { type: Object, required: true },
|
|
@@ -7915,10 +8250,10 @@ function render$4(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7915
8250
|
], 2 /* CLASS */))
|
|
7916
8251
|
}
|
|
7917
8252
|
|
|
7918
|
-
script$
|
|
7919
|
-
script$
|
|
8253
|
+
script$5.render = render$4;
|
|
8254
|
+
script$5.__file = "src/editors/NullableEditor.vue";
|
|
7920
8255
|
|
|
7921
|
-
var script$
|
|
8256
|
+
var script$4 = {
|
|
7922
8257
|
name: 'UnionEditor',
|
|
7923
8258
|
beforeCreate() {
|
|
7924
8259
|
if (!this.$options.components) this.$options.components = {};
|
|
@@ -8018,12 +8353,12 @@ function render$3(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
8018
8353
|
]))
|
|
8019
8354
|
}
|
|
8020
8355
|
|
|
8021
|
-
script$
|
|
8022
|
-
script$
|
|
8356
|
+
script$4.render = render$3;
|
|
8357
|
+
script$4.__file = "src/editors/UnionEditor.vue";
|
|
8023
8358
|
|
|
8024
|
-
var script$
|
|
8359
|
+
var script$3 = {
|
|
8025
8360
|
name: 'RelationEditor',
|
|
8026
|
-
components: { SfIcon: script$
|
|
8361
|
+
components: { SfIcon: script$8 },
|
|
8027
8362
|
props: {
|
|
8028
8363
|
schema: { type: Object, required: true },
|
|
8029
8364
|
modelValue: { default: null },
|
|
@@ -8291,24 +8626,82 @@ function render$2(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
8291
8626
|
], 2 /* CLASS */))
|
|
8292
8627
|
}
|
|
8293
8628
|
|
|
8294
|
-
script$
|
|
8295
|
-
script$
|
|
8629
|
+
script$3.render = render$2;
|
|
8630
|
+
script$3.__file = "src/editors/RelationEditor.vue";
|
|
8631
|
+
|
|
8632
|
+
var script$2 = {
|
|
8633
|
+
name: 'WebComponentWrapper',
|
|
8634
|
+
props: {
|
|
8635
|
+
tagName: { type: String, required: true },
|
|
8636
|
+
schema: { type: Object, required: true },
|
|
8637
|
+
modelValue: { default: undefined },
|
|
8638
|
+
path: { type: Array, default: () => [] },
|
|
8639
|
+
form: { type: Object, required: true },
|
|
8640
|
+
},
|
|
8641
|
+
emits: ['update:modelValue'],
|
|
8642
|
+
setup(props, { emit }) {
|
|
8643
|
+
const elRef = ref(null);
|
|
8644
|
+
|
|
8645
|
+
function syncProps() {
|
|
8646
|
+
const el = elRef.value;
|
|
8647
|
+
if (!el) return;
|
|
8648
|
+
el.schema = props.schema;
|
|
8649
|
+
el.modelValue = props.modelValue;
|
|
8650
|
+
el.path = props.path;
|
|
8651
|
+
el.form = props.form;
|
|
8652
|
+
}
|
|
8653
|
+
|
|
8654
|
+
function handleChange(e) {
|
|
8655
|
+
const value = e.detail != null
|
|
8656
|
+
? (Array.isArray(e.detail) ? e.detail[0] : e.detail)
|
|
8657
|
+
: undefined;
|
|
8658
|
+
emit('update:modelValue', value);
|
|
8659
|
+
}
|
|
8660
|
+
|
|
8661
|
+
onMounted(() => {
|
|
8662
|
+
syncProps();
|
|
8663
|
+
const el = elRef.value;
|
|
8664
|
+
if (el) {
|
|
8665
|
+
el.addEventListener('update:model-value', handleChange);
|
|
8666
|
+
el.addEventListener('change', handleChange);
|
|
8667
|
+
}
|
|
8668
|
+
});
|
|
8669
|
+
|
|
8670
|
+
onBeforeUnmount(() => {
|
|
8671
|
+
const el = elRef.value;
|
|
8672
|
+
if (el) {
|
|
8673
|
+
el.removeEventListener('update:model-value', handleChange);
|
|
8674
|
+
el.removeEventListener('change', handleChange);
|
|
8675
|
+
}
|
|
8676
|
+
});
|
|
8677
|
+
|
|
8678
|
+
watch(() => [props.schema, props.modelValue, props.path, props.form], syncProps, { deep: true });
|
|
8679
|
+
|
|
8680
|
+
return () => h(props.tagName, { ref: elRef });
|
|
8681
|
+
},
|
|
8682
|
+
};
|
|
8683
|
+
|
|
8684
|
+
script$2.__file = "src/editors/WebComponentWrapper.vue";
|
|
8296
8685
|
|
|
8297
8686
|
const MAX_DEPTH = 12;
|
|
8298
8687
|
|
|
8299
8688
|
var script$1 = {
|
|
8300
8689
|
name: 'SchemaEditor',
|
|
8301
8690
|
components: {
|
|
8302
|
-
StringEditor: script$
|
|
8303
|
-
NumberEditor: script$
|
|
8304
|
-
BooleanEditor: script$
|
|
8305
|
-
SelectEditor: script$
|
|
8306
|
-
HiddenEditor: script$
|
|
8307
|
-
ObjectEditor: script$
|
|
8308
|
-
ArrayEditor: script$
|
|
8309
|
-
NullableEditor: script$
|
|
8310
|
-
UnionEditor: script$
|
|
8311
|
-
RelationEditor: script$
|
|
8691
|
+
StringEditor: script$d,
|
|
8692
|
+
NumberEditor: script$c,
|
|
8693
|
+
BooleanEditor: script$b,
|
|
8694
|
+
SelectEditor: script$a,
|
|
8695
|
+
HiddenEditor: script$9,
|
|
8696
|
+
ObjectEditor: script$7,
|
|
8697
|
+
ArrayEditor: script$6,
|
|
8698
|
+
NullableEditor: script$5,
|
|
8699
|
+
UnionEditor: script$4,
|
|
8700
|
+
RelationEditor: script$3,
|
|
8701
|
+
WebComponentWrapper: script$2,
|
|
8702
|
+
},
|
|
8703
|
+
inject: {
|
|
8704
|
+
customEditors: { default: () => () => [] },
|
|
8312
8705
|
},
|
|
8313
8706
|
props: {
|
|
8314
8707
|
schema: { type: Object, required: true },
|
|
@@ -8330,11 +8723,20 @@ var script$1 = {
|
|
|
8330
8723
|
},
|
|
8331
8724
|
},
|
|
8332
8725
|
computed: {
|
|
8726
|
+
isWebComponent() {
|
|
8727
|
+
const c = this.editorComponent;
|
|
8728
|
+
return typeof c === 'string' && c.includes('-');
|
|
8729
|
+
},
|
|
8333
8730
|
editorComponent() {
|
|
8334
8731
|
const schema = this.schema;
|
|
8335
8732
|
|
|
8336
8733
|
if (this.path.length > MAX_DEPTH) return 'StringEditor';
|
|
8337
8734
|
|
|
8735
|
+
const overrides = this.customEditors();
|
|
8736
|
+
for (const override of overrides) {
|
|
8737
|
+
if (override.match(schema, this.path)) return override.component;
|
|
8738
|
+
}
|
|
8739
|
+
|
|
8338
8740
|
if (schema.type === 'relation') return 'RelationEditor';
|
|
8339
8741
|
if (schema.oneOf && schema.discriminator) return 'UnionEditor';
|
|
8340
8742
|
if ('const' in schema) return 'HiddenEditor';
|
|
@@ -8352,14 +8754,28 @@ var script$1 = {
|
|
|
8352
8754
|
};
|
|
8353
8755
|
|
|
8354
8756
|
function render$1(_ctx, _cache, $props, $setup, $data, $options) {
|
|
8355
|
-
|
|
8356
|
-
|
|
8357
|
-
|
|
8358
|
-
|
|
8359
|
-
|
|
8360
|
-
|
|
8361
|
-
|
|
8362
|
-
|
|
8757
|
+
const _component_WebComponentWrapper = resolveComponent("WebComponentWrapper");
|
|
8758
|
+
|
|
8759
|
+
return ($options.isWebComponent)
|
|
8760
|
+
? (openBlock(), createBlock(_component_WebComponentWrapper, {
|
|
8761
|
+
key: 0,
|
|
8762
|
+
ref: "editor",
|
|
8763
|
+
"tag-name": $options.editorComponent,
|
|
8764
|
+
schema: $props.schema,
|
|
8765
|
+
"model-value": $props.modelValue,
|
|
8766
|
+
path: $props.path,
|
|
8767
|
+
form: $props.form,
|
|
8768
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (_ctx.$emit('update:modelValue', $event)))
|
|
8769
|
+
}, null, 8 /* PROPS */, ["tag-name", "schema", "model-value", "path", "form"]))
|
|
8770
|
+
: (openBlock(), createBlock(resolveDynamicComponent($options.editorComponent), {
|
|
8771
|
+
key: 1,
|
|
8772
|
+
ref: "editor",
|
|
8773
|
+
schema: $props.schema,
|
|
8774
|
+
"model-value": $props.modelValue,
|
|
8775
|
+
path: $props.path,
|
|
8776
|
+
form: $props.form,
|
|
8777
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = $event => (_ctx.$emit('update:modelValue', $event)))
|
|
8778
|
+
}, null, 8 /* PROPS */, ["schema", "model-value", "path", "form"]))
|
|
8363
8779
|
}
|
|
8364
8780
|
|
|
8365
8781
|
script$1.render = render$1;
|
|
@@ -8372,9 +8788,15 @@ var script = {
|
|
|
8372
8788
|
schema: { type: [Object, String], default: () => ({}) },
|
|
8373
8789
|
initialData: { default: undefined },
|
|
8374
8790
|
errors: { type: Object, default: () => ({}) },
|
|
8791
|
+
customEditors: { type: Array, default: () => [] },
|
|
8375
8792
|
},
|
|
8376
8793
|
emits: ['change'],
|
|
8377
8794
|
expose: ['getValue'],
|
|
8795
|
+
provide() {
|
|
8796
|
+
return {
|
|
8797
|
+
customEditors: () => this.customEditors,
|
|
8798
|
+
};
|
|
8799
|
+
},
|
|
8378
8800
|
data() {
|
|
8379
8801
|
const parsedSchema = typeof this.schema === 'string' ? JSON.parse(this.schema) : this.schema;
|
|
8380
8802
|
const defs = parsedSchema.$defs || parsedSchema.definitions || {};
|
|
@@ -8392,6 +8814,7 @@ var script = {
|
|
|
8392
8814
|
return {
|
|
8393
8815
|
resolveSchema: (s) => this.resolveSchema(s),
|
|
8394
8816
|
getSchemaAtPath: (p) => this.getSchemaAtPath(p),
|
|
8817
|
+
getEffectiveSchemaAtPath: (p) => this.getEffectiveSchemaAtPath(p),
|
|
8395
8818
|
getErrorsForPath: (p) => this.getErrorsForPath(p),
|
|
8396
8819
|
};
|
|
8397
8820
|
},
|
|
@@ -8474,6 +8897,28 @@ var script = {
|
|
|
8474
8897
|
return schema;
|
|
8475
8898
|
},
|
|
8476
8899
|
|
|
8900
|
+
getEffectiveSchemaAtPath(path) {
|
|
8901
|
+
let schema = this.resolveSchema(this.rootSchema);
|
|
8902
|
+
let value = this.currentValue;
|
|
8903
|
+
for (const segment of path) {
|
|
8904
|
+
if (!schema) return null;
|
|
8905
|
+
if (schema.properties || schema.if || schema.allOf || schema.dependentSchemas) {
|
|
8906
|
+
if (hasConditionals(schema)) schema = applyConditionals(schema, value || {}, (s) => this.resolveSchema(s));
|
|
8907
|
+
}
|
|
8908
|
+
if (schema.properties && schema.properties[segment] !== undefined) {
|
|
8909
|
+
schema = this.resolveSchema(schema.properties[segment]);
|
|
8910
|
+
value = value != null ? value[segment] : undefined;
|
|
8911
|
+
} else if (schema.items) {
|
|
8912
|
+
schema = this.resolveSchema(schema.items);
|
|
8913
|
+
value = Array.isArray(value) ? value[segment] : undefined;
|
|
8914
|
+
} else {
|
|
8915
|
+
return null;
|
|
8916
|
+
}
|
|
8917
|
+
}
|
|
8918
|
+
if (schema && hasConditionals(schema)) schema = applyConditionals(schema, value || {});
|
|
8919
|
+
return schema;
|
|
8920
|
+
},
|
|
8921
|
+
|
|
8477
8922
|
onValueChange(val) {
|
|
8478
8923
|
this.currentValue = val;
|
|
8479
8924
|
this.$emit('change', val);
|
|
@@ -8513,6 +8958,115 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
8513
8958
|
script.render = render;
|
|
8514
8959
|
script.__file = "src/SchemaForm.vue";
|
|
8515
8960
|
|
|
8961
|
+
/**
|
|
8962
|
+
* Base class for creating web component custom editors.
|
|
8963
|
+
*
|
|
8964
|
+
* Handles the property contract with the structured-widget-editor wrapper:
|
|
8965
|
+
* - Receives `schema`, `modelValue`, `path`, and `form` as JS properties.
|
|
8966
|
+
* - Provides `emitChange(value)` to dispatch the value back to the form.
|
|
8967
|
+
* - Provides `getErrors()` to retrieve validation errors for this field.
|
|
8968
|
+
* - Calls `render()` once on `connectedCallback` and `update()` on property changes.
|
|
8969
|
+
*
|
|
8970
|
+
* @example
|
|
8971
|
+
* import { BaseEditorElement } from '@structured-field/widget-editor';
|
|
8972
|
+
*
|
|
8973
|
+
* class MyColorPicker extends BaseEditorElement {
|
|
8974
|
+
* render() {
|
|
8975
|
+
* const input = document.createElement('input');
|
|
8976
|
+
* input.type = 'color';
|
|
8977
|
+
* input.value = this.modelValue || '#000000';
|
|
8978
|
+
* input.addEventListener('input', () => this.emitChange(input.value));
|
|
8979
|
+
* this._input = input;
|
|
8980
|
+
* this.appendChild(input);
|
|
8981
|
+
* }
|
|
8982
|
+
*
|
|
8983
|
+
* update() {
|
|
8984
|
+
* if (this._input) this._input.value = this.modelValue || '#000000';
|
|
8985
|
+
* }
|
|
8986
|
+
* }
|
|
8987
|
+
*
|
|
8988
|
+
* customElements.define('my-color-picker', MyColorPicker);
|
|
8989
|
+
*/
|
|
8990
|
+
class BaseEditorElement extends HTMLElement {
|
|
8991
|
+
constructor() {
|
|
8992
|
+
super();
|
|
8993
|
+
this._schema = {};
|
|
8994
|
+
this._modelValue = undefined;
|
|
8995
|
+
this._path = [];
|
|
8996
|
+
this._form = null;
|
|
8997
|
+
this._connected = false;
|
|
8998
|
+
}
|
|
8999
|
+
|
|
9000
|
+
/* ── Property contract ─────────────────────────────────────────────── */
|
|
9001
|
+
|
|
9002
|
+
get schema() { return this._schema; }
|
|
9003
|
+
set schema(v) {
|
|
9004
|
+
this._schema = v;
|
|
9005
|
+
if (this._connected) this.update();
|
|
9006
|
+
}
|
|
9007
|
+
|
|
9008
|
+
get modelValue() { return this._modelValue; }
|
|
9009
|
+
set modelValue(v) {
|
|
9010
|
+
this._modelValue = v;
|
|
9011
|
+
if (this._connected) this.update();
|
|
9012
|
+
}
|
|
9013
|
+
|
|
9014
|
+
get path() { return this._path; }
|
|
9015
|
+
set path(v) {
|
|
9016
|
+
this._path = v;
|
|
9017
|
+
if (this._connected) this.update();
|
|
9018
|
+
}
|
|
9019
|
+
|
|
9020
|
+
get form() { return this._form; }
|
|
9021
|
+
set form(v) {
|
|
9022
|
+
this._form = v;
|
|
9023
|
+
if (this._connected) this.update();
|
|
9024
|
+
}
|
|
9025
|
+
|
|
9026
|
+
/* ── Lifecycle ─────────────────────────────────────────────────────── */
|
|
9027
|
+
|
|
9028
|
+
connectedCallback() {
|
|
9029
|
+
this._connected = true;
|
|
9030
|
+
this.render();
|
|
9031
|
+
}
|
|
9032
|
+
|
|
9033
|
+
disconnectedCallback() {
|
|
9034
|
+
this._connected = false;
|
|
9035
|
+
}
|
|
9036
|
+
|
|
9037
|
+
/* ── Helpers ───────────────────────────────────────────────────────── */
|
|
9038
|
+
|
|
9039
|
+
/**
|
|
9040
|
+
* Dispatch the new value back to the form.
|
|
9041
|
+
* @param {*} value - The new field value.
|
|
9042
|
+
*/
|
|
9043
|
+
emitChange(value) {
|
|
9044
|
+
this.dispatchEvent(new CustomEvent('change', { detail: value }));
|
|
9045
|
+
}
|
|
9046
|
+
|
|
9047
|
+
/**
|
|
9048
|
+
* Returns the current validation errors for this field.
|
|
9049
|
+
* @returns {string[]}
|
|
9050
|
+
*/
|
|
9051
|
+
getErrors() {
|
|
9052
|
+
return this._form?.getErrorsForPath?.(this._path) ?? [];
|
|
9053
|
+
}
|
|
9054
|
+
|
|
9055
|
+
/* ── Override points ───────────────────────────────────────────────── */
|
|
9056
|
+
|
|
9057
|
+
/**
|
|
9058
|
+
* Called once when the element is connected to the DOM.
|
|
9059
|
+
* Build the initial DOM structure here.
|
|
9060
|
+
*/
|
|
9061
|
+
render() {}
|
|
9062
|
+
|
|
9063
|
+
/**
|
|
9064
|
+
* Called whenever a property (schema, modelValue, path, form) changes
|
|
9065
|
+
* after the initial render. Update the DOM here.
|
|
9066
|
+
*/
|
|
9067
|
+
update() {}
|
|
9068
|
+
}
|
|
9069
|
+
|
|
8516
9070
|
const SchemaFormElement = defineCustomElement({
|
|
8517
9071
|
...script,
|
|
8518
9072
|
shadowRoot: false,
|
|
@@ -8524,5 +9078,5 @@ function registerCustomElement(tagName = 'schema-form') {
|
|
|
8524
9078
|
}
|
|
8525
9079
|
}
|
|
8526
9080
|
|
|
8527
|
-
export { script$
|
|
9081
|
+
export { script$6 as ArrayEditor, BaseEditorElement, script$b as BooleanEditor, script$9 as HiddenEditor, script$5 as NullableEditor, script$c as NumberEditor, script$7 as ObjectEditor, script$3 as RelationEditor, script$1 as SchemaEditor, script as SchemaForm, SchemaFormElement, script$a as SelectEditor, script$d as StringEditor, script$4 as UnionEditor, script$2 as WebComponentWrapper, applyConditionals, hasConditionals, matchesSchema, registerCustomElement };
|
|
8528
9082
|
//# sourceMappingURL=structured-widget-editor.esm.js.map
|