@kubohiroya/turbowarp-extension-data-editor 0.2.2 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4917,7 +4917,7 @@ var require_react_is_development = __commonJS({
4917
4917
  var ContextProvider = REACT_PROVIDER_TYPE;
4918
4918
  var Element = REACT_ELEMENT_TYPE;
4919
4919
  var ForwardRef = REACT_FORWARD_REF_TYPE;
4920
- var Fragment4 = REACT_FRAGMENT_TYPE;
4920
+ var Fragment5 = REACT_FRAGMENT_TYPE;
4921
4921
  var Lazy = REACT_LAZY_TYPE;
4922
4922
  var Memo = REACT_MEMO_TYPE;
4923
4923
  var Portal = REACT_PORTAL_TYPE;
@@ -4985,7 +4985,7 @@ var require_react_is_development = __commonJS({
4985
4985
  exports2.ContextProvider = ContextProvider;
4986
4986
  exports2.Element = Element;
4987
4987
  exports2.ForwardRef = ForwardRef;
4988
- exports2.Fragment = Fragment4;
4988
+ exports2.Fragment = Fragment5;
4989
4989
  exports2.Lazy = Lazy;
4990
4990
  exports2.Memo = Memo;
4991
4991
  exports2.Portal = Portal;
@@ -5027,7 +5027,317 @@ var require_react_is = __commonJS({
5027
5027
  });
5028
5028
 
5029
5029
  // dist/rjsf.js
5030
- import * as React4 from "react";
5030
+ import * as React6 from "react";
5031
+
5032
+ // dist/config/feature-flags.js
5033
+ function captureFeatureFlags(options = {}) {
5034
+ if (options.commonLayout !== void 0 && typeof options.commonLayout !== "boolean") {
5035
+ throw new TypeError("Invalid common layout feature flag.");
5036
+ }
5037
+ return Object.freeze({ commonLayout: options.commonLayout === true });
5038
+ }
5039
+
5040
+ // dist/layout-view.js
5041
+ import * as React2 from "react";
5042
+
5043
+ // dist/form-presentation.js
5044
+ import * as React from "react";
5045
+ function propertyLabel(key) {
5046
+ if (/^[a-z]{1,3}$/.test(key))
5047
+ return key;
5048
+ const text = key.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").replace(/\b(id|uri|url|json)\b/gi, (word) => word.toUpperCase());
5049
+ return text ? text[0].toUpperCase() + text.slice(1) : "\u8A2D\u5B9A";
5050
+ }
5051
+ function FormHelp({ description, id }) {
5052
+ if (typeof description !== "string" || !description.trim())
5053
+ return null;
5054
+ return description.length > 130 ? React.createElement(
5055
+ "details",
5056
+ { className: "editor-form-help", id },
5057
+ React.createElement("summary", null, "\u8AAC\u660E\u3092\u8868\u793A"),
5058
+ React.createElement("p", null, description)
5059
+ ) : React.createElement("p", { className: "editor-form-hint", id }, description);
5060
+ }
5061
+ var formStyles = `
5062
+ [data-editor-form]{--editor-accent:var(--block-editor-accent,#426ad6);--editor-line:var(--block-editor-border,#dde3ed);--editor-muted:var(--block-editor-muted,var(--block-editor-text,#637086));color:var(--block-editor-text,#25334a);font:14px/1.5 system-ui,sans-serif;min-width:0}
5063
+ [data-editor-form] *,[data-editor-form] *:before,[data-editor-form] *:after{box-sizing:border-box}
5064
+ [data-editor-form] fieldset{min-width:0}
5065
+ [data-editor-form] fieldset.editor-form-binding,[data-editor-form] .editor-form-section,[data-editor-form] .rjsf fieldset{padding:0;border:0;margin:0 0 18px}
5066
+ [data-editor-form] .editor-form-section>legend,[data-editor-form] .rjsf fieldset>legend{font-size:15px;font-weight:650;padding:0;margin:0 0 10px;color:inherit}
5067
+ [data-editor-form] .editor-form-field,[data-editor-form] .rjsf .form-group{margin:0 0 14px;min-width:0}
5068
+ [data-editor-form] .editor-form-field>label,[data-editor-form] .rjsf .control-label{display:block;font-size:13px;font-weight:600;margin:0 0 6px;color:inherit}
5069
+ [data-editor-form] .required{color:var(--editor-accent);margin-left:3px}
5070
+ [data-editor-form] input:not([type=checkbox]):not([type=radio]),[data-editor-form] select,[data-editor-form] textarea{display:block;width:100%;min-height:38px;margin:0;padding:8px 11px;border:1px solid var(--editor-line);border-radius:7px;background:var(--block-editor-input,white);color:inherit;font:inherit;box-shadow:0 1px 2px #172b4d05}
5071
+ [data-editor-form] textarea{min-height:76px;resize:vertical}
5072
+ [data-editor-form] input:focus-visible,[data-editor-form] select:focus-visible,[data-editor-form] textarea:focus-visible,[data-editor-form] button:focus-visible,[data-editor-form] summary:focus-visible{outline:2px solid var(--editor-accent);outline-offset:2px}
5073
+ [data-editor-form] input[readonly]{background:var(--block-editor-subtle,var(--block-editor-background,#f5f7fb));color:var(--editor-muted)}
5074
+ [data-editor-form] input[type=checkbox]{width:17px;height:17px;margin:0;accent-color:var(--editor-accent)}
5075
+ [data-editor-form] .editor-form-field>label.editor-form-toggle,[data-editor-form] .rjsf .checkbox>label{display:flex;align-items:center;gap:8px;font-weight:500;margin:8px 0}
5076
+ [data-editor-form] button{font:inherit;cursor:pointer;border:1px solid var(--editor-line);border-radius:6px;background:var(--block-editor-input,white);color:inherit;padding:6px 10px;margin:0}
5077
+ [data-editor-form] button:disabled{cursor:default;opacity:.5}
5078
+ [data-editor-form] .editor-form-hint,[data-editor-form] .editor-form-help{color:var(--editor-muted);font-size:12px;line-height:1.5;margin:5px 0 10px}
5079
+ [data-editor-form] .editor-form-help>summary{display:list-item;list-style:disclosure-closed inside;cursor:pointer;width:fit-content;font-weight:500}
5080
+ [data-editor-form] .editor-form-help[open]>summary{list-style-type:disclosure-open}
5081
+ [data-editor-form] .editor-form-help p{margin:8px 0}
5082
+ [data-editor-form] .block-editor-layout-tabs>[role=tablist]{display:flex;gap:4px;flex-wrap:wrap;padding:5px;background:var(--block-editor-subtle,var(--block-editor-background,#f1f4f9));border:1px solid var(--editor-line);border-radius:9px;margin:4px 0 20px}
5083
+ [data-editor-form] .block-editor-layout-tabs>[role=tablist]>button{border:0;border-radius:6px;background:transparent;color:var(--editor-muted);padding:8px 18px;margin:0;font-weight:550;text-decoration:none;min-width:76px}
5084
+ [data-editor-form] .block-editor-layout-tabs>[role=tablist]>[aria-selected=true]{background:var(--block-editor-input,white);color:var(--editor-accent);box-shadow:0 1px 4px #1d30431a}
5085
+ [data-editor-form] .editor-form-error-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;margin-left:7px;padding:0 5px;border-radius:10px;background:#fff0f0;color:#b53d45;font-size:11px}
5086
+ [data-editor-form] fieldset.block-editor-layout-group{border:1px solid var(--editor-line);border-radius:10px;padding:16px 18px 4px;margin:0 0 18px;background:var(--block-editor-background,white)}
5087
+ [data-editor-form] fieldset.block-editor-layout-group>legend{padding:0 6px;font-size:13px;font-weight:650}
5088
+ [data-editor-form] .block-editor-layout-grid{display:grid;gap:0 18px;grid-template-columns:repeat(var(--editor-columns),minmax(0,1fr));align-items:start}
5089
+ [data-editor-form] .block-editor-layout-grid>*{min-width:0}
5090
+ [data-editor-form] .block-editor-layout-tabs>[hidden]{display:none!important}
5091
+ [data-editor-form] .editor-form-toolbar{display:flex;align-items:start;justify-content:space-between;gap:12px;margin:0 0 18px;padding-bottom:14px;border-bottom:1px solid var(--editor-line)}
5092
+ [data-editor-form] .editor-form-modes{display:flex;gap:3px;border:1px solid var(--editor-line);border-radius:8px;padding:3px;background:var(--block-editor-subtle,var(--block-editor-background,#f1f4f9))}
5093
+ [data-editor-form] .editor-form-modes>button{border:0;border-radius:5px;padding:5px 14px;background:transparent;color:var(--editor-muted);margin:0}
5094
+ [data-editor-form] .editor-form-modes>[aria-pressed=true]{background:var(--block-editor-input,white);color:var(--editor-accent);box-shadow:0 1px 3px #1d30431a}
5095
+ [data-editor-form] .editor-form-tools{font-size:12px;color:var(--editor-muted);margin:0 0 12px}
5096
+ [data-editor-form] .editor-form-tools>summary{cursor:pointer;padding:5px 0;list-style-position:inside}
5097
+ [data-editor-form] .editor-form-tools[open]{padding:10px 12px;border:1px solid var(--editor-line);border-radius:8px;background:var(--block-editor-subtle,var(--block-editor-background,#f7f9fc))}
5098
+ [data-editor-form] .editor-form-tools button{border:1px solid var(--editor-line);border-radius:6px;background:var(--block-editor-input,white);padding:5px 9px;margin:5px 5px 5px 0;color:inherit}
5099
+ [data-editor-form] .editor-form-tools label{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:5px 0}
5100
+ [data-editor-form] .editor-form-invalid{font-size:12px;color:#b53d45;margin:5px 0}
5101
+ [data-editor-form] [data-source-error=true]>input,[data-editor-form] [data-source-error=true]>textarea{border-color:#b53d45}
5102
+ [data-editor-form] .editor-form-array-item{display:flex;align-items:start;gap:10px}
5103
+ [data-editor-form] .editor-form-array-item>.editor-form-field{flex:1;min-width:0}
5104
+ @media(max-width:600px){[data-editor-form] .block-editor-layout-grid{grid-template-columns:minmax(0,1fr)}[data-editor-form] fieldset.block-editor-layout-group{padding:12px 12px 0}[data-editor-form] .block-editor-layout-tabs>[role=tablist]>button{padding:7px 12px;min-width:60px}[data-editor-form] .editor-form-toolbar{flex-wrap:wrap}}
5105
+ `;
5106
+
5107
+ // dist/layout.js
5108
+ var record = (value) => !!value && typeof value === "object" && !Array.isArray(value);
5109
+ function resolveEditorLayout(ui, knownFields) {
5110
+ if (!record(ui) || !record(ui["ui:options"]) || !Object.hasOwn(ui["ui:options"], "extensionDataLayout"))
5111
+ return { kind: "absent" };
5112
+ const input = ui["ui:options"].extensionDataLayout;
5113
+ const known = new Set(knownFields), fields2 = /* @__PURE__ */ new Set();
5114
+ let count = 0;
5115
+ const fail2 = (message) => {
5116
+ throw new TypeError(message);
5117
+ };
5118
+ const keys2 = (node, expected) => {
5119
+ if (Object.keys(node).some((key) => !expected.includes(key)))
5120
+ fail2("Unknown layout option.");
5121
+ };
5122
+ const label = (text) => typeof text === "string" && text.trim().length > 0 && text.length <= 128 ? text : fail2("Invalid layout label.");
5123
+ const items = (value, depth) => {
5124
+ if (depth > 8 || !Array.isArray(value) || value.length > 256)
5125
+ return fail2("Layout limit exceeded.");
5126
+ return value.map((node) => {
5127
+ if (++count > 256 || !record(node))
5128
+ return fail2("Invalid layout item or limit exceeded.");
5129
+ if (Object.hasOwn(node, "field")) {
5130
+ keys2(node, ["field"]);
5131
+ if (typeof node.field !== "string" || !known.has(node.field))
5132
+ return fail2("Unknown layout field.");
5133
+ if (fields2.has(node.field))
5134
+ return fail2("Duplicate layout field.");
5135
+ fields2.add(node.field);
5136
+ return { field: node.field };
5137
+ }
5138
+ if (Object.hasOwn(node, "group")) {
5139
+ keys2(node, ["group", "items"]);
5140
+ return { group: label(node.group), items: items(node.items, depth + 1) };
5141
+ }
5142
+ if (Object.hasOwn(node, "grid")) {
5143
+ keys2(node, ["grid", "items"]);
5144
+ if (typeof node.grid !== "number" || !Number.isInteger(node.grid) || node.grid < 1 || node.grid > 4)
5145
+ return fail2("Grid columns must be 1\u20134.");
5146
+ return { grid: node.grid, items: items(node.items, depth + 1) };
5147
+ }
5148
+ if (Object.hasOwn(node, "tabs")) {
5149
+ keys2(node, ["tabs"]);
5150
+ if (!Array.isArray(node.tabs) || !node.tabs.length || node.tabs.length > 16)
5151
+ return fail2("Invalid tab count.");
5152
+ return { tabs: node.tabs.map((tab) => {
5153
+ if (++count > 256 || !record(tab))
5154
+ return fail2("Invalid tab or limit exceeded.");
5155
+ keys2(tab, ["label", "items"]);
5156
+ return { label: label(tab.label), items: items(tab.items, depth + 1) };
5157
+ }) };
5158
+ }
5159
+ return fail2("Unknown layout item.");
5160
+ });
5161
+ };
5162
+ try {
5163
+ if (!record(input) || input.version !== 1)
5164
+ return fail2("Unsupported layout version.");
5165
+ keys2(input, ["version", "items"]);
5166
+ return { kind: "layout", items: items(input.items, 0), fields: fields2 };
5167
+ } catch (error) {
5168
+ return { kind: "invalid", diagnostic: error instanceof Error ? error.message : "Invalid layout." };
5169
+ }
5170
+ }
5171
+
5172
+ // dist/layout-view.js
5173
+ var Environment = React2.createContext({ enabled: false, reveal: 0, disabled: false });
5174
+ var useCommonLayout = () => React2.useContext(Environment).enabled;
5175
+ var nextId = 0;
5176
+ function LayoutHost({ enabled, context, children }) {
5177
+ const [reveal, setReveal] = React2.useState(0);
5178
+ const [status, setStatus] = React2.useState(context.getState().status);
5179
+ const root2 = React2.useRef(null);
5180
+ React2.useLayoutEffect(() => {
5181
+ let saving = context.getState().status === "saving";
5182
+ let active = true;
5183
+ const stop = context.subscribe(() => {
5184
+ const state = context.getState();
5185
+ const failed = saving && state.status === "editing" && state.issues.length > 0;
5186
+ saving = state.status === "saving";
5187
+ setStatus(state.status);
5188
+ if (failed)
5189
+ void Promise.resolve().then(() => {
5190
+ if (active)
5191
+ setReveal((n2) => n2 + 1);
5192
+ });
5193
+ });
5194
+ return () => {
5195
+ active = false;
5196
+ stop();
5197
+ };
5198
+ }, [context]);
5199
+ React2.useEffect(() => {
5200
+ if (!enabled || !reveal)
5201
+ return;
5202
+ const timer = setTimeout(() => {
5203
+ var _a, _b, _c;
5204
+ const controls = (_a = root2.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll('[data-layout-error="true"] input, [data-layout-error="true"] textarea, [data-layout-error="true"] select');
5205
+ const candidates = Array.from(controls !== null && controls !== void 0 ? controls : []).filter((control) => !control.closest("[hidden]") && !control.matches(":disabled") && !control.hasAttribute("data-source-type-control"));
5206
+ const target = (_c = (_b = candidates.find((control) => {
5207
+ var _a2;
5208
+ return ((_a2 = control.closest("[data-source-path]")) === null || _a2 === void 0 ? void 0 : _a2.getAttribute("data-source-error")) === "true";
5209
+ })) !== null && _b !== void 0 ? _b : candidates.find((control) => {
5210
+ var _a2;
5211
+ return (_a2 = control.closest(".form-group")) === null || _a2 === void 0 ? void 0 : _a2.classList.contains("has-error");
5212
+ })) !== null && _c !== void 0 ? _c : candidates.find((control) => {
5213
+ var _a2;
5214
+ return ((_a2 = control.closest("[data-layout-field]")) === null || _a2 === void 0 ? void 0 : _a2.getAttribute("data-layout-error")) === "true";
5215
+ });
5216
+ target === null || target === void 0 ? void 0 : target.focus();
5217
+ }, 0);
5218
+ return () => clearTimeout(timer);
5219
+ }, [enabled, reveal]);
5220
+ return React2.createElement(Environment.Provider, { value: { enabled, reveal, disabled: status !== "editing" } }, enabled ? React2.createElement(
5221
+ "div",
5222
+ { ref: root2, "data-editor-form": "" },
5223
+ React2.createElement("style", null, formStyles),
5224
+ children
5225
+ ) : children);
5226
+ }
5227
+ function names(items) {
5228
+ return items.flatMap((item) => "field" in item ? [item.field] : "tabs" in item ? item.tabs.flatMap((tab) => names(tab.items)) : names(item.items));
5229
+ }
5230
+ function Items({ items, fields: fields2 }) {
5231
+ return React2.createElement(React2.Fragment, null, items.map((item, index) => {
5232
+ if ("field" in item) {
5233
+ const field = fields2.get(item.field);
5234
+ return field ? React2.createElement("div", { key: index, "data-layout-field": item.field, "data-layout-error": !!field.errors }, field.content) : null;
5235
+ }
5236
+ if ("tabs" in item)
5237
+ return React2.createElement(Tabs, { key: index, tabs: item.tabs, fields: fields2 });
5238
+ if ("group" in item)
5239
+ return React2.createElement(
5240
+ "fieldset",
5241
+ { className: "block-editor-layout-group", key: index },
5242
+ React2.createElement("legend", null, item.group),
5243
+ React2.createElement(Items, { items: item.items, fields: fields2 })
5244
+ );
5245
+ return React2.createElement(
5246
+ "div",
5247
+ { key: index, className: "block-editor-layout-grid", style: { "--editor-columns": item.grid } },
5248
+ React2.createElement(Items, { items: item.items, fields: fields2 })
5249
+ );
5250
+ }));
5251
+ }
5252
+ function Tabs({ tabs, fields: fields2 }) {
5253
+ const { reveal, disabled } = React2.useContext(Environment);
5254
+ const [selected, select] = React2.useState(0);
5255
+ const [id] = React2.useState(() => `block-editor-layout-${++nextId}`);
5256
+ const buttons = React2.useRef([]);
5257
+ const counts = tabs.map((tab) => names(tab.items).reduce((total, name) => {
5258
+ var _a, _b;
5259
+ return total + ((_b = (_a = fields2.get(name)) === null || _a === void 0 ? void 0 : _a.errors) !== null && _b !== void 0 ? _b : 0);
5260
+ }, 0));
5261
+ const errors = counts.join(",");
5262
+ const handled = React2.useRef(0);
5263
+ React2.useEffect(() => {
5264
+ if (reveal <= handled.current)
5265
+ return;
5266
+ const first = counts.findIndex((count) => count > 0);
5267
+ if (first >= 0) {
5268
+ handled.current = reveal;
5269
+ select(first);
5270
+ }
5271
+ }, [reveal, errors]);
5272
+ const current = Math.min(selected, tabs.length - 1);
5273
+ return React2.createElement(
5274
+ "div",
5275
+ { className: "block-editor-layout-tabs", "data-layout-errors": errors },
5276
+ React2.createElement("div", { role: "tablist", "aria-label": "\u30D5\u30A9\u30FC\u30E0\u306E\u9805\u76EE" }, tabs.map((tab, index) => React2.createElement(
5277
+ "button",
5278
+ { key: index, ref: (element) => {
5279
+ buttons.current[index] = element;
5280
+ }, type: "button", role: "tab", id: `${id}-tab-${index}`, "aria-controls": `${id}-panel-${index}`, "aria-selected": current === index, disabled, tabIndex: current === index ? 0 : -1, onClick: () => select(index), onKeyDown: (event) => {
5281
+ var _a;
5282
+ if (event.nativeEvent.isComposing || event.keyCode === 229)
5283
+ return;
5284
+ let target;
5285
+ switch (event.key) {
5286
+ case "ArrowRight":
5287
+ target = (index + 1) % tabs.length;
5288
+ break;
5289
+ case "ArrowLeft":
5290
+ target = (index + tabs.length - 1) % tabs.length;
5291
+ break;
5292
+ case "Home":
5293
+ target = 0;
5294
+ break;
5295
+ case "End":
5296
+ target = tabs.length - 1;
5297
+ break;
5298
+ default:
5299
+ return;
5300
+ }
5301
+ event.preventDefault();
5302
+ event.stopPropagation();
5303
+ select(target);
5304
+ (_a = buttons.current[target]) === null || _a === void 0 ? void 0 : _a.focus();
5305
+ } },
5306
+ tab.label,
5307
+ counts[index] ? React2.createElement("span", { className: "editor-form-error-badge", "aria-label": `\u30A8\u30E9\u30FC ${counts[index]} \u4EF6` }, counts[index]) : null
5308
+ ))),
5309
+ tabs.map((tab, index) => React2.createElement(
5310
+ "div",
5311
+ { key: index, role: "tabpanel", id: `${id}-panel-${index}`, "aria-labelledby": `${id}-tab-${index}`, hidden: current !== index },
5312
+ React2.createElement(Items, { items: tab.items, fields: fields2 })
5313
+ ))
5314
+ );
5315
+ }
5316
+ function ObjectLayout({ ui, fields: fields2, knownFields, fallback }) {
5317
+ const { enabled } = React2.useContext(Environment);
5318
+ const resolution = enabled ? resolveEditorLayout(ui, knownFields) : { kind: "absent" };
5319
+ if (resolution.kind === "absent")
5320
+ return React2.createElement(React2.Fragment, null, fallback);
5321
+ if (resolution.kind === "invalid")
5322
+ return React2.createElement(
5323
+ React2.Fragment,
5324
+ null,
5325
+ React2.createElement(
5326
+ "p",
5327
+ { role: "status", "data-layout-diagnostic": "" },
5328
+ "\u30EC\u30A4\u30A2\u30A6\u30C8\u3092\u9069\u7528\u3067\u304D\u307E\u305B\u3093: ",
5329
+ resolution.diagnostic
5330
+ ),
5331
+ fallback
5332
+ );
5333
+ const map2 = new Map(fields2.map((field) => [field.name, field]));
5334
+ return React2.createElement(
5335
+ React2.Fragment,
5336
+ null,
5337
+ React2.createElement(Items, { items: resolution.items, fields: map2 }),
5338
+ fields2.filter((field) => !resolution.fields.has(field.name)).map((field) => React2.createElement("div", { key: field.name, "data-layout-field": field.name, "data-layout-error": !!field.errors }, field.content))
5339
+ );
5340
+ }
5031
5341
 
5032
5342
  // node_modules/.pnpm/yaml@2.9.1/node_modules/yaml/browser/dist/nodes/identity.js
5033
5343
  var ALIAS = /* @__PURE__ */ Symbol.for("yaml.alias");
@@ -11403,7 +11713,7 @@ function sameData(left, right) {
11403
11713
  function fail() {
11404
11714
  throw new Error("Source cannot be edited without changing unedited data.");
11405
11715
  }
11406
- function record(value) {
11716
+ function record2(value) {
11407
11717
  return value !== null && typeof value === "object" && !Array.isArray(value);
11408
11718
  }
11409
11719
  function equal(left, right) {
@@ -11412,7 +11722,7 @@ function equal(left, right) {
11412
11722
  if (Array.isArray(left) && Array.isArray(right)) {
11413
11723
  return left.length === right.length && left.every((value, index) => equal(value, right[index]));
11414
11724
  }
11415
- if (record(left) && record(right)) {
11725
+ if (record2(left) && record2(right)) {
11416
11726
  const keys2 = Object.keys(left);
11417
11727
  return keys2.length === Object.keys(right).length && keys2.every((key) => Object.hasOwn(right, key) && equal(left[key], right[key]));
11418
11728
  }
@@ -11577,7 +11887,7 @@ function patchJson(source, original, edited) {
11577
11887
  const visit3 = (node, before, after) => {
11578
11888
  if (equal(before, after))
11579
11889
  return;
11580
- if (record(before) && record(after) && node.kind === "object") {
11890
+ if (record2(before) && record2(after) && node.kind === "object") {
11581
11891
  const entries = node.entries;
11582
11892
  const last2 = /* @__PURE__ */ new Map();
11583
11893
  entries.forEach((entry, index) => last2.set(entry.key, index));
@@ -11686,11 +11996,11 @@ function patchYaml(source, original, edited) {
11686
11996
  if (!node || isAlias(node) || "anchor" in node && node.anchor || node.tag)
11687
11997
  fail();
11688
11998
  const [start, end] = yamlRange(node);
11689
- if (isMap(node) && record(before) && record(after) || isSeq(node) && Array.isArray(before) && Array.isArray(after)) {
11999
+ if (isMap(node) && record2(before) && record2(after) || isSeq(node) && Array.isArray(before) && Array.isArray(after)) {
11690
12000
  const entries = [];
11691
12001
  const items = [];
11692
12002
  const additions = [];
11693
- if (isMap(node) && record(before) && record(after)) {
12003
+ if (isMap(node) && record2(before) && record2(after)) {
11694
12004
  for (const pair of node.items) {
11695
12005
  if (!isScalar(pair.key) || typeof pair.key.value !== "string")
11696
12006
  fail();
@@ -11818,9 +12128,130 @@ function prepareSourceVariant(variant) {
11818
12128
  }
11819
12129
 
11820
12130
  // dist/source-view.js
11821
- import * as React from "react";
12131
+ import * as React3 from "react";
11822
12132
  import * as ReactDOM from "react-dom";
11823
- var record2 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
12133
+
12134
+ // dist/schema-presentation.js
12135
+ var schemaRecord = (value) => !!value && typeof value === "object" && !Array.isArray(value);
12136
+ var jsonTypes = ["object", "array", "string", "number", "boolean", "null"];
12137
+ var valueType = (value) => value === null ? "null" : Array.isArray(value) ? "array" : typeof value;
12138
+ function presentationTypes(schema4, reference = () => void 0, seen = /* @__PURE__ */ new Set()) {
12139
+ if (schema4 === false)
12140
+ return /* @__PURE__ */ new Set();
12141
+ if (!schemaRecord(schema4) || seen.has(schema4))
12142
+ return new Set(jsonTypes);
12143
+ const visited = new Set(seen);
12144
+ visited.add(schema4);
12145
+ let types = new Set(jsonTypes);
12146
+ const intersect = (other) => {
12147
+ types = new Set([...types].filter((type) => other.has(type)));
12148
+ };
12149
+ const infer = (child) => presentationTypes(child, reference, visited);
12150
+ if (typeof schema4.$ref === "string")
12151
+ intersect(infer(reference(schema4.$ref)));
12152
+ if (schema4.type !== void 0) {
12153
+ const declared = Array.isArray(schema4.type) ? schema4.type : [schema4.type];
12154
+ intersect(new Set(declared.map((type) => type === "integer" ? "number" : type)));
12155
+ }
12156
+ if (Object.hasOwn(schema4, "const"))
12157
+ intersect(/* @__PURE__ */ new Set([valueType(schema4.const)]));
12158
+ if (Array.isArray(schema4.enum))
12159
+ intersect(new Set(schema4.enum.map(valueType)));
12160
+ if (Array.isArray(schema4.allOf))
12161
+ schema4.allOf.forEach((child) => intersect(infer(child)));
12162
+ for (const keyword of ["anyOf", "oneOf"]) {
12163
+ const children = schema4[keyword];
12164
+ if (Array.isArray(children))
12165
+ intersect(new Set(children.flatMap((child) => [...infer(child)])));
12166
+ }
12167
+ return types;
12168
+ }
12169
+ function presentationInitial(schema4) {
12170
+ if (schemaRecord(schema4)) {
12171
+ if (Object.hasOwn(schema4, "const"))
12172
+ return schema4.const;
12173
+ if (Array.isArray(schema4.enum) && schema4.enum.length)
12174
+ return schema4.enum[0];
12175
+ }
12176
+ const types = presentationTypes(schema4);
12177
+ if (types.size !== 1)
12178
+ return null;
12179
+ switch ([...types][0]) {
12180
+ case "object":
12181
+ return {};
12182
+ case "array":
12183
+ return [];
12184
+ case "string":
12185
+ return "";
12186
+ case "number":
12187
+ return 0;
12188
+ case "boolean":
12189
+ return false;
12190
+ default:
12191
+ return null;
12192
+ }
12193
+ }
12194
+ function presentationCondition(schema4, data, reference, seen = /* @__PURE__ */ new Set()) {
12195
+ if (typeof schema4 === "boolean")
12196
+ return schema4;
12197
+ if (!schemaRecord(schema4) || seen.has(schema4))
12198
+ return void 0;
12199
+ const supported = ["type", "const", "enum", "required", "properties", "allOf", "anyOf", "oneOf", "not", "$ref", "$id", "$schema", "title", "description", "$comment"];
12200
+ if (Object.keys(schema4).some((key) => !supported.includes(key)))
12201
+ return void 0;
12202
+ const visited = new Set(seen);
12203
+ visited.add(schema4);
12204
+ const test = (child, value = data) => presentationCondition(child, value, reference, visited);
12205
+ const equal2 = (a2, b2) => {
12206
+ if (a2 === b2)
12207
+ return true;
12208
+ if (Array.isArray(a2) && Array.isArray(b2))
12209
+ return a2.length === b2.length && a2.every((child, index) => equal2(child, b2[index]));
12210
+ return schemaRecord(a2) && schemaRecord(b2) && Object.keys(a2).length === Object.keys(b2).length && Object.keys(a2).every((key) => Object.hasOwn(b2, key) && equal2(a2[key], b2[key]));
12211
+ };
12212
+ const results = [];
12213
+ if (typeof schema4.$ref === "string")
12214
+ results.push(test(reference(schema4.$ref)));
12215
+ if (schema4.type !== void 0) {
12216
+ const types = Array.isArray(schema4.type) ? schema4.type : [schema4.type];
12217
+ results.push(types.some((type) => type === "integer" ? typeof data === "number" && Number.isInteger(data) : type === valueType(data)));
12218
+ }
12219
+ if (Object.hasOwn(schema4, "const"))
12220
+ results.push(equal2(data, schema4.const));
12221
+ if (Array.isArray(schema4.enum))
12222
+ results.push(schema4.enum.some((item) => equal2(data, item)));
12223
+ if (schemaRecord(data)) {
12224
+ if (Array.isArray(schema4.required))
12225
+ results.push(schema4.required.every((key) => typeof key === "string" && Object.hasOwn(data, key)));
12226
+ if (schemaRecord(schema4.properties)) {
12227
+ for (const [key, child] of Object.entries(schema4.properties))
12228
+ if (Object.hasOwn(data, key))
12229
+ results.push(test(child, data[key]));
12230
+ }
12231
+ }
12232
+ if (Array.isArray(schema4.allOf))
12233
+ results.push(...schema4.allOf.map((child) => test(child)));
12234
+ for (const keyword of ["anyOf", "oneOf"]) {
12235
+ const children = schema4[keyword];
12236
+ if (!Array.isArray(children))
12237
+ continue;
12238
+ const states = children.map((child) => test(child));
12239
+ if (keyword === "anyOf")
12240
+ results.push(states.includes(true) ? true : states.includes(void 0) ? void 0 : false);
12241
+ else
12242
+ results.push(states.includes(void 0) ? void 0 : states.filter(Boolean).length === 1);
12243
+ }
12244
+ if (Object.hasOwn(schema4, "not")) {
12245
+ const result = test(schema4.not);
12246
+ results.push(result === void 0 ? void 0 : !result);
12247
+ }
12248
+ return results.includes(false) ? false : results.includes(void 0) ? void 0 : true;
12249
+ }
12250
+
12251
+ // dist/source-view.js
12252
+ var nextFieldId = 0;
12253
+ var SourcePaths = React3.createContext([]);
12254
+ var record3 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
11824
12255
  var pointer = (path, key) => `${path}/${key.replace(/~/g, "~0").replace(/\//g, "~1")}`;
11825
12256
  var typeOf = (v2) => v2 === null ? "null" : Array.isArray(v2) ? "array" : typeof v2;
11826
12257
  var initial = (type) => {
@@ -11841,11 +12272,13 @@ var initial = (type) => {
11841
12272
  };
11842
12273
  function mergeHints(left, right) {
11843
12274
  const result = { ...left, ...right };
12275
+ if (Array.isArray(left.required) && Array.isArray(right.required))
12276
+ result.required = [.../* @__PURE__ */ new Set([...left.required, ...right.required])];
11844
12277
  for (const field of ["properties", "patternProperties"]) {
11845
- if (!record2(left[field]) && !record2(right[field]))
12278
+ if (!record3(left[field]) && !record3(right[field]))
11846
12279
  continue;
11847
- const a2 = record2(left[field]) ? left[field] : {};
11848
- const b2 = record2(right[field]) ? right[field] : {};
12280
+ const a2 = record3(left[field]) ? left[field] : {};
12281
+ const b2 = record3(right[field]) ? right[field] : {};
11849
12282
  const combined = { ...a2 };
11850
12283
  for (const [key, child] of Object.entries(b2))
11851
12284
  Object.defineProperty(combined, key, {
@@ -11861,9 +12294,9 @@ function mergeHints(left, right) {
11861
12294
  }
11862
12295
  function propertyHint(hints, key) {
11863
12296
  const matches = [];
11864
- if (record2(hints.properties) && Object.hasOwn(hints.properties, key))
12297
+ if (record3(hints.properties) && Object.hasOwn(hints.properties, key))
11865
12298
  matches.push(hints.properties[key]);
11866
- if (record2(hints.patternProperties))
12299
+ if (record3(hints.patternProperties))
11867
12300
  for (const [pattern, schema4] of Object.entries(hints.patternProperties)) {
11868
12301
  try {
11869
12302
  if (new RegExp(pattern, "u").test(key))
@@ -11873,54 +12306,61 @@ function propertyHint(hints, key) {
11873
12306
  }
11874
12307
  return matches.length > 1 ? { allOf: matches } : matches.length ? matches[0] : hints.additionalProperties;
11875
12308
  }
11876
- function resolveHints(variant, schema4, data, seen = /* @__PURE__ */ new Set()) {
12309
+ function sourceReference(variant, ref) {
12310
+ const hash = ref.indexOf("#");
12311
+ const uri2 = hash < 0 ? ref : ref.slice(0, hash);
12312
+ const resources = [variant.schemaBundle.root, ...variant.schemaBundle.resources];
12313
+ const resource = uri2 ? resources.find((r2) => r2.retrievalUri === uri2 || record3(r2.document) && r2.document.$id === uri2) : variant.schemaBundle.root;
12314
+ let target = resource === null || resource === void 0 ? void 0 : resource.document;
12315
+ const fragment = hash < 0 ? "" : decodeURIComponent(ref.slice(hash + 1));
12316
+ if (fragment.startsWith("/"))
12317
+ for (const part of fragment.slice(1).split("/")) {
12318
+ target = record3(target) || Array.isArray(target) ? target[part.replace(/~1/g, "/").replace(/~0/g, "~")] : void 0;
12319
+ }
12320
+ return !fragment || fragment.startsWith("/") ? target : void 0;
12321
+ }
12322
+ function resolveHints(variant, schema4, data, seen = /* @__PURE__ */ new Set(), conditional = false) {
11877
12323
  var _a;
11878
- if (!record2(schema4) || seen.has(schema4))
12324
+ if (!record3(schema4) || seen.has(schema4))
11879
12325
  return {};
11880
12326
  seen.add(schema4);
11881
12327
  let result = { ...schema4 };
11882
12328
  if (typeof schema4.$ref === "string") {
11883
- const ref = schema4.$ref;
11884
- const hash = ref.indexOf("#");
11885
- const uri2 = hash < 0 ? ref : ref.slice(0, hash);
11886
- const resources = [variant.schemaBundle.root, ...variant.schemaBundle.resources];
11887
- const resource = uri2 ? resources.find((r2) => r2.retrievalUri === uri2 || record2(r2.document) && r2.document.$id === uri2) : variant.schemaBundle.root;
11888
- let target = resource === null || resource === void 0 ? void 0 : resource.document;
11889
- const fragment = hash < 0 ? "" : decodeURIComponent(ref.slice(hash + 1));
11890
- if (fragment.startsWith("/"))
11891
- for (const part of fragment.slice(1).split("/")) {
11892
- target = record2(target) || Array.isArray(target) ? target[part.replace(/~1/g, "/").replace(/~0/g, "~")] : void 0;
11893
- }
11894
- if (!fragment || fragment.startsWith("/"))
11895
- result = mergeHints(resolveHints(variant, target, data, seen), result);
12329
+ result = mergeHints(resolveHints(variant, sourceReference(variant, schema4.$ref), data, seen, conditional), result);
11896
12330
  }
11897
12331
  if (Array.isArray(schema4.allOf))
11898
12332
  for (const part of schema4.allOf) {
11899
- const next = resolveHints(variant, part, data, seen);
12333
+ const next = resolveHints(variant, part, data, seen, conditional);
11900
12334
  result = mergeHints(result, next);
11901
12335
  }
12336
+ if (conditional && Object.hasOwn(schema4, "if")) {
12337
+ const matches = presentationCondition(schema4.if, data, (ref) => sourceReference(variant, ref));
12338
+ const branch = matches === true ? schema4.then : matches === false ? schema4.else : void 0;
12339
+ if (branch !== void 0)
12340
+ result = mergeHints(result, resolveHints(variant, branch, data, seen, conditional));
12341
+ }
11902
12342
  const alternatives = (_a = schema4.oneOf) !== null && _a !== void 0 ? _a : schema4.anyOf;
11903
12343
  if (Array.isArray(alternatives)) {
11904
12344
  const choices = alternatives.filter((part) => {
11905
- if (!record2(part))
12345
+ if (!record3(part))
11906
12346
  return false;
11907
12347
  if (typeof part.type === "string" && part.type !== typeOf(data) && !(part.type === "integer" && typeof data === "number"))
11908
12348
  return false;
11909
- if (record2(part.properties) && record2(data))
12349
+ if (record3(part.properties) && record3(data))
11910
12350
  for (const [key, child] of Object.entries(part.properties)) {
11911
- if (record2(child) && Object.hasOwn(child, "const") && data[key] !== child.const)
12351
+ if (record3(child) && Object.hasOwn(child, "const") && data[key] !== child.const)
11912
12352
  return false;
11913
12353
  }
11914
12354
  return true;
11915
12355
  });
11916
12356
  if (choices.length === 1)
11917
- result = mergeHints(result, resolveHints(variant, choices[0], data, seen));
12357
+ result = mergeHints(result, resolveHints(variant, choices[0], data, seen, conditional));
11918
12358
  }
11919
12359
  if (!Array.isArray(result.enum)) {
11920
12360
  if (Object.hasOwn(result, "const"))
11921
12361
  result.enum = [result.const];
11922
12362
  else if (Array.isArray(alternatives)) {
11923
- const enums = alternatives.map((part) => resolveHints(variant, part, data, new Set(seen)));
12363
+ const enums = alternatives.map((part) => resolveHints(variant, part, data, new Set(seen), conditional));
11924
12364
  if (enums.length && enums.every((part) => Array.isArray(part.enum))) {
11925
12365
  const values = enums.flatMap((part) => part.enum);
11926
12366
  result.enum = [...new Map(values.map((value) => [JSON.stringify(value), value])).values()];
@@ -11929,135 +12369,236 @@ function resolveHints(variant, schema4, data, seen = /* @__PURE__ */ new Set())
11929
12369
  }
11930
12370
  return result;
11931
12371
  }
11932
- function Tree({ value, path, schema: schema4, ui, variant, invalidNumbers, change: onChange }) {
12372
+ function Tree({ value, path, schema: schema4, ui, variant, invalidNumbers, required, change: onChange }) {
11933
12373
  var _a;
11934
- const hints = resolveHints(variant, schema4, value);
11935
- const uiHints = record2(ui) ? ui : {};
11936
- const [newKey, setNewKey] = React.useState("");
12374
+ const errors = React3.useContext(SourcePaths);
12375
+ const commonLayout = useCommonLayout();
12376
+ const hints = resolveHints(variant, schema4, value, /* @__PURE__ */ new Set(), commonLayout);
12377
+ const uiHints = record3(ui) ? ui : {};
12378
+ const [newKey, setNewKey] = React3.useState("");
12379
+ const [id] = React3.useState(() => `source-field-${++nextFieldId}`);
11937
12380
  const change = (next, edit = { path }) => onChange(next, edit);
11938
12381
  const choices = Array.isArray(hints.enum) ? hints.enum : Array.isArray(uiHints["ui:enum"]) ? uiHints["ui:enum"] : void 0;
11939
- const label = typeof hints.title === "string" ? hints.title : path || "/";
11940
- const props = { "aria-label": label };
12382
+ const key = path.slice(path.lastIndexOf("/") + 1).replace(/~1/g, "/").replace(/~0/g, "~");
12383
+ const label = commonLayout && typeof uiHints["ui:title"] === "string" ? uiHints["ui:title"] : typeof hints.title === "string" ? hints.title : commonLayout ? propertyLabel(key) : path || "/";
11941
12384
  const type = typeOf(value);
12385
+ const allowed = presentationTypes(schema4, (ref) => sourceReference(variant, ref));
12386
+ const fixedType = allowed.size === 1 && allowed.has(type);
12387
+ const readonly = commonLayout && (hints.readOnly === true || uiHints["ui:readonly"] === true || uiHints["ui:disabled"] === true);
12388
+ const props = { "aria-label": label, ...commonLayout ? { id, disabled: readonly, "aria-describedby": typeof hints.description === "string" && hints.description.trim() ? `${id}-help` : void 0 } : {} };
12389
+ const typeControl = !commonLayout || !fixedType ? React3.createElement("select", { "data-source-type-control": "", "aria-label": `Type ${path || "/"}`, disabled: readonly, value: type, onChange: (e2) => change(initial(e2.target.value)) }, (commonLayout && allowed.size ? [.../* @__PURE__ */ new Set([type, ...allowed])] : jsonTypes).map((t) => React3.createElement("option", { key: t }, t))) : null;
12390
+ const seed = (hint) => cloneJson(presentationInitial(hint));
11942
12391
  let field;
11943
12392
  if (choices) {
11944
12393
  const serialized2 = JSON.stringify(value);
11945
12394
  const options = choices.map((item) => JSON.stringify(item));
11946
12395
  if (!options.includes(serialized2))
11947
12396
  options.unshift(serialized2);
11948
- field = React.createElement("select", { ...props, value: serialized2, onChange: (e2) => change(JSON.parse(e2.target.value)) }, options.map((item) => React.createElement("option", { key: item, value: item }, item)));
12397
+ field = commonLayout && options.length === 1 ? React3.createElement("input", { ...props, readOnly: true, value: typeof value === "string" ? value : serialized2 }) : React3.createElement("select", { ...props, value: serialized2, onChange: (e2) => change(JSON.parse(e2.target.value)) }, options.map((item) => React3.createElement("option", { key: item, value: item }, commonLayout && typeof JSON.parse(item) === "string" ? JSON.parse(item) : item)));
11949
12398
  } else if (typeof value === "string") {
11950
- field = React.createElement("textarea", { ...props, value, onChange: (e2) => change(e2.target.value) });
12399
+ field = commonLayout && uiHints["ui:widget"] !== "textarea" && !value.includes("\n") ? React3.createElement("input", { ...props, type: "text", value, onChange: (e2) => change(e2.target.value) }) : React3.createElement("textarea", { ...props, value, onChange: (e2) => change(e2.target.value) });
11951
12400
  } else if (typeof value === "number") {
11952
- field = React.createElement("input", { ...props, type: "text", inputMode: "decimal", value: (_a = invalidNumbers[path]) !== null && _a !== void 0 ? _a : String(value), onChange: (e2) => {
12401
+ field = React3.createElement("input", { ...props, type: "text", inputMode: "decimal", value: (_a = invalidNumbers[path]) !== null && _a !== void 0 ? _a : String(value), onChange: (e2) => {
11953
12402
  const text = e2.target.value;
11954
12403
  const number = /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?$/.test(text) ? Number(text) : NaN;
11955
12404
  change(Number.isFinite(number) ? number : value, { path, ...Number.isFinite(number) ? {} : { invalidText: text } });
11956
12405
  } });
11957
12406
  } else if (typeof value === "boolean") {
11958
- field = React.createElement("input", { ...props, type: "checkbox", checked: value, onChange: (e2) => change(e2.target.checked) });
12407
+ field = React3.createElement("input", { ...props, type: "checkbox", checked: value, onChange: (e2) => change(e2.target.checked) });
11959
12408
  } else if (Array.isArray(value)) {
11960
- field = React.createElement(
12409
+ const itemHint = (index) => {
12410
+ var _a2, _b;
12411
+ return Array.isArray(hints.prefixItems) ? (_a2 = hints.prefixItems[index]) !== null && _a2 !== void 0 ? _a2 : hints.items : Array.isArray(hints.items) ? (_b = hints.items[index]) !== null && _b !== void 0 ? _b : hints.additionalItems : hints.items;
12412
+ };
12413
+ const tuple = Array.isArray(hints.prefixItems) || Array.isArray(hints.items);
12414
+ const canRemove = !commonLayout || value.length > (typeof hints.minItems === "number" ? hints.minItems : 0);
12415
+ const canAdd = !commonLayout || itemHint(value.length) !== false && (typeof hints.maxItems !== "number" || value.length < hints.maxItems);
12416
+ field = React3.createElement(
11961
12417
  "div",
11962
12418
  null,
11963
- value.map((child, index) => {
11964
- var _a2;
11965
- return React.createElement(
11966
- "div",
11967
- { key: index },
11968
- React.createElement(Tree, { invalidNumbers, value: child, path: pointer(path, String(index)), variant, schema: Array.isArray(hints.prefixItems) ? (_a2 = hints.prefixItems[index]) !== null && _a2 !== void 0 ? _a2 : hints.items : Array.isArray(hints.items) ? hints.items[index] : hints.items, ui: uiHints.items, change: (next, edit) => {
11969
- const copy = [...value];
11970
- copy[index] = next;
11971
- change(copy, edit);
11972
- } }),
11973
- React.createElement("button", { type: "button", "aria-label": `Remove ${pointer(path, String(index))}`, onClick: () => change(value.filter((_2, i2) => i2 !== index), { path, removeIndex: index }) }, "Remove"),
11974
- React.createElement("button", { type: "button", disabled: index === 0, "aria-label": `Move up ${pointer(path, String(index))}`, onClick: () => {
11975
- const copy = [...value];
11976
- [copy[index - 1], copy[index]] = [copy[index], copy[index - 1]];
11977
- change(copy, { path, swap: [index - 1, index] });
11978
- } }, "\u2191")
11979
- );
11980
- }),
11981
- React.createElement("button", { type: "button", "aria-label": `Add item ${path || "/"}`, onClick: () => change([...value, null], { path: pointer(path, String(value.length)) }) }, "Add item")
12419
+ commonLayout && value.length === 0 && React3.createElement("p", { className: "editor-form-hint" }, "\u9805\u76EE\u306A\u3057"),
12420
+ value.map((child, index) => React3.createElement(
12421
+ "div",
12422
+ { key: index, className: commonLayout ? "editor-form-array-item" : void 0 },
12423
+ React3.createElement(Tree, { invalidNumbers, value: child, path: pointer(path, String(index)), variant, schema: itemHint(index), ui: uiHints.items, change: (next, edit) => {
12424
+ const copy = [...value];
12425
+ copy[index] = next;
12426
+ change(copy, edit);
12427
+ } }),
12428
+ canRemove && React3.createElement("button", { type: "button", "aria-label": `Remove ${pointer(path, String(index))}`, onClick: () => change(value.filter((_2, i2) => i2 !== index), { path, removeIndex: index }) }, "Remove"),
12429
+ (!commonLayout || !tuple && value.length > 1) && React3.createElement("button", { type: "button", disabled: index === 0, "aria-label": `Move up ${pointer(path, String(index))}`, onClick: () => {
12430
+ const copy = [...value];
12431
+ [copy[index - 1], copy[index]] = [copy[index], copy[index - 1]];
12432
+ change(copy, { path, swap: [index - 1, index] });
12433
+ } }, "\u2191")
12434
+ )),
12435
+ canAdd && React3.createElement("button", { type: "button", "aria-label": `Add item ${path || "/"}`, onClick: () => change([...value, commonLayout ? seed(resolveHints(variant, itemHint(value.length), null)) : null], { path: pointer(path, String(value.length)) }) }, "Add item")
11982
12436
  );
11983
12437
  } else if (value !== null && typeof value === "object") {
11984
- const properties = record2(hints.properties) ? hints.properties : {};
11985
- field = React.createElement(
11986
- "div",
11987
- null,
11988
- Object.entries(value).map(([key, child]) => React.createElement(
12438
+ const properties = record3(hints.properties) ? hints.properties : {};
12439
+ const requiredKeys = new Set(Array.isArray(hints.required) ? hints.required : []);
12440
+ const optional = Object.keys(properties).filter((name) => !requiredKeys.has(name));
12441
+ const missing = Object.keys(properties).filter((name) => !Object.hasOwn(value, name));
12442
+ const remove = (name) => {
12443
+ const copy = cloneJson(value);
12444
+ delete copy[name];
12445
+ change(copy, { path: pointer(path, name) });
12446
+ };
12447
+ const add = (name) => {
12448
+ const hint = resolveHints(variant, propertyHint(hints, name), null);
12449
+ const copy = cloneJson(value);
12450
+ Object.defineProperty(copy, name, { value: seed(hint), enumerable: true, writable: true, configurable: true });
12451
+ change(copy, { path: pointer(path, name) });
12452
+ setNewKey("");
12453
+ };
12454
+ const fields2 = Object.entries(value).map(([name, child]) => ({
12455
+ name,
12456
+ errors: errors.filter((error) => error === pointer(path, name) || error.startsWith(pointer(path, name) + "/")).length,
12457
+ content: React3.createElement(
11989
12458
  "div",
11990
- { key },
11991
- React.createElement(Tree, { invalidNumbers, value: child, path: pointer(path, key), variant, schema: propertyHint(hints, key), ui: uiHints[key], change: (next, edit) => {
12459
+ { key: name },
12460
+ React3.createElement(Tree, { invalidNumbers, value: child, path: pointer(path, name), variant, schema: propertyHint(hints, name), required: requiredKeys.has(name), ui: uiHints[name], change: (next, edit) => {
11992
12461
  const copy = cloneJson(value);
11993
- Object.defineProperty(copy, key, { value: next, enumerable: true, writable: true, configurable: true });
12462
+ Object.defineProperty(copy, name, { value: next, enumerable: true, writable: true, configurable: true });
11994
12463
  change(copy, edit);
11995
12464
  } }),
11996
- React.createElement("button", { type: "button", "aria-label": `Remove ${pointer(path, key)}`, onClick: () => {
12465
+ (!commonLayout || !Object.hasOwn(properties, name) && !requiredKeys.has(name)) && React3.createElement("button", { type: "button", "aria-label": `Remove ${pointer(path, name)}`, onClick: () => remove(name) }, "Remove")
12466
+ )
12467
+ }));
12468
+ const dynamic = hints.additionalProperties !== false || record3(hints.patternProperties);
12469
+ field = React3.createElement(
12470
+ "div",
12471
+ null,
12472
+ React3.createElement(ObjectLayout, { ui: uiHints, knownFields: [.../* @__PURE__ */ new Set([...Object.keys(properties), ...Object.keys(value)])], fields: fields2, fallback: fields2.map((item) => item.content) }),
12473
+ commonLayout ? React3.createElement(
12474
+ React3.Fragment,
12475
+ null,
12476
+ (missing.length > 0 || optional.some((name) => Object.hasOwn(value, name))) && React3.createElement(
12477
+ "details",
12478
+ { className: "editor-form-tools" },
12479
+ React3.createElement("summary", null, "\u9805\u76EE\u3092\u7BA1\u7406"),
12480
+ missing.map((name) => React3.createElement(
12481
+ "button",
12482
+ { type: "button", key: name, onClick: () => add(name) },
12483
+ propertyLabel(name),
12484
+ "\u3092\u8FFD\u52A0"
12485
+ )),
12486
+ optional.filter((name) => Object.hasOwn(value, name)).map((name) => React3.createElement(
12487
+ "label",
12488
+ { key: name },
12489
+ propertyLabel(name),
12490
+ React3.createElement("button", { type: "button", "aria-label": `Remove ${pointer(path, name)}`, onClick: () => remove(name) }, "\u5024\u3092\u89E3\u9664")
12491
+ ))
12492
+ ),
12493
+ dynamic && React3.createElement(
12494
+ "details",
12495
+ { className: "editor-form-tools" },
12496
+ React3.createElement("summary", null, "\u8FFD\u52A0\u306E\u30D7\u30ED\u30D1\u30C6\u30A3"),
12497
+ React3.createElement("label", { htmlFor: `${id}-key` }, "\u9805\u76EE\u540D"),
12498
+ React3.createElement("input", { id: `${id}-key`, "aria-label": `New property ${path || "/"}`, value: newKey, onChange: (e2) => setNewKey(e2.target.value) }),
12499
+ React3.createElement("button", { type: "button", disabled: !newKey || Object.hasOwn(value, newKey) || propertyHint(hints, newKey) === false, onClick: () => add(newKey) }, "Add property")
12500
+ )
12501
+ ) : React3.createElement(
12502
+ React3.Fragment,
12503
+ null,
12504
+ React3.createElement(
12505
+ "label",
12506
+ null,
12507
+ "Property ",
12508
+ React3.createElement("input", { "aria-label": `New property ${path || "/"}`, value: newKey, onChange: (e2) => setNewKey(e2.target.value) })
12509
+ ),
12510
+ React3.createElement(
12511
+ "select",
12512
+ { "aria-label": `Known property ${path || "/"}`, value: "", onChange: (e2) => setNewKey(e2.target.value) },
12513
+ React3.createElement("option", { value: "" }, "Choose property"),
12514
+ missing.map((name) => React3.createElement("option", { key: name }, name))
12515
+ ),
12516
+ React3.createElement("button", { type: "button", disabled: !newKey || Object.hasOwn(value, newKey), onClick: () => {
11997
12517
  const copy = cloneJson(value);
11998
- delete copy[key];
11999
- change(copy, { path: pointer(path, key) });
12000
- } }, "Remove")
12001
- )),
12002
- React.createElement(
12518
+ Object.defineProperty(copy, newKey, { value: null, enumerable: true, writable: true, configurable: true });
12519
+ change(copy, { path: pointer(path, newKey) });
12520
+ setNewKey("");
12521
+ } }, "Add property")
12522
+ )
12523
+ );
12524
+ } else
12525
+ field = React3.createElement("span", null, "null");
12526
+ const containerProps = { "data-source-path": path, "data-source-error": commonLayout && errors.includes(path) };
12527
+ if (commonLayout && !Array.isArray(value) && !record3(value))
12528
+ return React3.createElement(
12529
+ "div",
12530
+ { ...containerProps, className: "editor-form-field" },
12531
+ typeof value === "boolean" && !choices ? React3.createElement(
12003
12532
  "label",
12533
+ { className: "editor-form-toggle", htmlFor: id },
12534
+ field,
12535
+ React3.createElement("span", null, label)
12536
+ ) : React3.createElement(
12537
+ React3.Fragment,
12004
12538
  null,
12005
- "Property ",
12006
- React.createElement("input", { "aria-label": `New property ${path || "/"}`, value: newKey, onChange: (e2) => setNewKey(e2.target.value) })
12007
- ),
12008
- React.createElement(
12009
- "select",
12010
- { "aria-label": `Known property ${path || "/"}`, value: "", onChange: (e2) => setNewKey(e2.target.value) },
12011
- React.createElement("option", { value: "" }, "Choose property"),
12012
- Object.keys(properties).filter((key) => !Object.hasOwn(value, key)).map((key) => React.createElement("option", { key }, key))
12539
+ React3.createElement(
12540
+ "label",
12541
+ { htmlFor: id },
12542
+ label,
12543
+ required && React3.createElement("span", { className: "required" }, " *")
12544
+ ),
12545
+ field
12013
12546
  ),
12014
- React.createElement("button", { type: "button", disabled: !newKey || Object.hasOwn(value, newKey), onClick: () => {
12015
- const copy = cloneJson(value);
12016
- Object.defineProperty(copy, newKey, { value: null, enumerable: true, writable: true, configurable: true });
12017
- change(copy, { path: pointer(path, newKey) });
12018
- setNewKey("");
12019
- } }, "Add property")
12547
+ typeControl,
12548
+ React3.createElement(FormHelp, { description: hints.description, id: `${id}-help` }),
12549
+ invalidNumbers[path] !== void 0 && React3.createElement("p", { className: "editor-form-invalid", role: "alert" }, "\u6709\u52B9\u306A\u6570\u5024\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002")
12020
12550
  );
12021
- } else
12022
- field = React.createElement("span", null, "null");
12023
- return React.createElement(
12551
+ return React3.createElement(
12024
12552
  "fieldset",
12025
- { "data-source-path": path },
12026
- React.createElement("legend", null, label),
12027
- React.createElement("select", { "aria-label": `Type ${path || "/"}`, value: type, onChange: (e2) => change(initial(e2.target.value)) }, ["object", "array", "string", "number", "boolean", "null"].map((t) => React.createElement("option", { key: t }, t))),
12553
+ { ...containerProps, className: commonLayout ? "editor-form-section" : void 0, disabled: readonly },
12554
+ React3.createElement("legend", null, label),
12555
+ commonLayout && React3.createElement(FormHelp, { description: hints.description }),
12556
+ typeControl,
12028
12557
  field
12029
12558
  );
12030
12559
  }
12031
- function liveIssues(draft, bindings) {
12560
+ function liveIssues(draft, bindings, commonLayout = false) {
12561
+ var _a;
12032
12562
  const issues = [];
12033
12563
  const sources = draft.sources;
12034
12564
  for (const binding of bindings) {
12035
12565
  const entry = sources[binding.argument];
12036
12566
  try {
12037
- if (entry.invalidForm === true)
12038
- throw new TypeError();
12039
- const doc = record2(entry.creating) ? { ...entry.creating, data: entry.data } : readSourceDocument(binding, entry.source);
12567
+ if (entry.invalidForm === true) {
12568
+ if (!commonLayout || !record3(entry.invalidNumbers) || !Object.keys(entry.invalidNumbers).length)
12569
+ throw new TypeError();
12570
+ for (const path of Object.keys((_a = entry.invalidNumbers) !== null && _a !== void 0 ? _a : {}))
12571
+ issues.push({ message: "Enter a valid JSON number.", path: pointer("", binding.argument) + path });
12572
+ }
12573
+ const doc = record3(entry.creating) ? { ...entry.creating, data: entry.data } : readSourceDocument(binding, entry.source);
12040
12574
  const validator = binding.validators.get(JSON.stringify([doc.format, doc.variantId]));
12041
- if (validator && validator.validate(entry.mode === "form" ? entry.data : doc.data).kind !== "valid") {
12042
- issues.push({ message: "Value does not satisfy the schema.", path: `/${binding.argument}` });
12575
+ if (validator) {
12576
+ const result = validator.validate(entry.mode === "form" ? entry.data : doc.data);
12577
+ if (result.kind !== "valid") {
12578
+ if (commonLayout)
12579
+ for (const diagnostic of result.diagnostics)
12580
+ issues.push({ message: "Value does not satisfy the schema.", path: pointer("", binding.argument) + ("dataPath" in diagnostic ? diagnostic.dataPath : "") });
12581
+ else
12582
+ issues.push({ message: "Value does not satisfy the schema.", path: `/${binding.argument}` });
12583
+ }
12043
12584
  }
12044
- } catch (_a) {
12585
+ } catch (_b) {
12045
12586
  issues.push({ message: "Repair the invalid source or form value.", path: `/${binding.argument}` });
12046
12587
  }
12047
12588
  }
12048
12589
  return issues;
12049
12590
  }
12050
- function SourceView({ context, bindings }) {
12051
- const [, redraw] = React.useState(0);
12052
- const [creating, selectCreateVariant] = React.useState({});
12053
- React.useEffect(() => {
12591
+ function SourceView({ context, bindings, commonLayout }) {
12592
+ const [, redraw] = React3.useState(0);
12593
+ const [creating, selectCreateVariant] = React3.useState({});
12594
+ React3.useLayoutEffect(() => {
12054
12595
  const stop = context.subscribe(() => redraw((n2) => n2 + 1));
12055
- context.setValidationIssues(liveIssues(context.getDraft(), bindings));
12596
+ context.setValidationIssues(liveIssues(context.getDraft(), bindings, commonLayout));
12056
12597
  return stop;
12057
- }, [context, bindings]);
12598
+ }, [context, bindings, commonLayout]);
12058
12599
  const state = context.getState();
12059
12600
  if (state.status !== "editing" && state.status !== "saving")
12060
- return React.createElement(React.Fragment, null);
12601
+ return React3.createElement(React3.Fragment, null);
12061
12602
  const draft = context.getDraft();
12062
12603
  const sources = draft.sources;
12063
12604
  const disabled = context.getState().status !== "editing";
@@ -12066,10 +12607,10 @@ function SourceView({ context, bindings }) {
12066
12607
  const nextSources = next.sources;
12067
12608
  Object.defineProperty(nextSources, argument, { value: entry, enumerable: true, configurable: true, writable: true });
12068
12609
  context.setDraft(next);
12069
- context.setValidationIssues(liveIssues(next, bindings));
12610
+ context.setValidationIssues(liveIssues(next, bindings, commonLayout));
12070
12611
  };
12071
- return React.createElement("div", { className: "block-editor-source-forms" }, bindings.map((binding) => {
12072
- var _a, _b;
12612
+ return React3.createElement("div", { className: "block-editor-source-forms" }, bindings.map((binding) => {
12613
+ var _a, _b, _c;
12073
12614
  const entry = sources[binding.argument];
12074
12615
  const selectedCreation = Object.hasOwn(creating, binding.argument) ? creating[binding.argument] : "";
12075
12616
  let document2;
@@ -12077,33 +12618,41 @@ function SourceView({ context, bindings }) {
12077
12618
  try {
12078
12619
  document2 = readSourceDocument(binding, entry.source);
12079
12620
  variant = binding.presentationVariants.find((v2) => v2.format === document2.format && v2.variantId === document2.variantId);
12080
- } catch (_c) {
12621
+ } catch (_d) {
12081
12622
  }
12082
- if (record2(entry.creating)) {
12623
+ if (record3(entry.creating)) {
12083
12624
  const creation = entry.creating;
12084
12625
  variant = binding.presentationVariants.find((v2) => v2.format === creation.format && v2.variantId === creation.variantId);
12085
12626
  }
12086
- return React.createElement(
12087
- "fieldset",
12088
- { key: binding.argument, disabled },
12089
- React.createElement("legend", null, (_a = binding.label) !== null && _a !== void 0 ? _a : binding.argument),
12090
- React.createElement("button", { type: "button", "aria-pressed": entry.mode === "source", onClick: () => {
12091
- try {
12092
- if (entry.invalidForm === true)
12093
- throw new TypeError();
12094
- const source = record2(entry.creating) ? createSourceCandidate(entry.creating.format, entry.data) : entry.mode === "form" && document2 && Object.hasOwn(entry, "data") ? patchDecodedSource(document2, entry.data, (source2) => readSourceDocument(binding, source2)) : entry.source;
12095
- const next = { ...entry, mode: "source", source, invalidForm: false, invalidNumbers: {} };
12096
- delete next.creating;
12097
- update(binding.argument, next);
12098
- } catch (_a2) {
12099
- context.setValidationIssues([{ message: "This edit cannot preserve the source. Repair the Source explicitly." }]);
12100
- }
12101
- } }, "Source"),
12102
- React.createElement(
12627
+ const argumentPath = pointer("", binding.argument);
12628
+ const errorPaths = [...new Set(state.issues.flatMap((issue2) => {
12629
+ var _a2;
12630
+ return ((_a2 = issue2.path) === null || _a2 === void 0 ? void 0 : _a2.startsWith(argumentPath + "/")) ? [issue2.path.slice(argumentPath.length)] : [];
12631
+ }).concat(Object.keys((_a = entry.invalidNumbers) !== null && _a !== void 0 ? _a : {})))];
12632
+ const sourceButton = React3.createElement("button", { type: "button", "aria-pressed": entry.mode === "source", onClick: () => {
12633
+ try {
12634
+ if (entry.invalidForm === true)
12635
+ throw new TypeError();
12636
+ const source = record3(entry.creating) ? createSourceCandidate(entry.creating.format, entry.data) : entry.mode === "form" && document2 && Object.hasOwn(entry, "data") ? patchDecodedSource(document2, entry.data, (source2) => readSourceDocument(binding, source2)) : entry.source;
12637
+ const next = { ...entry, mode: "source", source, invalidForm: false, invalidNumbers: {} };
12638
+ delete next.creating;
12639
+ update(binding.argument, next);
12640
+ } catch (_a2) {
12641
+ context.setValidationIssues([{ message: "This edit cannot preserve the source. Repair the Source explicitly." }]);
12642
+ }
12643
+ } }, "Source");
12644
+ const formButton = React3.createElement("button", { type: "button", disabled: !variant, "aria-pressed": entry.mode === "form", onClick: () => {
12645
+ if (document2 || entry.creating)
12646
+ update(binding.argument, { ...entry, mode: "form", data: Object.hasOwn(entry, "data") ? entry.data : document2.data });
12647
+ } }, "Form");
12648
+ const creationTools = React3.createElement(
12649
+ React3.Fragment,
12650
+ null,
12651
+ React3.createElement(
12103
12652
  "select",
12104
12653
  { "aria-label": `${binding.argument} New format and variant`, value: selectedCreation, onChange: (e2) => selectCreateVariant({ ...creating, [binding.argument]: e2.target.value }) },
12105
- React.createElement("option", { value: "" }, "Choose new format and variant"),
12106
- binding.presentationVariants.map((v2) => React.createElement(
12654
+ React3.createElement("option", { value: "" }, "Choose new format and variant"),
12655
+ binding.presentationVariants.map((v2) => React3.createElement(
12107
12656
  "option",
12108
12657
  { key: JSON.stringify([v2.format, v2.variantId]), value: JSON.stringify([v2.format, v2.variantId]) },
12109
12658
  v2.format,
@@ -12111,54 +12660,87 @@ function SourceView({ context, bindings }) {
12111
12660
  v2.variantId
12112
12661
  ))
12113
12662
  ),
12114
- React.createElement("button", { type: "button", disabled: !selectedCreation, onClick: () => {
12663
+ React3.createElement("button", { type: "button", disabled: !selectedCreation, onClick: () => {
12115
12664
  const [format, variantId] = JSON.parse(selectedCreation);
12116
12665
  const chosen = binding.presentationVariants.find((v2) => v2.format === format && v2.variantId === variantId);
12117
12666
  const root2 = chosen.schemaBundle.root.document;
12118
- const type = record2(root2) && typeof root2.type === "string" ? root2.type : "null";
12667
+ const type = record3(root2) && typeof root2.type === "string" ? root2.type : "null";
12119
12668
  update(binding.argument, { mode: "form", source: entry.source, sourceEdited: true, creating: { format, variantId }, data: initial(type) });
12120
- } }, "Create document (replace source)"),
12121
- React.createElement("button", { type: "button", disabled: !variant, "aria-pressed": entry.mode === "form", onClick: () => {
12122
- if (document2 || entry.creating)
12123
- update(binding.argument, { ...entry, mode: "form", data: Object.hasOwn(entry, "data") ? entry.data : document2.data });
12124
- } }, "Form"),
12125
- entry.mode === "form" && React.createElement("button", { type: "button", onClick: () => {
12126
- var _a2;
12127
- return update(binding.argument, { mode: "source", source: entry.source, sourceEdited: (_a2 = entry.sourceEdited) !== null && _a2 !== void 0 ? _a2 : false });
12128
- } }, "Discard form edits"),
12129
- entry.mode === "form" && variant && Object.hasOwn(entry, "data") ? React.createElement(Tree, { invalidNumbers: (_b = entry.invalidNumbers) !== null && _b !== void 0 ? _b : {}, value: entry.data, path: "", schema: variant.schemaBundle.root.document, ui: variant.uiSchema, variant, change: (data, edit = { path: "" }) => {
12130
- var _a2;
12131
- const pending = (_a2 = entry.invalidNumbers) !== null && _a2 !== void 0 ? _a2 : {};
12132
- const invalidNumbers = {};
12133
- const prefix = `${edit.path}/`;
12134
- for (const [path, text] of Object.entries(pending)) {
12135
- let target = path;
12136
- if (edit.removeIndex !== void 0 || edit.swap) {
12137
- if (path.startsWith(prefix)) {
12138
- const [head, ...tail] = path.slice(prefix.length).split("/");
12139
- let index = Number(head);
12140
- if (index === edit.removeIndex)
12141
- continue;
12142
- if (edit.removeIndex !== void 0 && index > edit.removeIndex)
12143
- index--;
12144
- if (edit.swap)
12145
- index = index === edit.swap[0] ? edit.swap[1] : index === edit.swap[1] ? edit.swap[0] : index;
12146
- target = `${prefix}${index}${tail.length ? "/" + tail.join("/") : ""}`;
12147
- }
12148
- } else if (path === edit.path || path.startsWith(prefix))
12149
- continue;
12150
- Object.defineProperty(invalidNumbers, target, { value: text, enumerable: true });
12151
- }
12152
- if (edit.invalidText !== void 0)
12153
- Object.defineProperty(invalidNumbers, edit.path, { value: edit.invalidText, enumerable: true });
12154
- update(binding.argument, { ...entry, data, invalidNumbers, invalidForm: Object.keys(invalidNumbers).length > 0 });
12155
- } }) : React.createElement("textarea", { "aria-label": `${binding.argument} Source`, value: entry.source, onChange: (e2) => update(binding.argument, { mode: "source", source: e2.target.value, sourceEdited: true }) }),
12156
- entry.invalidForm === true && React.createElement("p", { role: "alert" }, "Enter a valid JSON number.")
12669
+ } }, "Create document (replace source)")
12670
+ );
12671
+ const discard = entry.mode === "form" && React3.createElement("button", { type: "button", onClick: () => {
12672
+ var _a2;
12673
+ return update(binding.argument, { mode: "source", source: entry.source, sourceEdited: (_a2 = entry.sourceEdited) !== null && _a2 !== void 0 ? _a2 : false });
12674
+ } }, "Discard form edits");
12675
+ return React3.createElement(
12676
+ "fieldset",
12677
+ { key: binding.argument, disabled, className: commonLayout ? "editor-form-binding" : void 0 },
12678
+ (!commonLayout || binding.label || bindings.length > 1) && React3.createElement("legend", null, (_b = binding.label) !== null && _b !== void 0 ? _b : binding.argument),
12679
+ commonLayout ? React3.createElement(
12680
+ "div",
12681
+ { className: "editor-form-toolbar" },
12682
+ React3.createElement(
12683
+ "div",
12684
+ { className: "editor-form-modes" },
12685
+ sourceButton,
12686
+ formButton
12687
+ ),
12688
+ React3.createElement(
12689
+ "details",
12690
+ { className: "editor-form-tools" },
12691
+ React3.createElement("summary", null, "\u6587\u66F8\u306E\u64CD\u4F5C"),
12692
+ creationTools,
12693
+ discard
12694
+ )
12695
+ ) : React3.createElement(
12696
+ React3.Fragment,
12697
+ null,
12698
+ sourceButton,
12699
+ creationTools,
12700
+ formButton,
12701
+ discard
12702
+ ),
12703
+ entry.mode === "form" && variant && Object.hasOwn(entry, "data") ? React3.createElement(
12704
+ SourcePaths.Provider,
12705
+ { value: errorPaths },
12706
+ React3.createElement(Tree, { invalidNumbers: (_c = entry.invalidNumbers) !== null && _c !== void 0 ? _c : {}, value: entry.data, path: "", schema: variant.schemaBundle.root.document, ui: variant.uiSchema, variant, change: (data, edit = { path: "" }) => {
12707
+ var _a2;
12708
+ const pending = (_a2 = entry.invalidNumbers) !== null && _a2 !== void 0 ? _a2 : {};
12709
+ const invalidNumbers = {};
12710
+ const prefix = `${edit.path}/`;
12711
+ for (const [path, text] of Object.entries(pending)) {
12712
+ let target = path;
12713
+ if (edit.removeIndex !== void 0 || edit.swap) {
12714
+ if (path.startsWith(prefix)) {
12715
+ const [head, ...tail] = path.slice(prefix.length).split("/");
12716
+ let index = Number(head);
12717
+ if (index === edit.removeIndex)
12718
+ continue;
12719
+ if (edit.removeIndex !== void 0 && index > edit.removeIndex)
12720
+ index--;
12721
+ if (edit.swap)
12722
+ index = index === edit.swap[0] ? edit.swap[1] : index === edit.swap[1] ? edit.swap[0] : index;
12723
+ target = `${prefix}${index}${tail.length ? "/" + tail.join("/") : ""}`;
12724
+ }
12725
+ } else if (path === edit.path || path.startsWith(prefix))
12726
+ continue;
12727
+ Object.defineProperty(invalidNumbers, target, { value: text, enumerable: true });
12728
+ }
12729
+ if (edit.invalidText !== void 0)
12730
+ Object.defineProperty(invalidNumbers, edit.path, { value: edit.invalidText, enumerable: true });
12731
+ update(binding.argument, { ...entry, data, invalidNumbers, invalidForm: Object.keys(invalidNumbers).length > 0 });
12732
+ } })
12733
+ ) : React3.createElement("textarea", { "aria-label": `${binding.argument} Source`, value: entry.source, onChange: (e2) => update(binding.argument, { mode: "source", source: e2.target.value, sourceEdited: true }) }),
12734
+ entry.invalidForm === true && React3.createElement("p", { role: "alert" }, "Enter a valid JSON number.")
12157
12735
  );
12158
12736
  }));
12159
12737
  }
12160
- function mountSourceView(container, context, bindings) {
12161
- ReactDOM.render(React.createElement(SourceView, { context, bindings }), container);
12738
+ function mountSourceView(container, context, bindings, commonLayout = false) {
12739
+ ReactDOM.render(React3.createElement(
12740
+ LayoutHost,
12741
+ { enabled: commonLayout, context },
12742
+ React3.createElement(SourceView, { context, bindings, commonLayout })
12743
+ ), container);
12162
12744
  return () => {
12163
12745
  ReactDOM.unmountComponentAtNode(container);
12164
12746
  };
@@ -12209,21 +12791,22 @@ function entryFor(draft, argument) {
12209
12791
  }
12210
12792
  return entry;
12211
12793
  }
12212
- function createSourceEditor(options) {
12794
+ function createSourceEditor(options, featureOptions = {}) {
12213
12795
  var _a;
12796
+ const features = captureFeatureFlags(featureOptions);
12214
12797
  const { apiVersion, extensionId, editorId, validationContext: provider } = options;
12215
12798
  if (apiVersion !== 1 || typeof provider !== "function" || !Array.isArray(options.bindings) || !options.bindings.length) {
12216
12799
  throw new TypeError("Invalid source editor options.");
12217
12800
  }
12218
12801
  const inputBindings = options.bindings;
12219
12802
  const bindings = [];
12220
- const names = /* @__PURE__ */ new Set();
12803
+ const names2 = /* @__PURE__ */ new Set();
12221
12804
  for (let i2 = 0; i2 < inputBindings.length; i2++) {
12222
12805
  const binding = inputBindings[i2];
12223
12806
  const { argument, label, decode, validateSource } = binding;
12224
- if (typeof argument !== "string" || !argument || names.has(argument) || typeof decode !== "function" || typeof validateSource !== "function" || label !== void 0 && typeof label !== "string")
12807
+ if (typeof argument !== "string" || !argument || names2.has(argument) || typeof decode !== "function" || typeof validateSource !== "function" || label !== void 0 && typeof label !== "string")
12225
12808
  throw new TypeError("Invalid source binding.");
12226
- names.add(argument);
12809
+ names2.add(argument);
12227
12810
  const variants = snapshotJson(binding.variants);
12228
12811
  if (!Array.isArray(variants) || !variants.length)
12229
12812
  throw new TypeError("Source variants are required.");
@@ -12249,7 +12832,7 @@ function createSourceEditor(options) {
12249
12832
  extensionId,
12250
12833
  editorId,
12251
12834
  opcodes: Object.freeze([...options.opcodes]),
12252
- editableArguments: Object.freeze([...names]),
12835
+ editableArguments: Object.freeze([...names2]),
12253
12836
  saveContract: "prepared-source-v1",
12254
12837
  read: (snapshot2) => {
12255
12838
  const sources = {};
@@ -12299,7 +12882,11 @@ function createSourceEditor(options) {
12299
12882
  try {
12300
12883
  const entry = entryFor(draft, binding.argument);
12301
12884
  if (entry.invalidForm === true) {
12302
- issues.push(issue("form-value-invalid", path));
12885
+ if (features.commonLayout && isJsonRecord(entry.invalidNumbers) && Object.keys(entry.invalidNumbers).length > 0) {
12886
+ for (const pointer2 of Object.keys(entry.invalidNumbers))
12887
+ issues.push(issue("form-value-invalid", path + pointer2));
12888
+ } else
12889
+ issues.push(issue("form-value-invalid", path));
12303
12890
  continue;
12304
12891
  }
12305
12892
  const slot = snapshot2.arguments[binding.argument];
@@ -12350,7 +12937,13 @@ function createSourceEditor(options) {
12350
12937
  if (validation.result.kind !== "valid") {
12351
12938
  if (!["invalid", "execution-error", "schema-error"].includes(validation.result.kind))
12352
12939
  throw new TypeError();
12353
- issues.push(issue("owner-input-invalid", path));
12940
+ if (features.commonLayout && validation.result.diagnostics.length) {
12941
+ for (const diagnostic of validation.result.diagnostics) {
12942
+ const pointer2 = typeof diagnostic.dataPath === "string" && diagnostic.dataPath.startsWith("/") ? diagnostic.dataPath : "";
12943
+ issues.push(issue("owner-input-invalid", path + pointer2));
12944
+ }
12945
+ } else
12946
+ issues.push(issue("owner-input-invalid", path));
12354
12947
  continue;
12355
12948
  }
12356
12949
  if (validation.result.diagnostics.length)
@@ -12364,7 +12957,11 @@ function createSourceEditor(options) {
12364
12957
  if (validator) {
12365
12958
  const result = validator.validate(document2.data, { consumerId: context.consumerId });
12366
12959
  if (result.kind !== "valid") {
12367
- issues.push(issue("schema-data-invalid", path));
12960
+ if (features.commonLayout)
12961
+ for (const diagnostic of result.diagnostics)
12962
+ issues.push(issue("schema-data-invalid", path + ("dataPath" in diagnostic ? diagnostic.dataPath : "")));
12963
+ else
12964
+ issues.push(issue("schema-data-invalid", path));
12368
12965
  continue;
12369
12966
  }
12370
12967
  } else if (entry.mode === "form" || candidate !== slot.value && !((_a2 = binding.sourceOnlyVariants) === null || _a2 === void 0 ? void 0 : _a2.some((v2) => v2.variantId === document2.variantId && v2.format === document2.format))) {
@@ -12379,12 +12976,12 @@ function createSourceEditor(options) {
12379
12976
  }
12380
12977
  return issues.length ? { kind: "invalid", issues } : { kind: "ready", changes };
12381
12978
  },
12382
- mount: (container, context) => mountSourceView(container, context, bindings)
12979
+ mount: (container, context) => mountSourceView(container, context, bindings, features.commonLayout)
12383
12980
  });
12384
12981
  }
12385
12982
 
12386
12983
  // dist/fixed-input-view.js
12387
- import * as React2 from "react";
12984
+ import * as React4 from "react";
12388
12985
  import * as ReactDOM2 from "react-dom";
12389
12986
  var defaultMessages = Object.freeze({
12390
12987
  reset: "Reset",
@@ -12421,7 +13018,7 @@ function resolveFixedInputMessages(source) {
12421
13018
  throw error;
12422
13019
  }
12423
13020
  }
12424
- var record3 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
13021
+ var record4 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
12425
13022
  var display = (value) => typeof value === "string" ? value : typeof value === "number" && Object.is(value, -0) ? "-0" : value === void 0 ? "" : JSON.stringify(value);
12426
13023
  var serialized = (value) => value === void 0 ? "unavailable" : JSON.stringify(value);
12427
13024
  function preview(value) {
@@ -12439,9 +13036,9 @@ function describe(context) {
12439
13036
  }
12440
13037
  var nextFixedViewId = 0;
12441
13038
  function FixedInputView({ context, messages }) {
12442
- const [, redraw] = React2.useState(0);
12443
- const [viewId] = React2.useState(() => `block-editor-fixed-${++nextFixedViewId}`);
12444
- React2.useEffect(() => {
13039
+ const [, redraw] = React4.useState(0);
13040
+ const [viewId] = React4.useState(() => `block-editor-fixed-${++nextFixedViewId}`);
13041
+ React4.useEffect(() => {
12445
13042
  const stop = context.subscribe(() => redraw((value) => value + 1));
12446
13043
  if (context.getState().status === "editing" && !context.getState().issues.length) {
12447
13044
  context.setValidationIssues(describe(context).issues);
@@ -12450,10 +13047,10 @@ function FixedInputView({ context, messages }) {
12450
13047
  }, [context]);
12451
13048
  const state = context.getState();
12452
13049
  if (state.status !== "editing" && state.status !== "saving")
12453
- return React2.createElement(React2.Fragment, null);
13050
+ return React4.createElement(React4.Fragment, null);
12454
13051
  const description = describe(context);
12455
13052
  const draft = context.getDraft();
12456
- const inputs = record3(draft.inputs) ? draft.inputs : {};
13053
+ const inputs = record4(draft.inputs) ? draft.inputs : {};
12457
13054
  const update = (argument, value, buffer) => {
12458
13055
  if (context.getState().status !== "editing")
12459
13056
  return;
@@ -12461,28 +13058,28 @@ function FixedInputView({ context, messages }) {
12461
13058
  if (!latest || latest.state !== "editable")
12462
13059
  return;
12463
13060
  const next = context.getDraft();
12464
- if (!record3(next.inputs))
13061
+ if (!record4(next.inputs))
12465
13062
  throw new TypeError("Invalid fixed form draft.");
12466
13063
  const previous = next.inputs[argument];
12467
13064
  const entry = { value, changed: true };
12468
13065
  if (buffer !== void 0)
12469
13066
  entry.buffer = buffer;
12470
- if (record3(previous) && (previous.readOnly === true || previous.repair === true))
13067
+ if (record4(previous) && (previous.readOnly === true || previous.repair === true))
12471
13068
  entry.repair = true;
12472
13069
  Object.defineProperty(next.inputs, argument, { value: entry, enumerable: true, configurable: true, writable: true });
12473
13070
  context.setDraft(next);
12474
13071
  context.setValidationIssues(describe(context).issues);
12475
13072
  };
12476
- const hasInactiveEdits = Object.entries(description.inputs).some(([argument, input]) => input.state === "hidden" && record3(inputs[argument]) && inputs[argument].changed === true);
12477
- return React2.createElement(
13073
+ const hasInactiveEdits = Object.entries(description.inputs).some(([argument, input]) => input.state === "hidden" && record4(inputs[argument]) && inputs[argument].changed === true);
13074
+ return React4.createElement(
12478
13075
  "div",
12479
13076
  { className: "block-editor-fixed-inputs" },
12480
- hasInactiveEdits && React2.createElement("p", { className: "block-editor-fixed-inactive", "data-fixed-inactive-draft": "", role: "status" }, messages.inactiveDraft),
13077
+ hasInactiveEdits && React4.createElement("p", { className: "block-editor-fixed-inactive", "data-fixed-inactive-draft": "", role: "status" }, messages.inactiveDraft),
12481
13078
  Object.entries(description.inputs).map(([argument, input], index) => {
12482
13079
  var _a, _b, _c, _d, _e2;
12483
13080
  if (input.state === "hidden")
12484
13081
  return null;
12485
- const entry = record3(inputs[argument]) ? inputs[argument] : {};
13082
+ const entry = record4(inputs[argument]) ? inputs[argument] : {};
12486
13083
  const value = Object.hasOwn(entry, "value") ? entry.value : void 0;
12487
13084
  const label = (_a = input.label) !== null && _a !== void 0 ? _a : argument;
12488
13085
  const text = typeof entry.buffer === "string" ? entry.buffer : value === void 0 ? (_b = input.rawDisplay) !== null && _b !== void 0 ? _b : "" : display(value);
@@ -12505,31 +13102,31 @@ function FixedInputView({ context, messages }) {
12505
13102
  };
12506
13103
  let control;
12507
13104
  if (input.state === "readonly") {
12508
- control = React2.createElement(
12509
- React2.Fragment,
13105
+ control = React4.createElement(
13106
+ React4.Fragment,
12510
13107
  null,
12511
- React2.createElement("output", { "aria-label": label, ...attributes }, (_c = input.rawDisplay) !== null && _c !== void 0 ? _c : text),
12512
- React2.createElement("p", { id: reasonId, className: "block-editor-fixed-readonly" }, messages.readOnly)
13108
+ React4.createElement("output", { "aria-label": label, ...attributes }, (_c = input.rawDisplay) !== null && _c !== void 0 ? _c : text),
13109
+ React4.createElement("p", { id: reasonId, className: "block-editor-fixed-readonly" }, messages.readOnly)
12513
13110
  );
12514
13111
  } else if (input.control === "enum") {
12515
13112
  const choices = (_d = input.choices) !== null && _d !== void 0 ? _d : [];
12516
13113
  const current = serialized(value);
12517
13114
  const known = choices.some((choice) => serialized(choice.value) === current);
12518
- control = React2.createElement(
13115
+ control = React4.createElement(
12519
13116
  "select",
12520
13117
  { "aria-label": label, ...attributes, value: known ? current : "existing-raw", disabled, onChange: (event) => {
12521
13118
  const choice = choices.find((item) => serialized(item.value) === event.target.value);
12522
13119
  if (choice)
12523
13120
  update(argument, choice.value);
12524
13121
  } },
12525
- !known && React2.createElement("option", { value: "existing-raw", disabled: true }, ((_e2 = input.rawDisplay) !== null && _e2 !== void 0 ? _e2 : text) || messages.currentValue),
13122
+ !known && React4.createElement("option", { value: "existing-raw", disabled: true }, ((_e2 = input.rawDisplay) !== null && _e2 !== void 0 ? _e2 : text) || messages.currentValue),
12526
13123
  choices.map((choice, index2) => {
12527
13124
  var _a2;
12528
- return React2.createElement("option", { key: index2, value: serialized(choice.value) }, (_a2 = choice.label) !== null && _a2 !== void 0 ? _a2 : display(choice.value));
13125
+ return React4.createElement("option", { key: index2, value: serialized(choice.value) }, (_a2 = choice.label) !== null && _a2 !== void 0 ? _a2 : display(choice.value));
12529
13126
  })
12530
13127
  );
12531
13128
  } else if (input.control === "number") {
12532
- control = React2.createElement("input", { "aria-label": label, ...attributes, type: "text", inputMode: "decimal", value: text, disabled, onChange: (event) => {
13129
+ control = React4.createElement("input", { "aria-label": label, ...attributes, type: "text", inputMode: "decimal", value: text, disabled, onChange: (event) => {
12533
13130
  const buffer = event.target.value;
12534
13131
  if (input.valueType === "string" || input.valueType === void 0 && typeof value === "string") {
12535
13132
  update(argument, buffer);
@@ -12540,36 +13137,36 @@ function FixedInputView({ context, messages }) {
12540
13137
  } });
12541
13138
  } else if (input.control === "color") {
12542
13139
  const color = preview(text);
12543
- control = React2.createElement(
13140
+ control = React4.createElement(
12544
13141
  "div",
12545
13142
  { className: "block-editor-fixed-color" },
12546
- React2.createElement("input", { "aria-label": label, ...attributes, type: "text", value: text, disabled, onChange: (event) => update(argument, event.target.value) }),
12547
- color !== void 0 && React2.createElement("input", { type: "color", "aria-label": `${label} ${messages.colorPicker}`, ...attributes, value: color, disabled, onChange: (event) => update(argument, event.target.value) })
13143
+ React4.createElement("input", { "aria-label": label, ...attributes, type: "text", value: text, disabled, onChange: (event) => update(argument, event.target.value) }),
13144
+ color !== void 0 && React4.createElement("input", { type: "color", "aria-label": `${label} ${messages.colorPicker}`, ...attributes, value: color, disabled, onChange: (event) => update(argument, event.target.value) })
12548
13145
  );
12549
13146
  } else
12550
- control = React2.createElement("textarea", { "aria-label": label, ...attributes, value: text, disabled, onChange: (event) => update(argument, event.target.value) });
12551
- return React2.createElement(
13147
+ control = React4.createElement("textarea", { "aria-label": label, ...attributes, value: text, disabled, onChange: (event) => update(argument, event.target.value) });
13148
+ return React4.createElement(
12552
13149
  "fieldset",
12553
13150
  { key: argument, "data-fixed-argument": argument, disabled },
12554
- React2.createElement("legend", null, label),
13151
+ React4.createElement("legend", null, label),
12555
13152
  control,
12556
- input.state === "editable" && input.reset !== void 0 && React2.createElement("button", { type: "button", disabled, "aria-label": `${label} ${messages.reset}`, onClick: () => update(argument, input.reset) }, messages.reset),
12557
- showOriginal && React2.createElement(
13153
+ input.state === "editable" && input.reset !== void 0 && React4.createElement("button", { type: "button", disabled, "aria-label": `${label} ${messages.reset}`, onClick: () => update(argument, input.reset) }, messages.reset),
13154
+ showOriginal && React4.createElement(
12558
13155
  "p",
12559
13156
  { id: originalId, className: "block-editor-fixed-original", "data-fixed-original-value": "" },
12560
13157
  messages.currentValue,
12561
13158
  ": ",
12562
- React2.createElement("output", null, input.rawDisplay)
13159
+ React4.createElement("output", null, input.rawDisplay)
12563
13160
  ),
12564
- invalid && React2.createElement("p", { id: errorId2, className: "block-editor-fixed-error" }, messages.invalidValue),
12565
- input.unverified && React2.createElement("p", { id: unverifiedId, className: "block-editor-fixed-unverified" }, messages.unverified)
13161
+ invalid && React4.createElement("p", { id: errorId2, className: "block-editor-fixed-error" }, messages.invalidValue),
13162
+ input.unverified && React4.createElement("p", { id: unverifiedId, className: "block-editor-fixed-unverified" }, messages.unverified)
12566
13163
  );
12567
13164
  })
12568
13165
  );
12569
13166
  }
12570
13167
  function mountFixedInputView(container, context, messages = defaultMessages) {
12571
13168
  describe(context);
12572
- ReactDOM2.render(React2.createElement(FixedInputView, { context, messages }), container);
13169
+ ReactDOM2.render(React4.createElement(FixedInputView, { context, messages }), container);
12573
13170
  return () => {
12574
13171
  ReactDOM2.unmountComponentAtNode(container);
12575
13172
  };
@@ -17225,7 +17822,7 @@ function getTemplate(name, registry, uiOptions = {}) {
17225
17822
  // node_modules/.pnpm/@rjsf+utils@5.24.13_react@16.14.0/node_modules/@rjsf/utils/lib/getWidget.js
17226
17823
  var import_react_is = __toESM(require_react_is());
17227
17824
  import { jsx as _jsx } from "react/jsx-runtime.js";
17228
- import { createElement as createElement3 } from "react";
17825
+ import { createElement as createElement5 } from "react";
17229
17826
  var widgetMap = {
17230
17827
  boolean: {
17231
17828
  checkbox: "CheckboxWidget",
@@ -17291,7 +17888,7 @@ function mergeWidgetOptions(AWidget) {
17291
17888
  }
17292
17889
  function getWidget(schema4, widget, registeredWidgets = {}) {
17293
17890
  const type = getSchemaType(schema4);
17294
- if (typeof widget === "function" || widget && import_react_is.default.isForwardRef(createElement3(widget)) || import_react_is.default.isMemo(widget)) {
17891
+ if (typeof widget === "function" || widget && import_react_is.default.isForwardRef(createElement5(widget)) || import_react_is.default.isMemo(widget)) {
17295
17892
  return mergeWidgetOptions(widget);
17296
17893
  }
17297
17894
  if (typeof widget !== "string") {
@@ -18604,12 +19201,12 @@ var MultiSchemaField_default = AnyOfField;
18604
19201
 
18605
19202
  // node_modules/.pnpm/@rjsf+core@5.24.13_@rjsf+utils@5.24.13_react@16.14.0__react@16.14.0/node_modules/@rjsf/core/lib/components/fields/NumberField.js
18606
19203
  import { jsx as _jsx5 } from "react/jsx-runtime.js";
18607
- import { useState as useState3, useCallback } from "react";
19204
+ import { useState as useState4, useCallback } from "react";
18608
19205
  var trailingCharMatcherWithPrefix = /\.([0-9]*0)*$/;
18609
19206
  var trailingCharMatcher = /[0.]0*$/;
18610
19207
  function NumberField(props) {
18611
19208
  const { registry, onChange, formData, value: initialValue } = props;
18612
- const [lastValue, setLastValue] = useState3(initialValue);
19209
+ const [lastValue, setLastValue] = useState4(initialValue);
18613
19210
  const { StringField: StringField2 } = registry.fields;
18614
19211
  let value = formData;
18615
19212
  const handleChange = useCallback((value2, errorSchema, id) => {
@@ -19782,7 +20379,7 @@ var templates_default = templates;
19782
20379
 
19783
20380
  // node_modules/.pnpm/@rjsf+core@5.24.13_@rjsf+utils@5.24.13_react@16.14.0__react@16.14.0/node_modules/@rjsf/core/lib/components/widgets/AltDateWidget.js
19784
20381
  import { jsx as _jsx27, jsxs as _jsxs14 } from "react/jsx-runtime.js";
19785
- import { useCallback as useCallback4, useEffect as useEffect4, useReducer, useState as useState4 } from "react";
20382
+ import { useCallback as useCallback4, useEffect as useEffect4, useReducer, useState as useState5 } from "react";
19786
20383
  function readyForChange(state) {
19787
20384
  return Object.values(state).every((value) => value !== -1);
19788
20385
  }
@@ -19793,7 +20390,7 @@ function DateElement({ type, range, value, select, rootId, name, disabled, reado
19793
20390
  }
19794
20391
  function AltDateWidget({ time = false, disabled = false, readonly = false, autofocus = false, options, id, name, registry, onBlur, onFocus, onChange, value }) {
19795
20392
  const { translateString } = registry;
19796
- const [lastValue, setLastValue] = useState4(value);
20393
+ const [lastValue, setLastValue] = useState5(value);
19797
20394
  const [state, setState] = useReducer((state2, action) => {
19798
20395
  return { ...state2, ...action };
19799
20396
  }, parseDateString(value, time));
@@ -21303,17 +21900,93 @@ function fieldErrors(issues) {
21303
21900
  }
21304
21901
 
21305
21902
  // dist/rjsf-templates.js
21306
- import * as React3 from "react";
21307
- var ItemNumber = React3.createContext(1);
21308
- var PropertyKey = React3.createContext(void 0);
21903
+ import * as React5 from "react";
21904
+ var ItemNumber = React5.createContext(1);
21905
+ var PropertyKey = React5.createContext(void 0);
21906
+ function errorCount(value) {
21907
+ if (!value || typeof value !== "object")
21908
+ return 0;
21909
+ if (Array.isArray(value))
21910
+ return value.length;
21911
+ return Object.values(value).reduce((count, child) => count + errorCount(child), 0);
21912
+ }
21913
+ function layoutObjectTemplate(DefaultTemplate) {
21914
+ return function LayoutObject(props) {
21915
+ var _a, _b;
21916
+ const enabled = useCommonLayout();
21917
+ const title = enabled && !props.schema.title && !((_a = props.uiSchema) === null || _a === void 0 ? void 0 : _a["ui:title"]) ? propertyLabel(props.title) : props.title;
21918
+ const view = { ...props, title };
21919
+ const knownFields = [.../* @__PURE__ */ new Set([...Object.keys((_b = props.schema.properties) !== null && _b !== void 0 ? _b : {}), ...props.properties.map((property2) => property2.name)])];
21920
+ const resolution = enabled ? resolveEditorLayout(props.uiSchema, knownFields) : { kind: "absent" };
21921
+ if (resolution.kind === "absent")
21922
+ return React5.createElement(DefaultTemplate, { ...view });
21923
+ if (resolution.kind === "invalid")
21924
+ return React5.createElement(
21925
+ React5.Fragment,
21926
+ null,
21927
+ React5.createElement(
21928
+ "p",
21929
+ { role: "status", "data-layout-diagnostic": "" },
21930
+ "\u30EC\u30A4\u30A2\u30A6\u30C8\u3092\u9069\u7528\u3067\u304D\u307E\u305B\u3093: ",
21931
+ resolution.diagnostic
21932
+ ),
21933
+ React5.createElement(DefaultTemplate, { ...props })
21934
+ );
21935
+ const content = React5.createElement(ObjectLayout, { key: "__editor_layout__", ui: props.uiSchema, knownFields, fallback: null, fields: props.properties.map((property2) => {
21936
+ var _a2;
21937
+ return {
21938
+ name: property2.name,
21939
+ content: property2.content,
21940
+ errors: errorCount((_a2 = props.errorSchema) === null || _a2 === void 0 ? void 0 : _a2[property2.name])
21941
+ };
21942
+ }) });
21943
+ return React5.createElement(DefaultTemplate, { ...view, properties: [{ name: "__editor_layout__", content, hidden: false, disabled: !!props.disabled, readonly: !!props.readonly }] });
21944
+ };
21945
+ }
21946
+ function compactDescriptionTemplate(DefaultTemplate) {
21947
+ return function CompactDescription(props) {
21948
+ const enabled = useCommonLayout();
21949
+ return enabled && typeof props.description === "string" ? React5.createElement(FormHelp, { id: props.id, description: props.description }) : React5.createElement(DefaultTemplate, { ...props });
21950
+ };
21951
+ }
21952
+ function compactArrayTitleTemplate(DefaultTemplate) {
21953
+ return function CompactArrayTitle(props) {
21954
+ var _a;
21955
+ const enabled = useCommonLayout();
21956
+ if (!enabled || !props.title || props.schema.title || ((_a = props.uiSchema) === null || _a === void 0 ? void 0 : _a["ui:title"]))
21957
+ return React5.createElement(DefaultTemplate, { ...props });
21958
+ return React5.createElement(DefaultTemplate, { ...props, title: propertyLabel(props.title) });
21959
+ };
21960
+ }
21961
+ function compactArrayTemplate(DefaultTemplate) {
21962
+ return function CompactArray(props) {
21963
+ const enabled = useCommonLayout();
21964
+ return React5.createElement(
21965
+ React5.Fragment,
21966
+ null,
21967
+ React5.createElement(DefaultTemplate, { ...props }),
21968
+ enabled && props.items.length === 0 && React5.createElement("p", { className: "editor-form-hint" }, "\u9805\u76EE\u306A\u3057")
21969
+ );
21970
+ };
21971
+ }
21972
+ function compactCheckboxWidget(DefaultWidget) {
21973
+ return function CompactCheckbox(props) {
21974
+ var _a;
21975
+ const enabled = useCommonLayout();
21976
+ const label = enabled && !props.schema.title && !((_a = props.uiSchema) === null || _a === void 0 ? void 0 : _a["ui:title"]) && !props.options.title ? propertyLabel(props.label) : props.label;
21977
+ return React5.createElement(DefaultWidget, { ...props, label });
21978
+ };
21979
+ }
21309
21980
  function valueFieldTemplate(DefaultTemplate, flag) {
21310
21981
  return function ValueField2(props) {
21982
+ var _a;
21983
+ const enabled = useCommonLayout();
21311
21984
  if (!(flag in props.schema))
21312
- return React3.createElement(DefaultTemplate, { ...props });
21313
- return React3.createElement(
21985
+ return React5.createElement(DefaultTemplate, { ...props, label: enabled && !props.schema.title && !((_a = props.uiSchema) === null || _a === void 0 ? void 0 : _a["ui:title"]) ? propertyLabel(props.label) : props.label });
21986
+ return React5.createElement(
21314
21987
  PropertyKey.Provider,
21315
21988
  { value: props.label },
21316
- React3.createElement(DefaultTemplate, { ...props, label: "\u5024" })
21989
+ React5.createElement(DefaultTemplate, { ...props, label: "\u5024" })
21317
21990
  );
21318
21991
  };
21319
21992
  }
@@ -21325,49 +21998,49 @@ function numberedObjectTemplate(DefaultTemplate, flag) {
21325
21998
  const schema4 = (_a = props.schema.properties) === null || _a === void 0 ? void 0 : _a[property2.name];
21326
21999
  if (!schema4 || typeof schema4 !== "object" || !(flag in schema4) || property2.hidden)
21327
22000
  return property2;
21328
- return { ...property2, content: React3.createElement(ItemNumber.Provider, { key: property2.name, value: ++number }, property2.content) };
22001
+ return { ...property2, content: React5.createElement(ItemNumber.Provider, { key: property2.name, value: ++number }, property2.content) };
21329
22002
  });
21330
- return React3.createElement(DefaultTemplate, { ...props, properties });
22003
+ return React5.createElement(DefaultTemplate, { ...props, properties });
21331
22004
  };
21332
22005
  }
21333
22006
  function additionalItemTemplate(flag) {
21334
22007
  return function AdditionalItem2(props) {
21335
- const number = React3.useContext(ItemNumber);
21336
- const propertyKey = React3.useContext(PropertyKey);
22008
+ const number = React5.useContext(ItemNumber);
22009
+ const propertyKey = React5.useContext(PropertyKey);
21337
22010
  const { id, classNames, style, children, schema: schema4, label, disabled, readonly, onKeyChange, onDropPropertyClick } = props;
21338
22011
  if (!(flag in schema4))
21339
- return React3.createElement("div", { className: classNames, style }, children);
22012
+ return React5.createElement("div", { className: classNames, style }, children);
21340
22013
  const key = propertyKey !== null && propertyKey !== void 0 ? propertyKey : label;
21341
- return React3.createElement(
22014
+ return React5.createElement(
21342
22015
  "div",
21343
22016
  { className: classNames, style, "data-block-editor-item": "" },
21344
- React3.createElement(
22017
+ React5.createElement(
21345
22018
  "div",
21346
22019
  { "data-block-editor-item-heading": "" },
21347
- React3.createElement(
22020
+ React5.createElement(
21348
22021
  "span",
21349
22022
  null,
21350
22023
  "\u30FB\u9805\u76EE",
21351
22024
  number
21352
22025
  ),
21353
- React3.createElement(ItemMenu, { disabled: disabled || readonly, onClick: onDropPropertyClick(key) })
22026
+ React5.createElement(ItemMenu, { disabled: disabled || readonly, onClick: onDropPropertyClick(key) })
21354
22027
  ),
21355
- React3.createElement(
22028
+ React5.createElement(
21356
22029
  "div",
21357
22030
  { "data-block-editor-pair-row": "" },
21358
- React3.createElement("label", { htmlFor: `${id}-key` }, "\u30AD\u30FC"),
21359
- React3.createElement("input", { id: `${id}-key`, type: "text", defaultValue: key, disabled, readOnly: readonly, onBlur: (event) => onKeyChange(event.target.value) })
22031
+ React5.createElement("label", { htmlFor: `${id}-key` }, "\u30AD\u30FC"),
22032
+ React5.createElement("input", { id: `${id}-key`, type: "text", defaultValue: key, disabled, readOnly: readonly, onBlur: (event) => onKeyChange(event.target.value) })
21360
22033
  ),
21361
- React3.createElement("div", { "data-block-editor-pair-row": "" }, children)
22034
+ React5.createElement("div", { "data-block-editor-pair-row": "" }, children)
21362
22035
  );
21363
22036
  };
21364
22037
  }
21365
22038
  function ItemMenu({ disabled, onClick }) {
21366
- const [open, setOpen] = React3.useState(false);
21367
- const container = React3.useRef(null);
21368
- const trigger = React3.useRef(null);
21369
- const item = React3.useRef(null);
21370
- React3.useEffect(() => {
22039
+ const [open, setOpen] = React5.useState(false);
22040
+ const container = React5.useRef(null);
22041
+ const trigger = React5.useRef(null);
22042
+ const item = React5.useRef(null);
22043
+ React5.useEffect(() => {
21371
22044
  var _a;
21372
22045
  if (!open)
21373
22046
  return;
@@ -21394,11 +22067,11 @@ function ItemMenu({ disabled, onClick }) {
21394
22067
  document.removeEventListener("mousedown", closeOutside);
21395
22068
  };
21396
22069
  }, [open]);
21397
- React3.useEffect(() => {
22070
+ React5.useEffect(() => {
21398
22071
  if (disabled)
21399
22072
  setOpen(false);
21400
22073
  }, [disabled]);
21401
- return React3.createElement(
22074
+ return React5.createElement(
21402
22075
  "div",
21403
22076
  { "data-block-editor-item-menu": "", ref: container, onBlur: (event) => {
21404
22077
  if (!event.currentTarget.contains(event.relatedTarget))
@@ -21418,11 +22091,11 @@ function ItemMenu({ disabled, onClick }) {
21418
22091
  setOpen(true);
21419
22092
  }
21420
22093
  } },
21421
- React3.createElement("button", { "aria-label": "\u9805\u76EE\u306E\u30E1\u30CB\u30E5\u30FC", "aria-haspopup": "menu", "aria-expanded": open && !disabled, disabled, ref: trigger, type: "button", onClick: () => setOpen(!open) }, "\u2026"),
21422
- open && !disabled ? React3.createElement(
22094
+ React5.createElement("button", { "aria-label": "\u9805\u76EE\u306E\u30E1\u30CB\u30E5\u30FC", "aria-haspopup": "menu", "aria-expanded": open && !disabled, disabled, ref: trigger, type: "button", onClick: () => setOpen(!open) }, "\u2026"),
22095
+ open && !disabled ? React5.createElement(
21423
22096
  "div",
21424
22097
  { role: "menu", "aria-label": "\u9805\u76EE\u306E\u64CD\u4F5C" },
21425
- React3.createElement("button", { ref: item, role: "menuitem", type: "button", onClick: (event) => {
22098
+ React5.createElement("button", { ref: item, role: "menuitem", type: "button", onClick: (event) => {
21426
22099
  var _a;
21427
22100
  setOpen(false);
21428
22101
  (_a = trigger.current) === null || _a === void 0 ? void 0 : _a.focus();
@@ -21432,34 +22105,34 @@ function ItemMenu({ disabled, onClick }) {
21432
22105
  );
21433
22106
  }
21434
22107
  function AddItemButton({ disabled, onClick, className }) {
21435
- return React3.createElement("button", { className, "data-block-editor-add-item": "", disabled, type: "button", onClick }, "\u2795\u9805\u76EE\u3092\u8FFD\u52A0");
22108
+ return React5.createElement("button", { className, "data-block-editor-add-item": "", disabled, type: "button", onClick }, "\u2795\u9805\u76EE\u3092\u8FFD\u52A0");
21436
22109
  }
21437
22110
  function ArrayItem(props) {
21438
22111
  const { children, className, disabled, readonly, index, hasMoveUp, hasMoveDown, hasCopy, hasRemove, onReorderClick, onCopyIndexClick, onDropIndexClick } = props;
21439
22112
  const locked = disabled || readonly;
21440
- return React3.createElement(
22113
+ return React5.createElement(
21441
22114
  "div",
21442
22115
  { className, "data-block-editor-item": "" },
21443
- React3.createElement(
22116
+ React5.createElement(
21444
22117
  "div",
21445
22118
  { "data-block-editor-item-heading": "" },
21446
- React3.createElement(
22119
+ React5.createElement(
21447
22120
  "span",
21448
22121
  null,
21449
22122
  "\u30FB\u9805\u76EE",
21450
22123
  index + 1
21451
22124
  ),
21452
- React3.createElement(
22125
+ React5.createElement(
21453
22126
  "div",
21454
22127
  { "data-block-editor-item-actions": "" },
21455
- hasMoveUp || hasMoveDown ? React3.createElement(
21456
- React3.Fragment,
22128
+ hasMoveUp || hasMoveDown ? React5.createElement(
22129
+ React5.Fragment,
21457
22130
  null,
21458
- React3.createElement("button", { "aria-label": "\u9805\u76EE\u3092\u4E0A\u3078\u79FB\u52D5", disabled: locked || !hasMoveUp, type: "button", onClick: onReorderClick(index, index - 1) }, "\u2191"),
21459
- React3.createElement("button", { "aria-label": "\u9805\u76EE\u3092\u4E0B\u3078\u79FB\u52D5", disabled: locked || !hasMoveDown, type: "button", onClick: onReorderClick(index, index + 1) }, "\u2193")
22131
+ React5.createElement("button", { "aria-label": "\u9805\u76EE\u3092\u4E0A\u3078\u79FB\u52D5", disabled: locked || !hasMoveUp, type: "button", onClick: onReorderClick(index, index - 1) }, "\u2191"),
22132
+ React5.createElement("button", { "aria-label": "\u9805\u76EE\u3092\u4E0B\u3078\u79FB\u52D5", disabled: locked || !hasMoveDown, type: "button", onClick: onReorderClick(index, index + 1) }, "\u2193")
21460
22133
  ) : null,
21461
- hasCopy ? React3.createElement("button", { disabled: locked, type: "button", onClick: onCopyIndexClick(index) }, "\u9805\u76EE\u3092\u8907\u88FD") : null,
21462
- hasRemove ? React3.createElement(ItemMenu, { disabled: locked, onClick: onDropIndexClick(index) }) : null
22134
+ hasCopy ? React5.createElement("button", { disabled: locked, type: "button", onClick: onCopyIndexClick(index) }, "\u9805\u76EE\u3092\u8907\u88FD") : null,
22135
+ hasRemove ? React5.createElement(ItemMenu, { disabled: locked, onClick: onDropIndexClick(index) }) : null
21463
22136
  )
21464
22137
  ),
21465
22138
  children
@@ -21475,11 +22148,15 @@ var Form2 = moduleExports4(lib_exports2).default;
21475
22148
  var { getDefaultFormState: getDefaultFormState2, ADDITIONAL_PROPERTY_FLAG: ADDITIONAL_PROPERTY_FLAG2 } = moduleExports4(lib_exports);
21476
22149
  var { customizeValidator: customizeValidator2 } = moduleExports4(lib_exports3);
21477
22150
  var defaultTemplates = moduleExports4(lib_exports2).getDefaultRegistry().templates;
21478
- var ObjectItems = numberedObjectTemplate(defaultTemplates.ObjectFieldTemplate, ADDITIONAL_PROPERTY_FLAG2);
22151
+ var ObjectItems = numberedObjectTemplate(layoutObjectTemplate(defaultTemplates.ObjectFieldTemplate), ADDITIONAL_PROPERTY_FLAG2);
21479
22152
  var AdditionalItem = additionalItemTemplate(ADDITIONAL_PROPERTY_FLAG2);
21480
22153
  var ValueField = valueFieldTemplate(defaultTemplates.FieldTemplate, ADDITIONAL_PROPERTY_FLAG2);
22154
+ var Description = compactDescriptionTemplate(defaultTemplates.DescriptionFieldTemplate);
22155
+ var ArrayTitle = compactArrayTitleTemplate(defaultTemplates.ArrayFieldTitleTemplate);
22156
+ var ArrayBody = compactArrayTemplate(defaultTemplates.ArrayFieldTemplate);
22157
+ var Checkbox = compactCheckboxWidget(moduleExports4(lib_exports2).getDefaultRegistry().widgets.CheckboxWidget);
21481
22158
  var nextViewId = 0;
21482
- function createSchemaBundleEditor(options) {
22159
+ function createSchemaBundleEditor(options, features = {}) {
21483
22160
  const { schemaBundle, validationContext: provider, ownerValidate, apiVersion, extensionId, editorId, opcodes, argument, format, uiSchema, validateData } = options;
21484
22161
  let bundle;
21485
22162
  try {
@@ -21524,9 +22201,10 @@ function createSchemaBundleEditor(options) {
21524
22201
  ...format === void 0 ? {} : { format },
21525
22202
  ...uiSchema === void 0 ? {} : { uiSchema },
21526
22203
  ...validateData === void 0 ? {} : { validateData }
21527
- }, { issuesFor, dialect: result.validator.dialect });
22204
+ }, { issuesFor, dialect: result.validator.dialect }, captureFeatureFlags(features));
21528
22205
  }
21529
22206
  function createBlockEditorService(options) {
22207
+ const features = captureFeatureFlags(options);
21530
22208
  if ((options === null || options === void 0 ? void 0 : options.fixedInputs) !== void 0 && typeof options.fixedInputs !== "boolean")
21531
22209
  throw new TypeError("Invalid fixed input capability option.");
21532
22210
  const messageSource = options === null || options === void 0 ? void 0 : options.fixedInputMessages;
@@ -21557,7 +22235,7 @@ function createBlockEditorService(options) {
21557
22235
  apiVersion: EDITOR_API_VERSION,
21558
22236
  register: (definition) => {
21559
22237
  const custom = definition;
21560
- const editor = !custom.mount && Object.hasOwn(definition, "schema") ? createSchemaEditor(definition) : custom;
22238
+ const editor = !custom.mount && Object.hasOwn(definition, "schema") ? createSchemaEditor(definition, features) : custom;
21561
22239
  if (typeof editor.mount !== "function")
21562
22240
  throw new TypeError("A block editor must provide mount().");
21563
22241
  const remove = registry.register(editor);
@@ -21571,10 +22249,10 @@ function createBlockEditorService(options) {
21571
22249
  notify();
21572
22250
  };
21573
22251
  },
21574
- registerSchema: (definition) => api.register(createSchemaEditor(definition)),
21575
- registerSchemaBundle: (definition) => api.register(createSchemaBundleEditor(definition)),
22252
+ registerSchema: (definition) => api.register(createSchemaEditor(definition, features)),
22253
+ registerSchemaBundle: (definition) => api.register(createSchemaBundleEditor(definition, features)),
21576
22254
  registerSourceEditor: (definition) => {
21577
- const remove = registry.registerPrepared(createSourceEditor(definition));
22255
+ const remove = registry.registerPrepared(createSourceEditor(definition, features));
21578
22256
  notify();
21579
22257
  let active = true;
21580
22258
  return () => {
@@ -21593,10 +22271,10 @@ function createBlockEditorService(options) {
21593
22271
  };
21594
22272
  } };
21595
22273
  }
21596
- function createSchemaEditor(options) {
21597
- return createSchemaEditorImpl(options);
22274
+ function createSchemaEditor(options, features = {}) {
22275
+ return createSchemaEditorImpl(options, void 0, captureFeatureFlags(features));
21598
22276
  }
21599
- function createSchemaEditorImpl(options, bundle) {
22277
+ function createSchemaEditorImpl(options, bundle, features = captureFeatureFlags()) {
21600
22278
  var _a, _b;
21601
22279
  if (options.apiVersion !== EDITOR_API_VERSION || typeof options.argument !== "string" || !options.argument) {
21602
22280
  throw new TypeError("A supported API version and JSON argument name are required.");
@@ -21606,7 +22284,7 @@ function createSchemaEditorImpl(options, bundle) {
21606
22284
  if (format !== "json" && format !== "yaml")
21607
22285
  throw new TypeError("Unsupported source format.");
21608
22286
  const schema4 = cloneJson(options.schema);
21609
- const uiSchema = options.uiSchema ? cloneJson(options.uiSchema) : {};
22287
+ const uiSchema = options.uiSchema ? snapshotJson(options.uiSchema) : {};
21610
22288
  const validateData = options.validateData;
21611
22289
  const validator = customizeValidator2({
21612
22290
  ...(bundle === null || bundle === void 0 ? void 0 : bundle.dialect) === "2020-12" ? { AjvClass: import__3.Ajv2020 } : {},
@@ -21675,11 +22353,15 @@ function createSchemaEditorImpl(options, bundle) {
21675
22353
  uiSchema,
21676
22354
  validator,
21677
22355
  idPrefix,
22356
+ widgets: { CheckboxWidget: Checkbox },
21678
22357
  templates: {
21679
22358
  ArrayFieldItemTemplate: ArrayItem,
22359
+ ArrayFieldTitleTemplate: ArrayTitle,
22360
+ ArrayFieldTemplate: ArrayBody,
21680
22361
  ObjectFieldTemplate: ObjectItems,
21681
22362
  WrapIfAdditionalTemplate: AdditionalItem,
21682
22363
  FieldTemplate: ValueField,
22364
+ DescriptionFieldTemplate: Description,
21683
22365
  ButtonTemplates: { AddButton: AddItemButton, RemoveButton: ItemMenu }
21684
22366
  },
21685
22367
  formData: dataFor(context.getDraft()),
@@ -21702,7 +22384,7 @@ function createSchemaEditorImpl(options, bundle) {
21702
22384
  context.setValidationIssues(issuesFor(data));
21703
22385
  }
21704
22386
  };
21705
- ReactDOM3.render(React4.createElement(Form2, props, React4.createElement("span", { hidden: true })), container);
22387
+ ReactDOM3.render(React6.createElement(LayoutHost, { enabled: features.commonLayout, context, children: React6.createElement(Form2, props, React6.createElement("span", { hidden: true })) }), container);
21706
22388
  };
21707
22389
  const schedule = () => {
21708
22390
  if (scheduled || !active)