jedison 1.16.2 → 1.18.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.
@@ -96,7 +96,7 @@ function isBoolean(value) {
96
96
  function isArray(value) {
97
97
  return Array.isArray(value);
98
98
  }
99
- function isObject(value) {
99
+ function isObject$1(value) {
100
100
  return !isNull(value) && !isArray(value) && typeof value === "object";
101
101
  }
102
102
  function getType(value) {
@@ -111,7 +111,7 @@ function getType(value) {
111
111
  type2 = "array";
112
112
  } else if (isNull(value)) {
113
113
  type2 = "null";
114
- } else if (isObject(value)) {
114
+ } else if (isObject$1(value)) {
115
115
  type2 = "object";
116
116
  }
117
117
  return type2;
@@ -133,7 +133,7 @@ function filterAttributes(attributes, options = {}) {
133
133
  allowedPrefixes = DEFAULT_ATTRIBUTE_ALLOWED_PREFIXES
134
134
  } = options;
135
135
  const result = {};
136
- if (!isObject(attributes)) {
136
+ if (!isObject$1(attributes)) {
137
137
  return result;
138
138
  }
139
139
  const allowed = new Set(allowlist.map((name) => name.toLowerCase()));
@@ -150,10 +150,10 @@ const UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "protot
150
150
  function mergeDeep(target, ...sources) {
151
151
  if (!sources.length) return target;
152
152
  const source = sources.shift();
153
- if (isObject(target) && isObject(source)) {
153
+ if (isObject$1(target) && isObject$1(source)) {
154
154
  Object.keys(source).forEach((key) => {
155
155
  if (UNSAFE_KEYS.has(key)) return;
156
- if (isObject(source[key])) {
156
+ if (isObject$1(source[key])) {
157
157
  if (!target[key]) {
158
158
  Object.assign(target, {
159
159
  [key]: {}
@@ -174,11 +174,11 @@ function combineDeep(target, ...sources) {
174
174
  const source = sources.shift();
175
175
  if (Array.isArray(target) && Array.isArray(source)) {
176
176
  target.push(...source);
177
- } else if (isObject(target) && isObject(source)) {
177
+ } else if (isObject$1(target) && isObject$1(source)) {
178
178
  Object.keys(source).forEach((key) => {
179
179
  if (UNSAFE_KEYS.has(key)) return;
180
- if (isObject(source[key])) {
181
- if (!isObject(target[key])) {
180
+ if (isObject$1(source[key])) {
181
+ if (!isObject$1(target[key])) {
182
182
  Object.assign(target, {
183
183
  [key]: {}
184
184
  });
@@ -201,8 +201,8 @@ function combineDeep(target, ...sources) {
201
201
  const overwriteExistingProperties = (obj1, obj2) => {
202
202
  Object.keys(obj2).forEach((key) => {
203
203
  if (key in obj1) {
204
- if (isSet(obj1[key]) && isSet(obj2[key]) && (isObject(obj1[key]) && isObject(obj2[key]) || isArray(obj1[key]) && isArray(obj2[key]) || isString(obj1[key]) && isString(obj2[key]) || isNumber(obj1[key]) && isNumber(obj2[key]) || isBoolean(obj1[key]) && isBoolean(obj2[key]) || isNull(obj1[key]) && isNull(obj2[key]))) {
205
- if (isObject(obj1[key]) && isObject(obj2[key])) {
204
+ if (isSet(obj1[key]) && isSet(obj2[key]) && (isObject$1(obj1[key]) && isObject$1(obj2[key]) || isArray(obj1[key]) && isArray(obj2[key]) || isString(obj1[key]) && isString(obj2[key]) || isNumber(obj1[key]) && isNumber(obj2[key]) || isBoolean(obj1[key]) && isBoolean(obj2[key]) || isNull(obj1[key]) && isNull(obj2[key]))) {
205
+ if (isObject$1(obj1[key]) && isObject$1(obj2[key])) {
206
206
  overwriteExistingProperties(obj1[key], obj2[key]);
207
207
  } else {
208
208
  obj1[key] = obj2[key];
@@ -302,7 +302,7 @@ const Utils = {
302
302
  isString,
303
303
  isBoolean,
304
304
  isArray,
305
- isObject,
305
+ isObject: isObject$1,
306
306
  getType,
307
307
  mergeDeep,
308
308
  combineDeep,
@@ -330,10 +330,10 @@ function getSchemaSchema(schema) {
330
330
  return isString(schema.$schema) ? clone(schema.$schema) : void 0;
331
331
  }
332
332
  function getSchemaAdditionalProperties(schema) {
333
- return isObject(schema.additionalProperties) || isBoolean(schema.additionalProperties) ? clone(schema.additionalProperties) : void 0;
333
+ return isObject$1(schema.additionalProperties) || isBoolean(schema.additionalProperties) ? clone(schema.additionalProperties) : void 0;
334
334
  }
335
335
  function getSchemaPropertyNames(schema) {
336
- return isObject(schema.propertyNames) || isBoolean(schema.propertyNames) ? clone(schema.propertyNames) : void 0;
336
+ return isObject$1(schema.propertyNames) || isBoolean(schema.propertyNames) ? clone(schema.propertyNames) : void 0;
337
337
  }
338
338
  function getSchemaAllOf(schema) {
339
339
  return isArray(schema.allOf) ? clone(schema.allOf) : void 0;
@@ -345,22 +345,22 @@ function getSchemaConst(schema) {
345
345
  return clone(schema.const);
346
346
  }
347
347
  function getSchemaContains(schema) {
348
- return isObject(schema.contains) || isBoolean(schema.contains) ? clone(schema.contains) : void 0;
348
+ return isObject$1(schema.contains) || isBoolean(schema.contains) ? clone(schema.contains) : void 0;
349
349
  }
350
350
  function getSchemaDefault(schema) {
351
351
  return clone(schema.default);
352
352
  }
353
353
  function getSchemaDependentRequired(schema) {
354
- return isObject(schema.dependentRequired) ? clone(schema.dependentRequired) : void 0;
354
+ return isObject$1(schema.dependentRequired) ? clone(schema.dependentRequired) : void 0;
355
355
  }
356
356
  function getSchemaDependentSchemas(schema) {
357
- return isObject(schema.dependentSchemas) ? clone(schema.dependentSchemas) : void 0;
357
+ return isObject$1(schema.dependentSchemas) ? clone(schema.dependentSchemas) : void 0;
358
358
  }
359
359
  function getSchemaDescription(schema) {
360
360
  return isString(schema.description) ? clone(schema.description) : void 0;
361
361
  }
362
362
  function getSchemaElse(schema) {
363
- return isObject(schema.else) || isBoolean(schema.else) ? clone(schema.else) : void 0;
363
+ return isObject$1(schema.else) || isBoolean(schema.else) ? clone(schema.else) : void 0;
364
364
  }
365
365
  function getSchemaEnum(schema) {
366
366
  if (isArray(schema.enum) && schema.enum.length > 0) {
@@ -378,7 +378,7 @@ function getSchemaFormat(schema) {
378
378
  return isString(schema.format) ? clone(schema.format) : void 0;
379
379
  }
380
380
  function getSchemaIf(schema) {
381
- if (isObject(schema.if)) {
381
+ if (isObject$1(schema.if)) {
382
382
  return clone(schema.if);
383
383
  }
384
384
  if (isBoolean(schema.if)) {
@@ -387,7 +387,7 @@ function getSchemaIf(schema) {
387
387
  return void 0;
388
388
  }
389
389
  function getSchemaItems(schema) {
390
- return isObject(schema.items) || isBoolean(schema.items) ? clone(schema.items) : void 0;
390
+ return isObject$1(schema.items) || isBoolean(schema.items) ? clone(schema.items) : void 0;
391
391
  }
392
392
  function getSchemaMaximum(schema) {
393
393
  return isNumber(schema.maximum) ? clone(schema.maximum) : void 0;
@@ -450,7 +450,7 @@ function getSchemaMultipleOf(schema) {
450
450
  return void 0;
451
451
  }
452
452
  function getSchemaNot(schema) {
453
- return isObject(schema.not) || isBoolean(schema.not) ? clone(schema.not) : void 0;
453
+ return isObject$1(schema.not) || isBoolean(schema.not) ? clone(schema.not) : void 0;
454
454
  }
455
455
  function getSchemaXOption(schema, option) {
456
456
  const xOption = "x-" + option;
@@ -481,13 +481,13 @@ function getSchemaPattern(schema) {
481
481
  return isString(schema.pattern) ? clone(schema.pattern) : void 0;
482
482
  }
483
483
  function getSchemaPatternProperties(schema) {
484
- return isObject(schema.patternProperties) ? clone(schema.patternProperties) : void 0;
484
+ return isObject$1(schema.patternProperties) ? clone(schema.patternProperties) : void 0;
485
485
  }
486
486
  function getSchemaPrefixItems(schema) {
487
487
  return isArray(schema.prefixItems) ? clone(schema.prefixItems) : void 0;
488
488
  }
489
489
  function getSchemaProperties(schema) {
490
- return isObject(schema.properties) ? clone(schema.properties) : void 0;
490
+ return isObject$1(schema.properties) ? clone(schema.properties) : void 0;
491
491
  }
492
492
  function getSchemaReadOnly(schema) {
493
493
  return isBoolean(schema.readOnly) ? clone(schema.readOnly) : void 0;
@@ -496,7 +496,7 @@ function getSchemaRequired(schema) {
496
496
  return isArray(schema.required) ? [...new Set(schema.required)] : void 0;
497
497
  }
498
498
  function getSchemaThen(schema) {
499
- return isObject(schema.then) || isBoolean(schema.then) ? clone(schema.then) : void 0;
499
+ return isObject$1(schema.then) || isBoolean(schema.then) ? clone(schema.then) : void 0;
500
500
  }
501
501
  function getSchemaTitle(schema) {
502
502
  return isString(schema.title) ? clone(schema.title) : void 0;
@@ -795,7 +795,7 @@ function items(context) {
795
795
  constraint: "items",
796
796
  messages: [context.translator.translate("errorItems")]
797
797
  });
798
- } else if (isObject(items2)) {
798
+ } else if (isObject$1(items2)) {
799
799
  const enableSubErrors = getSchemaXOption(context.schema, "subErrors") ?? context.validator.subErrors;
800
800
  context.value.slice(prefixItemsSchemasCount).forEach((itemValue, i) => {
801
801
  const index2 = prefixItemsSchemasCount + i;
@@ -863,7 +863,7 @@ function maxLength(context) {
863
863
  function maxProperties(context) {
864
864
  const errors = [];
865
865
  const maxProperties2 = getSchemaMaxProperties(context.schema);
866
- if (isObject(context.value) && isSet(maxProperties2)) {
866
+ if (isObject$1(context.value) && isSet(maxProperties2)) {
867
867
  const propertiesCount = Object.keys(context.value).length;
868
868
  const invalid = propertiesCount > maxProperties2;
869
869
  if (invalid) {
@@ -924,7 +924,7 @@ function minItems(context) {
924
924
  function minProperties(context) {
925
925
  const errors = [];
926
926
  const minProperties2 = getSchemaMinProperties(context.schema);
927
- if (isObject(context.value) && isSet(minProperties2)) {
927
+ if (isObject$1(context.value) && isSet(minProperties2)) {
928
928
  const propertiesCount = Object.keys(context.value).length;
929
929
  const invalid = propertiesCount < minProperties2;
930
930
  if (invalid) {
@@ -1076,7 +1076,7 @@ function pattern(context) {
1076
1076
  function patternProperties(context) {
1077
1077
  let errors = [];
1078
1078
  const patternProperties2 = getSchemaPatternProperties(context.schema);
1079
- if (isObject(context.value) && isSet(patternProperties2)) {
1079
+ if (isObject$1(context.value) && isSet(patternProperties2)) {
1080
1080
  Object.keys(context.value).forEach((propertyName) => {
1081
1081
  Object.keys(patternProperties2).forEach((pattern2) => {
1082
1082
  const regexp = new RegExp(pattern2);
@@ -1102,7 +1102,7 @@ function properties(context) {
1102
1102
  const invalidProperties = [];
1103
1103
  const enableSubErrors = getSchemaXOption(context.schema, "subErrors") ?? context.validator.subErrors;
1104
1104
  const propertySubErrors = [];
1105
- if (isObject(context.value) && isSet(schemaProperties)) {
1105
+ if (isObject$1(context.value) && isSet(schemaProperties)) {
1106
1106
  Object.keys(schemaProperties).forEach((propertyName) => {
1107
1107
  if (hasOwn(context.value, propertyName)) {
1108
1108
  const propertySchema = schemaProperties[propertyName];
@@ -1140,7 +1140,7 @@ function properties(context) {
1140
1140
  function required(context) {
1141
1141
  const errors = [];
1142
1142
  const required2 = getSchemaRequired(context.schema);
1143
- if (isObject(context.value) && isSet(required2)) {
1143
+ if (isObject$1(context.value) && isSet(required2)) {
1144
1144
  const missingProperties = [];
1145
1145
  const keys = Object.keys(context.value);
1146
1146
  required2.forEach((key) => {
@@ -1177,7 +1177,7 @@ function type(context) {
1177
1177
  integer: (value) => isInteger(value),
1178
1178
  boolean: (value) => isBoolean(value),
1179
1179
  array: (value) => isArray(value),
1180
- object: (value) => isObject(value),
1180
+ object: (value) => isObject$1(value),
1181
1181
  null: (value) => isNull(value)
1182
1182
  };
1183
1183
  let valid = true;
@@ -1232,7 +1232,7 @@ function uniqueItems(context) {
1232
1232
  let hasDuplicatedItems = false;
1233
1233
  for (let i = 0; i < context.value.length; i++) {
1234
1234
  let item = context.value[i];
1235
- if (isObject(item)) {
1235
+ if (isObject$1(item)) {
1236
1236
  item = sortObject(item);
1237
1237
  }
1238
1238
  const itemStringified = JSON.stringify(item);
@@ -1262,7 +1262,7 @@ function additionalProperties(context) {
1262
1262
  const schemaAdditionalProperties = getSchemaAdditionalProperties(context.schema);
1263
1263
  const schemaPatternProperties = getSchemaPatternProperties(context.schema);
1264
1264
  const schemaProperties = getSchemaProperties(context.schema);
1265
- if (isObject(context.value) && isSet(schemaAdditionalProperties)) {
1265
+ if (isObject$1(context.value) && isSet(schemaAdditionalProperties)) {
1266
1266
  const properties2 = schemaProperties || {};
1267
1267
  const additionalProperties2 = schemaAdditionalProperties;
1268
1268
  const patternProperties2 = schemaPatternProperties || {};
@@ -1282,7 +1282,7 @@ function additionalProperties(context) {
1282
1282
  compileTemplate(context.translator.translate("errorAdditionalProperties"), { property })
1283
1283
  ]
1284
1284
  });
1285
- } else if (isObject(additionalProperties2)) {
1285
+ } else if (isObject$1(additionalProperties2)) {
1286
1286
  const additionalPropertyErrors = context.validator.getErrors(context.value[property], additionalProperties2, property, context.path + "/" + property).map((error) => ({
1287
1287
  type: "error",
1288
1288
  path: `${context.path}.${property}`,
@@ -1405,7 +1405,7 @@ function contains(context) {
1405
1405
  function dependentRequired(context) {
1406
1406
  const errors = [];
1407
1407
  const dependentRequired2 = getSchemaDependentRequired(context.schema);
1408
- if (isObject(context.value) && isSet(dependentRequired2)) {
1408
+ if (isObject$1(context.value) && isSet(dependentRequired2)) {
1409
1409
  let missingProperties = [];
1410
1410
  Object.keys(dependentRequired2).forEach((key) => {
1411
1411
  if (isSet(context.value[key])) {
@@ -1436,7 +1436,7 @@ function dependentRequired(context) {
1436
1436
  function dependentSchemas(context) {
1437
1437
  let errors = [];
1438
1438
  const dependentSchemas2 = getSchemaDependentSchemas(context.schema);
1439
- if (isObject(context.value) && isSet(dependentSchemas2)) {
1439
+ if (isObject$1(context.value) && isSet(dependentSchemas2)) {
1440
1440
  Object.keys(dependentSchemas2).forEach((key) => {
1441
1441
  if (isSet(context.value[key])) {
1442
1442
  const dependentSchema = dependentSchemas2[key];
@@ -1573,7 +1573,7 @@ function unevaluatedProperties(context) {
1573
1573
  const schemaAllOf = getSchemaAllOf(context.schema);
1574
1574
  const schemaAnyOf = getSchemaAnyOf(context.schema);
1575
1575
  const schemaOneOf = getSchemaOneOf(context.schema);
1576
- if (isObject(context.value) && isSet(schemaUnevaluatedProperties)) {
1576
+ if (isObject$1(context.value) && isSet(schemaUnevaluatedProperties)) {
1577
1577
  let properties2 = isSet(schemaProperties) ? schemaProperties : {};
1578
1578
  const unevaluatedProperties2 = schemaUnevaluatedProperties;
1579
1579
  const patternProperties2 = schemaPatternProperties;
@@ -1612,7 +1612,7 @@ function unevaluatedProperties(context) {
1612
1612
  ]
1613
1613
  });
1614
1614
  }
1615
- if (!definedInPatternProperty && isObject(unevaluatedProperties2) && !hasOwn(properties2, property)) {
1615
+ if (!definedInPatternProperty && isObject$1(unevaluatedProperties2) && !hasOwn(properties2, property)) {
1616
1616
  const unevaluatedPropertiesErrors = context.validator.getErrors(context.value[property], unevaluatedProperties2, property, context.path + "/" + property).map((error) => {
1617
1617
  return {
1618
1618
  type: "error",
@@ -1665,7 +1665,7 @@ const draft201909 = {
1665
1665
  function propertyNames(context) {
1666
1666
  const errors = [];
1667
1667
  const schemaPropertyNames = getSchemaPropertyNames(context.schema);
1668
- if (isObject(context.value) && isSet(schemaPropertyNames)) {
1668
+ if (isObject$1(context.value) && isSet(schemaPropertyNames)) {
1669
1669
  Object.keys(context.value).forEach((propertyName) => {
1670
1670
  const invalid = context.validator.getErrors(propertyName, schemaPropertyNames, propertyName, context.path).length > 0;
1671
1671
  if (invalid) {
@@ -1748,7 +1748,7 @@ class Validator {
1748
1748
  path
1749
1749
  }];
1750
1750
  }
1751
- if (this.refParser && isObject(schema) && hasOwn(schema, "$ref")) {
1751
+ if (this.refParser && isObject$1(schema) && hasOwn(schema, "$ref")) {
1752
1752
  schema = this.refParser.expand(schema);
1753
1753
  }
1754
1754
  const allConstraints = { ...this.draft, ...this.constraints };
@@ -1770,7 +1770,7 @@ class Validator {
1770
1770
  }
1771
1771
  const schemaOptionsMessages = getSchemaXOption(schema, "messages");
1772
1772
  if (isSet(schemaOptionsMessages)) {
1773
- if (isObject(schemaOptionsMessages)) {
1773
+ if (isObject$1(schemaOptionsMessages)) {
1774
1774
  schemaErrors.forEach((schemaError) => {
1775
1775
  var _a, _b;
1776
1776
  const schemaMessageListedByLanguage = (_b = schemaOptionsMessages == null ? void 0 : schemaOptionsMessages[(_a = this.translator) == null ? void 0 : _a.language]) == null ? void 0 : _b[schemaError == null ? void 0 : schemaError.constraint];
@@ -2250,7 +2250,7 @@ class Editor {
2250
2250
  this.control.container.setAttribute("data-path", this.instance.path);
2251
2251
  this.control.container.setAttribute("data-type", getSchemaType(this.instance.schema));
2252
2252
  const schemaContainerAttributes = getSchemaXOption(this.instance.schema, "containerAttributes");
2253
- if (isSet(schemaContainerAttributes) && isObject(schemaContainerAttributes)) {
2253
+ if (isSet(schemaContainerAttributes) && isObject$1(schemaContainerAttributes)) {
2254
2254
  for (const [key, value] of Object.entries(schemaContainerAttributes)) {
2255
2255
  if (key === "class") {
2256
2256
  const classes = value.split(" ");
@@ -2291,7 +2291,7 @@ class Editor {
2291
2291
  }
2292
2292
  const domPurifyOptions = this.instance.jedison.getOption("domPurifyOptions");
2293
2293
  buttons.forEach((config) => {
2294
- if (!isObject(config)) {
2294
+ if (!isObject$1(config)) {
2295
2295
  return;
2296
2296
  }
2297
2297
  const rawLabel = isString(config.label) ? config.label : "";
@@ -2299,7 +2299,7 @@ class Editor {
2299
2299
  const attributes = filterAttributes(config.attributes);
2300
2300
  const button = this.theme.getXButton({ label, attributes });
2301
2301
  this.control.container.appendChild(button);
2302
- const eventName = isObject(config.event) && isString(config.event.name) ? config.event.name : null;
2302
+ const eventName = isObject$1(config.event) && isString(config.event.name) ? config.event.name : null;
2303
2303
  if (!eventName) {
2304
2304
  return;
2305
2305
  }
@@ -2336,7 +2336,7 @@ class Editor {
2336
2336
  const input = this.control.input;
2337
2337
  if (isSet(input)) {
2338
2338
  const inputAttributes = getSchemaXOption(this.instance.schema, "inputAttributes");
2339
- if (isObject(inputAttributes)) {
2339
+ if (isObject$1(inputAttributes)) {
2340
2340
  for (const [key, value] of Object.entries(inputAttributes)) {
2341
2341
  input.setAttribute(key, value);
2342
2342
  }
@@ -2517,6 +2517,20 @@ class Editor {
2517
2517
  }
2518
2518
  return schemaInfo;
2519
2519
  }
2520
+ // Per-path view state on the shared root, so it survives an editor being
2521
+ // rebuilt or replaced (e.g. an if/then/else branch swap).
2522
+ getPersistentState(key, fallback) {
2523
+ const pathState = this.instance.jedison.persistentState[this.instance.path];
2524
+ const value = isSet(pathState) ? pathState[key] : void 0;
2525
+ return isSet(value) ? value : fallback;
2526
+ }
2527
+ setPersistentState(key, value) {
2528
+ const store = this.instance.jedison.persistentState;
2529
+ if (!isSet(store[this.instance.path])) {
2530
+ store[this.instance.path] = {};
2531
+ }
2532
+ store[this.instance.path][key] = value;
2533
+ }
2520
2534
  refreshLegendWarning() {
2521
2535
  }
2522
2536
  /**
@@ -2625,8 +2639,11 @@ class EditorIfThenElse extends Editor {
2625
2639
  }
2626
2640
  refreshUI() {
2627
2641
  this.refreshDisabledState();
2628
- this.control.childrenSlot.innerHTML = "";
2629
- this.control.childrenSlot.appendChild(this.instance.activeInstance.ui.control.container);
2642
+ const activeContainer = this.instance.activeInstance.ui.control.container;
2643
+ if (this.control.childrenSlot.firstChild !== activeContainer) {
2644
+ this.control.childrenSlot.innerHTML = "";
2645
+ this.control.childrenSlot.appendChild(activeContainer);
2646
+ }
2630
2647
  this.control.switcherSlot = this.instance.activeInstance.ui.control.switcherSlot;
2631
2648
  if (this.disabled || this.instance.isReadOnly()) {
2632
2649
  this.instance.activeInstance.ui.disable();
@@ -2701,7 +2718,7 @@ class InstanceIfThenElse extends Instance {
2701
2718
  this.activeInstance.register();
2702
2719
  this.instances.forEach((instance, index2) => {
2703
2720
  instance.off("notifyParent");
2704
- if (instance.children && isObject(value)) {
2721
+ if (instance.children && isObject$1(value)) {
2705
2722
  instance.children.forEach((child) => {
2706
2723
  const shouldUpdateValue = child.isMultiple && hasOwn(value, child.getKey());
2707
2724
  if (shouldUpdateValue) {
@@ -2711,7 +2728,7 @@ class InstanceIfThenElse extends Instance {
2711
2728
  }
2712
2729
  const startingValue = this.instanceStartingValues[index2];
2713
2730
  let instanceValue = value;
2714
- if (isObject(startingValue) && isObject(value)) {
2731
+ if (isObject$1(startingValue) && isObject$1(value)) {
2715
2732
  if (indexChanged && initiator !== "api") {
2716
2733
  instanceValue = overwriteExistingProperties(startingValue, withoutIf);
2717
2734
  } else {
@@ -2743,7 +2760,7 @@ class InstanceIfThenElse extends Instance {
2743
2760
  }
2744
2761
  getWithoutIfValueFromValue(value) {
2745
2762
  let withoutIf = this.instanceWithoutIf.getValue();
2746
- if (isObject(withoutIf) && isObject(value)) {
2763
+ if (isObject$1(withoutIf) && isObject$1(value)) {
2747
2764
  withoutIf = overwriteExistingProperties(withoutIf, value);
2748
2765
  return withoutIf;
2749
2766
  }
@@ -2964,7 +2981,7 @@ class InstanceMultiple extends Instance {
2964
2981
  */
2965
2982
  getFittestIndex(value) {
2966
2983
  const discriminator = getSchemaXOption(this.schema, "discriminator");
2967
- if (isSet(discriminator) && isObject(value)) {
2984
+ if (isSet(discriminator) && isObject$1(value)) {
2968
2985
  const propName = isString(discriminator) ? discriminator : discriminator.propertyName;
2969
2986
  const discriminatorValue = value[propName];
2970
2987
  if (isSet(discriminatorValue)) {
@@ -3222,7 +3239,7 @@ class InstanceObject extends Instance {
3222
3239
  const wasRefreshing = this.refreshingInstances;
3223
3240
  this.refreshingInstances = true;
3224
3241
  const value = this.getValue();
3225
- if (!isObject(value)) {
3242
+ if (!isObject$1(value)) {
3226
3243
  this.refreshingInstances = wasRefreshing;
3227
3244
  return;
3228
3245
  }
@@ -3264,7 +3281,7 @@ class InstanceObject extends Instance {
3264
3281
  class InstanceArray extends Instance {
3265
3282
  prepare() {
3266
3283
  this.schemaItems = getSchemaItems(this.schema);
3267
- if (isObject(this.schemaItems) && this.jedison.refParser && this.jedison.refParser.hasRef(this.schemaItems) && !this.schemaItems["x-recursive"]) {
3284
+ if (isObject$1(this.schemaItems) && this.jedison.refParser && this.jedison.refParser.hasRef(this.schemaItems) && !this.schemaItems["x-recursive"]) {
3268
3285
  this.schemaItems = this.jedison.refParser.expand(this.schemaItems);
3269
3286
  this.schema.items = this.schemaItems;
3270
3287
  }
@@ -3637,7 +3654,7 @@ class EditorStringRadios extends EditorString {
3637
3654
  getEnumSourceValues() {
3638
3655
  if (this.enumSourceValues !== void 0) {
3639
3656
  if (isArray(this.enumSourceValues)) return this.enumSourceValues;
3640
- if (isObject(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
3657
+ if (isObject$1(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
3641
3658
  return [];
3642
3659
  }
3643
3660
  return getSchemaEnum(this.instance.schema) || [];
@@ -3750,7 +3767,7 @@ class EditorStringSelect extends EditorString {
3750
3767
  getEnumSourceValues() {
3751
3768
  if (this.enumSourceValues !== void 0) {
3752
3769
  if (isArray(this.enumSourceValues)) return this.enumSourceValues;
3753
- if (isObject(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
3770
+ if (isObject$1(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
3754
3771
  return [];
3755
3772
  }
3756
3773
  return getSchemaEnum(this.instance.schema) || [];
@@ -4078,7 +4095,7 @@ class EditorNumberSelect extends EditorNumber {
4078
4095
  getEnumSourceValues() {
4079
4096
  if (this.enumSourceValues !== void 0) {
4080
4097
  if (isArray(this.enumSourceValues)) return this.enumSourceValues;
4081
- if (isObject(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
4098
+ if (isObject$1(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
4082
4099
  return [];
4083
4100
  }
4084
4101
  return getSchemaEnum(this.instance.schema) || [];
@@ -4330,7 +4347,7 @@ class EditorObject extends Editor {
4330
4347
  });
4331
4348
  }
4332
4349
  sanitize(value) {
4333
- if (isObject(value)) {
4350
+ if (isObject$1(value)) {
4334
4351
  return value;
4335
4352
  }
4336
4353
  return {};
@@ -4525,7 +4542,7 @@ class EditorObjectGrid extends EditorObject {
4525
4542
  class EditorObjectCategories extends EditorObject {
4526
4543
  static resolves(schema) {
4527
4544
  const format2 = getSchemaXOption(schema, "format");
4528
- const regex = /^categories-(horizontal|vertical(?:-\d+)?)$/;
4545
+ const regex = /^categories-(horizontal|vertical)$/;
4529
4546
  return getSchemaType(schema) === "object" && regex.test(format2);
4530
4547
  }
4531
4548
  init() {
@@ -4564,11 +4581,9 @@ class EditorObjectCategories extends EditorObject {
4564
4581
  const format2 = getSchemaXOption(this.instance.schema, "format");
4565
4582
  const formatParts = format2.split("-");
4566
4583
  const variant = formatParts[1];
4567
- const columns = formatParts[2];
4568
- const navColumns = variant === "horizontal" ? 12 : columns ?? 4;
4569
- const row = this.theme.getRow();
4570
- const tabListCol = this.theme.getCol(12, 12, navColumns, navColumns);
4571
- const tabContentCol = this.theme.getCol(12, 12, 12 - navColumns, 12 - navColumns);
4584
+ const navMinWidth = getSchemaXOption(this.instance.schema, "navMinWidth");
4585
+ const navMaxWidth = getSchemaXOption(this.instance.schema, "navMaxWidth");
4586
+ const { row, tabListCol, tabContentCol } = this.theme.getNavRow(variant, { minWidth: navMinWidth, maxWidth: navMaxWidth });
4572
4587
  const tabContent = this.theme.getTabContent();
4573
4588
  const tabList = this.theme.getTabList({
4574
4589
  variant
@@ -4647,7 +4662,7 @@ class EditorObjectCategories extends EditorObject {
4647
4662
  class EditorObjectNav extends EditorObject {
4648
4663
  static resolves(schema) {
4649
4664
  const format2 = getSchemaXOption(schema, "format");
4650
- const regex = /^nav-(horizontal|vertical(?:-\d+)?)$/;
4665
+ const regex = /^nav-(horizontal|vertical)$/;
4651
4666
  const hasNavFormat = regex.test(format2);
4652
4667
  return getSchemaType(schema) === "object" && hasNavFormat;
4653
4668
  }
@@ -4657,6 +4672,12 @@ class EditorObjectNav extends EditorObject {
4657
4672
  init() {
4658
4673
  super.init();
4659
4674
  this.activeTabIndex = 0;
4675
+ this.navTabs = /* @__PURE__ */ new Map();
4676
+ }
4677
+ // Persisted so the tab survives an if/then/else branch swap (issue #65).
4678
+ setActiveTabIndex(index2) {
4679
+ this.activeTabIndex = index2;
4680
+ this.setPersistentState("activeTab", index2);
4660
4681
  }
4661
4682
  isChildVisible(child) {
4662
4683
  if (!child.isActive) return false;
@@ -4671,7 +4692,7 @@ class EditorObjectNav extends EditorObject {
4671
4692
  }
4672
4693
  ensureActiveTabIsVisible(visibleIndices) {
4673
4694
  if (!visibleIndices.includes(this.activeTabIndex)) {
4674
- this.activeTabIndex = visibleIndices[0] ?? 0;
4695
+ this.setActiveTabIndex(visibleIndices[0] ?? 0);
4675
4696
  }
4676
4697
  }
4677
4698
  navigateTo(path) {
@@ -4679,61 +4700,98 @@ class EditorObjectNav extends EditorObject {
4679
4700
  if (nextChildPath) {
4680
4701
  const childIndex = this.instance.children.findIndex((c) => c.path === nextChildPath);
4681
4702
  if (childIndex !== -1) {
4682
- this.activeTabIndex = childIndex;
4703
+ this.setActiveTabIndex(childIndex);
4683
4704
  this.refreshUI();
4684
4705
  }
4685
4706
  }
4686
4707
  super.navigateTo(path);
4687
4708
  }
4688
- refreshEditors() {
4689
- while (this.control.childrenSlot.firstChild) {
4690
- this.control.childrenSlot.removeChild(this.control.childrenSlot.lastChild);
4691
- }
4709
+ buildNavShell() {
4692
4710
  const format2 = getSchemaXOption(this.instance.schema, "format");
4693
4711
  const formatParts = format2.split("-");
4694
4712
  const variant = formatParts[1];
4695
- const columns = formatParts[2];
4696
- const navColumns = variant === "horizontal" ? 12 : columns ?? 4;
4697
- const row = this.theme.getRow();
4698
- const tabListCol = this.theme.getCol(12, 12, navColumns, navColumns);
4699
- const tabContentCol = this.theme.getCol(12, 12, 12 - navColumns, 12 - navColumns);
4700
- const tabContent = this.theme.getTabContent();
4701
- const tabList = this.theme.getTabList({
4702
- variant
4703
- });
4704
- this.control.childrenSlot.appendChild(row);
4713
+ const navMinWidth = getSchemaXOption(this.instance.schema, "navMinWidth");
4714
+ const navMaxWidth = getSchemaXOption(this.instance.schema, "navMaxWidth");
4715
+ const { row, tabListCol, tabContentCol } = this.theme.getNavRow(variant, { minWidth: navMinWidth, maxWidth: navMaxWidth });
4716
+ this.navTabContent = this.theme.getTabContent();
4717
+ this.navTabList = this.theme.getTabList({ variant });
4705
4718
  row.appendChild(tabListCol);
4706
4719
  row.appendChild(tabContentCol);
4707
- tabListCol.appendChild(tabList);
4708
- tabContentCol.appendChild(tabContent);
4720
+ tabListCol.appendChild(this.navTabList);
4721
+ tabContentCol.appendChild(this.navTabContent);
4722
+ this.control.childrenSlot.appendChild(row);
4723
+ }
4724
+ createTab(child) {
4725
+ const tab = this.theme.getTab({
4726
+ title: this.getChildTitle(child),
4727
+ id: this.getIdFromPath(child.path)
4728
+ });
4729
+ tab.list.addEventListener("click", () => {
4730
+ this.setActiveTabIndex(this.instance.children.indexOf(child));
4731
+ });
4732
+ return tab;
4733
+ }
4734
+ getChildTitle(child) {
4735
+ const schemaTitle = getSchemaTitle(child.schema);
4736
+ return isSet(schemaTitle) ? schemaTitle : child.getKey();
4737
+ }
4738
+ updateTab(tab, child, active) {
4739
+ tab.list.classList.toggle("active", active);
4740
+ tab.link.classList.toggle("active", active);
4741
+ tab.text.textContent = this.getChildTitle(child);
4742
+ const navWarning = getSchemaXOption(this.instance.schema, "navWarning") ?? true;
4743
+ const navWarningMessage = getSchemaXOption(this.instance.schema, "navWarningMessage");
4744
+ const hasErrors = navWarning && child.hasNestedValidationErrors();
4745
+ const existing = tab.link.querySelector(".jedi-nav-warning");
4746
+ if (existing) existing.parentNode.removeChild(existing);
4747
+ if (hasErrors) {
4748
+ const warning = document.createElement("span");
4749
+ warning.classList.add("jedi-nav-warning");
4750
+ warning.textContent = "⚠ ";
4751
+ tab.link.appendChild(warning);
4752
+ if (navWarningMessage) tab.list.setAttribute("title", navWarningMessage);
4753
+ } else {
4754
+ tab.list.removeAttribute("title");
4755
+ }
4756
+ }
4757
+ refreshEditors() {
4758
+ this.activeTabIndex = this.getPersistentState("activeTab", this.activeTabIndex);
4759
+ if (!this.navTabContent) this.buildNavShell();
4709
4760
  const visibleIndices = this.getVisibleChildIndices();
4710
4761
  this.ensureActiveTabIsVisible(visibleIndices);
4762
+ const currentPaths = new Set(this.instance.children.map((child) => child.path));
4711
4763
  this.instance.children.forEach((child, index2) => {
4712
- if (!this.isChildVisible(child)) return;
4764
+ let tab = this.navTabs.get(child.path);
4765
+ if (!this.isChildVisible(child)) {
4766
+ if (tab && tab.list.parentNode) tab.list.parentNode.removeChild(tab.list);
4767
+ if (child.ui.control.container.parentNode === this.navTabContent) {
4768
+ this.navTabContent.removeChild(child.ui.control.container);
4769
+ }
4770
+ return;
4771
+ }
4772
+ if (!tab) {
4773
+ tab = this.createTab(child);
4774
+ this.navTabs.set(child.path, tab);
4775
+ }
4713
4776
  const active = index2 === this.activeTabIndex;
4714
- const id = this.getIdFromPath(child.path);
4715
- const schemaTitle = getSchemaTitle(child.schema);
4716
- const navWarning = getSchemaXOption(this.instance.schema, "navWarning") ?? true;
4717
- const navWarningMessage = getSchemaXOption(this.instance.schema, "navWarningMessage");
4718
- const tab = this.theme.getTab({
4719
- hasErrors: navWarning && child.hasNestedValidationErrors(),
4720
- navWarningMessage,
4721
- title: isSet(schemaTitle) ? schemaTitle : child.getKey(),
4722
- id,
4723
- active
4724
- });
4725
- tab.list.addEventListener("click", () => {
4726
- this.activeTabIndex = index2;
4727
- });
4728
- this.theme.setTabPaneAttributes(child.ui.control.container, active, id);
4729
- tabList.appendChild(tab.list);
4730
- tabContent.appendChild(child.ui.control.container);
4777
+ this.updateTab(tab, child, active);
4778
+ this.theme.setTabPaneAttributes(child.ui.control.container, active, this.getIdFromPath(child.path));
4779
+ if (tab.list.parentNode !== this.navTabList) this.navTabList.appendChild(tab.list);
4780
+ if (child.ui.control.container.parentNode !== this.navTabContent) {
4781
+ this.navTabContent.appendChild(child.ui.control.container);
4782
+ }
4731
4783
  if (this.disabled || this.instance.isReadOnly()) {
4732
4784
  child.ui.disable();
4733
4785
  } else {
4734
4786
  child.ui.enable();
4735
4787
  }
4736
4788
  });
4789
+ this.navTabs.forEach((tab, path) => {
4790
+ if (!currentPaths.has(path)) {
4791
+ if (tab.list.parentNode) tab.list.parentNode.removeChild(tab.list);
4792
+ this.navTabs.delete(path);
4793
+ }
4794
+ });
4737
4795
  }
4738
4796
  }
4739
4797
  class EditorObjectAccordion extends EditorObject {
@@ -4872,6 +4930,11 @@ class EditorArray extends Editor {
4872
4930
  super.init();
4873
4931
  this.activeItemIndex = 0;
4874
4932
  }
4933
+ // Persisted so EditorArrayNav's item survives an if/then/else swap (issue #65).
4934
+ setActiveItemIndex(index2) {
4935
+ this.activeItemIndex = index2;
4936
+ this.setPersistentState("activeItem", index2);
4937
+ }
4875
4938
  build() {
4876
4939
  this.control = this.theme.getArrayControl({
4877
4940
  title: this.getTitle(),
@@ -4987,7 +5050,7 @@ class EditorArray extends Editor {
4987
5050
  const globalConfirm = this.instance.jedison.getOption("arrayDeleteConfirm");
4988
5051
  const shouldConfirm = isSet(schemaConfirm) ? schemaConfirm : globalConfirm;
4989
5052
  const doDelete = () => {
4990
- this.activeItemIndex = clamp(index2 - 1, 0, this.instance.value.length - 1);
5053
+ this.setActiveItemIndex(clamp(index2 - 1, 0, this.instance.value.length - 1));
4991
5054
  this.instance.deleteItem(index2, "user");
4992
5055
  };
4993
5056
  if (shouldConfirm) {
@@ -5000,16 +5063,16 @@ class EditorArray extends Editor {
5000
5063
  });
5001
5064
  moveUpBtn.addEventListener("click", () => {
5002
5065
  const toIndex = index2 - 1;
5003
- this.activeItemIndex = toIndex;
5066
+ this.setActiveItemIndex(toIndex);
5004
5067
  this.instance.move(index2, toIndex, "user");
5005
5068
  });
5006
5069
  moveDownBtn.addEventListener("click", () => {
5007
5070
  const toIndex = index2 + 1;
5008
- this.activeItemIndex = toIndex;
5071
+ this.setActiveItemIndex(toIndex);
5009
5072
  this.instance.move(index2, toIndex, "user");
5010
5073
  });
5011
5074
  addAfterBtn.addEventListener("click", () => {
5012
- this.activeItemIndex = index2 + 1;
5075
+ this.setActiveItemIndex(index2 + 1);
5013
5076
  this.instance.addItemAfter(index2, "user");
5014
5077
  });
5015
5078
  if (index2 === 0) {
@@ -5524,7 +5587,7 @@ class EditorArrayChoices extends Editor {
5524
5587
  getEnumSourceValues() {
5525
5588
  if (this.enumSourceValues !== void 0) {
5526
5589
  if (isArray(this.enumSourceValues)) return this.enumSourceValues;
5527
- if (isObject(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
5590
+ if (isObject$1(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
5528
5591
  return [];
5529
5592
  }
5530
5593
  return this.instance.schema.items && this.instance.schema.items.enum || [];
@@ -5612,7 +5675,7 @@ class EditorArrayChoices extends Editor {
5612
5675
  class EditorArrayNav extends EditorArray {
5613
5676
  static resolves(schema) {
5614
5677
  const format2 = getSchemaXOption(schema, "format");
5615
- const regex = /^nav-(horizontal|vertical(?:-\d+)?)$/;
5678
+ const regex = /^nav-(horizontal|vertical)$/;
5616
5679
  const hasNavFormat = regex.test(format2);
5617
5680
  return getSchemaType(schema) === "array" && hasNavFormat;
5618
5681
  }
@@ -5624,7 +5687,7 @@ class EditorArrayNav extends EditorArray {
5624
5687
  if (nextChildPath) {
5625
5688
  const childIndex = this.instance.children.findIndex((c) => c.path === nextChildPath);
5626
5689
  if (childIndex !== -1) {
5627
- this.activeItemIndex = childIndex;
5690
+ this.setActiveItemIndex(childIndex);
5628
5691
  this.refreshUI();
5629
5692
  }
5630
5693
  }
@@ -5632,38 +5695,41 @@ class EditorArrayNav extends EditorArray {
5632
5695
  }
5633
5696
  addEventListeners() {
5634
5697
  this.control.addBtn.addEventListener("click", () => {
5635
- this.activeItemIndex = this.instance.value.length;
5698
+ this.setActiveItemIndex(this.instance.value.length);
5636
5699
  this.instance.addItem("user");
5637
5700
  });
5638
5701
  this.control.footerAddBtn.addEventListener("click", () => {
5639
- this.activeItemIndex = this.instance.value.length;
5702
+ this.setActiveItemIndex(this.instance.value.length);
5640
5703
  this.instance.addItem("user");
5641
5704
  });
5642
5705
  if (this.control.deleteAllBtn) {
5643
5706
  this.control.deleteAllBtn.addEventListener("click", () => {
5644
- this.activeItemIndex = 0;
5707
+ this.setActiveItemIndex(0);
5645
5708
  this.deleteAllItems();
5646
5709
  });
5647
5710
  }
5648
5711
  if (this.control.footerDeleteAllBtn) {
5649
5712
  this.control.footerDeleteAllBtn.addEventListener("click", () => {
5650
- this.activeItemIndex = 0;
5713
+ this.setActiveItemIndex(0);
5651
5714
  this.deleteAllItems();
5652
5715
  });
5653
5716
  }
5654
5717
  this.addJsonDataEventListeners();
5655
5718
  }
5656
5719
  refreshUI() {
5720
+ this.activeItemIndex = this.getPersistentState("activeItem", this.activeItemIndex);
5721
+ const lastIndex = this.instance.children.length - 1;
5722
+ if (this.activeItemIndex > lastIndex) {
5723
+ this.setActiveItemIndex(lastIndex < 0 ? 0 : lastIndex);
5724
+ }
5657
5725
  this.control.childrenSlot.innerHTML = "";
5658
5726
  this.clearStoredEventListeners();
5659
5727
  const format2 = getSchemaXOption(this.instance.schema, "format");
5660
5728
  const formatParts = format2.split("-");
5661
5729
  const variant = formatParts[1];
5662
- const columns = formatParts[2];
5663
- const navColumns = variant === "horizontal" ? 12 : columns ?? 4;
5664
- const row = this.theme.getRow();
5665
- const tabListCol = this.theme.getCol(12, 12, navColumns, navColumns);
5666
- const tabContentCol = this.theme.getCol(12, 12, 12 - navColumns, 12 - navColumns);
5730
+ const navMinWidth = getSchemaXOption(this.instance.schema, "navMinWidth");
5731
+ const navMaxWidth = getSchemaXOption(this.instance.schema, "navMaxWidth");
5732
+ const { row, tabListCol, tabContentCol } = this.theme.getNavRow(variant, { minWidth: navMinWidth, maxWidth: navMaxWidth });
5667
5733
  const tabContent = this.theme.getTabContent();
5668
5734
  const tabList = this.theme.getTabList({
5669
5735
  variant
@@ -5714,7 +5780,7 @@ class EditorArrayNav extends EditorArray {
5714
5780
  });
5715
5781
  arrayActions.appendChild(btnGroup);
5716
5782
  const clickHandler = () => {
5717
- this.activeItemIndex = index2;
5783
+ this.setActiveItemIndex(index2);
5718
5784
  };
5719
5785
  list.addEventListener("click", clickHandler);
5720
5786
  this.storedEventListeners.push({
@@ -5757,7 +5823,7 @@ class EditorArrayNav extends EditorArray {
5757
5823
  handle: ".jedi-array-drag",
5758
5824
  disabled: this.disabled || this.readOnly,
5759
5825
  onEnd: (evt) => {
5760
- this.activeItemIndex = evt.newIndex;
5826
+ this.setActiveItemIndex(evt.newIndex);
5761
5827
  this.instance.move(evt.oldIndex, evt.newIndex);
5762
5828
  }
5763
5829
  });
@@ -5841,8 +5907,11 @@ class EditorMultiple extends Editor {
5841
5907
  }
5842
5908
  refreshUI() {
5843
5909
  this.refreshDisabledState();
5844
- this.control.childrenSlot.innerHTML = "";
5845
- this.control.childrenSlot.appendChild(this.instance.activeInstance.ui.control.container);
5910
+ const activeContainer = this.instance.activeInstance.ui.control.container;
5911
+ if (this.control.childrenSlot.firstChild !== activeContainer) {
5912
+ this.control.childrenSlot.innerHTML = "";
5913
+ this.control.childrenSlot.appendChild(activeContainer);
5914
+ }
5846
5915
  const slot = this.instance.activeInstance.ui.control.switcherSlot;
5847
5916
  this.control.switcherSlot = slot;
5848
5917
  if (this.embedSwitcher || this.switcherInput === "modal" || this.switcherInput === "select-inline") {
@@ -6416,7 +6485,7 @@ class EditorArrayCheckboxes extends Editor {
6416
6485
  getEnumSourceValues() {
6417
6486
  if (this.enumSourceValues !== void 0) {
6418
6487
  if (isArray(this.enumSourceValues)) return this.enumSourceValues;
6419
- if (isObject(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
6488
+ if (isObject$1(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
6420
6489
  return [];
6421
6490
  }
6422
6491
  return getSchemaEnum(this.instance.schema.items) || [];
@@ -7201,6 +7270,7 @@ class Jedison extends EventEmitter {
7201
7270
  this.pathSeparator = "/";
7202
7271
  this.instances = /* @__PURE__ */ new Map();
7203
7272
  this.root = null;
7273
+ this.persistentState = {};
7204
7274
  this.translator = new Translator({
7205
7275
  language: this.options.language,
7206
7276
  translations: this.options.translations
@@ -7366,7 +7436,7 @@ class Jedison extends EventEmitter {
7366
7436
  this.hiddenInput.setAttribute("name", "json");
7367
7437
  this.hiddenInput.removeAttribute("aria-describedby");
7368
7438
  this.hiddenInput.removeAttribute("aria-hidden", "true");
7369
- if (this.options.hiddenInputAttributes && isObject(this.options.hiddenInputAttributes)) {
7439
+ if (this.options.hiddenInputAttributes && isObject$1(this.options.hiddenInputAttributes)) {
7370
7440
  Object.keys(this.options.hiddenInputAttributes).forEach((attr) => {
7371
7441
  this.hiddenInput.setAttribute(attr, this.options.hiddenInputAttributes[attr]);
7372
7442
  });
@@ -7469,7 +7539,7 @@ class Jedison extends EventEmitter {
7469
7539
  }
7470
7540
  });
7471
7541
  this.walker.traverse(config.schema, (node) => {
7472
- if (node.not && isObject(node.not)) {
7542
+ if (node.not && isObject$1(node.not)) {
7473
7543
  const nodeClone = clone(node);
7474
7544
  delete nodeClone.not;
7475
7545
  node.not = combineDeep({}, nodeClone, node.not);
@@ -8391,7 +8461,7 @@ class Theme {
8391
8461
  label.classList.add("jedi-x-button-label");
8392
8462
  label.innerHTML = config.label ?? "";
8393
8463
  button.appendChild(label);
8394
- const attributes = isObject(config.attributes) ? config.attributes : {};
8464
+ const attributes = isObject$1(config.attributes) ? config.attributes : {};
8395
8465
  for (const [key, value] of Object.entries(attributes)) {
8396
8466
  if (key === "class") {
8397
8467
  String(value).split(" ").forEach((cls) => {
@@ -8511,7 +8581,7 @@ class Theme {
8511
8581
  container.style.display = "inline-block";
8512
8582
  info.setAttribute("href", "#");
8513
8583
  info.classList.add("jedi-info-button");
8514
- if (isObject(config.attributes)) {
8584
+ if (isObject$1(config.attributes)) {
8515
8585
  for (const [key, value] of Object.entries(config.attributes)) {
8516
8586
  info.setAttribute(key, value);
8517
8587
  }
@@ -8605,7 +8675,7 @@ class Theme {
8605
8675
  this.infoAsModal(info, config.id, config.info);
8606
8676
  }
8607
8677
  container.appendChild(label);
8608
- if (isObject(config.info)) {
8678
+ if (isObject$1(config.info)) {
8609
8679
  container.appendChild(info.container);
8610
8680
  }
8611
8681
  container.appendChild(switcherSlot);
@@ -8699,7 +8769,7 @@ class Theme {
8699
8769
  container.appendChild(jsonData.dialog);
8700
8770
  }
8701
8771
  fieldset.appendChild(legend);
8702
- if (isObject(config.info)) {
8772
+ if (isObject$1(config.info)) {
8703
8773
  while (info.container.firstChild) {
8704
8774
  infoContainer.appendChild(info.container.firstChild);
8705
8775
  }
@@ -9024,7 +9094,7 @@ class Theme {
9024
9094
  container.appendChild(jsonData.dialog);
9025
9095
  }
9026
9096
  fieldset.appendChild(legend);
9027
- if (isObject(config.info)) {
9097
+ if (isObject$1(config.info)) {
9028
9098
  while (info.container.firstChild) {
9029
9099
  infoContainer.appendChild(info.container.firstChild);
9030
9100
  }
@@ -9236,7 +9306,7 @@ class Theme {
9236
9306
  this.infoAsModal(info, config.id, config.info);
9237
9307
  }
9238
9308
  container.appendChild(label);
9239
- if (isObject(config.info)) {
9309
+ if (isObject$1(config.info)) {
9240
9310
  container.appendChild(info.container);
9241
9311
  }
9242
9312
  container.appendChild(switcherSlot);
@@ -9280,7 +9350,7 @@ class Theme {
9280
9350
  this.infoAsModal(info, config.id, config.info);
9281
9351
  }
9282
9352
  container.appendChild(label);
9283
- if (isObject(config.info)) {
9353
+ if (isObject$1(config.info)) {
9284
9354
  container.appendChild(info.container);
9285
9355
  }
9286
9356
  container.appendChild(switcherSlot);
@@ -9330,7 +9400,7 @@ class Theme {
9330
9400
  if (((_a = config == null ? void 0 : config.info) == null ? void 0 : _a.variant) === "modal") {
9331
9401
  this.infoAsModal(info, config.id, config.info);
9332
9402
  }
9333
- if (isObject(config.info)) {
9403
+ if (isObject$1(config.info)) {
9334
9404
  container.appendChild(info.container);
9335
9405
  }
9336
9406
  container.appendChild(switcherSlot);
@@ -9412,7 +9482,7 @@ class Theme {
9412
9482
  container.appendChild(fieldset);
9413
9483
  fieldset.appendChild(legend);
9414
9484
  legend.appendChild(switcherSlot);
9415
- if (isObject(config.info)) {
9485
+ if (isObject$1(config.info)) {
9416
9486
  legendText.after(info.container);
9417
9487
  }
9418
9488
  radioControls.forEach((radioControl, index2) => {
@@ -9480,7 +9550,7 @@ class Theme {
9480
9550
  container.appendChild(actions);
9481
9551
  formGroup.appendChild(input);
9482
9552
  formGroup.appendChild(label);
9483
- if (isObject(config.info)) {
9553
+ if (isObject$1(config.info)) {
9484
9554
  formGroup.appendChild(info.container);
9485
9555
  }
9486
9556
  formGroup.appendChild(switcherSlot);
@@ -9547,7 +9617,7 @@ class Theme {
9547
9617
  container.appendChild(fieldset);
9548
9618
  fieldset.appendChild(legend);
9549
9619
  legend.appendChild(switcherSlot);
9550
- if (isObject(config.info)) {
9620
+ if (isObject$1(config.info)) {
9551
9621
  legendText.after(info.container);
9552
9622
  }
9553
9623
  checkboxControls.forEach((checkboxControl, index2) => {
@@ -9617,7 +9687,7 @@ class Theme {
9617
9687
  this.infoAsModal(info, config.id, config.info);
9618
9688
  }
9619
9689
  container.appendChild(label);
9620
- if (isObject(config.info)) {
9690
+ if (isObject$1(config.info)) {
9621
9691
  container.appendChild(info.container);
9622
9692
  }
9623
9693
  container.appendChild(switcherSlot);
@@ -9787,6 +9857,62 @@ class Theme {
9787
9857
  }
9788
9858
  return col;
9789
9859
  }
9860
+ /**
9861
+ * Row + two columns for nav-style editors (object-nav, array-nav,
9862
+ * object-categories). Horizontal keeps the fixed full-width split (the
9863
+ * zero-width content col intentionally forces it onto a new flex line
9864
+ * below the full-width tab list) built on the regular getRow()/getCol()
9865
+ * grid. Vertical uses a plain (non-grid) flex row instead: Bootstrap's
9866
+ * `.row > *` rule forces `width: 100%` on grid columns, which would
9867
+ * fight flex-basis:auto's content-based sizing, so the shrink-to-fit nav
9868
+ * column can't share that grid. It hugs its widest pill on wider
9869
+ * containers (constrained by widthOptions.minWidth/maxWidth) and stacks
9870
+ * full-width below the container-query breakpoint in ensureNavStyles().
9871
+ */
9872
+ getNavRow(variant, widthOptions = {}) {
9873
+ if (variant === "horizontal") {
9874
+ const row2 = this.getRow();
9875
+ const tabListCol2 = this.getCol(12, 12, 12, 12);
9876
+ const tabContentCol2 = this.getCol(12, 12, 0, 0);
9877
+ return { row: row2, tabListCol: tabListCol2, tabContentCol: tabContentCol2 };
9878
+ }
9879
+ this.ensureNavStyles();
9880
+ const row = document.createElement("div");
9881
+ row.classList.add("jedi-nav-row");
9882
+ const tabListCol = document.createElement("div");
9883
+ tabListCol.classList.add("jedi-col");
9884
+ tabListCol.classList.add("jedi-nav-list-col");
9885
+ tabListCol.style.setProperty("--jedi-nav-max-width", widthOptions.maxWidth ?? "40%");
9886
+ if (widthOptions.minWidth) tabListCol.style.setProperty("--jedi-nav-min-width", widthOptions.minWidth);
9887
+ const tabContentCol = document.createElement("div");
9888
+ tabContentCol.classList.add("jedi-col");
9889
+ tabContentCol.classList.add("jedi-nav-content-col");
9890
+ return { row, tabListCol, tabContentCol };
9891
+ }
9892
+ /**
9893
+ * Mobile-first: the nav row stacks at 100% width by default; a container
9894
+ * query (not a viewport media query) switches to shrink-to-fit once the
9895
+ * row itself has >= 576px to work with, so a narrow embed (a modal, a
9896
+ * sidebar) gets the same treatment as a narrow viewport regardless of
9897
+ * how wide the page around it is. Injected once, same pattern as
9898
+ * bootstrap5.js's jedi-accordion-button-style, since inline styles can't
9899
+ * express @container.
9900
+ */
9901
+ ensureNavStyles() {
9902
+ if (document.getElementById("jedi-nav-styles")) return;
9903
+ const style = document.createElement("style");
9904
+ style.id = "jedi-nav-styles";
9905
+ style.textContent = `
9906
+ .jedi-nav-row { display: flex; flex-wrap: wrap; gap: 1rem; container-type: inline-size; }
9907
+ .jedi-nav-list-col { flex: 1 1 100%; width: 100%; max-width: 100%; }
9908
+ .jedi-nav-content-col { flex: 1 1 100%; width: 100%; min-width: 0; }
9909
+ @container (min-width: 576px) {
9910
+ .jedi-nav-list-col { flex: 0 1 auto; width: auto; max-width: var(--jedi-nav-max-width, 40%); min-width: var(--jedi-nav-min-width, auto); }
9911
+ .jedi-nav-content-col { flex: 1 1 0%; width: auto; }
9912
+ }
9913
+ `;
9914
+ document.head.appendChild(style);
9915
+ }
9790
9916
  /**
9791
9917
  * Clearfix fixes layout issues in some libraries like bootstrap 3
9792
9918
  */
@@ -10799,7 +10925,7 @@ class ThemeBootstrap4 extends Theme {
10799
10925
  container.appendChild(formGroup);
10800
10926
  formGroup.appendChild(input);
10801
10927
  formGroup.appendChild(label);
10802
- if (isObject(config.info)) {
10928
+ if (isObject$1(config.info)) {
10803
10929
  label.appendChild(info.container);
10804
10930
  }
10805
10931
  container.appendChild(description);
@@ -11355,7 +11481,7 @@ class ThemeBootstrap5 extends Theme {
11355
11481
  container.appendChild(formGroup);
11356
11482
  formGroup.appendChild(input);
11357
11483
  formGroup.appendChild(label);
11358
- if (isObject(config.info)) {
11484
+ if (isObject$1(config.info)) {
11359
11485
  label.appendChild(info.container);
11360
11486
  }
11361
11487
  container.appendChild(description);
@@ -11549,6 +11675,225 @@ class ThemeBootstrap5 extends Theme {
11549
11675
  element.classList.remove("visually-hidden");
11550
11676
  }
11551
11677
  }
11678
+ function isObject(value) {
11679
+ return value !== null && typeof value === "object" && !Array.isArray(value);
11680
+ }
11681
+ function isContainer(value) {
11682
+ return value !== null && typeof value === "object";
11683
+ }
11684
+ function unsupported(path, detail) {
11685
+ throw new Error(`Jedison: unsupported JSONPath "${path}" — ${detail}. Supported: $, .name, ['name'], [n], *, and .. (no filters, slices, or functions).`);
11686
+ }
11687
+ function splitUnion(content) {
11688
+ const parts = [];
11689
+ let current = "";
11690
+ let quote = null;
11691
+ for (let i = 0; i < content.length; i++) {
11692
+ const char = content[i];
11693
+ if (quote) {
11694
+ if (char === quote) quote = null;
11695
+ current += char;
11696
+ } else if (char === "'" || char === '"') {
11697
+ quote = char;
11698
+ current += char;
11699
+ } else if (char === ",") {
11700
+ parts.push(current);
11701
+ current = "";
11702
+ } else {
11703
+ current += char;
11704
+ }
11705
+ }
11706
+ parts.push(current);
11707
+ return parts;
11708
+ }
11709
+ function parseBracket(content, path) {
11710
+ const trimmed = content.trim();
11711
+ if (trimmed === "*") {
11712
+ return [{ type: "wildcard" }];
11713
+ }
11714
+ if (trimmed.includes("?")) unsupported(path, "filter expressions are not supported");
11715
+ if (trimmed.includes("(")) unsupported(path, "function extensions are not supported");
11716
+ return splitUnion(trimmed).map((raw) => {
11717
+ const part = raw.trim();
11718
+ if (part.startsWith("'") && part.endsWith("'") || part.startsWith('"') && part.endsWith('"')) {
11719
+ return { type: "name", value: part.slice(1, -1) };
11720
+ }
11721
+ if (/^-?\d+$/.test(part)) {
11722
+ return { type: "index", value: parseInt(part, 10) };
11723
+ }
11724
+ if (part.includes(":")) unsupported(path, "array slices are not supported");
11725
+ unsupported(path, `cannot parse selector "${part}"`);
11726
+ });
11727
+ }
11728
+ function tokenize(path) {
11729
+ if (typeof path !== "string" || path[0] !== "$") {
11730
+ unsupported(path, 'must start with "$"');
11731
+ }
11732
+ const steps = [];
11733
+ let i = 1;
11734
+ const readName = () => {
11735
+ const start = i;
11736
+ while (i < path.length && path[i] !== "." && path[i] !== "[") i++;
11737
+ const name = path.slice(start, i);
11738
+ if (name === "") unsupported(path, 'empty name after "."');
11739
+ if (name.includes("(")) unsupported(path, "function extensions are not supported");
11740
+ return name;
11741
+ };
11742
+ const readDotSelector = (descendant) => {
11743
+ if (path[i] === "*") {
11744
+ i++;
11745
+ steps.push({ descendant, selectors: [{ type: "wildcard" }] });
11746
+ } else {
11747
+ steps.push({ descendant, selectors: [{ type: "name", value: readName() }] });
11748
+ }
11749
+ };
11750
+ const readBracket = (descendant) => {
11751
+ i++;
11752
+ let content = "";
11753
+ let quote = null;
11754
+ while (i < path.length && (quote || path[i] !== "]")) {
11755
+ const char = path[i];
11756
+ if (quote) {
11757
+ if (char === quote) quote = null;
11758
+ } else if (char === "'" || char === '"') {
11759
+ quote = char;
11760
+ }
11761
+ content += char;
11762
+ i++;
11763
+ }
11764
+ if (path[i] !== "]") unsupported(path, 'unterminated "["');
11765
+ i++;
11766
+ steps.push({ descendant, selectors: parseBracket(content, path) });
11767
+ };
11768
+ while (i < path.length) {
11769
+ if (path[i] === "." && path[i + 1] === ".") {
11770
+ i += 2;
11771
+ if (path[i] === "[") readBracket(true);
11772
+ else readDotSelector(true);
11773
+ } else if (path[i] === ".") {
11774
+ i++;
11775
+ readDotSelector(false);
11776
+ } else if (path[i] === "[") {
11777
+ readBracket(false);
11778
+ } else {
11779
+ unsupported(path, `unexpected character "${path[i]}"`);
11780
+ }
11781
+ }
11782
+ return steps;
11783
+ }
11784
+ function withDescendants(nodeRef) {
11785
+ const list = [nodeRef];
11786
+ const walk = (container) => {
11787
+ if (Array.isArray(container)) {
11788
+ container.forEach((value, index2) => {
11789
+ list.push({ parent: container, key: index2, value });
11790
+ walk(value);
11791
+ });
11792
+ } else if (isObject(container)) {
11793
+ Object.keys(container).forEach((key) => {
11794
+ list.push({ parent: container, key, value: container[key] });
11795
+ walk(container[key]);
11796
+ });
11797
+ }
11798
+ };
11799
+ walk(nodeRef.value);
11800
+ return list;
11801
+ }
11802
+ function applySelector(container, selector, out) {
11803
+ if (!isContainer(container)) return;
11804
+ if (selector.type === "wildcard") {
11805
+ if (Array.isArray(container)) {
11806
+ container.forEach((value, index2) => out.push({ parent: container, key: index2, value }));
11807
+ } else {
11808
+ Object.keys(container).forEach((key) => out.push({ parent: container, key, value: container[key] }));
11809
+ }
11810
+ return;
11811
+ }
11812
+ if (selector.type === "name") {
11813
+ if (isObject(container) && Object.prototype.hasOwnProperty.call(container, selector.value)) {
11814
+ out.push({ parent: container, key: selector.value, value: container[selector.value] });
11815
+ }
11816
+ return;
11817
+ }
11818
+ if (selector.type === "index") {
11819
+ if (Array.isArray(container)) {
11820
+ const index2 = selector.value < 0 ? container.length + selector.value : selector.value;
11821
+ if (index2 >= 0 && index2 < container.length) {
11822
+ out.push({ parent: container, key: index2, value: container[index2] });
11823
+ }
11824
+ }
11825
+ }
11826
+ }
11827
+ function selectNodes(root, path) {
11828
+ const steps = tokenize(path);
11829
+ let current = [{ parent: null, key: null, value: root }];
11830
+ for (const step of steps) {
11831
+ const bases = step.descendant ? current.flatMap(withDescendants) : current;
11832
+ const next = [];
11833
+ for (const node of bases) {
11834
+ for (const selector of step.selectors) {
11835
+ applySelector(node.value, selector, next);
11836
+ }
11837
+ }
11838
+ current = next;
11839
+ }
11840
+ return current;
11841
+ }
11842
+ function applyUpdate(nodeRef, update) {
11843
+ const { parent, key, value } = nodeRef;
11844
+ const incoming = clone(update);
11845
+ if (isArray(value)) {
11846
+ if (isArray(incoming)) value.push(...incoming);
11847
+ else value.push(incoming);
11848
+ return;
11849
+ }
11850
+ if (isObject$1(value) && isObject$1(incoming)) {
11851
+ combineDeep(value, incoming);
11852
+ return;
11853
+ }
11854
+ if (parent === null) {
11855
+ throw new Error("Jedison: overlay cannot replace the root schema with a non-object update.");
11856
+ }
11857
+ parent[key] = incoming;
11858
+ }
11859
+ function applyRemove(nodes) {
11860
+ if (nodes.some((node) => node.parent === null)) {
11861
+ throw new Error("Jedison: overlay cannot remove the root schema.");
11862
+ }
11863
+ nodes.filter((node) => node.parent && !isArray(node.parent)).forEach((node) => {
11864
+ delete node.parent[node.key];
11865
+ });
11866
+ const arrayGroups = /* @__PURE__ */ new Map();
11867
+ nodes.filter((node) => isArray(node.parent)).forEach((node) => {
11868
+ if (!arrayGroups.has(node.parent)) arrayGroups.set(node.parent, []);
11869
+ arrayGroups.get(node.parent).push(node.key);
11870
+ });
11871
+ arrayGroups.forEach((indices, array) => {
11872
+ indices.sort((a, b) => b - a).forEach((index2) => array.splice(index2, 1));
11873
+ });
11874
+ }
11875
+ function applyOverlay(schema, overlay) {
11876
+ const result = clone(schema);
11877
+ if (overlay === null || typeof overlay === "undefined") {
11878
+ return result;
11879
+ }
11880
+ if (!isObject$1(overlay) || !isArray(overlay.actions)) {
11881
+ throw new Error('Jedison: overlay must be an object with an "actions" array.');
11882
+ }
11883
+ overlay.actions.forEach((action, index2) => {
11884
+ if (!isObject$1(action) || typeof action.target !== "string") {
11885
+ throw new Error(`Jedison: overlay action ${index2} must be an object with a string "target".`);
11886
+ }
11887
+ const nodes = selectNodes(result, action.target);
11888
+ if (nodes.length === 0) return;
11889
+ if (action.remove === true) {
11890
+ applyRemove(nodes);
11891
+ } else if (typeof action.update !== "undefined") {
11892
+ nodes.forEach((node) => applyUpdate(node, action.update));
11893
+ }
11894
+ });
11895
+ return result;
11896
+ }
11552
11897
  const index = {
11553
11898
  Schema,
11554
11899
  Utils,
@@ -11588,7 +11933,8 @@ const index = {
11588
11933
  ThemeBootstrap5,
11589
11934
  RefParser,
11590
11935
  Create: Jedison,
11591
- SchemaGenerator
11936
+ SchemaGenerator,
11937
+ applyOverlay
11592
11938
  };
11593
11939
  export {
11594
11940
  index as default