@ohhwells/bridge 0.1.65-next.182 → 0.1.65-next.183
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +66 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +66 -21
- package/dist/index.js.map +1 -1
- package/dist/styles.css +3 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -7018,6 +7018,7 @@ var FIELD_TYPES = [
|
|
|
7018
7018
|
];
|
|
7019
7019
|
var FIELD_ATTR = "data-ohw-form-field";
|
|
7020
7020
|
var FIELD_TYPE_ATTR = "data-ohw-field-type";
|
|
7021
|
+
var PLACEHOLDER_EDIT_ATTR = "data-ohw-placeholder-edit";
|
|
7021
7022
|
function fieldsKey(formKey) {
|
|
7022
7023
|
return `${formKey}-fields`;
|
|
7023
7024
|
}
|
|
@@ -7055,7 +7056,7 @@ function ensureFieldLabel(wrapper, key) {
|
|
|
7055
7056
|
label.style.lineHeight = "1.3";
|
|
7056
7057
|
const fromPlaceholder = input?.getAttribute("placeholder")?.trim();
|
|
7057
7058
|
const text = fromPlaceholder && fromPlaceholder.length < 40 ? fromPlaceholder : key.replace(/[-_]/g, " ");
|
|
7058
|
-
label.textContent =
|
|
7059
|
+
label.textContent = text;
|
|
7059
7060
|
if (input && input.parentElement === wrapper) wrapper.insertBefore(label, input);
|
|
7060
7061
|
else wrapper.insertBefore(label, wrapper.firstChild);
|
|
7061
7062
|
return label;
|
|
@@ -7111,8 +7112,11 @@ function readFieldsFromDom(form) {
|
|
|
7111
7112
|
return {
|
|
7112
7113
|
key: fieldKeyOf(wrapper),
|
|
7113
7114
|
type: fieldTypeOf(wrapper),
|
|
7114
|
-
label: fieldLabelOf(wrapper)
|
|
7115
|
-
|
|
7115
|
+
label: fieldLabelText(fieldLabelOf(wrapper)).trim(),
|
|
7116
|
+
// While a field is selected its placeholder text lives in the value (see
|
|
7117
|
+
// beginPlaceholderEdit), so reading the attribute would store an empty one — whoever
|
|
7118
|
+
// happens to save at that moment must still record what the owner typed.
|
|
7119
|
+
placeholder: input ? input.hasAttribute(PLACEHOLDER_EDIT_ATTR) ? input.value : input.getAttribute("placeholder") ?? "" : "",
|
|
7116
7120
|
required: Boolean(input?.hasAttribute("required"))
|
|
7117
7121
|
};
|
|
7118
7122
|
});
|
|
@@ -7140,7 +7144,7 @@ function applyFieldType(wrapper, type) {
|
|
|
7140
7144
|
const followsDefaults = {
|
|
7141
7145
|
// A label the owner wrote stays; one that still reads as a type name (or as the old
|
|
7142
7146
|
// placeholder the template shipped) follows the new type.
|
|
7143
|
-
label: isDefaultText(label?.textContent ?? "", (d) => d.label) || (label
|
|
7147
|
+
label: isDefaultText(label?.textContent ?? "", (d) => d.label) || fieldLabelText(label).trim() === placeholder.trim()
|
|
7144
7148
|
};
|
|
7145
7149
|
const { tag, inputType } = inputTagFor(type);
|
|
7146
7150
|
wrapper.setAttribute(FIELD_TYPE_ATTR, type);
|
|
@@ -7154,8 +7158,7 @@ function applyFieldType(wrapper, type) {
|
|
|
7154
7158
|
const applyDefaults = (el) => {
|
|
7155
7159
|
el.setAttribute("placeholder", defaults.placeholder);
|
|
7156
7160
|
if (label && followsDefaults.label) {
|
|
7157
|
-
|
|
7158
|
-
label.textContent = required ? `${defaults.label} *` : defaults.label;
|
|
7161
|
+
label.textContent = defaults.label;
|
|
7159
7162
|
}
|
|
7160
7163
|
};
|
|
7161
7164
|
if (input.tagName.toLowerCase() === tag) {
|
|
@@ -7175,13 +7178,19 @@ function applyFieldType(wrapper, type) {
|
|
|
7175
7178
|
input.replaceWith(next);
|
|
7176
7179
|
applyDefaults(next);
|
|
7177
7180
|
}
|
|
7181
|
+
var REQUIRED_MARK_ATTR = "data-ohw-field-required";
|
|
7182
|
+
function fieldLabelText(label) {
|
|
7183
|
+
if (!label) return "";
|
|
7184
|
+
return (label.textContent ?? "").replace(/\s*\*\s*$/, "").trimEnd();
|
|
7185
|
+
}
|
|
7178
7186
|
function syncRequiredMark(wrapper) {
|
|
7179
7187
|
const label = fieldLabelOf(wrapper);
|
|
7180
7188
|
if (!label) return;
|
|
7181
|
-
|
|
7182
|
-
const
|
|
7183
|
-
|
|
7184
|
-
if (
|
|
7189
|
+
label.querySelectorAll("[data-ohw-required-mark]").forEach((el) => el.remove());
|
|
7190
|
+
const words = fieldLabelText(label);
|
|
7191
|
+
if ((label.textContent ?? "") !== words) label.textContent = words;
|
|
7192
|
+
if (isFieldRequired(wrapper)) label.setAttribute(REQUIRED_MARK_ATTR, "");
|
|
7193
|
+
else label.removeAttribute(REQUIRED_MARK_ATTR);
|
|
7185
7194
|
}
|
|
7186
7195
|
function setFieldRequired(wrapper, required) {
|
|
7187
7196
|
const input = fieldInputOf(wrapper);
|
|
@@ -7191,7 +7200,6 @@ function setFieldRequired(wrapper, required) {
|
|
|
7191
7200
|
else input.removeAttribute("required");
|
|
7192
7201
|
if (label) syncRequiredMark(wrapper);
|
|
7193
7202
|
}
|
|
7194
|
-
var PLACEHOLDER_EDIT_ATTR = "data-ohw-placeholder-edit";
|
|
7195
7203
|
function beginPlaceholderEdit(wrapper) {
|
|
7196
7204
|
const input = fieldInputOf(wrapper);
|
|
7197
7205
|
if (!input || input.hasAttribute(PLACEHOLDER_EDIT_ATTR)) return;
|
|
@@ -7270,14 +7278,25 @@ function duplicateField(form, wrapper) {
|
|
|
7270
7278
|
function removeField(wrapper) {
|
|
7271
7279
|
wrapper.remove();
|
|
7272
7280
|
}
|
|
7273
|
-
function
|
|
7281
|
+
function applyFieldOrder(form, keys) {
|
|
7274
7282
|
const wrappers = listFieldWrappers(form);
|
|
7275
|
-
const
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
const
|
|
7279
|
-
|
|
7280
|
-
|
|
7283
|
+
const byKey = new Map(wrappers.map((wrapper) => [fieldKeyOf(wrapper), wrapper]));
|
|
7284
|
+
const ordered = keys.map((key) => byKey.get(key)).filter((w) => Boolean(w));
|
|
7285
|
+
if (ordered.length !== wrappers.length) return;
|
|
7286
|
+
const slots = wrappers.map((wrapper) => {
|
|
7287
|
+
const slot = document.createComment("ohw-field-slot");
|
|
7288
|
+
wrapper.replaceWith(slot);
|
|
7289
|
+
return slot;
|
|
7290
|
+
});
|
|
7291
|
+
ordered.forEach((wrapper, index) => slots[index].replaceWith(wrapper));
|
|
7292
|
+
}
|
|
7293
|
+
function moveField(form, key, toIndex) {
|
|
7294
|
+
const keys = listFieldWrappers(form).map(fieldKeyOf);
|
|
7295
|
+
const from = keys.indexOf(key);
|
|
7296
|
+
if (from === -1) return;
|
|
7297
|
+
const rest = keys.filter((k) => k !== key);
|
|
7298
|
+
rest.splice(Math.max(0, Math.min(rest.length, toIndex)), 0, key);
|
|
7299
|
+
applyFieldOrder(form, rest);
|
|
7281
7300
|
}
|
|
7282
7301
|
function reconcileFieldsFromContent(form, content) {
|
|
7283
7302
|
const formKey = form.getAttribute("data-ohw-key");
|
|
@@ -7303,14 +7322,18 @@ function reconcileFieldsFromContent(form, content) {
|
|
|
7303
7322
|
setFieldRequired(wrapper, spec.required);
|
|
7304
7323
|
setFieldPlaceholder(wrapper, spec.placeholder);
|
|
7305
7324
|
const label = fieldLabelOf(wrapper);
|
|
7306
|
-
if (label && spec.label) label.textContent = spec.label;
|
|
7325
|
+
if (label && spec.label) label.textContent = spec.label.replace(/\s*\*\s*$/, "").trimEnd();
|
|
7307
7326
|
syncRequiredMark(wrapper);
|
|
7308
7327
|
});
|
|
7309
7328
|
const wanted = new Set(stored.map((spec) => spec.key));
|
|
7310
7329
|
listFieldWrappers(form).forEach((wrapper) => {
|
|
7311
7330
|
if (!wanted.has(fieldKeyOf(wrapper))) wrapper.remove();
|
|
7312
7331
|
});
|
|
7313
|
-
|
|
7332
|
+
const currentOrder = listFieldWrappers(form).map(fieldKeyOf).join("\0");
|
|
7333
|
+
const storedOrder = stored.map((spec) => spec.key).join("\0");
|
|
7334
|
+
if (currentOrder !== storedOrder) {
|
|
7335
|
+
applyFieldOrder(form, stored.map((spec) => spec.key));
|
|
7336
|
+
}
|
|
7314
7337
|
}
|
|
7315
7338
|
|
|
7316
7339
|
// src/ui/form-field-toolbar.tsx
|
|
@@ -15236,8 +15259,8 @@ function OhhwellsBridge() {
|
|
|
15236
15259
|
if (!wrapper || !form) return;
|
|
15237
15260
|
commitPlaceholderEdit(wrapper);
|
|
15238
15261
|
run(form, wrapper);
|
|
15239
|
-
beginPlaceholderEdit(wrapper);
|
|
15240
15262
|
persistFields(form);
|
|
15263
|
+
beginPlaceholderEdit(wrapper);
|
|
15241
15264
|
setFormPickRect(form.getBoundingClientRect());
|
|
15242
15265
|
},
|
|
15243
15266
|
[persistFields]
|
|
@@ -15595,6 +15618,12 @@ function OhhwellsBridge() {
|
|
|
15595
15618
|
}
|
|
15596
15619
|
el.removeAttribute("contenteditable");
|
|
15597
15620
|
el.removeAttribute("data-ohw-editing");
|
|
15621
|
+
const labelField = getFieldWrapper(el);
|
|
15622
|
+
if (labelField) {
|
|
15623
|
+
syncRequiredMark(labelField);
|
|
15624
|
+
const owner = labelField.closest('[data-ohw-editable="form"]');
|
|
15625
|
+
if (owner) persistFieldsRef.current(owner);
|
|
15626
|
+
}
|
|
15598
15627
|
activeElRef.current = null;
|
|
15599
15628
|
setNavGroupForceOpen(null, false);
|
|
15600
15629
|
setReorderHrefKey(null);
|
|
@@ -15750,6 +15779,12 @@ function OhhwellsBridge() {
|
|
|
15750
15779
|
}
|
|
15751
15780
|
el.removeAttribute("contenteditable");
|
|
15752
15781
|
el.removeAttribute("data-ohw-editing");
|
|
15782
|
+
const labelField = getFieldWrapper(el);
|
|
15783
|
+
if (labelField) {
|
|
15784
|
+
syncRequiredMark(labelField);
|
|
15785
|
+
const owner = labelField.closest('[data-ohw-editable="form"]');
|
|
15786
|
+
if (owner) persistFieldsRef.current(owner);
|
|
15787
|
+
}
|
|
15753
15788
|
activeElRef.current = null;
|
|
15754
15789
|
setMaxBadge(null);
|
|
15755
15790
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
@@ -16876,6 +16911,9 @@ function OhhwellsBridge() {
|
|
|
16876
16911
|
reconcileFooterOrderFromContent(content);
|
|
16877
16912
|
reconcileSocialsFromContent(content);
|
|
16878
16913
|
applySocialsDisplayFromContent(content);
|
|
16914
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
|
|
16915
|
+
listFieldWrappers(form).forEach(syncRequiredMark);
|
|
16916
|
+
});
|
|
16879
16917
|
} finally {
|
|
16880
16918
|
observer?.observe(document.body, { childList: true, subtree: true });
|
|
16881
16919
|
}
|
|
@@ -19003,6 +19041,13 @@ function OhhwellsBridge() {
|
|
|
19003
19041
|
if (brandKitRef.current) {
|
|
19004
19042
|
nodes.push({ key: BRAND_KIT_KEY, type: "brand", text: brandKitRef.current });
|
|
19005
19043
|
}
|
|
19044
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
|
|
19045
|
+
const formKey = formKeyOf(form);
|
|
19046
|
+
if (!formKey) return;
|
|
19047
|
+
const specs = readFieldsFromDom(form);
|
|
19048
|
+
const text = specs.length ? JSON.stringify(specs) : editContentRef.current[fieldsKey(formKey)];
|
|
19049
|
+
if (text) nodes.push({ key: fieldsKey(formKey), type: "text", text });
|
|
19050
|
+
});
|
|
19006
19051
|
postToParentRef.current({ type: "ow:save-result", nodes });
|
|
19007
19052
|
};
|
|
19008
19053
|
const handleInsertSection = (e) => {
|