@structured-field/widget-editor 1.2.0 → 1.2.2

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.
@@ -1,4 +1,4 @@
1
- var script$d = {
1
+ var script$e = {
2
2
  name: 'StringEditor',
3
3
  props: {
4
4
  schema: { type: Object, required: true },
@@ -21,6 +21,12 @@ var script$d = {
21
21
  isLong() {
22
22
  return this.schema.maxLength > 255 || this.schema.format === 'textarea';
23
23
  },
24
+ isNullable() {
25
+ return !!this.schema._nullable;
26
+ },
27
+ isNullValue() {
28
+ return this.modelValue === null || this.modelValue === undefined;
29
+ },
24
30
  fieldErrors() {
25
31
  if (!this.form || !this.form.getErrorsForPath) return [];
26
32
  return this.form.getErrorsForPath(this.path);
@@ -6759,7 +6765,7 @@ class VueElement extends BaseClass {
6759
6765
  _update() {
6760
6766
  const vnode = this._createVNode();
6761
6767
  if (this._app) vnode.appContext = this._app._context;
6762
- render$d(vnode, this._root);
6768
+ render$e(vnode, this._root);
6763
6769
  }
6764
6770
  _createVNode() {
6765
6771
  const baseProps = {};
@@ -7026,7 +7032,7 @@ let renderer;
7026
7032
  function ensureRenderer() {
7027
7033
  return renderer || (renderer = createRenderer(rendererOptions));
7028
7034
  }
7029
- const render$d = ((...args) => {
7035
+ const render$e = ((...args) => {
7030
7036
  ensureRenderer().render(...args);
7031
7037
  });
7032
7038
  const createApp = ((...args) => {
@@ -7067,39 +7073,61 @@ function normalizeContainer(container) {
7067
7073
  return container;
7068
7074
  }
7069
7075
 
7070
- const _hoisted_1$b = ["value", "placeholder"];
7071
- const _hoisted_2$9 = ["value", "placeholder"];
7072
- const _hoisted_3$8 = {
7073
- key: 2,
7076
+ const _hoisted_1$c = {
7077
+ key: 0,
7078
+ class: "sf-null-badge"
7079
+ };
7080
+ const _hoisted_2$a = ["value", "placeholder"];
7081
+ const _hoisted_3$a = ["value", "placeholder"];
7082
+ const _hoisted_4$7 = {
7083
+ key: 0,
7074
7084
  class: "errorlist"
7075
7085
  };
7076
7086
 
7077
- function render$c(_ctx, _cache, $props, $setup, $data, $options) {
7087
+ function render$d(_ctx, _cache, $props, $setup, $data, $options) {
7078
7088
  return (openBlock(), createElementBlock("div", {
7079
7089
  class: normalizeClass(["sf-field", { errors: $options.fieldErrors.length }])
7080
7090
  }, [
7081
- createBaseVNode("label", {
7091
+ createBaseVNode("span", {
7082
7092
  class: normalizeClass(["sf-label", { required: $options.isRequired }])
7083
- }, toDisplayString($options.title), 3 /* TEXT, CLASS */),
7084
- ($options.isLong)
7085
- ? (openBlock(), createElementBlock("textarea", {
7086
- key: 0,
7087
- class: "sf-input sf-textarea",
7088
- rows: "3",
7089
- value: $props.modelValue,
7090
- placeholder: $props.schema.placeholder || '',
7091
- onInput: _cache[0] || (_cache[0] = $event => (_ctx.$emit('update:modelValue', $event.target.value)))
7092
- }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_1$b))
7093
- : (openBlock(), createElementBlock("input", {
7094
- key: 1,
7095
- type: "text",
7096
- class: "sf-input",
7097
- value: $props.modelValue != null ? String($props.modelValue) : '',
7098
- placeholder: $props.schema.placeholder || '',
7099
- onInput: _cache[1] || (_cache[1] = $event => (_ctx.$emit('update:modelValue', $event.target.value)))
7100
- }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_2$9)),
7093
+ }, [
7094
+ createTextVNode(toDisplayString($options.title) + " ", 1 /* TEXT */),
7095
+ ($options.isNullable && $options.isNullValue)
7096
+ ? (openBlock(), createElementBlock("span", _hoisted_1$c, "null"))
7097
+ : createCommentVNode("v-if", true)
7098
+ ], 2 /* CLASS */),
7099
+ createBaseVNode("div", {
7100
+ class: normalizeClass($options.isNullable ? 'sf-input-row' : null)
7101
+ }, [
7102
+ ($options.isLong)
7103
+ ? (openBlock(), createElementBlock("textarea", {
7104
+ key: 0,
7105
+ class: "sf-input sf-textarea",
7106
+ rows: "3",
7107
+ value: $options.isNullValue ? '' : $props.modelValue,
7108
+ placeholder: $options.isNullValue ? 'null' : ($props.schema.placeholder || ''),
7109
+ onInput: _cache[0] || (_cache[0] = $event => (_ctx.$emit('update:modelValue', $event.target.value)))
7110
+ }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_2$a))
7111
+ : (openBlock(), createElementBlock("input", {
7112
+ key: 1,
7113
+ type: "text",
7114
+ class: "sf-input",
7115
+ value: $options.isNullValue ? '' : ($props.modelValue != null ? String($props.modelValue) : ''),
7116
+ placeholder: $options.isNullValue ? 'null' : ($props.schema.placeholder || ''),
7117
+ onInput: _cache[1] || (_cache[1] = $event => (_ctx.$emit('update:modelValue', $event.target.value)))
7118
+ }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_3$a)),
7119
+ ($options.isNullable && !$options.isNullValue)
7120
+ ? (openBlock(), createElementBlock("button", {
7121
+ key: 2,
7122
+ type: "button",
7123
+ class: "sf-null-clear-btn",
7124
+ title: "Set to null",
7125
+ onClick: _cache[2] || (_cache[2] = $event => (_ctx.$emit('update:modelValue', null)))
7126
+ }, "✕"))
7127
+ : createCommentVNode("v-if", true)
7128
+ ], 2 /* CLASS */),
7101
7129
  ($options.fieldErrors.length)
7102
- ? (openBlock(), createElementBlock("ul", _hoisted_3$8, [
7130
+ ? (openBlock(), createElementBlock("ul", _hoisted_4$7, [
7103
7131
  (openBlock(true), createElementBlock(Fragment, null, renderList($options.fieldErrors, (err, i) => {
7104
7132
  return (openBlock(), createElementBlock("li", { key: i }, toDisplayString(err), 1 /* TEXT */))
7105
7133
  }), 128 /* KEYED_FRAGMENT */))
@@ -7108,10 +7136,10 @@ function render$c(_ctx, _cache, $props, $setup, $data, $options) {
7108
7136
  ], 2 /* CLASS */))
7109
7137
  }
7110
7138
 
7111
- script$d.render = render$c;
7112
- script$d.__file = "src/editors/StringEditor.vue";
7139
+ script$e.render = render$d;
7140
+ script$e.__file = "src/editors/StringEditor.vue";
7113
7141
 
7114
- var script$c = {
7142
+ var script$d = {
7115
7143
  name: 'NumberEditor',
7116
7144
  props: {
7117
7145
  schema: { type: Object, required: true },
@@ -7131,6 +7159,12 @@ var script$c = {
7131
7159
  const parentSchema = this.form.getSchemaAtPath(parentPath);
7132
7160
  return parentSchema && Array.isArray(parentSchema.required) && parentSchema.required.includes(fieldName);
7133
7161
  },
7162
+ isNullable() {
7163
+ return !!this.schema._nullable;
7164
+ },
7165
+ isNullValue() {
7166
+ return this.modelValue === null || this.modelValue === undefined;
7167
+ },
7134
7168
  fieldErrors() {
7135
7169
  if (!this.form || !this.form.getErrorsForPath) return [];
7136
7170
  return this.form.getErrorsForPath(this.path);
@@ -7152,30 +7186,53 @@ var script$c = {
7152
7186
  },
7153
7187
  };
7154
7188
 
7155
- const _hoisted_1$a = ["step", "min", "max", "value"];
7156
- const _hoisted_2$8 = {
7189
+ const _hoisted_1$b = {
7190
+ key: 0,
7191
+ class: "sf-null-badge"
7192
+ };
7193
+ const _hoisted_2$9 = ["step", "min", "max", "value", "placeholder"];
7194
+ const _hoisted_3$9 = {
7157
7195
  key: 0,
7158
7196
  class: "errorlist"
7159
7197
  };
7160
7198
 
7161
- function render$b(_ctx, _cache, $props, $setup, $data, $options) {
7199
+ function render$c(_ctx, _cache, $props, $setup, $data, $options) {
7162
7200
  return (openBlock(), createElementBlock("div", {
7163
7201
  class: normalizeClass(["sf-field", { errors: $options.fieldErrors.length }])
7164
7202
  }, [
7165
- createBaseVNode("label", {
7203
+ createBaseVNode("span", {
7166
7204
  class: normalizeClass(["sf-label", { required: $options.isRequired }])
7167
- }, toDisplayString($options.title), 3 /* TEXT, CLASS */),
7168
- createBaseVNode("input", {
7169
- type: "number",
7170
- class: "sf-input",
7171
- step: $props.schema.type === 'integer' ? '1' : 'any',
7172
- min: $props.schema.minimum != null ? String($props.schema.minimum) : undefined,
7173
- max: $props.schema.maximum != null ? String($props.schema.maximum) : undefined,
7174
- value: $props.modelValue != null ? $props.modelValue : '',
7175
- onInput: _cache[0] || (_cache[0] = (...args) => ($options.onInput && $options.onInput(...args)))
7176
- }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_1$a),
7205
+ }, [
7206
+ createTextVNode(toDisplayString($options.title) + " ", 1 /* TEXT */),
7207
+ ($options.isNullable && $options.isNullValue)
7208
+ ? (openBlock(), createElementBlock("span", _hoisted_1$b, "null"))
7209
+ : createCommentVNode("v-if", true)
7210
+ ], 2 /* CLASS */),
7211
+ createBaseVNode("div", {
7212
+ class: normalizeClass($options.isNullable ? 'sf-input-row' : null)
7213
+ }, [
7214
+ createBaseVNode("input", {
7215
+ type: "number",
7216
+ class: "sf-input",
7217
+ step: $props.schema.type === 'integer' ? '1' : 'any',
7218
+ min: $props.schema.minimum != null ? String($props.schema.minimum) : undefined,
7219
+ max: $props.schema.maximum != null ? String($props.schema.maximum) : undefined,
7220
+ value: $options.isNullValue ? '' : $props.modelValue,
7221
+ placeholder: $options.isNullValue ? 'null' : undefined,
7222
+ onInput: _cache[0] || (_cache[0] = (...args) => ($options.onInput && $options.onInput(...args)))
7223
+ }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_2$9),
7224
+ ($options.isNullable && !$options.isNullValue)
7225
+ ? (openBlock(), createElementBlock("button", {
7226
+ key: 0,
7227
+ type: "button",
7228
+ class: "sf-null-clear-btn",
7229
+ title: "Set to null",
7230
+ onClick: _cache[1] || (_cache[1] = $event => (_ctx.$emit('update:modelValue', null)))
7231
+ }, "✕"))
7232
+ : createCommentVNode("v-if", true)
7233
+ ], 2 /* CLASS */),
7177
7234
  ($options.fieldErrors.length)
7178
- ? (openBlock(), createElementBlock("ul", _hoisted_2$8, [
7235
+ ? (openBlock(), createElementBlock("ul", _hoisted_3$9, [
7179
7236
  (openBlock(true), createElementBlock(Fragment, null, renderList($options.fieldErrors, (err, i) => {
7180
7237
  return (openBlock(), createElementBlock("li", { key: i }, toDisplayString(err), 1 /* TEXT */))
7181
7238
  }), 128 /* KEYED_FRAGMENT */))
@@ -7184,10 +7241,10 @@ function render$b(_ctx, _cache, $props, $setup, $data, $options) {
7184
7241
  ], 2 /* CLASS */))
7185
7242
  }
7186
7243
 
7187
- script$c.render = render$b;
7188
- script$c.__file = "src/editors/NumberEditor.vue";
7244
+ script$d.render = render$c;
7245
+ script$d.__file = "src/editors/NumberEditor.vue";
7189
7246
 
7190
- var script$b = {
7247
+ var script$c = {
7191
7248
  name: 'BooleanEditor',
7192
7249
  props: {
7193
7250
  schema: { type: Object, required: true },
@@ -7200,6 +7257,12 @@ var script$b = {
7200
7257
  title() {
7201
7258
  return this.schema.title || this.humanize(this.path[this.path.length - 1]) || '';
7202
7259
  },
7260
+ isNullable() {
7261
+ return !!this.schema._nullable;
7262
+ },
7263
+ isNullValue() {
7264
+ return this.modelValue === null || this.modelValue === undefined;
7265
+ },
7203
7266
  fieldErrors() {
7204
7267
  if (!this.form || !this.form.getErrorsForPath) return [];
7205
7268
  return this.form.getErrorsForPath(this.path);
@@ -7213,28 +7276,47 @@ var script$b = {
7213
7276
  },
7214
7277
  };
7215
7278
 
7216
- const _hoisted_1$9 = { class: "sf-checkbox-label" };
7217
- const _hoisted_2$7 = ["checked"];
7218
- const _hoisted_3$7 = {
7279
+ const _hoisted_1$a = { class: "sf-boolean-row" };
7280
+ const _hoisted_2$8 = { class: "sf-checkbox-label" };
7281
+ const _hoisted_3$8 = ["checked"];
7282
+ const _hoisted_4$6 = {
7283
+ key: 0,
7284
+ class: "sf-null-badge"
7285
+ };
7286
+ const _hoisted_5$6 = {
7219
7287
  key: 0,
7220
7288
  class: "errorlist"
7221
7289
  };
7222
7290
 
7223
- function render$a(_ctx, _cache, $props, $setup, $data, $options) {
7291
+ function render$b(_ctx, _cache, $props, $setup, $data, $options) {
7224
7292
  return (openBlock(), createElementBlock("div", {
7225
7293
  class: normalizeClass(["sf-field sf-field-boolean", { errors: $options.fieldErrors.length }])
7226
7294
  }, [
7227
- createBaseVNode("label", _hoisted_1$9, [
7228
- createBaseVNode("input", {
7229
- type: "checkbox",
7230
- class: "sf-checkbox",
7231
- checked: !!$props.modelValue,
7232
- onChange: _cache[0] || (_cache[0] = $event => (_ctx.$emit('update:modelValue', $event.target.checked)))
7233
- }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_2$7),
7234
- createTextVNode(" " + toDisplayString($options.title), 1 /* TEXT */)
7295
+ createBaseVNode("div", _hoisted_1$a, [
7296
+ createBaseVNode("label", _hoisted_2$8, [
7297
+ createBaseVNode("input", {
7298
+ type: "checkbox",
7299
+ class: "sf-checkbox",
7300
+ checked: !!$props.modelValue,
7301
+ onChange: _cache[0] || (_cache[0] = $event => (_ctx.$emit('update:modelValue', $event.target.checked)))
7302
+ }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_3$8),
7303
+ createTextVNode(" " + toDisplayString($options.title) + " ", 1 /* TEXT */),
7304
+ ($options.isNullable && $options.isNullValue)
7305
+ ? (openBlock(), createElementBlock("span", _hoisted_4$6, "null"))
7306
+ : createCommentVNode("v-if", true)
7307
+ ]),
7308
+ ($options.isNullable && !$options.isNullValue)
7309
+ ? (openBlock(), createElementBlock("button", {
7310
+ key: 0,
7311
+ type: "button",
7312
+ class: "sf-null-clear-btn",
7313
+ title: "Set to null",
7314
+ onClick: _cache[1] || (_cache[1] = $event => (_ctx.$emit('update:modelValue', null)))
7315
+ }, "✕"))
7316
+ : createCommentVNode("v-if", true)
7235
7317
  ]),
7236
7318
  ($options.fieldErrors.length)
7237
- ? (openBlock(), createElementBlock("ul", _hoisted_3$7, [
7319
+ ? (openBlock(), createElementBlock("ul", _hoisted_5$6, [
7238
7320
  (openBlock(true), createElementBlock(Fragment, null, renderList($options.fieldErrors, (err, i) => {
7239
7321
  return (openBlock(), createElementBlock("li", { key: i }, toDisplayString(err), 1 /* TEXT */))
7240
7322
  }), 128 /* KEYED_FRAGMENT */))
@@ -7243,10 +7325,10 @@ function render$a(_ctx, _cache, $props, $setup, $data, $options) {
7243
7325
  ], 2 /* CLASS */))
7244
7326
  }
7245
7327
 
7246
- script$b.render = render$a;
7247
- script$b.__file = "src/editors/BooleanEditor.vue";
7328
+ script$c.render = render$b;
7329
+ script$c.__file = "src/editors/BooleanEditor.vue";
7248
7330
 
7249
- var script$a = {
7331
+ var script$b = {
7250
7332
  name: 'SelectEditor',
7251
7333
  props: {
7252
7334
  schema: { type: Object, required: true },
@@ -7266,6 +7348,12 @@ var script$a = {
7266
7348
  const parentSchema = this.form.getSchemaAtPath(parentPath);
7267
7349
  return parentSchema && Array.isArray(parentSchema.required) && parentSchema.required.includes(fieldName);
7268
7350
  },
7351
+ isNullable() {
7352
+ return !!this.schema._nullable;
7353
+ },
7354
+ isNullValue() {
7355
+ return this.modelValue === null || this.modelValue === undefined;
7356
+ },
7269
7357
  fieldErrors() {
7270
7358
  if (!this.form || !this.form.getErrorsForPath) return [];
7271
7359
  return this.form.getErrorsForPath(this.path);
@@ -7279,34 +7367,65 @@ var script$a = {
7279
7367
  },
7280
7368
  };
7281
7369
 
7282
- const _hoisted_1$8 = ["value"];
7283
- const _hoisted_2$6 = ["value"];
7284
- const _hoisted_3$6 = {
7370
+ const _hoisted_1$9 = {
7371
+ key: 0,
7372
+ class: "sf-null-badge"
7373
+ };
7374
+ const _hoisted_2$7 = ["value"];
7375
+ const _hoisted_3$7 = {
7376
+ key: 0,
7377
+ value: "",
7378
+ disabled: "",
7379
+ selected: ""
7380
+ };
7381
+ const _hoisted_4$5 = ["value"];
7382
+ const _hoisted_5$5 = {
7285
7383
  key: 0,
7286
7384
  class: "errorlist"
7287
7385
  };
7288
7386
 
7289
- function render$9(_ctx, _cache, $props, $setup, $data, $options) {
7387
+ function render$a(_ctx, _cache, $props, $setup, $data, $options) {
7290
7388
  return (openBlock(), createElementBlock("div", {
7291
7389
  class: normalizeClass(["sf-field", { errors: $options.fieldErrors.length }])
7292
7390
  }, [
7293
- createBaseVNode("label", {
7391
+ createBaseVNode("span", {
7294
7392
  class: normalizeClass(["sf-label", { required: $options.isRequired }])
7295
- }, toDisplayString($options.title), 3 /* TEXT, CLASS */),
7296
- createBaseVNode("select", {
7297
- class: "sf-input sf-select",
7298
- value: $props.modelValue != null ? String($props.modelValue) : '',
7299
- onChange: _cache[0] || (_cache[0] = $event => (_ctx.$emit('update:modelValue', $event.target.value)))
7300
7393
  }, [
7301
- (openBlock(true), createElementBlock(Fragment, null, renderList(($props.schema.enum || []), (opt) => {
7302
- return (openBlock(), createElementBlock("option", {
7303
- key: opt,
7304
- value: String(opt)
7305
- }, toDisplayString(opt), 9 /* TEXT, PROPS */, _hoisted_2$6))
7306
- }), 128 /* KEYED_FRAGMENT */))
7307
- ], 40 /* PROPS, NEED_HYDRATION */, _hoisted_1$8),
7394
+ createTextVNode(toDisplayString($options.title) + " ", 1 /* TEXT */),
7395
+ ($options.isNullable && $options.isNullValue)
7396
+ ? (openBlock(), createElementBlock("span", _hoisted_1$9, "null"))
7397
+ : createCommentVNode("v-if", true)
7398
+ ], 2 /* CLASS */),
7399
+ createBaseVNode("div", {
7400
+ class: normalizeClass($options.isNullable ? 'sf-input-row' : null)
7401
+ }, [
7402
+ createBaseVNode("select", {
7403
+ class: "sf-input sf-select",
7404
+ value: $options.isNullValue ? '' : ($props.modelValue != null ? String($props.modelValue) : ''),
7405
+ onChange: _cache[0] || (_cache[0] = $event => (_ctx.$emit('update:modelValue', $event.target.value)))
7406
+ }, [
7407
+ ($options.isNullable && $options.isNullValue)
7408
+ ? (openBlock(), createElementBlock("option", _hoisted_3$7, "null"))
7409
+ : createCommentVNode("v-if", true),
7410
+ (openBlock(true), createElementBlock(Fragment, null, renderList(($props.schema.enum || []), (opt) => {
7411
+ return (openBlock(), createElementBlock("option", {
7412
+ key: opt,
7413
+ value: String(opt)
7414
+ }, toDisplayString(opt), 9 /* TEXT, PROPS */, _hoisted_4$5))
7415
+ }), 128 /* KEYED_FRAGMENT */))
7416
+ ], 40 /* PROPS, NEED_HYDRATION */, _hoisted_2$7),
7417
+ ($options.isNullable && !$options.isNullValue)
7418
+ ? (openBlock(), createElementBlock("button", {
7419
+ key: 0,
7420
+ type: "button",
7421
+ class: "sf-null-clear-btn",
7422
+ title: "Set to null",
7423
+ onClick: _cache[1] || (_cache[1] = $event => (_ctx.$emit('update:modelValue', null)))
7424
+ }, "✕"))
7425
+ : createCommentVNode("v-if", true)
7426
+ ], 2 /* CLASS */),
7308
7427
  ($options.fieldErrors.length)
7309
- ? (openBlock(), createElementBlock("ul", _hoisted_3$6, [
7428
+ ? (openBlock(), createElementBlock("ul", _hoisted_5$5, [
7310
7429
  (openBlock(true), createElementBlock(Fragment, null, renderList($options.fieldErrors, (err, i) => {
7311
7430
  return (openBlock(), createElementBlock("li", { key: i }, toDisplayString(err), 1 /* TEXT */))
7312
7431
  }), 128 /* KEYED_FRAGMENT */))
@@ -7315,10 +7434,10 @@ function render$9(_ctx, _cache, $props, $setup, $data, $options) {
7315
7434
  ], 2 /* CLASS */))
7316
7435
  }
7317
7436
 
7318
- script$a.render = render$9;
7319
- script$a.__file = "src/editors/SelectEditor.vue";
7437
+ script$b.render = render$a;
7438
+ script$b.__file = "src/editors/SelectEditor.vue";
7320
7439
 
7321
- var script$9 = {
7440
+ var script$a = {
7322
7441
  name: 'HiddenEditor',
7323
7442
  props: {
7324
7443
  schema: { type: Object, required: true },
@@ -7346,16 +7465,16 @@ var script$9 = {
7346
7465
  },
7347
7466
  };
7348
7467
 
7349
- const _hoisted_1$7 = { style: {"display":"none"} };
7468
+ const _hoisted_1$8 = { style: {"display":"none"} };
7350
7469
 
7351
- function render$8(_ctx, _cache, $props, $setup, $data, $options) {
7352
- return (openBlock(), createElementBlock("div", _hoisted_1$7))
7470
+ function render$9(_ctx, _cache, $props, $setup, $data, $options) {
7471
+ return (openBlock(), createElementBlock("div", _hoisted_1$8))
7353
7472
  }
7354
7473
 
7355
- script$9.render = render$8;
7356
- script$9.__file = "src/editors/HiddenEditor.vue";
7474
+ script$a.render = render$9;
7475
+ script$a.__file = "src/editors/HiddenEditor.vue";
7357
7476
 
7358
- var script$8 = {
7477
+ var script$9 = {
7359
7478
  name: 'SfIcon',
7360
7479
  props: {
7361
7480
  name: { type: String, required: true },
@@ -7363,17 +7482,17 @@ var script$8 = {
7363
7482
  },
7364
7483
  };
7365
7484
 
7366
- const _hoisted_1$6 = ["width", "height"];
7367
- const _hoisted_2$5 = {
7485
+ const _hoisted_1$7 = ["width", "height"];
7486
+ const _hoisted_2$6 = {
7368
7487
  key: 4,
7369
7488
  points: "6 9 12 15 18 9"
7370
7489
  };
7371
- const _hoisted_3$5 = {
7490
+ const _hoisted_3$6 = {
7372
7491
  key: 5,
7373
7492
  points: "18 15 12 9 6 15"
7374
7493
  };
7375
7494
 
7376
- function render$7(_ctx, _cache, $props, $setup, $data, $options) {
7495
+ function render$8(_ctx, _cache, $props, $setup, $data, $options) {
7377
7496
  return (openBlock(), createElementBlock("svg", {
7378
7497
  class: "sf-icon",
7379
7498
  width: $props.size,
@@ -7436,19 +7555,19 @@ function render$7(_ctx, _cache, $props, $setup, $data, $options) {
7436
7555
  _cache[7] || (_cache[7] = createBaseVNode("polyline", { points: "19 12 12 19 5 12" }, null, -1 /* CACHED */))
7437
7556
  ], 64 /* STABLE_FRAGMENT */))
7438
7557
  : ($props.name === 'chevron-down')
7439
- ? (openBlock(), createElementBlock("polyline", _hoisted_2$5))
7558
+ ? (openBlock(), createElementBlock("polyline", _hoisted_2$6))
7440
7559
  : ($props.name === 'chevron-up')
7441
- ? (openBlock(), createElementBlock("polyline", _hoisted_3$5))
7560
+ ? (openBlock(), createElementBlock("polyline", _hoisted_3$6))
7442
7561
  : ($props.name === 'grip')
7443
7562
  ? (openBlock(), createElementBlock(Fragment, { key: 6 }, [
7444
7563
  _cache[8] || (_cache[8] = createStaticVNode("<circle cx=\"9\" cy=\"7\" r=\"1\" fill=\"currentColor\" stroke=\"none\"></circle><circle cx=\"15\" cy=\"7\" r=\"1\" fill=\"currentColor\" stroke=\"none\"></circle><circle cx=\"9\" cy=\"12\" r=\"1\" fill=\"currentColor\" stroke=\"none\"></circle><circle cx=\"15\" cy=\"12\" r=\"1\" fill=\"currentColor\" stroke=\"none\"></circle><circle cx=\"9\" cy=\"17\" r=\"1\" fill=\"currentColor\" stroke=\"none\"></circle><circle cx=\"15\" cy=\"17\" r=\"1\" fill=\"currentColor\" stroke=\"none\"></circle>", 6))
7445
7564
  ], 64 /* STABLE_FRAGMENT */))
7446
7565
  : createCommentVNode("v-if", true)
7447
- ], 8 /* PROPS */, _hoisted_1$6))
7566
+ ], 8 /* PROPS */, _hoisted_1$7))
7448
7567
  }
7449
7568
 
7450
- script$8.render = render$7;
7451
- script$8.__file = "src/editors/SfIcon.vue";
7569
+ script$9.render = render$8;
7570
+ script$9.__file = "src/editors/SfIcon.vue";
7452
7571
 
7453
7572
  // JSON Schema conditional evaluation for form rendering.
7454
7573
  //
@@ -7699,12 +7818,12 @@ function hasConditionals(schema) {
7699
7818
  return false;
7700
7819
  }
7701
7820
 
7702
- var script$7 = {
7821
+ var script$8 = {
7703
7822
  name: 'ObjectEditor',
7704
7823
  beforeCreate() {
7705
7824
  if (!this.$options.components) this.$options.components = {};
7706
7825
  this.$options.components.SchemaEditor = script$1;
7707
- this.$options.components.SfIcon = script$8;
7826
+ this.$options.components.SfIcon = script$9;
7708
7827
  },
7709
7828
  props: {
7710
7829
  schema: { type: Object, required: true },
@@ -7775,27 +7894,27 @@ var script$7 = {
7775
7894
  },
7776
7895
  };
7777
7896
 
7778
- const _hoisted_1$5 = {
7897
+ const _hoisted_1$6 = {
7779
7898
  key: 0,
7780
7899
  class: "sf-object sf-object-root"
7781
7900
  };
7782
- const _hoisted_2$4 = { class: "sf-object-fields" };
7783
- const _hoisted_3$4 = { class: "sf-object-title" };
7784
- const _hoisted_4$3 = ["aria-label"];
7785
- const _hoisted_5$3 = { class: "sf-object-title-text" };
7901
+ const _hoisted_2$5 = { class: "sf-object-fields" };
7902
+ const _hoisted_3$5 = { class: "sf-object-title" };
7903
+ const _hoisted_4$4 = ["aria-label"];
7904
+ const _hoisted_5$4 = { class: "sf-object-title-text" };
7786
7905
  const _hoisted_6$3 = {
7787
7906
  key: 0,
7788
7907
  class: "sf-object-summary"
7789
7908
  };
7790
7909
  const _hoisted_7$2 = { class: "sf-object-fields" };
7791
7910
 
7792
- function render$6(_ctx, _cache, $props, $setup, $data, $options) {
7911
+ function render$7(_ctx, _cache, $props, $setup, $data, $options) {
7793
7912
  const _component_SchemaEditor = resolveComponent("SchemaEditor");
7794
7913
  const _component_SfIcon = resolveComponent("SfIcon");
7795
7914
 
7796
7915
  return ($options.isRoot)
7797
- ? (openBlock(), createElementBlock("div", _hoisted_1$5, [
7798
- createBaseVNode("div", _hoisted_2$4, [
7916
+ ? (openBlock(), createElementBlock("div", _hoisted_1$6, [
7917
+ createBaseVNode("div", _hoisted_2$5, [
7799
7918
  (openBlock(true), createElementBlock(Fragment, null, renderList(($options.effectiveSchema.properties || {}), (propSchema, key) => {
7800
7919
  return (openBlock(), createBlock(_component_SchemaEditor, {
7801
7920
  key: key,
@@ -7812,7 +7931,7 @@ function render$6(_ctx, _cache, $props, $setup, $data, $options) {
7812
7931
  key: 1,
7813
7932
  class: normalizeClass(["sf-object", { 'sf-object-collapsed': $data.collapsed }])
7814
7933
  }, [
7815
- createBaseVNode("legend", _hoisted_3$4, [
7934
+ createBaseVNode("legend", _hoisted_3$5, [
7816
7935
  createBaseVNode("button", {
7817
7936
  type: "button",
7818
7937
  class: "sf-collapse-btn",
@@ -7823,8 +7942,8 @@ function render$6(_ctx, _cache, $props, $setup, $data, $options) {
7823
7942
  name: $data.collapsed ? 'chevron-down' : 'chevron-up',
7824
7943
  size: 12
7825
7944
  }, null, 8 /* PROPS */, ["name"])
7826
- ], 8 /* PROPS */, _hoisted_4$3),
7827
- createBaseVNode("span", _hoisted_5$3, toDisplayString($options.title), 1 /* TEXT */),
7945
+ ], 8 /* PROPS */, _hoisted_4$4),
7946
+ createBaseVNode("span", _hoisted_5$4, toDisplayString($options.title), 1 /* TEXT */),
7828
7947
  ($data.collapsed && $options.summary)
7829
7948
  ? (openBlock(), createElementBlock("span", _hoisted_6$3, toDisplayString($options.summary), 1 /* TEXT */))
7830
7949
  : createCommentVNode("v-if", true)
@@ -7846,8 +7965,8 @@ function render$6(_ctx, _cache, $props, $setup, $data, $options) {
7846
7965
  ], 2 /* CLASS */))
7847
7966
  }
7848
7967
 
7849
- script$7.render = render$6;
7850
- script$7.__file = "src/editors/ObjectEditor.vue";
7968
+ script$8.render = render$7;
7969
+ script$8.__file = "src/editors/ObjectEditor.vue";
7851
7970
 
7852
7971
  function debounce(fn, delay) {
7853
7972
  let timer;
@@ -7890,12 +8009,12 @@ function getDefaultForSchema(schema) {
7890
8009
 
7891
8010
  let keyCounter = 0;
7892
8011
 
7893
- var script$6 = {
8012
+ var script$7 = {
7894
8013
  name: 'ArrayEditor',
7895
8014
  beforeCreate() {
7896
8015
  if (!this.$options.components) this.$options.components = {};
7897
8016
  this.$options.components.SchemaEditor = script$1;
7898
- this.$options.components.SfIcon = script$8;
8017
+ this.$options.components.SfIcon = script$9;
7899
8018
  },
7900
8019
  props: {
7901
8020
  schema: { type: Object, required: true },
@@ -7995,11 +8114,11 @@ var script$6 = {
7995
8114
  },
7996
8115
  };
7997
8116
 
7998
- const _hoisted_1$4 = { class: "sf-array-header" };
7999
- const _hoisted_2$3 = { class: "sf-label" };
8000
- const _hoisted_3$3 = { class: "sf-array-count" };
8001
- const _hoisted_4$2 = ["title"];
8002
- const _hoisted_5$2 = { class: "sf-array-items" };
8117
+ const _hoisted_1$5 = { class: "sf-array-header" };
8118
+ const _hoisted_2$4 = { class: "sf-label" };
8119
+ const _hoisted_3$4 = { class: "sf-array-count" };
8120
+ const _hoisted_4$3 = ["title"];
8121
+ const _hoisted_5$3 = { class: "sf-array-items" };
8003
8122
  const _hoisted_6$2 = ["onDragstart", "onDragover", "onDragleave", "onDrop"];
8004
8123
  const _hoisted_7$1 = { class: "sf-array-item-header" };
8005
8124
  const _hoisted_8$1 = { class: "sf-array-item-left" };
@@ -8018,16 +8137,16 @@ const _hoisted_16 = {
8018
8137
  class: "errorlist"
8019
8138
  };
8020
8139
 
8021
- function render$5(_ctx, _cache, $props, $setup, $data, $options) {
8140
+ function render$6(_ctx, _cache, $props, $setup, $data, $options) {
8022
8141
  const _component_SfIcon = resolveComponent("SfIcon");
8023
8142
  const _component_SchemaEditor = resolveComponent("SchemaEditor");
8024
8143
 
8025
8144
  return (openBlock(), createElementBlock("div", {
8026
8145
  class: normalizeClass(["sf-array", { errors: $options.fieldErrors.length }])
8027
8146
  }, [
8028
- createBaseVNode("div", _hoisted_1$4, [
8029
- createBaseVNode("span", _hoisted_2$3, toDisplayString($options.title), 1 /* TEXT */),
8030
- createBaseVNode("span", _hoisted_3$3, toDisplayString($data.items.length), 1 /* TEXT */),
8147
+ createBaseVNode("div", _hoisted_1$5, [
8148
+ createBaseVNode("span", _hoisted_2$4, toDisplayString($options.title), 1 /* TEXT */),
8149
+ createBaseVNode("span", _hoisted_3$4, toDisplayString($data.items.length), 1 /* TEXT */),
8031
8150
  createBaseVNode("button", {
8032
8151
  type: "button",
8033
8152
  class: "sf-btn sf-btn-add",
@@ -8046,10 +8165,10 @@ function render$5(_ctx, _cache, $props, $setup, $data, $options) {
8046
8165
  createVNode(_component_SfIcon, {
8047
8166
  name: $data.allCollapsed ? 'chevron-down' : 'chevron-up'
8048
8167
  }, null, 8 /* PROPS */, ["name"])
8049
- ], 8 /* PROPS */, _hoisted_4$2))
8168
+ ], 8 /* PROPS */, _hoisted_4$3))
8050
8169
  : createCommentVNode("v-if", true)
8051
8170
  ]),
8052
- createBaseVNode("div", _hoisted_5$2, [
8171
+ createBaseVNode("div", _hoisted_5$3, [
8053
8172
  (openBlock(true), createElementBlock(Fragment, null, renderList($data.items, (item, index) => {
8054
8173
  return (openBlock(), createElementBlock("div", {
8055
8174
  key: item._key,
@@ -8126,15 +8245,15 @@ function render$5(_ctx, _cache, $props, $setup, $data, $options) {
8126
8245
  ], 2 /* CLASS */))
8127
8246
  }
8128
8247
 
8129
- script$6.render = render$5;
8130
- script$6.__file = "src/editors/ArrayEditor.vue";
8248
+ script$7.render = render$6;
8249
+ script$7.__file = "src/editors/ArrayEditor.vue";
8131
8250
 
8132
- var script$5 = {
8251
+ var script$6 = {
8133
8252
  name: 'NullableEditor',
8134
8253
  beforeCreate() {
8135
8254
  if (!this.$options.components) this.$options.components = {};
8136
8255
  this.$options.components.SchemaEditor = script$1;
8137
- this.$options.components.SfIcon = script$8;
8256
+ this.$options.components.SfIcon = script$9;
8138
8257
  },
8139
8258
  props: {
8140
8259
  schema: { type: Object, required: true },
@@ -8194,22 +8313,22 @@ var script$5 = {
8194
8313
  },
8195
8314
  };
8196
8315
 
8197
- const _hoisted_1$3 = { class: "sf-nullable-header" };
8198
- const _hoisted_2$2 = { class: "sf-nullable-body" };
8199
- const _hoisted_3$2 = {
8316
+ const _hoisted_1$4 = { class: "sf-nullable-header" };
8317
+ const _hoisted_2$3 = { class: "sf-nullable-body" };
8318
+ const _hoisted_3$3 = {
8200
8319
  key: 0,
8201
8320
  class: "errorlist"
8202
8321
  };
8203
8322
 
8204
- function render$4(_ctx, _cache, $props, $setup, $data, $options) {
8323
+ function render$5(_ctx, _cache, $props, $setup, $data, $options) {
8205
8324
  const _component_SfIcon = resolveComponent("SfIcon");
8206
8325
  const _component_SchemaEditor = resolveComponent("SchemaEditor");
8207
8326
 
8208
8327
  return (openBlock(), createElementBlock("div", {
8209
8328
  class: normalizeClass(["sf-nullable", { errors: $options.fieldErrors.length }])
8210
8329
  }, [
8211
- createBaseVNode("div", _hoisted_1$3, [
8212
- createBaseVNode("label", {
8330
+ createBaseVNode("div", _hoisted_1$4, [
8331
+ createBaseVNode("span", {
8213
8332
  class: normalizeClass(["sf-label", { required: $options.isRequired }])
8214
8333
  }, toDisplayString($options.title), 3 /* TEXT, CLASS */),
8215
8334
  createBaseVNode("button", {
@@ -8228,7 +8347,7 @@ function render$4(_ctx, _cache, $props, $setup, $data, $options) {
8228
8347
  ], 64 /* STABLE_FRAGMENT */))
8229
8348
  ], 2 /* CLASS */)
8230
8349
  ]),
8231
- createBaseVNode("div", _hoisted_2$2, [
8350
+ createBaseVNode("div", _hoisted_2$3, [
8232
8351
  (!$data.isNull)
8233
8352
  ? (openBlock(), createBlock(_component_SchemaEditor, {
8234
8353
  key: 0,
@@ -8241,7 +8360,7 @@ function render$4(_ctx, _cache, $props, $setup, $data, $options) {
8241
8360
  : createCommentVNode("v-if", true)
8242
8361
  ]),
8243
8362
  ($options.fieldErrors.length)
8244
- ? (openBlock(), createElementBlock("ul", _hoisted_3$2, [
8363
+ ? (openBlock(), createElementBlock("ul", _hoisted_3$3, [
8245
8364
  (openBlock(true), createElementBlock(Fragment, null, renderList($options.fieldErrors, (err, i) => {
8246
8365
  return (openBlock(), createElementBlock("li", { key: i }, toDisplayString(err), 1 /* TEXT */))
8247
8366
  }), 128 /* KEYED_FRAGMENT */))
@@ -8250,10 +8369,10 @@ function render$4(_ctx, _cache, $props, $setup, $data, $options) {
8250
8369
  ], 2 /* CLASS */))
8251
8370
  }
8252
8371
 
8253
- script$5.render = render$4;
8254
- script$5.__file = "src/editors/NullableEditor.vue";
8372
+ script$6.render = render$5;
8373
+ script$6.__file = "src/editors/NullableEditor.vue";
8255
8374
 
8256
- var script$4 = {
8375
+ var script$5 = {
8257
8376
  name: 'UnionEditor',
8258
8377
  beforeCreate() {
8259
8378
  if (!this.$options.components) this.$options.components = {};
@@ -8314,19 +8433,19 @@ var script$4 = {
8314
8433
  },
8315
8434
  };
8316
8435
 
8317
- const _hoisted_1$2 = { class: "sf-union" };
8318
- const _hoisted_2$1 = { class: "sf-field" };
8319
- const _hoisted_3$1 = { class: "sf-label" };
8320
- const _hoisted_4$1 = ["value"];
8321
- const _hoisted_5$1 = ["value"];
8436
+ const _hoisted_1$3 = { class: "sf-union" };
8437
+ const _hoisted_2$2 = { class: "sf-field" };
8438
+ const _hoisted_3$2 = { class: "sf-label" };
8439
+ const _hoisted_4$2 = ["value"];
8440
+ const _hoisted_5$2 = ["value"];
8322
8441
  const _hoisted_6$1 = { class: "sf-union-body" };
8323
8442
 
8324
- function render$3(_ctx, _cache, $props, $setup, $data, $options) {
8443
+ function render$4(_ctx, _cache, $props, $setup, $data, $options) {
8325
8444
  const _component_SchemaEditor = resolveComponent("SchemaEditor");
8326
8445
 
8327
- return (openBlock(), createElementBlock("div", _hoisted_1$2, [
8328
- createBaseVNode("div", _hoisted_2$1, [
8329
- createBaseVNode("label", _hoisted_3$1, toDisplayString($options.title), 1 /* TEXT */),
8446
+ return (openBlock(), createElementBlock("div", _hoisted_1$3, [
8447
+ createBaseVNode("div", _hoisted_2$2, [
8448
+ createBaseVNode("span", _hoisted_3$2, toDisplayString($options.title), 1 /* TEXT */),
8330
8449
  createBaseVNode("select", {
8331
8450
  class: "sf-input sf-select",
8332
8451
  value: $data.currentType,
@@ -8336,9 +8455,9 @@ function render$3(_ctx, _cache, $props, $setup, $data, $options) {
8336
8455
  return (openBlock(), createElementBlock("option", {
8337
8456
  key: key,
8338
8457
  value: key
8339
- }, toDisplayString($options.humanize(key)), 9 /* TEXT, PROPS */, _hoisted_5$1))
8458
+ }, toDisplayString($options.humanize(key)), 9 /* TEXT, PROPS */, _hoisted_5$2))
8340
8459
  }), 128 /* KEYED_FRAGMENT */))
8341
- ], 40 /* PROPS, NEED_HYDRATION */, _hoisted_4$1)
8460
+ ], 40 /* PROPS, NEED_HYDRATION */, _hoisted_4$2)
8342
8461
  ]),
8343
8462
  createBaseVNode("div", _hoisted_6$1, [
8344
8463
  (openBlock(), createBlock(_component_SchemaEditor, {
@@ -8353,12 +8472,15 @@ function render$3(_ctx, _cache, $props, $setup, $data, $options) {
8353
8472
  ]))
8354
8473
  }
8355
8474
 
8356
- script$4.render = render$3;
8357
- script$4.__file = "src/editors/UnionEditor.vue";
8475
+ script$5.render = render$4;
8476
+ script$5.__file = "src/editors/UnionEditor.vue";
8358
8477
 
8359
- var script$3 = {
8478
+ var script$4 = {
8360
8479
  name: 'RelationEditor',
8361
- components: { SfIcon: script$8 },
8480
+ components: { SfIcon: script$9 },
8481
+ inject: {
8482
+ language: { from: 'language', default: () => () => '' },
8483
+ },
8362
8484
  props: {
8363
8485
  schema: { type: Object, required: true },
8364
8486
  modelValue: { default: null },
@@ -8464,6 +8586,8 @@ var script$3 = {
8464
8586
  const url = new URL(this.searchUrl, window.location.origin);
8465
8587
  url.searchParams.set('_q', query || '');
8466
8588
  url.searchParams.set('page', String(page));
8589
+ const lang = typeof this.language === 'function' ? this.language() : this.language;
8590
+ if (lang) url.searchParams.set('_lang', lang);
8467
8591
 
8468
8592
  const response = await fetch(url, { credentials: 'same-origin' });
8469
8593
  if (!response.ok) return;
@@ -8521,14 +8645,14 @@ var script$3 = {
8521
8645
  },
8522
8646
  };
8523
8647
 
8524
- const _hoisted_1$1 = { class: "sf-relation-wrapper" };
8525
- const _hoisted_2 = {
8648
+ const _hoisted_1$2 = { class: "sf-relation-wrapper" };
8649
+ const _hoisted_2$1 = {
8526
8650
  key: 0,
8527
8651
  class: "sf-relation-selected"
8528
8652
  };
8529
- const _hoisted_3 = { class: "sf-relation-tag-text" };
8530
- const _hoisted_4 = ["onClick"];
8531
- const _hoisted_5 = { class: "sf-relation-search" };
8653
+ const _hoisted_3$1 = { class: "sf-relation-tag-text" };
8654
+ const _hoisted_4$1 = ["onClick"];
8655
+ const _hoisted_5$1 = { class: "sf-relation-search" };
8532
8656
  const _hoisted_6 = ["placeholder"];
8533
8657
  const _hoisted_7 = { class: "sf-relation-dropdown" };
8534
8658
  const _hoisted_8 = {
@@ -8541,26 +8665,26 @@ const _hoisted_10 = {
8541
8665
  class: "errorlist"
8542
8666
  };
8543
8667
 
8544
- function render$2(_ctx, _cache, $props, $setup, $data, $options) {
8668
+ function render$3(_ctx, _cache, $props, $setup, $data, $options) {
8545
8669
  const _component_SfIcon = resolveComponent("SfIcon");
8546
8670
 
8547
8671
  return (openBlock(), createElementBlock("div", {
8548
8672
  class: normalizeClass(["sf-field sf-relation", { errors: $options.fieldErrors.length }]),
8549
8673
  ref: "root"
8550
8674
  }, [
8551
- createBaseVNode("label", {
8675
+ createBaseVNode("span", {
8552
8676
  class: normalizeClass(["sf-label", { required: $options.isRequired }])
8553
8677
  }, toDisplayString($options.title), 3 /* TEXT, CLASS */),
8554
- createBaseVNode("div", _hoisted_1$1, [
8678
+ createBaseVNode("div", _hoisted_1$2, [
8555
8679
  createCommentVNode(" Selected items "),
8556
8680
  ($data.selected.length)
8557
- ? (openBlock(), createElementBlock("div", _hoisted_2, [
8681
+ ? (openBlock(), createElementBlock("div", _hoisted_2$1, [
8558
8682
  (openBlock(true), createElementBlock(Fragment, null, renderList($data.selected, (item) => {
8559
8683
  return (openBlock(), createElementBlock("div", {
8560
8684
  key: $options.itemKey(item),
8561
8685
  class: "sf-relation-tag"
8562
8686
  }, [
8563
- createBaseVNode("span", _hoisted_3, toDisplayString($options.getDisplayName(item)), 1 /* TEXT */),
8687
+ createBaseVNode("span", _hoisted_3$1, toDisplayString($options.getDisplayName(item)), 1 /* TEXT */),
8564
8688
  ($data.isMultiple || $data.allowClear)
8565
8689
  ? (openBlock(), createElementBlock("button", {
8566
8690
  key: 0,
@@ -8569,14 +8693,14 @@ function render$2(_ctx, _cache, $props, $setup, $data, $options) {
8569
8693
  onClick: withModifiers($event => ($options.removeItem(item)), ["stop"])
8570
8694
  }, [
8571
8695
  createVNode(_component_SfIcon, { name: "times" })
8572
- ], 8 /* PROPS */, _hoisted_4))
8696
+ ], 8 /* PROPS */, _hoisted_4$1))
8573
8697
  : createCommentVNode("v-if", true)
8574
8698
  ]))
8575
8699
  }), 128 /* KEYED_FRAGMENT */))
8576
8700
  ]))
8577
8701
  : createCommentVNode("v-if", true),
8578
8702
  createCommentVNode(" Search box "),
8579
- withDirectives(createBaseVNode("div", _hoisted_5, [
8703
+ withDirectives(createBaseVNode("div", _hoisted_5$1, [
8580
8704
  withDirectives(createBaseVNode("input", {
8581
8705
  ref: "searchInput",
8582
8706
  type: "text",
@@ -8626,8 +8750,217 @@ function render$2(_ctx, _cache, $props, $setup, $data, $options) {
8626
8750
  ], 2 /* CLASS */))
8627
8751
  }
8628
8752
 
8753
+ script$4.render = render$3;
8754
+ script$4.__file = "src/editors/RelationEditor.vue";
8755
+
8756
+ const ACE_CDN = 'https://cdnjs.cloudflare.com/ajax/libs/ace/1.37.5/ace.min.js';
8757
+
8758
+ function loadAce() {
8759
+ if (window.ace) return Promise.resolve(window.ace);
8760
+ return new Promise((resolve, reject) => {
8761
+ const existing = document.querySelector(`script[src="${ACE_CDN}"]`);
8762
+ if (existing) {
8763
+ existing.addEventListener('load', () => resolve(window.ace));
8764
+ existing.addEventListener('error', reject);
8765
+ return;
8766
+ }
8767
+ const s = document.createElement('script');
8768
+ s.src = ACE_CDN;
8769
+ s.async = true;
8770
+ s.onload = () => resolve(window.ace);
8771
+ s.onerror = () => reject(new Error('Failed to load Ace Editor'));
8772
+ document.head.appendChild(s);
8773
+ });
8774
+ }
8775
+
8776
+ var script$3 = {
8777
+ name: 'JsonEditor',
8778
+ props: {
8779
+ schema: { type: Object, required: true },
8780
+ modelValue: { default: null },
8781
+ path: { type: Array, default: () => [] },
8782
+ form: { type: Object, default: null },
8783
+ },
8784
+ emits: ['update:modelValue'],
8785
+ data() {
8786
+ return {
8787
+ rawValue: this.modelValue != null ? JSON.stringify(this.modelValue, null, 2) : '{}',
8788
+ ready: false,
8789
+ hasErrors: false,
8790
+ loadError: null,
8791
+ _editor: null,
8792
+ _silent: false,
8793
+ };
8794
+ },
8795
+ computed: {
8796
+ title() {
8797
+ return this.schema.title || this.humanize(this.path[this.path.length - 1]) || '';
8798
+ },
8799
+ isRequired() {
8800
+ if (this.path.length < 2 || !this.form) return false;
8801
+ const parentPath = this.path.slice(0, -1);
8802
+ const fieldName = this.path[this.path.length - 1];
8803
+ const parentSchema = this.form.getSchemaAtPath(parentPath);
8804
+ return parentSchema && Array.isArray(parentSchema.required) && parentSchema.required.includes(fieldName);
8805
+ },
8806
+ fieldErrors() {
8807
+ if (!this.form || !this.form.getErrorsForPath) return [];
8808
+ return this.form.getErrorsForPath(this.path);
8809
+ },
8810
+ },
8811
+ watch: {
8812
+ modelValue(val) {
8813
+ if (this._silent) return;
8814
+ const external = val != null ? JSON.stringify(val, null, 2) : '{}';
8815
+ try {
8816
+ if (JSON.stringify(JSON.parse(this.rawValue)) !== JSON.stringify(val)) {
8817
+ this.rawValue = external;
8818
+ if (this._editor) {
8819
+ this._silent = true;
8820
+ this._editor.setValue(external, -1);
8821
+ this._silent = false;
8822
+ }
8823
+ }
8824
+ } catch { /* rawValue is invalid, leave it */ }
8825
+ },
8826
+ },
8827
+ async mounted() {
8828
+ try {
8829
+ const ace = await loadAce();
8830
+ const container = this.$refs.aceContainer;
8831
+ if (!container) return;
8832
+
8833
+ const editor = ace.edit(container);
8834
+ editor.setTheme(this._isDark() ? 'ace/theme/one_dark' : 'ace/theme/chrome');
8835
+ editor.session.setMode('ace/mode/json');
8836
+ editor.session.setTabSize(2);
8837
+ editor.session.setUseSoftTabs(true);
8838
+ editor.setShowPrintMargin(false);
8839
+ editor.setOption('minLines', 5);
8840
+ editor.setOption('maxLines', 20);
8841
+ editor.setValue(this.rawValue, -1);
8842
+ editor.$blockScrolling = Infinity;
8843
+
8844
+ editor.session.on('change', () => {
8845
+ if (this._silent) return;
8846
+ const text = editor.getValue();
8847
+ this.rawValue = text;
8848
+ try {
8849
+ const parsed = JSON.parse(text);
8850
+ this.hasErrors = false;
8851
+ this._silent = true;
8852
+ this.$emit('update:modelValue', parsed);
8853
+ this._silent = false;
8854
+ } catch {
8855
+ this.hasErrors = true;
8856
+ }
8857
+ });
8858
+
8859
+ // Reflect annotation (lint) errors on hasErrors
8860
+ editor.session.on('changeAnnotation', () => {
8861
+ const annotations = editor.session.getAnnotations();
8862
+ this.hasErrors = annotations.some(a => a.type === 'error');
8863
+ });
8864
+
8865
+ this._editor = editor;
8866
+ this.ready = true;
8867
+ } catch (err) {
8868
+ this.loadError = `Editor unavailable: ${err.message}`;
8869
+ }
8870
+ },
8871
+ beforeUnmount() {
8872
+ if (this._editor) {
8873
+ this._editor.destroy();
8874
+ this._editor = null;
8875
+ }
8876
+ },
8877
+ methods: {
8878
+ humanize(str) {
8879
+ if (!str) return '';
8880
+ return str.replace(/_/g, ' ').replace(/([a-z])([A-Z])/g, '$1 $2').replace(/^./, s => s.toUpperCase());
8881
+ },
8882
+ _isDark() {
8883
+ return document.documentElement.dataset.colorScheme === 'dark' ||
8884
+ window.matchMedia?.('(prefers-color-scheme: dark)').matches;
8885
+ },
8886
+ format() {
8887
+ if (!this._editor) return;
8888
+ try {
8889
+ const formatted = JSON.stringify(JSON.parse(this._editor.getValue()), null, 2);
8890
+ this._silent = true;
8891
+ this._editor.setValue(formatted, -1);
8892
+ this._silent = false;
8893
+ this.rawValue = formatted;
8894
+ } catch { /* invalid JSON */ }
8895
+ },
8896
+ onFallbackInput(e) {
8897
+ this.rawValue = e.target.value;
8898
+ try { this.$emit('update:modelValue', JSON.parse(this.rawValue)); } catch { /* ignore */ }
8899
+ },
8900
+ },
8901
+ };
8902
+
8903
+ const _hoisted_1$1 = { class: "sf-json-toolbar" };
8904
+ const _hoisted_2 = {
8905
+ key: 0,
8906
+ class: "sf-json-error-msg"
8907
+ };
8908
+ const _hoisted_3 = {
8909
+ ref: "aceContainer",
8910
+ class: "sf-json-ace-container"
8911
+ };
8912
+ const _hoisted_4 = ["value"];
8913
+ const _hoisted_5 = {
8914
+ key: 0,
8915
+ class: "errorlist"
8916
+ };
8917
+
8918
+ function render$2(_ctx, _cache, $props, $setup, $data, $options) {
8919
+ return (openBlock(), createElementBlock("div", {
8920
+ class: normalizeClass(["sf-field sf-field-json", { errors: $options.fieldErrors.length }])
8921
+ }, [
8922
+ createBaseVNode("span", {
8923
+ class: normalizeClass(["sf-label", { required: $options.isRequired }])
8924
+ }, toDisplayString($options.title), 3 /* TEXT, CLASS */),
8925
+ createBaseVNode("div", {
8926
+ class: normalizeClass(["sf-json-editor", { 'sf-json-error': $data.hasErrors }])
8927
+ }, [
8928
+ createBaseVNode("div", _hoisted_1$1, [
8929
+ ($data.loadError)
8930
+ ? (openBlock(), createElementBlock("span", _hoisted_2, toDisplayString($data.loadError), 1 /* TEXT */))
8931
+ : createCommentVNode("v-if", true),
8932
+ ($data.ready)
8933
+ ? (openBlock(), createElementBlock("button", {
8934
+ key: 1,
8935
+ type: "button",
8936
+ class: "sf-btn sf-btn-sm sf-json-format-btn",
8937
+ onClick: _cache[0] || (_cache[0] = (...args) => ($options.format && $options.format(...args)))
8938
+ }, " Format "))
8939
+ : createCommentVNode("v-if", true)
8940
+ ]),
8941
+ createBaseVNode("div", _hoisted_3, null, 512 /* NEED_PATCH */),
8942
+ (!$data.ready)
8943
+ ? (openBlock(), createElementBlock("textarea", {
8944
+ key: 0,
8945
+ class: "sf-input sf-textarea sf-json-textarea-fallback",
8946
+ value: $data.rawValue,
8947
+ spellcheck: "false",
8948
+ onInput: _cache[1] || (_cache[1] = (...args) => ($options.onFallbackInput && $options.onFallbackInput(...args)))
8949
+ }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_4))
8950
+ : createCommentVNode("v-if", true)
8951
+ ], 2 /* CLASS */),
8952
+ ($options.fieldErrors.length)
8953
+ ? (openBlock(), createElementBlock("ul", _hoisted_5, [
8954
+ (openBlock(true), createElementBlock(Fragment, null, renderList($options.fieldErrors, (err, i) => {
8955
+ return (openBlock(), createElementBlock("li", { key: i }, toDisplayString(err), 1 /* TEXT */))
8956
+ }), 128 /* KEYED_FRAGMENT */))
8957
+ ]))
8958
+ : createCommentVNode("v-if", true)
8959
+ ], 2 /* CLASS */))
8960
+ }
8961
+
8629
8962
  script$3.render = render$2;
8630
- script$3.__file = "src/editors/RelationEditor.vue";
8963
+ script$3.__file = "src/editors/JsonEditor.vue";
8631
8964
 
8632
8965
  var script$2 = {
8633
8966
  name: 'WebComponentWrapper',
@@ -8688,16 +9021,17 @@ const MAX_DEPTH = 12;
8688
9021
  var script$1 = {
8689
9022
  name: 'SchemaEditor',
8690
9023
  components: {
8691
- StringEditor: script$d,
8692
- NumberEditor: script$c,
8693
- BooleanEditor: script$b,
8694
- SelectEditor: script$a,
8695
- HiddenEditor: script$9,
8696
- ObjectEditor: script$7,
8697
- ArrayEditor: script$6,
8698
- NullableEditor: script$5,
8699
- UnionEditor: script$4,
8700
- RelationEditor: script$3,
9024
+ StringEditor: script$e,
9025
+ NumberEditor: script$d,
9026
+ BooleanEditor: script$c,
9027
+ SelectEditor: script$b,
9028
+ HiddenEditor: script$a,
9029
+ ObjectEditor: script$8,
9030
+ ArrayEditor: script$7,
9031
+ NullableEditor: script$6,
9032
+ UnionEditor: script$5,
9033
+ RelationEditor: script$4,
9034
+ JsonEditor: script$3,
8701
9035
  WebComponentWrapper: script$2,
8702
9036
  },
8703
9037
  inject: {
@@ -8741,8 +9075,9 @@ var script$1 = {
8741
9075
  if (schema.oneOf && schema.discriminator) return 'UnionEditor';
8742
9076
  if ('const' in schema) return 'HiddenEditor';
8743
9077
  if (schema.enum && schema.enum.length === 1 && schema.type === 'string') return 'HiddenEditor';
8744
- if (schema._nullable) return 'NullableEditor';
9078
+ if (schema._nullable && (schema.type === 'object' || schema.type === 'array')) return 'NullableEditor';
8745
9079
  if (schema.type === 'object' && schema.properties) return 'ObjectEditor';
9080
+ if (schema.type === 'object') return 'JsonEditor';
8746
9081
  if (schema.type === 'array') return 'ArrayEditor';
8747
9082
  if (schema.enum) return 'SelectEditor';
8748
9083
  if (schema.type === 'boolean') return 'BooleanEditor';
@@ -8789,12 +9124,14 @@ var script = {
8789
9124
  initialData: { default: undefined },
8790
9125
  errors: { type: Object, default: () => ({}) },
8791
9126
  customEditors: { type: Array, default: () => [] },
9127
+ language: { type: String, default: '' },
8792
9128
  },
8793
9129
  emits: ['change'],
8794
9130
  expose: ['getValue'],
8795
9131
  provide() {
8796
9132
  return {
8797
9133
  customEditors: () => this.customEditors,
9134
+ language: () => this.language,
8798
9135
  };
8799
9136
  },
8800
9137
  data() {
@@ -9078,5 +9415,5 @@ function registerCustomElement(tagName = 'schema-form') {
9078
9415
  }
9079
9416
  }
9080
9417
 
9081
- export { script$6 as ArrayEditor, BaseEditorElement, script$b as BooleanEditor, script$9 as HiddenEditor, script$5 as NullableEditor, script$c as NumberEditor, script$7 as ObjectEditor, script$3 as RelationEditor, script$1 as SchemaEditor, script as SchemaForm, SchemaFormElement, script$a as SelectEditor, script$d as StringEditor, script$4 as UnionEditor, script$2 as WebComponentWrapper, applyConditionals, hasConditionals, matchesSchema, registerCustomElement };
9418
+ export { script$7 as ArrayEditor, BaseEditorElement, script$c as BooleanEditor, script$a as HiddenEditor, script$6 as NullableEditor, script$d as NumberEditor, script$8 as ObjectEditor, script$4 as RelationEditor, script$1 as SchemaEditor, script as SchemaForm, SchemaFormElement, script$b as SelectEditor, script$e as StringEditor, script$5 as UnionEditor, script$2 as WebComponentWrapper, applyConditionals, hasConditionals, matchesSchema, registerCustomElement };
9082
9419
  //# sourceMappingURL=structured-widget-editor.esm.js.map