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

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