@structured-field/widget-editor 1.1.1 → 1.2.1
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.css +1 -1
- package/dist/structured-widget-editor.esm.js +618 -60
- package/dist/structured-widget-editor.esm.js.map +1 -1
- package/dist/structured-widget-editor.iife.js +5 -6
- 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 +32 -0
- package/src/conditionals.js +248 -0
- package/src/editors/ObjectEditor.vue +24 -4
- package/src/editors/RelationEditor.vue +5 -0
- package/src/editors/SchemaEditor.vue +25 -0
- package/src/editors/WebComponentWrapper.vue +55 -0
- package/src/index.js +3 -0
- package/src/scss/components/editors.scss +3 -1
|
@@ -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
|
+
}
|
|
7516
|
+
|
|
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;
|
|
7388
7520
|
|
|
7389
|
-
|
|
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 },
|
|
@@ -7794,15 +8126,15 @@ function render$5(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7794
8126
|
], 2 /* CLASS */))
|
|
7795
8127
|
}
|
|
7796
8128
|
|
|
7797
|
-
script$
|
|
7798
|
-
script$
|
|
8129
|
+
script$6.render = render$5;
|
|
8130
|
+
script$6.__file = "src/editors/ArrayEditor.vue";
|
|
7799
8131
|
|
|
7800
|
-
var script$
|
|
8132
|
+
var script$5 = {
|
|
7801
8133
|
name: 'NullableEditor',
|
|
7802
8134
|
beforeCreate() {
|
|
7803
8135
|
if (!this.$options.components) this.$options.components = {};
|
|
7804
8136
|
this.$options.components.SchemaEditor = script$1;
|
|
7805
|
-
this.$options.components.SfIcon = script$
|
|
8137
|
+
this.$options.components.SfIcon = script$8;
|
|
7806
8138
|
},
|
|
7807
8139
|
props: {
|
|
7808
8140
|
schema: { type: Object, required: true },
|
|
@@ -7918,10 +8250,10 @@ function render$4(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7918
8250
|
], 2 /* CLASS */))
|
|
7919
8251
|
}
|
|
7920
8252
|
|
|
7921
|
-
script$
|
|
7922
|
-
script$
|
|
8253
|
+
script$5.render = render$4;
|
|
8254
|
+
script$5.__file = "src/editors/NullableEditor.vue";
|
|
7923
8255
|
|
|
7924
|
-
var script$
|
|
8256
|
+
var script$4 = {
|
|
7925
8257
|
name: 'UnionEditor',
|
|
7926
8258
|
beforeCreate() {
|
|
7927
8259
|
if (!this.$options.components) this.$options.components = {};
|
|
@@ -8021,12 +8353,15 @@ function render$3(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
8021
8353
|
]))
|
|
8022
8354
|
}
|
|
8023
8355
|
|
|
8024
|
-
script$
|
|
8025
|
-
script$
|
|
8356
|
+
script$4.render = render$3;
|
|
8357
|
+
script$4.__file = "src/editors/UnionEditor.vue";
|
|
8026
8358
|
|
|
8027
|
-
var script$
|
|
8359
|
+
var script$3 = {
|
|
8028
8360
|
name: 'RelationEditor',
|
|
8029
|
-
components: { SfIcon: script$
|
|
8361
|
+
components: { SfIcon: script$8 },
|
|
8362
|
+
inject: {
|
|
8363
|
+
language: { from: 'language', default: () => () => '' },
|
|
8364
|
+
},
|
|
8030
8365
|
props: {
|
|
8031
8366
|
schema: { type: Object, required: true },
|
|
8032
8367
|
modelValue: { default: null },
|
|
@@ -8132,6 +8467,8 @@ var script$2 = {
|
|
|
8132
8467
|
const url = new URL(this.searchUrl, window.location.origin);
|
|
8133
8468
|
url.searchParams.set('_q', query || '');
|
|
8134
8469
|
url.searchParams.set('page', String(page));
|
|
8470
|
+
const lang = typeof this.language === 'function' ? this.language() : this.language;
|
|
8471
|
+
if (lang) url.searchParams.set('_lang', lang);
|
|
8135
8472
|
|
|
8136
8473
|
const response = await fetch(url, { credentials: 'same-origin' });
|
|
8137
8474
|
if (!response.ok) return;
|
|
@@ -8294,24 +8631,82 @@ function render$2(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
8294
8631
|
], 2 /* CLASS */))
|
|
8295
8632
|
}
|
|
8296
8633
|
|
|
8297
|
-
script$
|
|
8298
|
-
script$
|
|
8634
|
+
script$3.render = render$2;
|
|
8635
|
+
script$3.__file = "src/editors/RelationEditor.vue";
|
|
8636
|
+
|
|
8637
|
+
var script$2 = {
|
|
8638
|
+
name: 'WebComponentWrapper',
|
|
8639
|
+
props: {
|
|
8640
|
+
tagName: { type: String, required: true },
|
|
8641
|
+
schema: { type: Object, required: true },
|
|
8642
|
+
modelValue: { default: undefined },
|
|
8643
|
+
path: { type: Array, default: () => [] },
|
|
8644
|
+
form: { type: Object, required: true },
|
|
8645
|
+
},
|
|
8646
|
+
emits: ['update:modelValue'],
|
|
8647
|
+
setup(props, { emit }) {
|
|
8648
|
+
const elRef = ref(null);
|
|
8649
|
+
|
|
8650
|
+
function syncProps() {
|
|
8651
|
+
const el = elRef.value;
|
|
8652
|
+
if (!el) return;
|
|
8653
|
+
el.schema = props.schema;
|
|
8654
|
+
el.modelValue = props.modelValue;
|
|
8655
|
+
el.path = props.path;
|
|
8656
|
+
el.form = props.form;
|
|
8657
|
+
}
|
|
8658
|
+
|
|
8659
|
+
function handleChange(e) {
|
|
8660
|
+
const value = e.detail != null
|
|
8661
|
+
? (Array.isArray(e.detail) ? e.detail[0] : e.detail)
|
|
8662
|
+
: undefined;
|
|
8663
|
+
emit('update:modelValue', value);
|
|
8664
|
+
}
|
|
8665
|
+
|
|
8666
|
+
onMounted(() => {
|
|
8667
|
+
syncProps();
|
|
8668
|
+
const el = elRef.value;
|
|
8669
|
+
if (el) {
|
|
8670
|
+
el.addEventListener('update:model-value', handleChange);
|
|
8671
|
+
el.addEventListener('change', handleChange);
|
|
8672
|
+
}
|
|
8673
|
+
});
|
|
8674
|
+
|
|
8675
|
+
onBeforeUnmount(() => {
|
|
8676
|
+
const el = elRef.value;
|
|
8677
|
+
if (el) {
|
|
8678
|
+
el.removeEventListener('update:model-value', handleChange);
|
|
8679
|
+
el.removeEventListener('change', handleChange);
|
|
8680
|
+
}
|
|
8681
|
+
});
|
|
8682
|
+
|
|
8683
|
+
watch(() => [props.schema, props.modelValue, props.path, props.form], syncProps, { deep: true });
|
|
8684
|
+
|
|
8685
|
+
return () => h(props.tagName, { ref: elRef });
|
|
8686
|
+
},
|
|
8687
|
+
};
|
|
8688
|
+
|
|
8689
|
+
script$2.__file = "src/editors/WebComponentWrapper.vue";
|
|
8299
8690
|
|
|
8300
8691
|
const MAX_DEPTH = 12;
|
|
8301
8692
|
|
|
8302
8693
|
var script$1 = {
|
|
8303
8694
|
name: 'SchemaEditor',
|
|
8304
8695
|
components: {
|
|
8305
|
-
StringEditor: script$
|
|
8306
|
-
NumberEditor: script$
|
|
8307
|
-
BooleanEditor: script$
|
|
8308
|
-
SelectEditor: script$
|
|
8309
|
-
HiddenEditor: script$
|
|
8310
|
-
ObjectEditor: script$
|
|
8311
|
-
ArrayEditor: script$
|
|
8312
|
-
NullableEditor: script$
|
|
8313
|
-
UnionEditor: script$
|
|
8314
|
-
RelationEditor: script$
|
|
8696
|
+
StringEditor: script$d,
|
|
8697
|
+
NumberEditor: script$c,
|
|
8698
|
+
BooleanEditor: script$b,
|
|
8699
|
+
SelectEditor: script$a,
|
|
8700
|
+
HiddenEditor: script$9,
|
|
8701
|
+
ObjectEditor: script$7,
|
|
8702
|
+
ArrayEditor: script$6,
|
|
8703
|
+
NullableEditor: script$5,
|
|
8704
|
+
UnionEditor: script$4,
|
|
8705
|
+
RelationEditor: script$3,
|
|
8706
|
+
WebComponentWrapper: script$2,
|
|
8707
|
+
},
|
|
8708
|
+
inject: {
|
|
8709
|
+
customEditors: { default: () => () => [] },
|
|
8315
8710
|
},
|
|
8316
8711
|
props: {
|
|
8317
8712
|
schema: { type: Object, required: true },
|
|
@@ -8333,11 +8728,20 @@ var script$1 = {
|
|
|
8333
8728
|
},
|
|
8334
8729
|
},
|
|
8335
8730
|
computed: {
|
|
8731
|
+
isWebComponent() {
|
|
8732
|
+
const c = this.editorComponent;
|
|
8733
|
+
return typeof c === 'string' && c.includes('-');
|
|
8734
|
+
},
|
|
8336
8735
|
editorComponent() {
|
|
8337
8736
|
const schema = this.schema;
|
|
8338
8737
|
|
|
8339
8738
|
if (this.path.length > MAX_DEPTH) return 'StringEditor';
|
|
8340
8739
|
|
|
8740
|
+
const overrides = this.customEditors();
|
|
8741
|
+
for (const override of overrides) {
|
|
8742
|
+
if (override.match(schema, this.path)) return override.component;
|
|
8743
|
+
}
|
|
8744
|
+
|
|
8341
8745
|
if (schema.type === 'relation') return 'RelationEditor';
|
|
8342
8746
|
if (schema.oneOf && schema.discriminator) return 'UnionEditor';
|
|
8343
8747
|
if ('const' in schema) return 'HiddenEditor';
|
|
@@ -8355,14 +8759,28 @@ var script$1 = {
|
|
|
8355
8759
|
};
|
|
8356
8760
|
|
|
8357
8761
|
function render$1(_ctx, _cache, $props, $setup, $data, $options) {
|
|
8358
|
-
|
|
8359
|
-
|
|
8360
|
-
|
|
8361
|
-
|
|
8362
|
-
|
|
8363
|
-
|
|
8364
|
-
|
|
8365
|
-
|
|
8762
|
+
const _component_WebComponentWrapper = resolveComponent("WebComponentWrapper");
|
|
8763
|
+
|
|
8764
|
+
return ($options.isWebComponent)
|
|
8765
|
+
? (openBlock(), createBlock(_component_WebComponentWrapper, {
|
|
8766
|
+
key: 0,
|
|
8767
|
+
ref: "editor",
|
|
8768
|
+
"tag-name": $options.editorComponent,
|
|
8769
|
+
schema: $props.schema,
|
|
8770
|
+
"model-value": $props.modelValue,
|
|
8771
|
+
path: $props.path,
|
|
8772
|
+
form: $props.form,
|
|
8773
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (_ctx.$emit('update:modelValue', $event)))
|
|
8774
|
+
}, null, 8 /* PROPS */, ["tag-name", "schema", "model-value", "path", "form"]))
|
|
8775
|
+
: (openBlock(), createBlock(resolveDynamicComponent($options.editorComponent), {
|
|
8776
|
+
key: 1,
|
|
8777
|
+
ref: "editor",
|
|
8778
|
+
schema: $props.schema,
|
|
8779
|
+
"model-value": $props.modelValue,
|
|
8780
|
+
path: $props.path,
|
|
8781
|
+
form: $props.form,
|
|
8782
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = $event => (_ctx.$emit('update:modelValue', $event)))
|
|
8783
|
+
}, null, 8 /* PROPS */, ["schema", "model-value", "path", "form"]))
|
|
8366
8784
|
}
|
|
8367
8785
|
|
|
8368
8786
|
script$1.render = render$1;
|
|
@@ -8375,9 +8793,17 @@ var script = {
|
|
|
8375
8793
|
schema: { type: [Object, String], default: () => ({}) },
|
|
8376
8794
|
initialData: { default: undefined },
|
|
8377
8795
|
errors: { type: Object, default: () => ({}) },
|
|
8796
|
+
customEditors: { type: Array, default: () => [] },
|
|
8797
|
+
language: { type: String, default: '' },
|
|
8378
8798
|
},
|
|
8379
8799
|
emits: ['change'],
|
|
8380
8800
|
expose: ['getValue'],
|
|
8801
|
+
provide() {
|
|
8802
|
+
return {
|
|
8803
|
+
customEditors: () => this.customEditors,
|
|
8804
|
+
language: () => this.language,
|
|
8805
|
+
};
|
|
8806
|
+
},
|
|
8381
8807
|
data() {
|
|
8382
8808
|
const parsedSchema = typeof this.schema === 'string' ? JSON.parse(this.schema) : this.schema;
|
|
8383
8809
|
const defs = parsedSchema.$defs || parsedSchema.definitions || {};
|
|
@@ -8395,6 +8821,7 @@ var script = {
|
|
|
8395
8821
|
return {
|
|
8396
8822
|
resolveSchema: (s) => this.resolveSchema(s),
|
|
8397
8823
|
getSchemaAtPath: (p) => this.getSchemaAtPath(p),
|
|
8824
|
+
getEffectiveSchemaAtPath: (p) => this.getEffectiveSchemaAtPath(p),
|
|
8398
8825
|
getErrorsForPath: (p) => this.getErrorsForPath(p),
|
|
8399
8826
|
};
|
|
8400
8827
|
},
|
|
@@ -8477,6 +8904,28 @@ var script = {
|
|
|
8477
8904
|
return schema;
|
|
8478
8905
|
},
|
|
8479
8906
|
|
|
8907
|
+
getEffectiveSchemaAtPath(path) {
|
|
8908
|
+
let schema = this.resolveSchema(this.rootSchema);
|
|
8909
|
+
let value = this.currentValue;
|
|
8910
|
+
for (const segment of path) {
|
|
8911
|
+
if (!schema) return null;
|
|
8912
|
+
if (schema.properties || schema.if || schema.allOf || schema.dependentSchemas) {
|
|
8913
|
+
if (hasConditionals(schema)) schema = applyConditionals(schema, value || {}, (s) => this.resolveSchema(s));
|
|
8914
|
+
}
|
|
8915
|
+
if (schema.properties && schema.properties[segment] !== undefined) {
|
|
8916
|
+
schema = this.resolveSchema(schema.properties[segment]);
|
|
8917
|
+
value = value != null ? value[segment] : undefined;
|
|
8918
|
+
} else if (schema.items) {
|
|
8919
|
+
schema = this.resolveSchema(schema.items);
|
|
8920
|
+
value = Array.isArray(value) ? value[segment] : undefined;
|
|
8921
|
+
} else {
|
|
8922
|
+
return null;
|
|
8923
|
+
}
|
|
8924
|
+
}
|
|
8925
|
+
if (schema && hasConditionals(schema)) schema = applyConditionals(schema, value || {});
|
|
8926
|
+
return schema;
|
|
8927
|
+
},
|
|
8928
|
+
|
|
8480
8929
|
onValueChange(val) {
|
|
8481
8930
|
this.currentValue = val;
|
|
8482
8931
|
this.$emit('change', val);
|
|
@@ -8516,6 +8965,115 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
8516
8965
|
script.render = render;
|
|
8517
8966
|
script.__file = "src/SchemaForm.vue";
|
|
8518
8967
|
|
|
8968
|
+
/**
|
|
8969
|
+
* Base class for creating web component custom editors.
|
|
8970
|
+
*
|
|
8971
|
+
* Handles the property contract with the structured-widget-editor wrapper:
|
|
8972
|
+
* - Receives `schema`, `modelValue`, `path`, and `form` as JS properties.
|
|
8973
|
+
* - Provides `emitChange(value)` to dispatch the value back to the form.
|
|
8974
|
+
* - Provides `getErrors()` to retrieve validation errors for this field.
|
|
8975
|
+
* - Calls `render()` once on `connectedCallback` and `update()` on property changes.
|
|
8976
|
+
*
|
|
8977
|
+
* @example
|
|
8978
|
+
* import { BaseEditorElement } from '@structured-field/widget-editor';
|
|
8979
|
+
*
|
|
8980
|
+
* class MyColorPicker extends BaseEditorElement {
|
|
8981
|
+
* render() {
|
|
8982
|
+
* const input = document.createElement('input');
|
|
8983
|
+
* input.type = 'color';
|
|
8984
|
+
* input.value = this.modelValue || '#000000';
|
|
8985
|
+
* input.addEventListener('input', () => this.emitChange(input.value));
|
|
8986
|
+
* this._input = input;
|
|
8987
|
+
* this.appendChild(input);
|
|
8988
|
+
* }
|
|
8989
|
+
*
|
|
8990
|
+
* update() {
|
|
8991
|
+
* if (this._input) this._input.value = this.modelValue || '#000000';
|
|
8992
|
+
* }
|
|
8993
|
+
* }
|
|
8994
|
+
*
|
|
8995
|
+
* customElements.define('my-color-picker', MyColorPicker);
|
|
8996
|
+
*/
|
|
8997
|
+
class BaseEditorElement extends HTMLElement {
|
|
8998
|
+
constructor() {
|
|
8999
|
+
super();
|
|
9000
|
+
this._schema = {};
|
|
9001
|
+
this._modelValue = undefined;
|
|
9002
|
+
this._path = [];
|
|
9003
|
+
this._form = null;
|
|
9004
|
+
this._connected = false;
|
|
9005
|
+
}
|
|
9006
|
+
|
|
9007
|
+
/* ── Property contract ─────────────────────────────────────────────── */
|
|
9008
|
+
|
|
9009
|
+
get schema() { return this._schema; }
|
|
9010
|
+
set schema(v) {
|
|
9011
|
+
this._schema = v;
|
|
9012
|
+
if (this._connected) this.update();
|
|
9013
|
+
}
|
|
9014
|
+
|
|
9015
|
+
get modelValue() { return this._modelValue; }
|
|
9016
|
+
set modelValue(v) {
|
|
9017
|
+
this._modelValue = v;
|
|
9018
|
+
if (this._connected) this.update();
|
|
9019
|
+
}
|
|
9020
|
+
|
|
9021
|
+
get path() { return this._path; }
|
|
9022
|
+
set path(v) {
|
|
9023
|
+
this._path = v;
|
|
9024
|
+
if (this._connected) this.update();
|
|
9025
|
+
}
|
|
9026
|
+
|
|
9027
|
+
get form() { return this._form; }
|
|
9028
|
+
set form(v) {
|
|
9029
|
+
this._form = v;
|
|
9030
|
+
if (this._connected) this.update();
|
|
9031
|
+
}
|
|
9032
|
+
|
|
9033
|
+
/* ── Lifecycle ─────────────────────────────────────────────────────── */
|
|
9034
|
+
|
|
9035
|
+
connectedCallback() {
|
|
9036
|
+
this._connected = true;
|
|
9037
|
+
this.render();
|
|
9038
|
+
}
|
|
9039
|
+
|
|
9040
|
+
disconnectedCallback() {
|
|
9041
|
+
this._connected = false;
|
|
9042
|
+
}
|
|
9043
|
+
|
|
9044
|
+
/* ── Helpers ───────────────────────────────────────────────────────── */
|
|
9045
|
+
|
|
9046
|
+
/**
|
|
9047
|
+
* Dispatch the new value back to the form.
|
|
9048
|
+
* @param {*} value - The new field value.
|
|
9049
|
+
*/
|
|
9050
|
+
emitChange(value) {
|
|
9051
|
+
this.dispatchEvent(new CustomEvent('change', { detail: value }));
|
|
9052
|
+
}
|
|
9053
|
+
|
|
9054
|
+
/**
|
|
9055
|
+
* Returns the current validation errors for this field.
|
|
9056
|
+
* @returns {string[]}
|
|
9057
|
+
*/
|
|
9058
|
+
getErrors() {
|
|
9059
|
+
return this._form?.getErrorsForPath?.(this._path) ?? [];
|
|
9060
|
+
}
|
|
9061
|
+
|
|
9062
|
+
/* ── Override points ───────────────────────────────────────────────── */
|
|
9063
|
+
|
|
9064
|
+
/**
|
|
9065
|
+
* Called once when the element is connected to the DOM.
|
|
9066
|
+
* Build the initial DOM structure here.
|
|
9067
|
+
*/
|
|
9068
|
+
render() {}
|
|
9069
|
+
|
|
9070
|
+
/**
|
|
9071
|
+
* Called whenever a property (schema, modelValue, path, form) changes
|
|
9072
|
+
* after the initial render. Update the DOM here.
|
|
9073
|
+
*/
|
|
9074
|
+
update() {}
|
|
9075
|
+
}
|
|
9076
|
+
|
|
8519
9077
|
const SchemaFormElement = defineCustomElement({
|
|
8520
9078
|
...script,
|
|
8521
9079
|
shadowRoot: false,
|
|
@@ -8527,5 +9085,5 @@ function registerCustomElement(tagName = 'schema-form') {
|
|
|
8527
9085
|
}
|
|
8528
9086
|
}
|
|
8529
9087
|
|
|
8530
|
-
export { script$
|
|
9088
|
+
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 };
|
|
8531
9089
|
//# sourceMappingURL=structured-widget-editor.esm.js.map
|