@ohhwells/bridge 0.1.64-next.176 → 0.1.64-next.177
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 +1362 -260
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1346 -244
- package/dist/index.js.map +1 -1
- package/dist/styles.css +92 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6589,6 +6589,7 @@ function getChromeStyle(state) {
|
|
|
6589
6589
|
}
|
|
6590
6590
|
function ClampedToolbarSlot({
|
|
6591
6591
|
placement,
|
|
6592
|
+
align = "center",
|
|
6592
6593
|
children
|
|
6593
6594
|
}) {
|
|
6594
6595
|
const slotRef = (0, import_react7.useRef)(null);
|
|
@@ -6610,7 +6611,7 @@ function ClampedToolbarSlot({
|
|
|
6610
6611
|
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN - half)
|
|
6611
6612
|
);
|
|
6612
6613
|
const offsetX = clampedCenter - centerX;
|
|
6613
|
-
slot.style.transform = `translateX(calc(-50% + ${offsetX}px))`;
|
|
6614
|
+
slot.style.transform = align === "left" ? "none" : `translateX(calc(-50% + ${offsetX}px))`;
|
|
6614
6615
|
};
|
|
6615
6616
|
clamp();
|
|
6616
6617
|
const ro = new ResizeObserver(clamp);
|
|
@@ -6621,19 +6622,20 @@ function ClampedToolbarSlot({
|
|
|
6621
6622
|
ro.disconnect();
|
|
6622
6623
|
window.removeEventListener("resize", clamp);
|
|
6623
6624
|
};
|
|
6624
|
-
}, [placement, children]);
|
|
6625
|
+
}, [placement, children, align]);
|
|
6625
6626
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
6626
6627
|
"div",
|
|
6627
6628
|
{
|
|
6628
6629
|
ref: slotRef,
|
|
6629
6630
|
className: cn(
|
|
6630
|
-
"pointer-events-auto absolute
|
|
6631
|
+
"pointer-events-auto absolute",
|
|
6632
|
+
align === "left" ? "left-0" : "left-1/2",
|
|
6631
6633
|
placement === "top" ? "bottom-full" : "top-full"
|
|
6632
6634
|
),
|
|
6633
6635
|
style: {
|
|
6634
6636
|
marginBottom: placement === "top" ? TOOLBAR_STROKE_GAP : void 0,
|
|
6635
6637
|
marginTop: placement === "bottom" ? TOOLBAR_STROKE_GAP : void 0,
|
|
6636
|
-
transform: "translateX(-50%)"
|
|
6638
|
+
transform: align === "left" ? "none" : "translateX(-50%)"
|
|
6637
6639
|
},
|
|
6638
6640
|
"data-ohw-item-toolbar-anchor": placement,
|
|
6639
6641
|
children
|
|
@@ -6702,6 +6704,7 @@ function ItemInteractionLayer({
|
|
|
6702
6704
|
onItemClick,
|
|
6703
6705
|
itemDragSurface = true,
|
|
6704
6706
|
chromeGap,
|
|
6707
|
+
toolbarAlign = "center",
|
|
6705
6708
|
className
|
|
6706
6709
|
}) {
|
|
6707
6710
|
if (state === "default") return null;
|
|
@@ -6789,8 +6792,8 @@ function ItemInteractionLayer({
|
|
|
6789
6792
|
)
|
|
6790
6793
|
}
|
|
6791
6794
|
),
|
|
6792
|
-
showToolbar && state === "active-top" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ClampedToolbarSlot, { placement: "top", children: toolbar }),
|
|
6793
|
-
showToolbar && state === "active-bottom" && !useDetachedBelowToolbar && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ClampedToolbarSlot, { placement: "bottom", children: toolbar }),
|
|
6795
|
+
showToolbar && state === "active-top" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ClampedToolbarSlot, { align: toolbarAlign, placement: "top", children: toolbar }),
|
|
6796
|
+
showToolbar && state === "active-bottom" && !useDetachedBelowToolbar && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ClampedToolbarSlot, { align: toolbarAlign, placement: "bottom", children: toolbar }),
|
|
6794
6797
|
useDetachedBelowToolbar && toolbarBelowRect ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
6795
6798
|
DetachedBelowToolbarSlot,
|
|
6796
6799
|
{
|
|
@@ -6804,14 +6807,580 @@ function ItemInteractionLayer({
|
|
|
6804
6807
|
);
|
|
6805
6808
|
}
|
|
6806
6809
|
|
|
6810
|
+
// src/lib/forms.ts
|
|
6811
|
+
var FORM_SELECTOR = '[data-ohw-editable="form"]';
|
|
6812
|
+
function getFormElement(el) {
|
|
6813
|
+
if (!el) return null;
|
|
6814
|
+
return el.closest(FORM_SELECTOR);
|
|
6815
|
+
}
|
|
6816
|
+
function formKeyOf(form) {
|
|
6817
|
+
return form.getAttribute("data-ohw-key");
|
|
6818
|
+
}
|
|
6819
|
+
function formHasLongText(form) {
|
|
6820
|
+
return form.querySelector("textarea") !== null;
|
|
6821
|
+
}
|
|
6822
|
+
function collectFormFields(form) {
|
|
6823
|
+
const fields = {};
|
|
6824
|
+
form.querySelectorAll(
|
|
6825
|
+
"input, textarea, select"
|
|
6826
|
+
).forEach((input) => {
|
|
6827
|
+
const type = input.type;
|
|
6828
|
+
if (type === "submit" || type === "button" || type === "reset") return;
|
|
6829
|
+
const key = input.getAttribute("name") ?? input.getAttribute("data-ohw-key");
|
|
6830
|
+
if (!key) return;
|
|
6831
|
+
if (type === "checkbox") {
|
|
6832
|
+
fields[key] = input.checked ? "yes" : "no";
|
|
6833
|
+
return;
|
|
6834
|
+
}
|
|
6835
|
+
fields[key] = input.value;
|
|
6836
|
+
});
|
|
6837
|
+
return fields;
|
|
6838
|
+
}
|
|
6839
|
+
function formStateContainer(form) {
|
|
6840
|
+
return form.closest("[data-ohw-editable-state]") ?? form.parentElement ?? form;
|
|
6841
|
+
}
|
|
6842
|
+
function showSuccess(form, message) {
|
|
6843
|
+
const container = formStateContainer(form);
|
|
6844
|
+
const views = container.querySelectorAll("[data-ohw-state-view]");
|
|
6845
|
+
if (views.length > 0) {
|
|
6846
|
+
views.forEach((view) => {
|
|
6847
|
+
view.style.display = view.getAttribute("data-ohw-state-view") === "success" ? "block" : "none";
|
|
6848
|
+
});
|
|
6849
|
+
return;
|
|
6850
|
+
}
|
|
6851
|
+
const text = message ?? form.getAttribute("data-ohw-success-text") ?? DEFAULT_SUCCESS_TEXT;
|
|
6852
|
+
const note = document.createElement("p");
|
|
6853
|
+
note.setAttribute("data-ohw-form-success", "");
|
|
6854
|
+
note.setAttribute("role", "status");
|
|
6855
|
+
note.innerHTML = text;
|
|
6856
|
+
form.replaceChildren(note);
|
|
6857
|
+
}
|
|
6858
|
+
function showSubmitError(form) {
|
|
6859
|
+
let note = form.querySelector("[data-ohw-form-error]");
|
|
6860
|
+
if (!note) {
|
|
6861
|
+
note = document.createElement("p");
|
|
6862
|
+
note.setAttribute("data-ohw-form-error", "");
|
|
6863
|
+
note.setAttribute("role", "alert");
|
|
6864
|
+
note.style.marginTop = "8px";
|
|
6865
|
+
form.appendChild(note);
|
|
6866
|
+
}
|
|
6867
|
+
note.textContent = "Something went wrong. Please try again.";
|
|
6868
|
+
note.style.display = "";
|
|
6869
|
+
}
|
|
6870
|
+
function clearSubmitError(form) {
|
|
6871
|
+
const note = form.querySelector("[data-ohw-form-error]");
|
|
6872
|
+
if (note) note.style.display = "none";
|
|
6873
|
+
}
|
|
6874
|
+
var SUCCESS_TEXT_ATTR = "data-ohw-form-success-text";
|
|
6875
|
+
var HIDDEN_ATTR = "data-ohw-form-hidden";
|
|
6876
|
+
var DEFAULT_SUCCESS_TEXT = "Thanks! We'll be in touch.";
|
|
6877
|
+
function formSuccessKey(formKey) {
|
|
6878
|
+
return `${formKey}-success`;
|
|
6879
|
+
}
|
|
6880
|
+
function ensureSuccessTextEl(form, formKey, initialText) {
|
|
6881
|
+
let el = form.querySelector(`[${SUCCESS_TEXT_ATTR}]`);
|
|
6882
|
+
if (el) return el;
|
|
6883
|
+
el = document.createElement("p");
|
|
6884
|
+
el.setAttribute(SUCCESS_TEXT_ATTR, "");
|
|
6885
|
+
el.setAttribute("data-ohw-editable", "text");
|
|
6886
|
+
el.setAttribute("data-ohw-key", formSuccessKey(formKey));
|
|
6887
|
+
el.innerHTML = initialText;
|
|
6888
|
+
el.style.display = "none";
|
|
6889
|
+
el.style.margin = "56px 4px 16px";
|
|
6890
|
+
form.appendChild(el);
|
|
6891
|
+
return el;
|
|
6892
|
+
}
|
|
6893
|
+
function setFormViewState(form, formKey, state, initialText) {
|
|
6894
|
+
const success = ensureSuccessTextEl(form, formKey, initialText);
|
|
6895
|
+
Array.from(form.children).forEach((child) => {
|
|
6896
|
+
if (!(child instanceof HTMLElement) || child === success) return;
|
|
6897
|
+
if (state === "success") {
|
|
6898
|
+
if (!child.hasAttribute(HIDDEN_ATTR)) {
|
|
6899
|
+
child.setAttribute(HIDDEN_ATTR, child.style.display);
|
|
6900
|
+
child.style.display = "none";
|
|
6901
|
+
}
|
|
6902
|
+
} else if (child.hasAttribute(HIDDEN_ATTR)) {
|
|
6903
|
+
child.style.display = child.getAttribute(HIDDEN_ATTR) ?? "";
|
|
6904
|
+
child.removeAttribute(HIDDEN_ATTR);
|
|
6905
|
+
}
|
|
6906
|
+
});
|
|
6907
|
+
success.style.display = state === "success" ? "" : "none";
|
|
6908
|
+
}
|
|
6909
|
+
var BOUND_ATTR = "data-ohw-form-bound";
|
|
6910
|
+
function bindPublishedForms(apiUrl, subdomain, content = {}) {
|
|
6911
|
+
document.querySelectorAll(FORM_SELECTOR).forEach((form) => {
|
|
6912
|
+
if (form.hasAttribute(BOUND_ATTR)) return;
|
|
6913
|
+
if (!(form instanceof HTMLFormElement)) return;
|
|
6914
|
+
const formKey = formKeyOf(form);
|
|
6915
|
+
if (!formKey) return;
|
|
6916
|
+
form.setAttribute(BOUND_ATTR, "");
|
|
6917
|
+
form.addEventListener("submit", async (e) => {
|
|
6918
|
+
e.preventDefault();
|
|
6919
|
+
clearSubmitError(form);
|
|
6920
|
+
const submitButton = form.querySelector(
|
|
6921
|
+
'button[type="submit"], input[type="submit"], button:not([type])'
|
|
6922
|
+
);
|
|
6923
|
+
if (submitButton) submitButton.disabled = true;
|
|
6924
|
+
try {
|
|
6925
|
+
const response = await fetch(`${apiUrl}/api/public/sites/${subdomain}/forms/submissions`, {
|
|
6926
|
+
method: "POST",
|
|
6927
|
+
headers: { "Content-Type": "application/json" },
|
|
6928
|
+
body: JSON.stringify({
|
|
6929
|
+
formKey,
|
|
6930
|
+
fields: collectFormFields(form),
|
|
6931
|
+
hasLongText: formHasLongText(form)
|
|
6932
|
+
})
|
|
6933
|
+
});
|
|
6934
|
+
if (!response.ok) throw new Error(`submit failed: ${response.status}`);
|
|
6935
|
+
showSuccess(form, content[formSuccessKey(formKey)]);
|
|
6936
|
+
} catch {
|
|
6937
|
+
showSubmitError(form);
|
|
6938
|
+
if (submitButton) submitButton.disabled = false;
|
|
6939
|
+
}
|
|
6940
|
+
});
|
|
6941
|
+
});
|
|
6942
|
+
}
|
|
6943
|
+
|
|
6944
|
+
// src/lib/form-fields.ts
|
|
6945
|
+
var FIELD_DEFAULTS = {
|
|
6946
|
+
"short-text": { label: "Short text", placeholder: "Type placeholder text..." },
|
|
6947
|
+
"long-text": { label: "Long text", placeholder: "How can we help?" },
|
|
6948
|
+
email: { label: "Email", placeholder: "hello@example.com" },
|
|
6949
|
+
phone: { label: "Phone number", placeholder: "(555) 000-0000" }
|
|
6950
|
+
};
|
|
6951
|
+
var FIELD_TYPES = [
|
|
6952
|
+
{ type: "short-text", label: "Short text" },
|
|
6953
|
+
{ type: "long-text", label: "Long text" },
|
|
6954
|
+
{ type: "email", label: "Email" },
|
|
6955
|
+
{ type: "phone", label: "Phone" }
|
|
6956
|
+
];
|
|
6957
|
+
var FIELD_ATTR = "data-ohw-form-field";
|
|
6958
|
+
var FIELD_TYPE_ATTR = "data-ohw-field-type";
|
|
6959
|
+
function fieldsKey(formKey) {
|
|
6960
|
+
return `${formKey}-fields`;
|
|
6961
|
+
}
|
|
6962
|
+
function inputTagFor(type) {
|
|
6963
|
+
if (type === "long-text") return { tag: "textarea" };
|
|
6964
|
+
if (type === "email") return { tag: "input", inputType: "email" };
|
|
6965
|
+
if (type === "phone") return { tag: "input", inputType: "tel" };
|
|
6966
|
+
return { tag: "input", inputType: "text" };
|
|
6967
|
+
}
|
|
6968
|
+
function inferType(input) {
|
|
6969
|
+
if (input.tagName === "TEXTAREA") return "long-text";
|
|
6970
|
+
const type = input.type;
|
|
6971
|
+
if (type === "email") return "email";
|
|
6972
|
+
if (type === "tel") return "phone";
|
|
6973
|
+
return "short-text";
|
|
6974
|
+
}
|
|
6975
|
+
function ensureFieldLabel(wrapper, key) {
|
|
6976
|
+
const existing = fieldLabelOf(wrapper);
|
|
6977
|
+
if (existing) {
|
|
6978
|
+
if (!existing.hasAttribute("data-ohw-editable")) {
|
|
6979
|
+
existing.setAttribute("data-ohw-editable", "text");
|
|
6980
|
+
existing.setAttribute("data-ohw-key", `${key}-label`);
|
|
6981
|
+
}
|
|
6982
|
+
return existing;
|
|
6983
|
+
}
|
|
6984
|
+
const input = fieldInputOf(wrapper);
|
|
6985
|
+
const label = document.createElement("label");
|
|
6986
|
+
label.setAttribute("data-ohw-editable", "text");
|
|
6987
|
+
label.setAttribute("data-ohw-key", `${key}-label`);
|
|
6988
|
+
label.setAttribute("data-ohw-field-label", "");
|
|
6989
|
+
label.style.display = "block";
|
|
6990
|
+
label.style.marginBottom = "6px";
|
|
6991
|
+
label.style.fontSize = "13px";
|
|
6992
|
+
label.style.fontWeight = "500";
|
|
6993
|
+
label.style.lineHeight = "1.3";
|
|
6994
|
+
const fromPlaceholder = input?.getAttribute("placeholder")?.trim();
|
|
6995
|
+
const text = fromPlaceholder && fromPlaceholder.length < 40 ? fromPlaceholder : key.replace(/[-_]/g, " ");
|
|
6996
|
+
label.textContent = input?.hasAttribute("required") ? `${text} *` : text;
|
|
6997
|
+
if (input && input.parentElement === wrapper) wrapper.insertBefore(label, input);
|
|
6998
|
+
else wrapper.insertBefore(label, wrapper.firstChild);
|
|
6999
|
+
return label;
|
|
7000
|
+
}
|
|
7001
|
+
function listFieldWrappers(form) {
|
|
7002
|
+
return Array.from(form.querySelectorAll(`[${FIELD_ATTR}]`));
|
|
7003
|
+
}
|
|
7004
|
+
function getFieldWrapper(el) {
|
|
7005
|
+
return el?.closest(`[${FIELD_ATTR}]`) ?? null;
|
|
7006
|
+
}
|
|
7007
|
+
function fieldInputOf(wrapper) {
|
|
7008
|
+
return wrapper.querySelector("input, textarea");
|
|
7009
|
+
}
|
|
7010
|
+
function fieldLabelOf(wrapper) {
|
|
7011
|
+
return wrapper.querySelector("label");
|
|
7012
|
+
}
|
|
7013
|
+
function fieldKeyOf(wrapper) {
|
|
7014
|
+
return wrapper.getAttribute(FIELD_ATTR) ?? "";
|
|
7015
|
+
}
|
|
7016
|
+
function fieldTypeOf(wrapper) {
|
|
7017
|
+
return wrapper.getAttribute(FIELD_TYPE_ATTR) ?? "short-text";
|
|
7018
|
+
}
|
|
7019
|
+
function isFieldRequired(wrapper) {
|
|
7020
|
+
return fieldInputOf(wrapper)?.hasAttribute("required") ?? false;
|
|
7021
|
+
}
|
|
7022
|
+
function markFormFields(form) {
|
|
7023
|
+
form.querySelectorAll("input, textarea").forEach((input) => {
|
|
7024
|
+
const type = input.type;
|
|
7025
|
+
if (type === "submit" || type === "button" || type === "reset" || type === "hidden") return;
|
|
7026
|
+
if (getFieldWrapper(input)) return;
|
|
7027
|
+
let wrapper = input;
|
|
7028
|
+
while (wrapper.parentElement && wrapper.parentElement !== form && wrapper.parentElement.querySelectorAll("input, textarea").length === 1) {
|
|
7029
|
+
wrapper = wrapper.parentElement;
|
|
7030
|
+
}
|
|
7031
|
+
if (wrapper === input) {
|
|
7032
|
+
const box = document.createElement("div");
|
|
7033
|
+
box.setAttribute("data-ohw-field-box", "");
|
|
7034
|
+
input.replaceWith(box);
|
|
7035
|
+
box.appendChild(input);
|
|
7036
|
+
wrapper = box;
|
|
7037
|
+
}
|
|
7038
|
+
const key = input.getAttribute("name") ?? input.getAttribute("data-ohw-key") ?? `field-${Date.now()}`;
|
|
7039
|
+
wrapper.setAttribute(FIELD_ATTR, key);
|
|
7040
|
+
wrapper.setAttribute(FIELD_TYPE_ATTR, inferType(input));
|
|
7041
|
+
ensureFieldLabel(wrapper, key);
|
|
7042
|
+
syncRequiredMark(wrapper);
|
|
7043
|
+
});
|
|
7044
|
+
return listFieldWrappers(form);
|
|
7045
|
+
}
|
|
7046
|
+
function readFieldsFromDom(form) {
|
|
7047
|
+
return listFieldWrappers(form).map((wrapper) => {
|
|
7048
|
+
const input = fieldInputOf(wrapper);
|
|
7049
|
+
return {
|
|
7050
|
+
key: fieldKeyOf(wrapper),
|
|
7051
|
+
type: fieldTypeOf(wrapper),
|
|
7052
|
+
label: fieldLabelOf(wrapper)?.textContent?.trim() ?? "",
|
|
7053
|
+
placeholder: input?.getAttribute("placeholder") ?? "",
|
|
7054
|
+
required: Boolean(input?.hasAttribute("required"))
|
|
7055
|
+
};
|
|
7056
|
+
});
|
|
7057
|
+
}
|
|
7058
|
+
function parseFieldSpecs(raw) {
|
|
7059
|
+
if (!raw) return null;
|
|
7060
|
+
try {
|
|
7061
|
+
const parsed = JSON.parse(raw);
|
|
7062
|
+
return Array.isArray(parsed) ? parsed : null;
|
|
7063
|
+
} catch {
|
|
7064
|
+
return null;
|
|
7065
|
+
}
|
|
7066
|
+
}
|
|
7067
|
+
function isDefaultText(value, pick) {
|
|
7068
|
+
const trimmed = value.trim().replace(/\s*\*$/, "");
|
|
7069
|
+
if (!trimmed) return true;
|
|
7070
|
+
return Object.values(FIELD_DEFAULTS).some((defaults) => pick(defaults) === trimmed);
|
|
7071
|
+
}
|
|
7072
|
+
function applyFieldType(wrapper, type) {
|
|
7073
|
+
const input = fieldInputOf(wrapper);
|
|
7074
|
+
if (!input) return;
|
|
7075
|
+
const defaults = FIELD_DEFAULTS[type];
|
|
7076
|
+
const placeholder = input.getAttribute("placeholder") ?? "";
|
|
7077
|
+
const label = fieldLabelOf(wrapper);
|
|
7078
|
+
const followsDefaults = {
|
|
7079
|
+
// A label the owner wrote stays; one that still reads as a type name (or as the old
|
|
7080
|
+
// placeholder the template shipped) follows the new type.
|
|
7081
|
+
label: isDefaultText(label?.textContent ?? "", (d) => d.label) || (label?.textContent ?? "").trim().replace(/\s*\*$/, "") === placeholder.trim()
|
|
7082
|
+
};
|
|
7083
|
+
const { tag, inputType } = inputTagFor(type);
|
|
7084
|
+
wrapper.setAttribute(FIELD_TYPE_ATTR, type);
|
|
7085
|
+
const shedSize = (el) => {
|
|
7086
|
+
if (type === "long-text") return;
|
|
7087
|
+
el.style.removeProperty("height");
|
|
7088
|
+
el.style.removeProperty("min-height");
|
|
7089
|
+
el.style.removeProperty("resize");
|
|
7090
|
+
el.removeAttribute("rows");
|
|
7091
|
+
};
|
|
7092
|
+
const applyDefaults = (el) => {
|
|
7093
|
+
el.setAttribute("placeholder", defaults.placeholder);
|
|
7094
|
+
if (label && followsDefaults.label) {
|
|
7095
|
+
const required = (label.textContent ?? "").trim().endsWith("*");
|
|
7096
|
+
label.textContent = required ? `${defaults.label} *` : defaults.label;
|
|
7097
|
+
}
|
|
7098
|
+
};
|
|
7099
|
+
if (input.tagName.toLowerCase() === tag) {
|
|
7100
|
+
if (inputType) input.type = inputType;
|
|
7101
|
+
shedSize(input);
|
|
7102
|
+
applyDefaults(input);
|
|
7103
|
+
return;
|
|
7104
|
+
}
|
|
7105
|
+
const next = document.createElement(tag);
|
|
7106
|
+
Array.from(input.attributes).forEach((attr) => {
|
|
7107
|
+
if (attr.name === "type") return;
|
|
7108
|
+
next.setAttribute(attr.name, attr.value);
|
|
7109
|
+
});
|
|
7110
|
+
if (inputType) next.setAttribute("type", inputType);
|
|
7111
|
+
shedSize(next);
|
|
7112
|
+
if (type === "long-text") next.setAttribute("rows", "4");
|
|
7113
|
+
input.replaceWith(next);
|
|
7114
|
+
applyDefaults(next);
|
|
7115
|
+
}
|
|
7116
|
+
function syncRequiredMark(wrapper) {
|
|
7117
|
+
const label = fieldLabelOf(wrapper);
|
|
7118
|
+
if (!label) return;
|
|
7119
|
+
const required = isFieldRequired(wrapper);
|
|
7120
|
+
const base = (label.textContent ?? "").replace(/\s*\*\s*$/, "").trimEnd();
|
|
7121
|
+
const next = required ? `${base} *` : base;
|
|
7122
|
+
if (label.textContent !== next) label.textContent = next;
|
|
7123
|
+
}
|
|
7124
|
+
function setFieldRequired(wrapper, required) {
|
|
7125
|
+
const input = fieldInputOf(wrapper);
|
|
7126
|
+
const label = fieldLabelOf(wrapper);
|
|
7127
|
+
if (!input) return;
|
|
7128
|
+
if (required) input.setAttribute("required", "");
|
|
7129
|
+
else input.removeAttribute("required");
|
|
7130
|
+
if (label) syncRequiredMark(wrapper);
|
|
7131
|
+
}
|
|
7132
|
+
var PLACEHOLDER_EDIT_ATTR = "data-ohw-placeholder-edit";
|
|
7133
|
+
function beginPlaceholderEdit(wrapper) {
|
|
7134
|
+
const input = fieldInputOf(wrapper);
|
|
7135
|
+
if (!input || input.hasAttribute(PLACEHOLDER_EDIT_ATTR)) return;
|
|
7136
|
+
input.setAttribute(PLACEHOLDER_EDIT_ATTR, "");
|
|
7137
|
+
input.value = input.getAttribute("placeholder") ?? "";
|
|
7138
|
+
input.setAttribute("placeholder", "");
|
|
7139
|
+
}
|
|
7140
|
+
function commitPlaceholderEdit(wrapper) {
|
|
7141
|
+
if (!wrapper) return false;
|
|
7142
|
+
const input = fieldInputOf(wrapper);
|
|
7143
|
+
if (!input || !input.hasAttribute(PLACEHOLDER_EDIT_ATTR)) return false;
|
|
7144
|
+
const typed = input.value;
|
|
7145
|
+
input.removeAttribute(PLACEHOLDER_EDIT_ATTR);
|
|
7146
|
+
input.value = "";
|
|
7147
|
+
const previous = input.getAttribute("placeholder") ?? "";
|
|
7148
|
+
input.setAttribute("placeholder", typed);
|
|
7149
|
+
return previous !== typed;
|
|
7150
|
+
}
|
|
7151
|
+
function setFieldPlaceholder(wrapper, placeholder) {
|
|
7152
|
+
fieldInputOf(wrapper)?.setAttribute("placeholder", placeholder);
|
|
7153
|
+
}
|
|
7154
|
+
function uniqueKey(form, base) {
|
|
7155
|
+
const taken = new Set(listFieldWrappers(form).map(fieldKeyOf));
|
|
7156
|
+
if (!taken.has(base)) return base;
|
|
7157
|
+
let n = 2;
|
|
7158
|
+
while (taken.has(`${base}-${n}`)) n += 1;
|
|
7159
|
+
return `${base}-${n}`;
|
|
7160
|
+
}
|
|
7161
|
+
function insertField(form, type) {
|
|
7162
|
+
const existing = listFieldWrappers(form);
|
|
7163
|
+
const source = existing[existing.length - 1] ?? null;
|
|
7164
|
+
const key = uniqueKey(form, type);
|
|
7165
|
+
let wrapper;
|
|
7166
|
+
if (source) {
|
|
7167
|
+
wrapper = source.cloneNode(true);
|
|
7168
|
+
source.after(wrapper);
|
|
7169
|
+
} else {
|
|
7170
|
+
wrapper = document.createElement("div");
|
|
7171
|
+
const label2 = document.createElement("label");
|
|
7172
|
+
const input2 = document.createElement("input");
|
|
7173
|
+
wrapper.append(label2, input2);
|
|
7174
|
+
const submit = form.querySelector('button, input[type="submit"]');
|
|
7175
|
+
if (submit) submit.before(wrapper);
|
|
7176
|
+
else form.appendChild(wrapper);
|
|
7177
|
+
}
|
|
7178
|
+
wrapper.setAttribute(FIELD_ATTR, key);
|
|
7179
|
+
wrapper.setAttribute(FIELD_TYPE_ATTR, type);
|
|
7180
|
+
applyFieldType(wrapper, type);
|
|
7181
|
+
const defaults = FIELD_DEFAULTS[type];
|
|
7182
|
+
const input = fieldInputOf(wrapper);
|
|
7183
|
+
if (input) {
|
|
7184
|
+
input.setAttribute("name", key);
|
|
7185
|
+
input.setAttribute("data-ohw-key", key);
|
|
7186
|
+
input.removeAttribute("required");
|
|
7187
|
+
input.setAttribute("placeholder", defaults.placeholder);
|
|
7188
|
+
input.value = "";
|
|
7189
|
+
}
|
|
7190
|
+
const label = ensureFieldLabel(wrapper, key);
|
|
7191
|
+
label.textContent = defaults.label;
|
|
7192
|
+
label.setAttribute("data-ohw-key", `${key}-label`);
|
|
7193
|
+
return wrapper;
|
|
7194
|
+
}
|
|
7195
|
+
function duplicateField(form, wrapper) {
|
|
7196
|
+
const copy = wrapper.cloneNode(true);
|
|
7197
|
+
const key = uniqueKey(form, `${fieldKeyOf(wrapper)}-copy`);
|
|
7198
|
+
copy.setAttribute(FIELD_ATTR, key);
|
|
7199
|
+
const input = fieldInputOf(copy);
|
|
7200
|
+
if (input) {
|
|
7201
|
+
input.setAttribute("name", key);
|
|
7202
|
+
input.setAttribute("data-ohw-key", key);
|
|
7203
|
+
input.value = "";
|
|
7204
|
+
}
|
|
7205
|
+
wrapper.after(copy);
|
|
7206
|
+
return copy;
|
|
7207
|
+
}
|
|
7208
|
+
function removeField(wrapper) {
|
|
7209
|
+
wrapper.remove();
|
|
7210
|
+
}
|
|
7211
|
+
function moveField(form, key, toIndex) {
|
|
7212
|
+
const wrappers = listFieldWrappers(form);
|
|
7213
|
+
const moving = wrappers.find((wrapper) => fieldKeyOf(wrapper) === key);
|
|
7214
|
+
if (!moving) return;
|
|
7215
|
+
const rest = wrappers.filter((wrapper) => wrapper !== moving);
|
|
7216
|
+
const target = rest[Math.max(0, Math.min(rest.length, toIndex))];
|
|
7217
|
+
if (target) target.before(moving);
|
|
7218
|
+
else rest[rest.length - 1]?.after(moving);
|
|
7219
|
+
}
|
|
7220
|
+
function reconcileFieldsFromContent(form, content) {
|
|
7221
|
+
const formKey = form.getAttribute("data-ohw-key");
|
|
7222
|
+
if (!formKey) return;
|
|
7223
|
+
markFormFields(form);
|
|
7224
|
+
const stored = parseFieldSpecs(content[fieldsKey(formKey)]);
|
|
7225
|
+
if (!stored) return;
|
|
7226
|
+
const byKey = new Map(listFieldWrappers(form).map((wrapper) => [fieldKeyOf(wrapper), wrapper]));
|
|
7227
|
+
stored.forEach((spec) => {
|
|
7228
|
+
let wrapper = byKey.get(spec.key) ?? null;
|
|
7229
|
+
if (!wrapper) {
|
|
7230
|
+
wrapper = insertField(form, spec.type);
|
|
7231
|
+
if (!wrapper) return;
|
|
7232
|
+
wrapper.setAttribute(FIELD_ATTR, spec.key);
|
|
7233
|
+
const input = fieldInputOf(wrapper);
|
|
7234
|
+
if (input) {
|
|
7235
|
+
input.setAttribute("name", spec.key);
|
|
7236
|
+
input.setAttribute("data-ohw-key", spec.key);
|
|
7237
|
+
}
|
|
7238
|
+
byKey.set(spec.key, wrapper);
|
|
7239
|
+
}
|
|
7240
|
+
applyFieldType(wrapper, spec.type);
|
|
7241
|
+
setFieldRequired(wrapper, spec.required);
|
|
7242
|
+
setFieldPlaceholder(wrapper, spec.placeholder);
|
|
7243
|
+
const label = fieldLabelOf(wrapper);
|
|
7244
|
+
if (label && spec.label) label.textContent = spec.label;
|
|
7245
|
+
});
|
|
7246
|
+
const wanted = new Set(stored.map((spec) => spec.key));
|
|
7247
|
+
listFieldWrappers(form).forEach((wrapper) => {
|
|
7248
|
+
if (!wanted.has(fieldKeyOf(wrapper))) wrapper.remove();
|
|
7249
|
+
});
|
|
7250
|
+
stored.forEach((spec, index) => moveField(form, spec.key, index));
|
|
7251
|
+
}
|
|
7252
|
+
|
|
7253
|
+
// src/ui/form-field-toolbar.tsx
|
|
7254
|
+
var import_lucide_react4 = require("lucide-react");
|
|
7255
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
7256
|
+
var TYPE_ICONS = {
|
|
7257
|
+
"short-text": import_lucide_react4.Type,
|
|
7258
|
+
"long-text": import_lucide_react4.TextQuote,
|
|
7259
|
+
email: import_lucide_react4.AtSign,
|
|
7260
|
+
phone: import_lucide_react4.Phone
|
|
7261
|
+
};
|
|
7262
|
+
function FormFieldToolbar({
|
|
7263
|
+
type,
|
|
7264
|
+
required,
|
|
7265
|
+
onTypeChange,
|
|
7266
|
+
onRequiredToggle,
|
|
7267
|
+
onDuplicate,
|
|
7268
|
+
onDelete
|
|
7269
|
+
}) {
|
|
7270
|
+
const TypeIcon = TYPE_ICONS[type];
|
|
7271
|
+
const typeLabel = FIELD_TYPES.find((entry) => entry.type === type)?.label ?? "Short text";
|
|
7272
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
7273
|
+
"div",
|
|
7274
|
+
{
|
|
7275
|
+
"data-ohw-field-toolbar": "",
|
|
7276
|
+
className: "pointer-events-auto flex items-center gap-0.5 whitespace-nowrap rounded-lg border border-border bg-background p-1 shadow-md",
|
|
7277
|
+
children: [
|
|
7278
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenu, { children: [
|
|
7279
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
7280
|
+
"button",
|
|
7281
|
+
{
|
|
7282
|
+
type: "button",
|
|
7283
|
+
className: "flex h-7 items-center gap-1.5 whitespace-nowrap rounded-md px-2 text-[13px] font-medium text-foreground transition-colors hover:bg-muted/70",
|
|
7284
|
+
"data-ohw-field-type-trigger": "",
|
|
7285
|
+
children: [
|
|
7286
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TypeIcon, { size: 14, strokeWidth: 1.75, "aria-hidden": true }),
|
|
7287
|
+
typeLabel,
|
|
7288
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.ChevronDown, { size: 13, className: "text-muted-foreground", "aria-hidden": true })
|
|
7289
|
+
]
|
|
7290
|
+
}
|
|
7291
|
+
) }),
|
|
7292
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-[190px] p-1", children: FIELD_TYPES.map((entry) => {
|
|
7293
|
+
const Icon = TYPE_ICONS[entry.type];
|
|
7294
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
7295
|
+
DropdownMenuItem,
|
|
7296
|
+
{
|
|
7297
|
+
onSelect: () => onTypeChange(entry.type),
|
|
7298
|
+
className: "rounded-md py-2 text-[13px] " + (entry.type === type ? "bg-primary/10" : ""),
|
|
7299
|
+
children: [
|
|
7300
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { size: 14, strokeWidth: 1.75, className: "shrink-0", "aria-hidden": true }),
|
|
7301
|
+
entry.label
|
|
7302
|
+
]
|
|
7303
|
+
},
|
|
7304
|
+
entry.type
|
|
7305
|
+
);
|
|
7306
|
+
}) })
|
|
7307
|
+
] }),
|
|
7308
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
|
|
7309
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
7310
|
+
"button",
|
|
7311
|
+
{
|
|
7312
|
+
type: "button",
|
|
7313
|
+
"aria-pressed": required,
|
|
7314
|
+
onClick: onRequiredToggle,
|
|
7315
|
+
className: "flex h-7 items-center gap-1.5 whitespace-nowrap rounded-md px-2 text-[13px] font-medium transition-colors " + (required ? "bg-primary/10 text-primary" : "text-foreground hover:bg-muted/70"),
|
|
7316
|
+
"data-ohw-field-required": "",
|
|
7317
|
+
children: [
|
|
7318
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.Asterisk, { size: 14, strokeWidth: 2, "aria-hidden": true }),
|
|
7319
|
+
"Required"
|
|
7320
|
+
]
|
|
7321
|
+
}
|
|
7322
|
+
),
|
|
7323
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
|
|
7324
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenu, { children: [
|
|
7325
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
7326
|
+
"button",
|
|
7327
|
+
{
|
|
7328
|
+
type: "button",
|
|
7329
|
+
title: "More",
|
|
7330
|
+
"aria-label": "More",
|
|
7331
|
+
className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/70",
|
|
7332
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.MoreHorizontal, { size: 15, "aria-hidden": true })
|
|
7333
|
+
}
|
|
7334
|
+
) }),
|
|
7335
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-[170px] p-1", children: [
|
|
7336
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuItem, { onSelect: onDuplicate, className: "rounded-md py-2 text-[13px]", children: [
|
|
7337
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.Copy, { size: 14, strokeWidth: 1.75, className: "shrink-0", "aria-hidden": true }),
|
|
7338
|
+
"Duplicate"
|
|
7339
|
+
] }),
|
|
7340
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuItem, { variant: "destructive", onSelect: onDelete, className: "rounded-md py-2 text-[13px]", children: [
|
|
7341
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.Trash2, { size: 14, strokeWidth: 1.75, className: "shrink-0", "aria-hidden": true }),
|
|
7342
|
+
"Delete"
|
|
7343
|
+
] })
|
|
7344
|
+
] })
|
|
7345
|
+
] })
|
|
7346
|
+
]
|
|
7347
|
+
}
|
|
7348
|
+
);
|
|
7349
|
+
}
|
|
7350
|
+
function FieldTypePicker({ onPick }) {
|
|
7351
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
7352
|
+
"div",
|
|
7353
|
+
{
|
|
7354
|
+
"data-ohw-field-type-picker": "",
|
|
7355
|
+
className: "pointer-events-auto grid w-[420px] grid-cols-3 gap-3 rounded-xl border border-border bg-background p-4 shadow-lg",
|
|
7356
|
+
children: FIELD_TYPES.map((entry) => {
|
|
7357
|
+
const Icon = TYPE_ICONS[entry.type];
|
|
7358
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
7359
|
+
"button",
|
|
7360
|
+
{
|
|
7361
|
+
type: "button",
|
|
7362
|
+
onClick: () => onPick(entry.type),
|
|
7363
|
+
className: "flex h-[104px] flex-col items-center justify-center gap-3 rounded-xl border border-border text-[15px] font-medium text-foreground transition-colors hover:border-primary hover:bg-primary/5",
|
|
7364
|
+
children: [
|
|
7365
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { size: 26, strokeWidth: 1.5, "aria-hidden": true }),
|
|
7366
|
+
entry.label
|
|
7367
|
+
]
|
|
7368
|
+
},
|
|
7369
|
+
entry.type
|
|
7370
|
+
);
|
|
7371
|
+
})
|
|
7372
|
+
}
|
|
7373
|
+
);
|
|
7374
|
+
}
|
|
7375
|
+
|
|
6807
7376
|
// src/ui/MediaOverlay.tsx
|
|
6808
7377
|
var React7 = __toESM(require("react"), 1);
|
|
6809
|
-
var
|
|
7378
|
+
var import_lucide_react5 = require("lucide-react");
|
|
6810
7379
|
|
|
6811
7380
|
// src/ui/button.tsx
|
|
6812
7381
|
var React6 = __toESM(require("react"), 1);
|
|
6813
7382
|
var import_radix_ui5 = require("radix-ui");
|
|
6814
|
-
var
|
|
7383
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
6815
7384
|
var buttonVariants = cva(
|
|
6816
7385
|
"inline-flex items-center justify-center gap-1 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none disabled:pointer-events-none disabled:opacity-50 min-w-[80px] px-3 py-2",
|
|
6817
7386
|
{
|
|
@@ -6835,7 +7404,7 @@ var buttonVariants = cva(
|
|
|
6835
7404
|
var Button = React6.forwardRef(
|
|
6836
7405
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
6837
7406
|
const Comp = asChild ? import_radix_ui5.Slot.Root : "button";
|
|
6838
|
-
return /* @__PURE__ */ (0,
|
|
7407
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
6839
7408
|
Comp,
|
|
6840
7409
|
{
|
|
6841
7410
|
ref,
|
|
@@ -6849,7 +7418,7 @@ var Button = React6.forwardRef(
|
|
|
6849
7418
|
Button.displayName = "Button";
|
|
6850
7419
|
|
|
6851
7420
|
// src/ui/MediaOverlay.tsx
|
|
6852
|
-
var
|
|
7421
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
6853
7422
|
var MEDIA_UPLOAD_FADE_MS = 300;
|
|
6854
7423
|
var VIDEO_SETTINGS_BAR_INSET = 8;
|
|
6855
7424
|
var OVERLAY_BUTTON_STYLE = {
|
|
@@ -6907,7 +7476,7 @@ function MediaOverlay({
|
|
|
6907
7476
|
return () => anim.cancel();
|
|
6908
7477
|
}, [isUploading, fadingOut, onFadeOutComplete, hover.key]);
|
|
6909
7478
|
if (isUploading) {
|
|
6910
|
-
return /* @__PURE__ */ (0,
|
|
7479
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
6911
7480
|
"div",
|
|
6912
7481
|
{
|
|
6913
7482
|
ref: skeletonRef,
|
|
@@ -6916,11 +7485,11 @@ function MediaOverlay({
|
|
|
6916
7485
|
"data-ohw-media-skeleton": "",
|
|
6917
7486
|
"aria-hidden": true,
|
|
6918
7487
|
style: { ...box, pointerEvents: "none" },
|
|
6919
|
-
children: /* @__PURE__ */ (0,
|
|
7488
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("style", { children: SKELETON_CSS })
|
|
6920
7489
|
}
|
|
6921
7490
|
);
|
|
6922
7491
|
}
|
|
6923
|
-
const settingsBar = isVideo && !hover.isDragOver ? /* @__PURE__ */ (0,
|
|
7492
|
+
const settingsBar = isVideo && !hover.isDragOver ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
6924
7493
|
"div",
|
|
6925
7494
|
{
|
|
6926
7495
|
"data-ohw-bridge": "",
|
|
@@ -6936,7 +7505,7 @@ function MediaOverlay({
|
|
|
6936
7505
|
},
|
|
6937
7506
|
onClick: (e) => e.stopPropagation(),
|
|
6938
7507
|
children: [
|
|
6939
|
-
/* @__PURE__ */ (0,
|
|
7508
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
6940
7509
|
Button,
|
|
6941
7510
|
{
|
|
6942
7511
|
"data-ohw-media-overlay": "",
|
|
@@ -6951,10 +7520,10 @@ function MediaOverlay({
|
|
|
6951
7520
|
e.stopPropagation();
|
|
6952
7521
|
onVideoSettingsChange?.(hover.key, { autoplay: !autoplay });
|
|
6953
7522
|
},
|
|
6954
|
-
children: autoplay ? /* @__PURE__ */ (0,
|
|
7523
|
+
children: autoplay ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.Pause, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.Play, { size: 14 })
|
|
6955
7524
|
}
|
|
6956
7525
|
),
|
|
6957
|
-
/* @__PURE__ */ (0,
|
|
7526
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
6958
7527
|
Button,
|
|
6959
7528
|
{
|
|
6960
7529
|
"data-ohw-media-overlay": "",
|
|
@@ -6969,15 +7538,15 @@ function MediaOverlay({
|
|
|
6969
7538
|
e.stopPropagation();
|
|
6970
7539
|
onVideoSettingsChange?.(hover.key, { muted: !muted });
|
|
6971
7540
|
},
|
|
6972
|
-
children: muted ? /* @__PURE__ */ (0,
|
|
7541
|
+
children: muted ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.VolumeX, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.Volume2, { size: 14 })
|
|
6973
7542
|
}
|
|
6974
7543
|
)
|
|
6975
7544
|
]
|
|
6976
7545
|
}
|
|
6977
7546
|
) : null;
|
|
6978
|
-
return /* @__PURE__ */ (0,
|
|
7547
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
6979
7548
|
settingsBar,
|
|
6980
|
-
/* @__PURE__ */ (0,
|
|
7549
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
6981
7550
|
"div",
|
|
6982
7551
|
{
|
|
6983
7552
|
"data-ohw-bridge": "",
|
|
@@ -6994,7 +7563,7 @@ function MediaOverlay({
|
|
|
6994
7563
|
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
6995
7564
|
},
|
|
6996
7565
|
onClick: () => onReplace(hover.key),
|
|
6997
|
-
children: /* @__PURE__ */ (0,
|
|
7566
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
6998
7567
|
Button,
|
|
6999
7568
|
{
|
|
7000
7569
|
"data-ohw-media-overlay": "",
|
|
@@ -7012,7 +7581,7 @@ function MediaOverlay({
|
|
|
7012
7581
|
onReplace(hover.key);
|
|
7013
7582
|
},
|
|
7014
7583
|
children: [
|
|
7015
|
-
isVideo ? /* @__PURE__ */ (0,
|
|
7584
|
+
isVideo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.ImageIcon, { size: 14 }),
|
|
7016
7585
|
isVideo ? "Replace video" : "Replace image"
|
|
7017
7586
|
]
|
|
7018
7587
|
}
|
|
@@ -7023,8 +7592,8 @@ function MediaOverlay({
|
|
|
7023
7592
|
}
|
|
7024
7593
|
|
|
7025
7594
|
// src/ui/CarouselOverlay.tsx
|
|
7026
|
-
var
|
|
7027
|
-
var
|
|
7595
|
+
var import_lucide_react6 = require("lucide-react");
|
|
7596
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
7028
7597
|
var OVERLAY_BUTTON_STYLE2 = {
|
|
7029
7598
|
pointerEvents: "auto",
|
|
7030
7599
|
fontFamily: "Inter, sans-serif",
|
|
@@ -7036,7 +7605,7 @@ function CarouselOverlay({
|
|
|
7036
7605
|
onEdit
|
|
7037
7606
|
}) {
|
|
7038
7607
|
const { rect } = hover;
|
|
7039
|
-
return /* @__PURE__ */ (0,
|
|
7608
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
7040
7609
|
"div",
|
|
7041
7610
|
{
|
|
7042
7611
|
"data-ohw-bridge": "",
|
|
@@ -7054,7 +7623,7 @@ function CarouselOverlay({
|
|
|
7054
7623
|
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
7055
7624
|
},
|
|
7056
7625
|
onClick: () => onEdit(hover.key),
|
|
7057
|
-
children: /* @__PURE__ */ (0,
|
|
7626
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
7058
7627
|
Button,
|
|
7059
7628
|
{
|
|
7060
7629
|
"data-ohw-carousel-overlay": "",
|
|
@@ -7068,7 +7637,7 @@ function CarouselOverlay({
|
|
|
7068
7637
|
onEdit(hover.key);
|
|
7069
7638
|
},
|
|
7070
7639
|
children: [
|
|
7071
|
-
/* @__PURE__ */ (0,
|
|
7640
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.GalleryHorizontal, { size: 14 }),
|
|
7072
7641
|
"Edit gallery"
|
|
7073
7642
|
]
|
|
7074
7643
|
}
|
|
@@ -7079,7 +7648,7 @@ function CarouselOverlay({
|
|
|
7079
7648
|
|
|
7080
7649
|
// src/ui/ai-section/AiSectionOverlay.tsx
|
|
7081
7650
|
var import_react8 = require("react");
|
|
7082
|
-
var
|
|
7651
|
+
var import_lucide_react7 = require("lucide-react");
|
|
7083
7652
|
|
|
7084
7653
|
// src/lib/sections.ts
|
|
7085
7654
|
var LINK_PICKER_EXCLUDED_IDS = /* @__PURE__ */ new Set(["navbar", "footer"]);
|
|
@@ -7109,7 +7678,7 @@ function parseSectionsFromHtml(html) {
|
|
|
7109
7678
|
}
|
|
7110
7679
|
|
|
7111
7680
|
// src/ui/ai-section/AiSectionOverlay.tsx
|
|
7112
|
-
var
|
|
7681
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
7113
7682
|
function findSectionElement(instanceId) {
|
|
7114
7683
|
const escaped = CSS.escape(instanceId);
|
|
7115
7684
|
return document.querySelector(`[data-ohw-instance="${escaped}"]`) ?? document.querySelector(`[data-ohw-section="${escaped}"]:not([data-ohw-instance])`);
|
|
@@ -7177,8 +7746,8 @@ function ReviewButton({
|
|
|
7177
7746
|
color
|
|
7178
7747
|
}) {
|
|
7179
7748
|
const [hover, setHover] = (0, import_react8.useState)(false);
|
|
7180
|
-
return /* @__PURE__ */ (0,
|
|
7181
|
-
/* @__PURE__ */ (0,
|
|
7749
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { position: "relative" }, children: [
|
|
7750
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7182
7751
|
"button",
|
|
7183
7752
|
{
|
|
7184
7753
|
type: "button",
|
|
@@ -7202,7 +7771,7 @@ function ReviewButton({
|
|
|
7202
7771
|
children
|
|
7203
7772
|
}
|
|
7204
7773
|
),
|
|
7205
|
-
hover && /* @__PURE__ */ (0,
|
|
7774
|
+
hover && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7206
7775
|
"div",
|
|
7207
7776
|
{
|
|
7208
7777
|
style: {
|
|
@@ -7368,8 +7937,8 @@ function AiSectionOverlay({
|
|
|
7368
7937
|
isLast
|
|
7369
7938
|
});
|
|
7370
7939
|
}, [activeSelectionId, selectionRect, postToParent2]);
|
|
7371
|
-
return /* @__PURE__ */ (0,
|
|
7372
|
-
hoverRect && /* @__PURE__ */ (0,
|
|
7940
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
7941
|
+
hoverRect && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7373
7942
|
"div",
|
|
7374
7943
|
{
|
|
7375
7944
|
"data-ohw-ai-section-hover": "",
|
|
@@ -7387,7 +7956,7 @@ function AiSectionOverlay({
|
|
|
7387
7956
|
}
|
|
7388
7957
|
}
|
|
7389
7958
|
),
|
|
7390
|
-
selectionRect && /* @__PURE__ */ (0,
|
|
7959
|
+
selectionRect && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7391
7960
|
"div",
|
|
7392
7961
|
{
|
|
7393
7962
|
"data-ohw-ai-section-selected": "",
|
|
@@ -7405,7 +7974,7 @@ function AiSectionOverlay({
|
|
|
7405
7974
|
}
|
|
7406
7975
|
}
|
|
7407
7976
|
),
|
|
7408
|
-
reviewRect && /* @__PURE__ */ (0,
|
|
7977
|
+
reviewRect && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7409
7978
|
"div",
|
|
7410
7979
|
{
|
|
7411
7980
|
"data-ohw-ai-review": "",
|
|
@@ -7427,7 +7996,7 @@ function AiSectionOverlay({
|
|
|
7427
7996
|
cursor: "default"
|
|
7428
7997
|
},
|
|
7429
7998
|
onClick: (e) => e.stopPropagation(),
|
|
7430
|
-
children: !reviewButtonsHidden && /* @__PURE__ */ (0,
|
|
7999
|
+
children: !reviewButtonsHidden && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
7431
8000
|
"div",
|
|
7432
8001
|
{
|
|
7433
8002
|
style: {
|
|
@@ -7440,8 +8009,8 @@ function AiSectionOverlay({
|
|
|
7440
8009
|
paddingTop: 12
|
|
7441
8010
|
},
|
|
7442
8011
|
children: [
|
|
7443
|
-
/* @__PURE__ */ (0,
|
|
7444
|
-
/* @__PURE__ */ (0,
|
|
8012
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ReviewButton, { label: "Accept", onClick: () => decide("accept"), background: PRIMARY2, color: "#ffffff", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react7.Check, { size: 16, strokeWidth: 2.5, "aria-hidden": true }) }),
|
|
8013
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ReviewButton, { label: "Discard", onClick: () => decide("discard"), background: "#EFF6FF", color: "#0c0a09", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react7.X, { size: 16, strokeWidth: 2, "aria-hidden": true }) })
|
|
7445
8014
|
]
|
|
7446
8015
|
}
|
|
7447
8016
|
)
|
|
@@ -7800,23 +8369,23 @@ var import_react12 = require("react");
|
|
|
7800
8369
|
// src/ui/dialog.tsx
|
|
7801
8370
|
var React8 = __toESM(require("react"), 1);
|
|
7802
8371
|
var import_radix_ui6 = require("radix-ui");
|
|
7803
|
-
var
|
|
7804
|
-
var
|
|
8372
|
+
var import_lucide_react8 = require("lucide-react");
|
|
8373
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
7805
8374
|
function Dialog2({
|
|
7806
8375
|
...props
|
|
7807
8376
|
}) {
|
|
7808
|
-
return /* @__PURE__ */ (0,
|
|
8377
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
7809
8378
|
}
|
|
7810
8379
|
function DialogPortal({
|
|
7811
8380
|
...props
|
|
7812
8381
|
}) {
|
|
7813
|
-
return /* @__PURE__ */ (0,
|
|
8382
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
|
|
7814
8383
|
}
|
|
7815
8384
|
function DialogOverlay({
|
|
7816
8385
|
className,
|
|
7817
8386
|
...props
|
|
7818
8387
|
}) {
|
|
7819
|
-
return /* @__PURE__ */ (0,
|
|
8388
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
7820
8389
|
import_radix_ui6.Dialog.Overlay,
|
|
7821
8390
|
{
|
|
7822
8391
|
"data-slot": "dialog-overlay",
|
|
@@ -7829,9 +8398,9 @@ function DialogOverlay({
|
|
|
7829
8398
|
var DialogContent = React8.forwardRef(
|
|
7830
8399
|
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
7831
8400
|
const positionMode = container ? "absolute" : "fixed";
|
|
7832
|
-
return /* @__PURE__ */ (0,
|
|
7833
|
-
/* @__PURE__ */ (0,
|
|
7834
|
-
/* @__PURE__ */ (0,
|
|
8401
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
8402
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
8403
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
7835
8404
|
import_radix_ui6.Dialog.Content,
|
|
7836
8405
|
{
|
|
7837
8406
|
ref,
|
|
@@ -7847,13 +8416,13 @@ var DialogContent = React8.forwardRef(
|
|
|
7847
8416
|
...props,
|
|
7848
8417
|
children: [
|
|
7849
8418
|
children,
|
|
7850
|
-
showCloseButton ? /* @__PURE__ */ (0,
|
|
8419
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
7851
8420
|
import_radix_ui6.Dialog.Close,
|
|
7852
8421
|
{
|
|
7853
8422
|
type: "button",
|
|
7854
8423
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
7855
8424
|
"aria-label": "Close",
|
|
7856
|
-
children: /* @__PURE__ */ (0,
|
|
8425
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.X, { size: 16, "aria-hidden": true })
|
|
7857
8426
|
}
|
|
7858
8427
|
) : null
|
|
7859
8428
|
]
|
|
@@ -7867,13 +8436,13 @@ function DialogHeader({
|
|
|
7867
8436
|
className,
|
|
7868
8437
|
...props
|
|
7869
8438
|
}) {
|
|
7870
|
-
return /* @__PURE__ */ (0,
|
|
8439
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
7871
8440
|
}
|
|
7872
8441
|
function DialogFooter({
|
|
7873
8442
|
className,
|
|
7874
8443
|
...props
|
|
7875
8444
|
}) {
|
|
7876
|
-
return /* @__PURE__ */ (0,
|
|
8445
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
7877
8446
|
"div",
|
|
7878
8447
|
{
|
|
7879
8448
|
className: cn("flex items-center justify-end gap-2", className),
|
|
@@ -7881,7 +8450,7 @@ function DialogFooter({
|
|
|
7881
8450
|
}
|
|
7882
8451
|
);
|
|
7883
8452
|
}
|
|
7884
|
-
var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
8453
|
+
var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
7885
8454
|
import_radix_ui6.Dialog.Title,
|
|
7886
8455
|
{
|
|
7887
8456
|
ref,
|
|
@@ -7893,7 +8462,7 @@ var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
7893
8462
|
}
|
|
7894
8463
|
));
|
|
7895
8464
|
DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
|
|
7896
|
-
var DialogDescription = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
8465
|
+
var DialogDescription = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
7897
8466
|
import_radix_ui6.Dialog.Description,
|
|
7898
8467
|
{
|
|
7899
8468
|
ref,
|
|
@@ -7905,63 +8474,63 @@ DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
|
|
|
7905
8474
|
var DialogClose = import_radix_ui6.Dialog.Close;
|
|
7906
8475
|
|
|
7907
8476
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
7908
|
-
var
|
|
8477
|
+
var import_lucide_react12 = require("lucide-react");
|
|
7909
8478
|
|
|
7910
8479
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
7911
|
-
var
|
|
7912
|
-
var
|
|
8480
|
+
var import_lucide_react9 = require("lucide-react");
|
|
8481
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
7913
8482
|
function DestinationBreadcrumb({
|
|
7914
8483
|
pageTitle,
|
|
7915
8484
|
sectionLabel
|
|
7916
8485
|
}) {
|
|
7917
|
-
return /* @__PURE__ */ (0,
|
|
7918
|
-
/* @__PURE__ */ (0,
|
|
7919
|
-
/* @__PURE__ */ (0,
|
|
7920
|
-
/* @__PURE__ */ (0,
|
|
7921
|
-
/* @__PURE__ */ (0,
|
|
7922
|
-
/* @__PURE__ */ (0,
|
|
8486
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
|
|
8487
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
|
|
8488
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
8489
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
8490
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
8491
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
|
|
7923
8492
|
] }),
|
|
7924
|
-
/* @__PURE__ */ (0,
|
|
7925
|
-
|
|
8493
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
8494
|
+
import_lucide_react9.ArrowRight,
|
|
7926
8495
|
{
|
|
7927
8496
|
size: 16,
|
|
7928
8497
|
className: "shrink-0 text-muted-foreground",
|
|
7929
8498
|
"aria-hidden": true
|
|
7930
8499
|
}
|
|
7931
8500
|
),
|
|
7932
|
-
/* @__PURE__ */ (0,
|
|
7933
|
-
/* @__PURE__ */ (0,
|
|
7934
|
-
|
|
8501
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
8502
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
8503
|
+
import_lucide_react9.GalleryVertical,
|
|
7935
8504
|
{
|
|
7936
8505
|
size: 16,
|
|
7937
8506
|
className: "shrink-0 text-foreground",
|
|
7938
8507
|
"aria-hidden": true
|
|
7939
8508
|
}
|
|
7940
8509
|
),
|
|
7941
|
-
/* @__PURE__ */ (0,
|
|
8510
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
7942
8511
|
] })
|
|
7943
8512
|
] })
|
|
7944
8513
|
] });
|
|
7945
8514
|
}
|
|
7946
8515
|
|
|
7947
8516
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
7948
|
-
var
|
|
7949
|
-
var
|
|
8517
|
+
var import_lucide_react10 = require("lucide-react");
|
|
8518
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
7950
8519
|
function SectionTreeItem({
|
|
7951
8520
|
section,
|
|
7952
8521
|
onSelect,
|
|
7953
8522
|
selected
|
|
7954
8523
|
}) {
|
|
7955
8524
|
const interactive = Boolean(onSelect);
|
|
7956
|
-
return /* @__PURE__ */ (0,
|
|
7957
|
-
/* @__PURE__ */ (0,
|
|
8525
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
8526
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
7958
8527
|
"div",
|
|
7959
8528
|
{
|
|
7960
8529
|
className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
7961
8530
|
"aria-hidden": true
|
|
7962
8531
|
}
|
|
7963
8532
|
),
|
|
7964
|
-
/* @__PURE__ */ (0,
|
|
8533
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
7965
8534
|
"div",
|
|
7966
8535
|
{
|
|
7967
8536
|
role: interactive ? "button" : void 0,
|
|
@@ -7979,15 +8548,15 @@ function SectionTreeItem({
|
|
|
7979
8548
|
interactive && selected && "border-primary"
|
|
7980
8549
|
),
|
|
7981
8550
|
children: [
|
|
7982
|
-
/* @__PURE__ */ (0,
|
|
7983
|
-
|
|
8551
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
8552
|
+
import_lucide_react10.GalleryVertical,
|
|
7984
8553
|
{
|
|
7985
8554
|
size: 16,
|
|
7986
8555
|
className: "shrink-0 text-foreground",
|
|
7987
8556
|
"aria-hidden": true
|
|
7988
8557
|
}
|
|
7989
8558
|
),
|
|
7990
|
-
/* @__PURE__ */ (0,
|
|
8559
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
7991
8560
|
]
|
|
7992
8561
|
}
|
|
7993
8562
|
)
|
|
@@ -7999,10 +8568,10 @@ var import_react9 = require("react");
|
|
|
7999
8568
|
|
|
8000
8569
|
// src/ui/input.tsx
|
|
8001
8570
|
var React9 = __toESM(require("react"), 1);
|
|
8002
|
-
var
|
|
8571
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
8003
8572
|
var Input = React9.forwardRef(
|
|
8004
8573
|
({ className, type, ...props }, ref) => {
|
|
8005
|
-
return /* @__PURE__ */ (0,
|
|
8574
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
8006
8575
|
"input",
|
|
8007
8576
|
{
|
|
8008
8577
|
type,
|
|
@@ -8021,9 +8590,9 @@ Input.displayName = "Input";
|
|
|
8021
8590
|
|
|
8022
8591
|
// src/ui/label.tsx
|
|
8023
8592
|
var import_radix_ui7 = require("radix-ui");
|
|
8024
|
-
var
|
|
8593
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
8025
8594
|
function Label({ className, ...props }) {
|
|
8026
|
-
return /* @__PURE__ */ (0,
|
|
8595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8027
8596
|
import_radix_ui7.Label.Root,
|
|
8028
8597
|
{
|
|
8029
8598
|
"data-slot": "label",
|
|
@@ -8034,12 +8603,12 @@ function Label({ className, ...props }) {
|
|
|
8034
8603
|
}
|
|
8035
8604
|
|
|
8036
8605
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
8037
|
-
var
|
|
8038
|
-
var
|
|
8606
|
+
var import_lucide_react11 = require("lucide-react");
|
|
8607
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
8039
8608
|
function FieldChevron({
|
|
8040
8609
|
onClick
|
|
8041
8610
|
}) {
|
|
8042
|
-
return /* @__PURE__ */ (0,
|
|
8611
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8043
8612
|
"button",
|
|
8044
8613
|
{
|
|
8045
8614
|
type: "button",
|
|
@@ -8047,7 +8616,7 @@ function FieldChevron({
|
|
|
8047
8616
|
onClick,
|
|
8048
8617
|
"aria-label": "Open page list",
|
|
8049
8618
|
tabIndex: -1,
|
|
8050
|
-
children: /* @__PURE__ */ (0,
|
|
8619
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.ChevronDown, { size: 16 })
|
|
8051
8620
|
}
|
|
8052
8621
|
);
|
|
8053
8622
|
}
|
|
@@ -8108,19 +8677,19 @@ function UrlOrPageInput({
|
|
|
8108
8677
|
"data-ohw-link-field flex h-[36px] w-full items-center overflow-hidden rounded-md border bg-background pl-3 pr-3 py-2 outline-none transition-[border-color,box-shadow]",
|
|
8109
8678
|
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
8110
8679
|
);
|
|
8111
|
-
return /* @__PURE__ */ (0,
|
|
8112
|
-
/* @__PURE__ */ (0,
|
|
8113
|
-
/* @__PURE__ */ (0,
|
|
8114
|
-
/* @__PURE__ */ (0,
|
|
8115
|
-
selectedPage ? /* @__PURE__ */ (0,
|
|
8116
|
-
|
|
8680
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
8681
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
8682
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { ref: rootRef, className: "relative w-full", children: [
|
|
8683
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
8684
|
+
selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8685
|
+
import_lucide_react11.File,
|
|
8117
8686
|
{
|
|
8118
8687
|
size: 16,
|
|
8119
8688
|
className: "shrink-0 text-foreground",
|
|
8120
8689
|
"aria-hidden": true
|
|
8121
8690
|
}
|
|
8122
8691
|
) }) : null,
|
|
8123
|
-
readOnly ? /* @__PURE__ */ (0,
|
|
8692
|
+
readOnly ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8124
8693
|
Input,
|
|
8125
8694
|
{
|
|
8126
8695
|
ref: inputRef,
|
|
@@ -8146,7 +8715,7 @@ function UrlOrPageInput({
|
|
|
8146
8715
|
)
|
|
8147
8716
|
}
|
|
8148
8717
|
),
|
|
8149
|
-
selectedPage && !readOnly ? /* @__PURE__ */ (0,
|
|
8718
|
+
selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8150
8719
|
"button",
|
|
8151
8720
|
{
|
|
8152
8721
|
type: "button",
|
|
@@ -8154,26 +8723,26 @@ function UrlOrPageInput({
|
|
|
8154
8723
|
onMouseDown: clearSelection,
|
|
8155
8724
|
"aria-label": "Clear selected page",
|
|
8156
8725
|
tabIndex: -1,
|
|
8157
|
-
children: /* @__PURE__ */ (0,
|
|
8726
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.X, { size: 16, "aria-hidden": true })
|
|
8158
8727
|
}
|
|
8159
8728
|
) : null,
|
|
8160
|
-
!readOnly ? /* @__PURE__ */ (0,
|
|
8729
|
+
!readOnly ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
|
|
8161
8730
|
] }),
|
|
8162
|
-
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0,
|
|
8731
|
+
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8163
8732
|
"div",
|
|
8164
8733
|
{
|
|
8165
8734
|
"data-ohw-link-page-dropdown": "",
|
|
8166
8735
|
className: "absolute left-0 right-0 top-[calc(100%+4px)] z-50 max-h-48 overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg",
|
|
8167
8736
|
onMouseDown: (e) => e.preventDefault(),
|
|
8168
|
-
children: filteredPages.map((page) => /* @__PURE__ */ (0,
|
|
8737
|
+
children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8169
8738
|
"button",
|
|
8170
8739
|
{
|
|
8171
8740
|
type: "button",
|
|
8172
8741
|
className: "flex h-9 w-full items-center gap-2 border-0 bg-transparent px-3 text-left text-sm leading-5 text-foreground outline-none hover:bg-muted",
|
|
8173
8742
|
onClick: () => onPageSelect(page),
|
|
8174
8743
|
children: [
|
|
8175
|
-
/* @__PURE__ */ (0,
|
|
8176
|
-
/* @__PURE__ */ (0,
|
|
8744
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.File, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
8745
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "truncate", children: page.title })
|
|
8177
8746
|
]
|
|
8178
8747
|
},
|
|
8179
8748
|
page.path
|
|
@@ -8181,34 +8750,34 @@ function UrlOrPageInput({
|
|
|
8181
8750
|
}
|
|
8182
8751
|
) : null
|
|
8183
8752
|
] }),
|
|
8184
|
-
urlError ? /* @__PURE__ */ (0,
|
|
8753
|
+
urlError ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
|
|
8185
8754
|
] });
|
|
8186
8755
|
}
|
|
8187
8756
|
|
|
8188
8757
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
8189
|
-
var
|
|
8758
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
8190
8759
|
function LinkEditorPanel({ state, onClose }) {
|
|
8191
8760
|
const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
|
|
8192
|
-
return /* @__PURE__ */ (0,
|
|
8193
|
-
/* @__PURE__ */ (0,
|
|
8761
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
8762
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
8194
8763
|
"button",
|
|
8195
8764
|
{
|
|
8196
8765
|
type: "button",
|
|
8197
8766
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
|
|
8198
8767
|
"aria-label": "Close",
|
|
8199
8768
|
onClick: onClose,
|
|
8200
|
-
children: /* @__PURE__ */ (0,
|
|
8769
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react12.X, { size: 16, "aria-hidden": true })
|
|
8201
8770
|
}
|
|
8202
8771
|
) }),
|
|
8203
|
-
/* @__PURE__ */ (0,
|
|
8204
|
-
/* @__PURE__ */ (0,
|
|
8205
|
-
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0,
|
|
8772
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
8773
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
8774
|
+
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
8206
8775
|
DestinationBreadcrumb,
|
|
8207
8776
|
{
|
|
8208
8777
|
pageTitle: state.selectedPage.title,
|
|
8209
8778
|
sectionLabel: state.selectedSection.label
|
|
8210
8779
|
}
|
|
8211
|
-
) : /* @__PURE__ */ (0,
|
|
8780
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
8212
8781
|
UrlOrPageInput,
|
|
8213
8782
|
{
|
|
8214
8783
|
value: state.searchValue,
|
|
@@ -8221,8 +8790,8 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
8221
8790
|
urlError: state.urlError
|
|
8222
8791
|
}
|
|
8223
8792
|
),
|
|
8224
|
-
state.showChooseSection ? /* @__PURE__ */ (0,
|
|
8225
|
-
/* @__PURE__ */ (0,
|
|
8793
|
+
state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
8794
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
8226
8795
|
Button,
|
|
8227
8796
|
{
|
|
8228
8797
|
type: "button",
|
|
@@ -8233,15 +8802,15 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
8233
8802
|
children: "Choose a section"
|
|
8234
8803
|
}
|
|
8235
8804
|
),
|
|
8236
|
-
/* @__PURE__ */ (0,
|
|
8237
|
-
/* @__PURE__ */ (0,
|
|
8238
|
-
/* @__PURE__ */ (0,
|
|
8805
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
8806
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react12.Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
8807
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: "Pick a section this link should scroll to." })
|
|
8239
8808
|
] })
|
|
8240
8809
|
] }) : null,
|
|
8241
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0,
|
|
8810
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
8242
8811
|
] }),
|
|
8243
|
-
/* @__PURE__ */ (0,
|
|
8244
|
-
/* @__PURE__ */ (0,
|
|
8812
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
8813
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
8245
8814
|
Button,
|
|
8246
8815
|
{
|
|
8247
8816
|
type: "button",
|
|
@@ -8256,7 +8825,7 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
8256
8825
|
children: state.secondaryLabel
|
|
8257
8826
|
}
|
|
8258
8827
|
),
|
|
8259
|
-
/* @__PURE__ */ (0,
|
|
8828
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
8260
8829
|
Button,
|
|
8261
8830
|
{
|
|
8262
8831
|
type: "button",
|
|
@@ -8277,9 +8846,9 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
8277
8846
|
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
8278
8847
|
var import_react10 = require("react");
|
|
8279
8848
|
var import_react_dom2 = require("react-dom");
|
|
8280
|
-
var
|
|
8849
|
+
var import_lucide_react13 = require("lucide-react");
|
|
8281
8850
|
var import_navigation2 = require("next/navigation");
|
|
8282
|
-
var
|
|
8851
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
8283
8852
|
var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
|
|
8284
8853
|
function rectsEqual(a, b) {
|
|
8285
8854
|
if (a.size !== b.size) return false;
|
|
@@ -8508,7 +9077,7 @@ function SectionPickerOverlay({
|
|
|
8508
9077
|
const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
|
|
8509
9078
|
if (!portalRoot) return null;
|
|
8510
9079
|
return (0, import_react_dom2.createPortal)(
|
|
8511
|
-
/* @__PURE__ */ (0,
|
|
9080
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
8512
9081
|
"div",
|
|
8513
9082
|
{
|
|
8514
9083
|
"data-ohw-section-picker": "",
|
|
@@ -8518,12 +9087,12 @@ function SectionPickerOverlay({
|
|
|
8518
9087
|
role: "dialog",
|
|
8519
9088
|
"aria-label": "Choose a section",
|
|
8520
9089
|
children: [
|
|
8521
|
-
/* @__PURE__ */ (0,
|
|
9090
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8522
9091
|
"div",
|
|
8523
9092
|
{
|
|
8524
9093
|
className: "pointer-events-auto fixed left-5 z-[2]",
|
|
8525
9094
|
style: { top: chromeClip.top + 20 },
|
|
8526
|
-
children: /* @__PURE__ */ (0,
|
|
9095
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
8527
9096
|
Button,
|
|
8528
9097
|
{
|
|
8529
9098
|
type: "button",
|
|
@@ -8532,14 +9101,14 @@ function SectionPickerOverlay({
|
|
|
8532
9101
|
className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
|
|
8533
9102
|
onClick: onBack,
|
|
8534
9103
|
children: [
|
|
8535
|
-
/* @__PURE__ */ (0,
|
|
9104
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react13.ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
8536
9105
|
"Back"
|
|
8537
9106
|
]
|
|
8538
9107
|
}
|
|
8539
9108
|
)
|
|
8540
9109
|
}
|
|
8541
9110
|
),
|
|
8542
|
-
/* @__PURE__ */ (0,
|
|
9111
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8543
9112
|
"div",
|
|
8544
9113
|
{
|
|
8545
9114
|
className: "pointer-events-none fixed left-1/2 z-[2] rounded-lg px-4 py-3 text-xs leading-4 tracking-[0.18px] text-white shadow-md",
|
|
@@ -8552,7 +9121,7 @@ function SectionPickerOverlay({
|
|
|
8552
9121
|
children: "Click on section to select"
|
|
8553
9122
|
}
|
|
8554
9123
|
),
|
|
8555
|
-
!isOnTargetPage ? /* @__PURE__ */ (0,
|
|
9124
|
+
!isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8556
9125
|
"div",
|
|
8557
9126
|
{
|
|
8558
9127
|
className: "pointer-events-none fixed left-1/2 z-[1] -translate-x-1/2 rounded-md px-3 py-2 text-sm text-muted-foreground shadow-sm",
|
|
@@ -8560,14 +9129,14 @@ function SectionPickerOverlay({
|
|
|
8560
9129
|
children: "Loading page preview\u2026"
|
|
8561
9130
|
}
|
|
8562
9131
|
) : null,
|
|
8563
|
-
isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ (0,
|
|
9132
|
+
isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
|
|
8564
9133
|
isOnTargetPage ? liveSections.map((section) => {
|
|
8565
9134
|
const rect = rects.get(section.id);
|
|
8566
9135
|
if (!rect || rect.width <= 0 || rect.height <= 0) return null;
|
|
8567
9136
|
const isSelected = selectedId === section.id;
|
|
8568
9137
|
const isHovered = hoveredId === section.id;
|
|
8569
9138
|
const isLit = isSelected || isHovered;
|
|
8570
|
-
return /* @__PURE__ */ (0,
|
|
9139
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
8571
9140
|
"button",
|
|
8572
9141
|
{
|
|
8573
9142
|
type: "button",
|
|
@@ -8582,7 +9151,7 @@ function SectionPickerOverlay({
|
|
|
8582
9151
|
"aria-label": `Select section ${section.label}`,
|
|
8583
9152
|
onClick: () => handleSelect(section),
|
|
8584
9153
|
children: [
|
|
8585
|
-
isLit ? /* @__PURE__ */ (0,
|
|
9154
|
+
isLit ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8586
9155
|
"span",
|
|
8587
9156
|
{
|
|
8588
9157
|
className: "pointer-events-none absolute",
|
|
@@ -8595,13 +9164,13 @@ function SectionPickerOverlay({
|
|
|
8595
9164
|
"aria-hidden": true
|
|
8596
9165
|
}
|
|
8597
9166
|
) : null,
|
|
8598
|
-
isSelected ? /* @__PURE__ */ (0,
|
|
9167
|
+
isSelected ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8599
9168
|
"span",
|
|
8600
9169
|
{
|
|
8601
9170
|
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
8602
9171
|
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
8603
9172
|
"aria-hidden": true,
|
|
8604
|
-
children: /* @__PURE__ */ (0,
|
|
9173
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react13.Check, { className: "size-5" })
|
|
8605
9174
|
}
|
|
8606
9175
|
) : null
|
|
8607
9176
|
]
|
|
@@ -8781,7 +9350,7 @@ function useLinkModalState({
|
|
|
8781
9350
|
}
|
|
8782
9351
|
|
|
8783
9352
|
// src/ui/link-modal/LinkPopover.tsx
|
|
8784
|
-
var
|
|
9353
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
8785
9354
|
function postToParent(data) {
|
|
8786
9355
|
window.parent?.postMessage(data, "*");
|
|
8787
9356
|
}
|
|
@@ -8877,15 +9446,15 @@ function LinkPopover({
|
|
|
8877
9446
|
);
|
|
8878
9447
|
};
|
|
8879
9448
|
}, [open, sectionPickerActive]);
|
|
8880
|
-
return /* @__PURE__ */ (0,
|
|
8881
|
-
/* @__PURE__ */ (0,
|
|
9449
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
9450
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
8882
9451
|
Dialog2,
|
|
8883
9452
|
{
|
|
8884
9453
|
open: open && !sectionPickerActive,
|
|
8885
9454
|
onOpenChange: (next) => {
|
|
8886
9455
|
if (!next) onClose?.();
|
|
8887
9456
|
},
|
|
8888
|
-
children: /* @__PURE__ */ (0,
|
|
9457
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
8889
9458
|
DialogContent,
|
|
8890
9459
|
{
|
|
8891
9460
|
ref: panelRef,
|
|
@@ -8895,12 +9464,12 @@ function LinkPopover({
|
|
|
8895
9464
|
"data-ohw-bridge": "",
|
|
8896
9465
|
showCloseButton: false,
|
|
8897
9466
|
className: "gap-0 p-0 w-full max-w-[448px] pointer-events-auto z-[2147483646] overflow-visible",
|
|
8898
|
-
children: /* @__PURE__ */ (0,
|
|
9467
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(LinkEditorPanel, { state, onClose })
|
|
8899
9468
|
}
|
|
8900
9469
|
)
|
|
8901
9470
|
}
|
|
8902
9471
|
),
|
|
8903
|
-
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0,
|
|
9472
|
+
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
8904
9473
|
SectionPickerOverlay,
|
|
8905
9474
|
{
|
|
8906
9475
|
pagePath: state.selectedPage.path,
|
|
@@ -10126,13 +10695,14 @@ function listSocialItems(row) {
|
|
|
10126
10695
|
return isSocialItem(anchor) ? anchor : null;
|
|
10127
10696
|
}).filter((item) => item !== null);
|
|
10128
10697
|
}
|
|
10129
|
-
function socialRowUnit(item) {
|
|
10130
|
-
const row = findSocialsRow(item);
|
|
10698
|
+
function socialRowUnit(item, knownRow) {
|
|
10699
|
+
const row = knownRow ?? findSocialsRow(item);
|
|
10700
|
+
if (!row || !row.contains(item)) return null;
|
|
10131
10701
|
let node = item;
|
|
10132
10702
|
while (node.parentElement && node.parentElement !== row) {
|
|
10133
10703
|
node = node.parentElement;
|
|
10134
10704
|
}
|
|
10135
|
-
return node;
|
|
10705
|
+
return node.parentElement === row ? node : null;
|
|
10136
10706
|
}
|
|
10137
10707
|
function listSocialsRows(root = document) {
|
|
10138
10708
|
const rows = /* @__PURE__ */ new Set();
|
|
@@ -10151,7 +10721,8 @@ function markSocialsRows(root = document) {
|
|
|
10151
10721
|
listSocialsRows(root).forEach((row) => {
|
|
10152
10722
|
row.setAttribute(SOCIALS_ROW_ATTR, "");
|
|
10153
10723
|
const items = listSocialItems(row);
|
|
10154
|
-
|
|
10724
|
+
const firstUnit = items[0] ? socialRowUnit(items[0], row) : null;
|
|
10725
|
+
if (firstUnit) rowTemplates.set(rowKeyOf(row), firstUnit.outerHTML);
|
|
10155
10726
|
items.forEach((item, index) => {
|
|
10156
10727
|
item.setAttribute(SOCIALS_ITEM_ATTR, String(index));
|
|
10157
10728
|
const iconKey = socialIconKey(item);
|
|
@@ -10295,7 +10866,8 @@ function removeSocialItem(item, content) {
|
|
|
10295
10866
|
const previousContent = Object.fromEntries(
|
|
10296
10867
|
removedKeys.filter((key) => key in content).map((key) => [key, content[key]])
|
|
10297
10868
|
);
|
|
10298
|
-
const unit = socialRowUnit(item);
|
|
10869
|
+
const unit = socialRowUnit(item, row);
|
|
10870
|
+
if (!unit) return null;
|
|
10299
10871
|
const nextSibling = unit.nextElementSibling;
|
|
10300
10872
|
unit.remove();
|
|
10301
10873
|
markSocialsRows(row.ownerDocument);
|
|
@@ -10318,7 +10890,9 @@ function applySocialsOrder(order, root = document) {
|
|
|
10318
10890
|
const byKey = new Map(listSocialItems(row).map((item) => [socialHrefKey(item), item]));
|
|
10319
10891
|
wanted.forEach((key) => {
|
|
10320
10892
|
const item = byKey.get(key);
|
|
10321
|
-
if (item)
|
|
10893
|
+
if (!item) return;
|
|
10894
|
+
const unit = socialRowUnit(item, row);
|
|
10895
|
+
if (unit) row.appendChild(unit);
|
|
10322
10896
|
});
|
|
10323
10897
|
});
|
|
10324
10898
|
markSocialsRows(root);
|
|
@@ -10348,7 +10922,7 @@ function reconcileSocialsFromContent(content, root = document) {
|
|
|
10348
10922
|
});
|
|
10349
10923
|
if (surviving.length) {
|
|
10350
10924
|
present.forEach((item) => {
|
|
10351
|
-
if (!surviving.includes(item)) socialRowUnit(item)
|
|
10925
|
+
if (!surviving.includes(item)) socialRowUnit(item)?.remove();
|
|
10352
10926
|
});
|
|
10353
10927
|
}
|
|
10354
10928
|
});
|
|
@@ -11684,8 +12258,8 @@ function addFooterColumnWithPersist({
|
|
|
11684
12258
|
|
|
11685
12259
|
// src/ui/FloatingPanel.tsx
|
|
11686
12260
|
var import_react13 = require("react");
|
|
11687
|
-
var
|
|
11688
|
-
var
|
|
12261
|
+
var import_lucide_react14 = require("lucide-react");
|
|
12262
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
11689
12263
|
var PANEL_WIDTH = 256;
|
|
11690
12264
|
var EDGE_MARGIN = 16;
|
|
11691
12265
|
function getVisibleClip(parentScroll) {
|
|
@@ -11800,7 +12374,7 @@ function FloatingPanel({
|
|
|
11800
12374
|
}, [open]);
|
|
11801
12375
|
(0, import_react13.useEffect)(() => () => document.documentElement.removeAttribute("data-ohw-panel-dragging"), []);
|
|
11802
12376
|
if (!open) return null;
|
|
11803
|
-
return /* @__PURE__ */ (0,
|
|
12377
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
11804
12378
|
"div",
|
|
11805
12379
|
{
|
|
11806
12380
|
ref: panelRef,
|
|
@@ -11817,7 +12391,7 @@ function FloatingPanel({
|
|
|
11817
12391
|
onPointerDown: (e) => e.stopPropagation(),
|
|
11818
12392
|
onClick: (e) => e.stopPropagation(),
|
|
11819
12393
|
children: [
|
|
11820
|
-
/* @__PURE__ */ (0,
|
|
12394
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
11821
12395
|
"div",
|
|
11822
12396
|
{
|
|
11823
12397
|
"data-ohw-floating-panel-header": "",
|
|
@@ -11827,14 +12401,14 @@ function FloatingPanel({
|
|
|
11827
12401
|
onPointerUp: endDrag,
|
|
11828
12402
|
onPointerCancel: endDrag,
|
|
11829
12403
|
children: [
|
|
11830
|
-
/* @__PURE__ */ (0,
|
|
11831
|
-
/* @__PURE__ */ (0,
|
|
11832
|
-
icon ? /* @__PURE__ */ (0,
|
|
11833
|
-
/* @__PURE__ */ (0,
|
|
12404
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [
|
|
12405
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
12406
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "shrink-0 text-foreground", children: icon }) : null,
|
|
12407
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "min-w-0 flex-1 text-lg font-semibold leading-7 text-foreground", children: title })
|
|
11834
12408
|
] }),
|
|
11835
|
-
context ? /* @__PURE__ */ (0,
|
|
12409
|
+
context ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "w-full text-sm leading-5 text-muted-foreground", children: context }) : null
|
|
11836
12410
|
] }),
|
|
11837
|
-
/* @__PURE__ */ (0,
|
|
12411
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
11838
12412
|
"button",
|
|
11839
12413
|
{
|
|
11840
12414
|
type: "button",
|
|
@@ -11846,13 +12420,13 @@ function FloatingPanel({
|
|
|
11846
12420
|
onClose();
|
|
11847
12421
|
},
|
|
11848
12422
|
onPointerDown: (e) => e.stopPropagation(),
|
|
11849
|
-
children: /* @__PURE__ */ (0,
|
|
12423
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.X, { size: 16, "aria-hidden": true })
|
|
11850
12424
|
}
|
|
11851
12425
|
)
|
|
11852
12426
|
]
|
|
11853
12427
|
}
|
|
11854
12428
|
),
|
|
11855
|
-
/* @__PURE__ */ (0,
|
|
12429
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
11856
12430
|
"div",
|
|
11857
12431
|
{
|
|
11858
12432
|
"data-ohw-floating-panel-body": "",
|
|
@@ -11866,30 +12440,30 @@ function FloatingPanel({
|
|
|
11866
12440
|
}
|
|
11867
12441
|
|
|
11868
12442
|
// src/ui/logo-size-panel.tsx
|
|
11869
|
-
var
|
|
11870
|
-
var
|
|
12443
|
+
var import_lucide_react15 = require("lucide-react");
|
|
12444
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
11871
12445
|
function SizeSlider({
|
|
11872
12446
|
value,
|
|
11873
12447
|
onChange
|
|
11874
12448
|
}) {
|
|
11875
12449
|
const pct = (value - LOGO_SIZE_MIN) / (LOGO_SIZE_MAX - LOGO_SIZE_MIN) * 100;
|
|
11876
|
-
return /* @__PURE__ */ (0,
|
|
11877
|
-
/* @__PURE__ */ (0,
|
|
11878
|
-
/* @__PURE__ */ (0,
|
|
11879
|
-
/* @__PURE__ */ (0,
|
|
12450
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex w-full flex-col gap-3", children: [
|
|
12451
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex w-full items-center gap-2 text-sm font-medium leading-5", children: [
|
|
12452
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "min-w-0 flex-1 text-foreground", children: "Size" }),
|
|
12453
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "shrink-0 whitespace-nowrap text-muted-foreground", children: [
|
|
11880
12454
|
value,
|
|
11881
12455
|
" px"
|
|
11882
12456
|
] })
|
|
11883
12457
|
] }),
|
|
11884
|
-
/* @__PURE__ */ (0,
|
|
11885
|
-
/* @__PURE__ */ (0,
|
|
12458
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "relative h-2 w-full rounded-full bg-primary-50", children: [
|
|
12459
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11886
12460
|
"div",
|
|
11887
12461
|
{
|
|
11888
12462
|
className: "absolute inset-y-0 left-0 rounded-full bg-primary",
|
|
11889
12463
|
style: { width: `${pct}%` }
|
|
11890
12464
|
}
|
|
11891
12465
|
),
|
|
11892
|
-
/* @__PURE__ */ (0,
|
|
12466
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11893
12467
|
"input",
|
|
11894
12468
|
{
|
|
11895
12469
|
type: "range",
|
|
@@ -11926,14 +12500,14 @@ function LogoSizePanel({
|
|
|
11926
12500
|
const showFollowing = viewport === "mobile" && mobileFollowing;
|
|
11927
12501
|
const showMobileSlider = viewport === "mobile" && !mobileFollowing;
|
|
11928
12502
|
const showDesktopSlider = viewport === "desktop";
|
|
11929
|
-
return /* @__PURE__ */ (0,
|
|
11930
|
-
showFollowing ? /* @__PURE__ */ (0,
|
|
11931
|
-
/* @__PURE__ */ (0,
|
|
11932
|
-
/* @__PURE__ */ (0,
|
|
11933
|
-
/* @__PURE__ */ (0,
|
|
12503
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn("flex w-full flex-col gap-4", className), children: [
|
|
12504
|
+
showFollowing ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
|
|
12505
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-start gap-1", children: [
|
|
12506
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react15.Link, { size: 16, className: "mt-0.5 shrink-0 text-foreground", "aria-hidden": true }),
|
|
12507
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-sm font-semibold leading-5 text-foreground", children: "Following desktop size" })
|
|
11934
12508
|
] }),
|
|
11935
|
-
/* @__PURE__ */ (0,
|
|
11936
|
-
/* @__PURE__ */ (0,
|
|
12509
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-sm leading-5 text-muted-foreground", children: "Mobile uses the desktop size until you customize it. Change the desktop size and it follows automatically." }),
|
|
12510
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11937
12511
|
Button,
|
|
11938
12512
|
{
|
|
11939
12513
|
type: "button",
|
|
@@ -11945,8 +12519,8 @@ function LogoSizePanel({
|
|
|
11945
12519
|
}
|
|
11946
12520
|
)
|
|
11947
12521
|
] }) : null,
|
|
11948
|
-
showDesktopSlider || showMobileSlider ? /* @__PURE__ */ (0,
|
|
11949
|
-
showMobileSlider ? /* @__PURE__ */ (0,
|
|
12522
|
+
showDesktopSlider || showMobileSlider ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SizeSlider, { value: sizePx, onChange: onSizeChange }) : null,
|
|
12523
|
+
showMobileSlider ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11950
12524
|
Button,
|
|
11951
12525
|
{
|
|
11952
12526
|
type: "button",
|
|
@@ -11957,8 +12531,8 @@ function LogoSizePanel({
|
|
|
11957
12531
|
children: "Reset to desktop size"
|
|
11958
12532
|
}
|
|
11959
12533
|
) : null,
|
|
11960
|
-
/* @__PURE__ */ (0,
|
|
11961
|
-
/* @__PURE__ */ (0,
|
|
12534
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "h-px w-full bg-border", role: "separator" }),
|
|
12535
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
11962
12536
|
Button,
|
|
11963
12537
|
{
|
|
11964
12538
|
type: "button",
|
|
@@ -11968,24 +12542,24 @@ function LogoSizePanel({
|
|
|
11968
12542
|
onClick: onUpdateEverywhere,
|
|
11969
12543
|
children: [
|
|
11970
12544
|
"Update logo everywhere",
|
|
11971
|
-
/* @__PURE__ */ (0,
|
|
12545
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react15.ArrowUpRight, { size: 16, "aria-hidden": true })
|
|
11972
12546
|
]
|
|
11973
12547
|
}
|
|
11974
12548
|
),
|
|
11975
|
-
/* @__PURE__ */ (0,
|
|
12549
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-sm leading-5 text-muted-foreground", children: "Matches the right version to your background." })
|
|
11976
12550
|
] });
|
|
11977
12551
|
}
|
|
11978
12552
|
|
|
11979
12553
|
// src/ui/socials-display-panel.tsx
|
|
11980
|
-
var
|
|
12554
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
11981
12555
|
function DisplaySwitch({
|
|
11982
12556
|
label,
|
|
11983
12557
|
checked,
|
|
11984
12558
|
disabled,
|
|
11985
12559
|
onChange
|
|
11986
12560
|
}) {
|
|
11987
|
-
return /* @__PURE__ */ (0,
|
|
11988
|
-
/* @__PURE__ */ (0,
|
|
12561
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex w-full items-center gap-2", children: [
|
|
12562
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
11989
12563
|
"span",
|
|
11990
12564
|
{
|
|
11991
12565
|
className: cn(
|
|
@@ -11995,7 +12569,7 @@ function DisplaySwitch({
|
|
|
11995
12569
|
children: label
|
|
11996
12570
|
}
|
|
11997
12571
|
),
|
|
11998
|
-
/* @__PURE__ */ (0,
|
|
12572
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
11999
12573
|
"button",
|
|
12000
12574
|
{
|
|
12001
12575
|
type: "button",
|
|
@@ -12009,7 +12583,7 @@ function DisplaySwitch({
|
|
|
12009
12583
|
checked ? "bg-primary" : "bg-primary-50",
|
|
12010
12584
|
disabled ? "cursor-default opacity-50" : "cursor-pointer"
|
|
12011
12585
|
),
|
|
12012
|
-
children: /* @__PURE__ */ (0,
|
|
12586
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
12013
12587
|
"span",
|
|
12014
12588
|
{
|
|
12015
12589
|
className: cn(
|
|
@@ -12023,8 +12597,8 @@ function DisplaySwitch({
|
|
|
12023
12597
|
] });
|
|
12024
12598
|
}
|
|
12025
12599
|
function SocialsDisplayPanel({ display, onChange, className }) {
|
|
12026
|
-
return /* @__PURE__ */ (0,
|
|
12027
|
-
/* @__PURE__ */ (0,
|
|
12600
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: cn("flex w-full flex-col gap-3", className), children: [
|
|
12601
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
12028
12602
|
DisplaySwitch,
|
|
12029
12603
|
{
|
|
12030
12604
|
label: "Text",
|
|
@@ -12033,7 +12607,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
|
|
|
12033
12607
|
onChange: (text) => onChange({ ...display, text })
|
|
12034
12608
|
}
|
|
12035
12609
|
),
|
|
12036
|
-
/* @__PURE__ */ (0,
|
|
12610
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
12037
12611
|
DisplaySwitch,
|
|
12038
12612
|
{
|
|
12039
12613
|
label: "Icon",
|
|
@@ -12593,8 +13167,8 @@ function useNavItemDrag({
|
|
|
12593
13167
|
}
|
|
12594
13168
|
|
|
12595
13169
|
// src/ui/footer-container-chrome.tsx
|
|
12596
|
-
var
|
|
12597
|
-
var
|
|
13170
|
+
var import_lucide_react16 = require("lucide-react");
|
|
13171
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
12598
13172
|
function FooterContainerChrome({
|
|
12599
13173
|
rect,
|
|
12600
13174
|
onAdd,
|
|
@@ -12602,7 +13176,7 @@ function FooterContainerChrome({
|
|
|
12602
13176
|
}) {
|
|
12603
13177
|
const chromeGap = 6;
|
|
12604
13178
|
const buttonMargin = 7;
|
|
12605
|
-
return /* @__PURE__ */ (0,
|
|
13179
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
12606
13180
|
"div",
|
|
12607
13181
|
{
|
|
12608
13182
|
"data-ohw-footer-container-chrome": "",
|
|
@@ -12614,8 +13188,8 @@ function FooterContainerChrome({
|
|
|
12614
13188
|
width: rect.width + chromeGap * 2,
|
|
12615
13189
|
height: rect.height + chromeGap * 2
|
|
12616
13190
|
},
|
|
12617
|
-
children: /* @__PURE__ */ (0,
|
|
12618
|
-
/* @__PURE__ */ (0,
|
|
13191
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Tooltip, { children: [
|
|
13192
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
12619
13193
|
"button",
|
|
12620
13194
|
{
|
|
12621
13195
|
type: "button",
|
|
@@ -12634,10 +13208,10 @@ function FooterContainerChrome({
|
|
|
12634
13208
|
if (addDisabled) return;
|
|
12635
13209
|
onAdd();
|
|
12636
13210
|
},
|
|
12637
|
-
children: /* @__PURE__ */ (0,
|
|
13211
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react16.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
12638
13212
|
}
|
|
12639
13213
|
) }),
|
|
12640
|
-
/* @__PURE__ */ (0,
|
|
13214
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
|
|
12641
13215
|
] })
|
|
12642
13216
|
}
|
|
12643
13217
|
) });
|
|
@@ -13097,14 +13671,14 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
13097
13671
|
}
|
|
13098
13672
|
|
|
13099
13673
|
// src/ui/navbar-container-chrome.tsx
|
|
13100
|
-
var
|
|
13101
|
-
var
|
|
13674
|
+
var import_lucide_react17 = require("lucide-react");
|
|
13675
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
13102
13676
|
function NavbarContainerChrome({
|
|
13103
13677
|
rect,
|
|
13104
13678
|
onAdd
|
|
13105
13679
|
}) {
|
|
13106
13680
|
const chromeGap = 6;
|
|
13107
|
-
return /* @__PURE__ */ (0,
|
|
13681
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
13108
13682
|
"div",
|
|
13109
13683
|
{
|
|
13110
13684
|
"data-ohw-navbar-container-chrome": "",
|
|
@@ -13116,7 +13690,7 @@ function NavbarContainerChrome({
|
|
|
13116
13690
|
width: rect.width + chromeGap * 2,
|
|
13117
13691
|
height: rect.height + chromeGap * 2
|
|
13118
13692
|
},
|
|
13119
|
-
children: /* @__PURE__ */ (0,
|
|
13693
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
13120
13694
|
"button",
|
|
13121
13695
|
{
|
|
13122
13696
|
type: "button",
|
|
@@ -13133,7 +13707,7 @@ function NavbarContainerChrome({
|
|
|
13133
13707
|
e.stopPropagation();
|
|
13134
13708
|
onAdd();
|
|
13135
13709
|
},
|
|
13136
|
-
children: /* @__PURE__ */ (0,
|
|
13710
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react17.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
13137
13711
|
}
|
|
13138
13712
|
)
|
|
13139
13713
|
}
|
|
@@ -13142,7 +13716,7 @@ function NavbarContainerChrome({
|
|
|
13142
13716
|
|
|
13143
13717
|
// src/ui/drop-indicator.tsx
|
|
13144
13718
|
var React10 = __toESM(require("react"), 1);
|
|
13145
|
-
var
|
|
13719
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
13146
13720
|
var dropIndicatorVariants = cva(
|
|
13147
13721
|
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
13148
13722
|
{
|
|
@@ -13166,7 +13740,7 @@ var dropIndicatorVariants = cva(
|
|
|
13166
13740
|
);
|
|
13167
13741
|
var DropIndicator = React10.forwardRef(
|
|
13168
13742
|
({ className, direction, state, ...props }, ref) => {
|
|
13169
|
-
return /* @__PURE__ */ (0,
|
|
13743
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
13170
13744
|
"div",
|
|
13171
13745
|
{
|
|
13172
13746
|
ref,
|
|
@@ -13183,7 +13757,7 @@ var DropIndicator = React10.forwardRef(
|
|
|
13183
13757
|
DropIndicator.displayName = "DropIndicator";
|
|
13184
13758
|
|
|
13185
13759
|
// src/ui/badge.tsx
|
|
13186
|
-
var
|
|
13760
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
13187
13761
|
var badgeVariants = cva(
|
|
13188
13762
|
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
13189
13763
|
{
|
|
@@ -13201,12 +13775,12 @@ var badgeVariants = cva(
|
|
|
13201
13775
|
}
|
|
13202
13776
|
);
|
|
13203
13777
|
function Badge({ className, variant, ...props }) {
|
|
13204
|
-
return /* @__PURE__ */ (0,
|
|
13778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
13205
13779
|
}
|
|
13206
13780
|
|
|
13207
13781
|
// src/OhhwellsBridge.tsx
|
|
13208
|
-
var
|
|
13209
|
-
var
|
|
13782
|
+
var import_lucide_react18 = require("lucide-react");
|
|
13783
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
13210
13784
|
var PRIMARY3 = "#0885FE";
|
|
13211
13785
|
var IMAGE_FADE_MS = 300;
|
|
13212
13786
|
function runOpacityFade(el, onDone) {
|
|
@@ -13375,7 +13949,7 @@ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, be
|
|
|
13375
13949
|
const root = (0, import_client2.createRoot)(container);
|
|
13376
13950
|
(0, import_react_dom3.flushSync)(() => {
|
|
13377
13951
|
root.render(
|
|
13378
|
-
/* @__PURE__ */ (0,
|
|
13952
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
13379
13953
|
SchedulingWidget,
|
|
13380
13954
|
{
|
|
13381
13955
|
notifyOnConnect,
|
|
@@ -13490,7 +14064,7 @@ function isIconEditable(el) {
|
|
|
13490
14064
|
return el.dataset.ohwEditable === "icon";
|
|
13491
14065
|
}
|
|
13492
14066
|
var MEDIA_SELECTOR = '[data-ohw-editable="image"], [data-ohw-editable="bg-image"], [data-ohw-editable="video"]';
|
|
13493
|
-
var NON_MEDIA_SELECTOR = '[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]):not([data-ohw-editable="icon"])';
|
|
14067
|
+
var NON_MEDIA_SELECTOR = '[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]):not([data-ohw-editable="icon"]):not([data-ohw-editable="form"])';
|
|
13494
14068
|
function getVideoEl2(el) {
|
|
13495
14069
|
return el instanceof HTMLVideoElement ? el : el.querySelector("video");
|
|
13496
14070
|
}
|
|
@@ -14051,7 +14625,7 @@ function EditGlowChrome({
|
|
|
14051
14625
|
hideHandle = false
|
|
14052
14626
|
}) {
|
|
14053
14627
|
const GAP = SELECTION_CHROME_GAP2;
|
|
14054
|
-
return /* @__PURE__ */ (0,
|
|
14628
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
14055
14629
|
"div",
|
|
14056
14630
|
{
|
|
14057
14631
|
ref: elRef,
|
|
@@ -14066,7 +14640,7 @@ function EditGlowChrome({
|
|
|
14066
14640
|
zIndex: 2147483646
|
|
14067
14641
|
},
|
|
14068
14642
|
children: [
|
|
14069
|
-
/* @__PURE__ */ (0,
|
|
14643
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14070
14644
|
"div",
|
|
14071
14645
|
{
|
|
14072
14646
|
style: {
|
|
@@ -14079,7 +14653,7 @@ function EditGlowChrome({
|
|
|
14079
14653
|
}
|
|
14080
14654
|
}
|
|
14081
14655
|
),
|
|
14082
|
-
reorderHrefKey && !hideHandle && /* @__PURE__ */ (0,
|
|
14656
|
+
reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14083
14657
|
"div",
|
|
14084
14658
|
{
|
|
14085
14659
|
"data-ohw-drag-handle-container": "",
|
|
@@ -14091,7 +14665,7 @@ function EditGlowChrome({
|
|
|
14091
14665
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
14092
14666
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
14093
14667
|
},
|
|
14094
|
-
children: /* @__PURE__ */ (0,
|
|
14668
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14095
14669
|
DragHandle,
|
|
14096
14670
|
{
|
|
14097
14671
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -14301,7 +14875,7 @@ function FloatingToolbar({
|
|
|
14301
14875
|
return () => ro.disconnect();
|
|
14302
14876
|
}, [showEditLink, activeCommands]);
|
|
14303
14877
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
|
|
14304
|
-
return /* @__PURE__ */ (0,
|
|
14878
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14305
14879
|
"div",
|
|
14306
14880
|
{
|
|
14307
14881
|
ref: setRefs,
|
|
@@ -14313,12 +14887,12 @@ function FloatingToolbar({
|
|
|
14313
14887
|
zIndex: 2147483647,
|
|
14314
14888
|
pointerEvents: "auto"
|
|
14315
14889
|
},
|
|
14316
|
-
children: /* @__PURE__ */ (0,
|
|
14317
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0,
|
|
14318
|
-
gi > 0 && /* @__PURE__ */ (0,
|
|
14890
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(CustomToolbar, { children: [
|
|
14891
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react16.default.Fragment, { children: [
|
|
14892
|
+
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(CustomToolbarDivider, {}),
|
|
14319
14893
|
btns.map((btn) => {
|
|
14320
14894
|
const isActive = activeCommands.has(btn.cmd);
|
|
14321
|
-
return /* @__PURE__ */ (0,
|
|
14895
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14322
14896
|
CustomToolbarButton,
|
|
14323
14897
|
{
|
|
14324
14898
|
title: btn.title,
|
|
@@ -14327,7 +14901,7 @@ function FloatingToolbar({
|
|
|
14327
14901
|
e.preventDefault();
|
|
14328
14902
|
onCommand(btn.cmd);
|
|
14329
14903
|
},
|
|
14330
|
-
children: /* @__PURE__ */ (0,
|
|
14904
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14331
14905
|
"svg",
|
|
14332
14906
|
{
|
|
14333
14907
|
width: "16",
|
|
@@ -14348,7 +14922,7 @@ function FloatingToolbar({
|
|
|
14348
14922
|
);
|
|
14349
14923
|
})
|
|
14350
14924
|
] }, gi)),
|
|
14351
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
14925
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14352
14926
|
CustomToolbarButton,
|
|
14353
14927
|
{
|
|
14354
14928
|
type: "button",
|
|
@@ -14362,7 +14936,7 @@ function FloatingToolbar({
|
|
|
14362
14936
|
e.preventDefault();
|
|
14363
14937
|
e.stopPropagation();
|
|
14364
14938
|
},
|
|
14365
|
-
children: /* @__PURE__ */ (0,
|
|
14939
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
14366
14940
|
}
|
|
14367
14941
|
) : null
|
|
14368
14942
|
] })
|
|
@@ -14379,7 +14953,7 @@ function StateToggle({
|
|
|
14379
14953
|
states,
|
|
14380
14954
|
onStateChange
|
|
14381
14955
|
}) {
|
|
14382
|
-
return /* @__PURE__ */ (0,
|
|
14956
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14383
14957
|
ToggleGroup,
|
|
14384
14958
|
{
|
|
14385
14959
|
"data-ohw-state-toggle": "",
|
|
@@ -14393,7 +14967,7 @@ function StateToggle({
|
|
|
14393
14967
|
left: rect.right - 8,
|
|
14394
14968
|
transform: "translateX(-100%)"
|
|
14395
14969
|
},
|
|
14396
|
-
children: states.map((state) => /* @__PURE__ */ (0,
|
|
14970
|
+
children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
14397
14971
|
}
|
|
14398
14972
|
);
|
|
14399
14973
|
}
|
|
@@ -14516,6 +15090,157 @@ function OhhwellsBridge() {
|
|
|
14516
15090
|
const sectionsLoadedRef = (0, import_react16.useRef)(false);
|
|
14517
15091
|
const pendingScheduleConfigRequests = (0, import_react16.useRef)([]);
|
|
14518
15092
|
const [toolbarRect, setToolbarRect] = (0, import_react16.useState)(null);
|
|
15093
|
+
const [formPickRect, setFormPickRect] = (0, import_react16.useState)(null);
|
|
15094
|
+
const formPickElRef = (0, import_react16.useRef)(null);
|
|
15095
|
+
const [formViewState, setFormViewStateUi] = (0, import_react16.useState)("default");
|
|
15096
|
+
const [formPickCount, setFormPickCount] = (0, import_react16.useState)(null);
|
|
15097
|
+
const [formHoverRect, setFormHoverRect] = (0, import_react16.useState)(null);
|
|
15098
|
+
const formHoverElRef = (0, import_react16.useRef)(null);
|
|
15099
|
+
const [fieldPickRect, setFieldPickRect] = (0, import_react16.useState)(null);
|
|
15100
|
+
const fieldPickElRef = (0, import_react16.useRef)(null);
|
|
15101
|
+
const [fieldPickState, setFieldPickState] = (0, import_react16.useState)(null);
|
|
15102
|
+
const [fieldTypePickerOpen, setFieldTypePickerOpen] = (0, import_react16.useState)(false);
|
|
15103
|
+
const clearFormPick = (0, import_react16.useCallback)(() => {
|
|
15104
|
+
const form = formPickElRef.current;
|
|
15105
|
+
if (form) {
|
|
15106
|
+
const key = formKeyOf(form);
|
|
15107
|
+
if (key) setFormViewState(form, key, "default", DEFAULT_SUCCESS_TEXT);
|
|
15108
|
+
}
|
|
15109
|
+
setFormViewStateUi("default");
|
|
15110
|
+
setFormPickCount(null);
|
|
15111
|
+
setFieldTypePickerOpen(false);
|
|
15112
|
+
fieldPickElRef.current = null;
|
|
15113
|
+
setFieldPickRect(null);
|
|
15114
|
+
setFieldPickState(null);
|
|
15115
|
+
formPickElRef.current = null;
|
|
15116
|
+
setFormPickRect(null);
|
|
15117
|
+
}, []);
|
|
15118
|
+
const clearFieldPick = (0, import_react16.useCallback)(() => {
|
|
15119
|
+
const wrapper = fieldPickElRef.current;
|
|
15120
|
+
if (commitPlaceholderEdit(wrapper) && wrapper) {
|
|
15121
|
+
const form = wrapper.closest('[data-ohw-editable="form"]');
|
|
15122
|
+
if (form) persistFieldsRef.current(form);
|
|
15123
|
+
}
|
|
15124
|
+
fieldPickElRef.current = null;
|
|
15125
|
+
setFieldPickRect(null);
|
|
15126
|
+
setFieldPickState(null);
|
|
15127
|
+
}, []);
|
|
15128
|
+
const persistFieldsRef = (0, import_react16.useRef)(() => {
|
|
15129
|
+
});
|
|
15130
|
+
const persistFields = (0, import_react16.useCallback)(
|
|
15131
|
+
(form) => {
|
|
15132
|
+
const key = formKeyOf(form);
|
|
15133
|
+
if (!key) return;
|
|
15134
|
+
const json = JSON.stringify(readFieldsFromDom(form));
|
|
15135
|
+
editContentRef.current = { ...editContentRef.current, [fieldsKey(key)]: json };
|
|
15136
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key: fieldsKey(key), text: json }] });
|
|
15137
|
+
},
|
|
15138
|
+
[]
|
|
15139
|
+
);
|
|
15140
|
+
persistFieldsRef.current = persistFields;
|
|
15141
|
+
const selectField = (0, import_react16.useCallback)((wrapper) => {
|
|
15142
|
+
if (fieldPickElRef.current && fieldPickElRef.current !== wrapper) {
|
|
15143
|
+
commitPlaceholderEdit(fieldPickElRef.current);
|
|
15144
|
+
}
|
|
15145
|
+
syncRequiredMark(wrapper);
|
|
15146
|
+
beginPlaceholderEdit(wrapper);
|
|
15147
|
+
formHoverElRef.current = null;
|
|
15148
|
+
setFormHoverRect(null);
|
|
15149
|
+
fieldPickElRef.current = wrapper;
|
|
15150
|
+
setFieldPickRect(wrapper.getBoundingClientRect());
|
|
15151
|
+
setFieldPickState({ type: fieldTypeOf(wrapper), required: isFieldRequired(wrapper) });
|
|
15152
|
+
setFieldTypePickerOpen(false);
|
|
15153
|
+
}, []);
|
|
15154
|
+
const withSelectedField = (0, import_react16.useCallback)(
|
|
15155
|
+
(run) => {
|
|
15156
|
+
const wrapper = fieldPickElRef.current;
|
|
15157
|
+
const form = formPickElRef.current;
|
|
15158
|
+
if (!wrapper || !form) return;
|
|
15159
|
+
commitPlaceholderEdit(wrapper);
|
|
15160
|
+
run(form, wrapper);
|
|
15161
|
+
beginPlaceholderEdit(wrapper);
|
|
15162
|
+
persistFields(form);
|
|
15163
|
+
setFormPickRect(form.getBoundingClientRect());
|
|
15164
|
+
},
|
|
15165
|
+
[persistFields]
|
|
15166
|
+
);
|
|
15167
|
+
const handleFieldTypeChange = (0, import_react16.useCallback)(
|
|
15168
|
+
(type) => withSelectedField((_form, wrapper) => {
|
|
15169
|
+
applyFieldType(wrapper, type);
|
|
15170
|
+
selectField(wrapper);
|
|
15171
|
+
}),
|
|
15172
|
+
[selectField, withSelectedField]
|
|
15173
|
+
);
|
|
15174
|
+
const handleFieldRequiredToggle = (0, import_react16.useCallback)(
|
|
15175
|
+
() => withSelectedField((_form, wrapper) => {
|
|
15176
|
+
setFieldRequired(wrapper, !isFieldRequired(wrapper));
|
|
15177
|
+
selectField(wrapper);
|
|
15178
|
+
}),
|
|
15179
|
+
[selectField, withSelectedField]
|
|
15180
|
+
);
|
|
15181
|
+
const handleFieldDuplicate = (0, import_react16.useCallback)(
|
|
15182
|
+
() => withSelectedField((form, wrapper) => {
|
|
15183
|
+
const copy = duplicateField(form, wrapper);
|
|
15184
|
+
selectField(copy);
|
|
15185
|
+
}),
|
|
15186
|
+
[selectField, withSelectedField]
|
|
15187
|
+
);
|
|
15188
|
+
const handleFieldDelete = (0, import_react16.useCallback)(
|
|
15189
|
+
() => withSelectedField((_form, wrapper) => {
|
|
15190
|
+
removeField(wrapper);
|
|
15191
|
+
clearFieldPick();
|
|
15192
|
+
postToParentRef.current({ type: "ow:toast", title: "Form field deleted" });
|
|
15193
|
+
}),
|
|
15194
|
+
[clearFieldPick, withSelectedField]
|
|
15195
|
+
);
|
|
15196
|
+
const handleAddField = (0, import_react16.useCallback)(
|
|
15197
|
+
(type) => {
|
|
15198
|
+
const form = formPickElRef.current;
|
|
15199
|
+
if (!form) return;
|
|
15200
|
+
const wrapper = insertField(form, type);
|
|
15201
|
+
setFieldTypePickerOpen(false);
|
|
15202
|
+
if (!wrapper) return;
|
|
15203
|
+
persistFields(form);
|
|
15204
|
+
setFormPickRect(null);
|
|
15205
|
+
requestAnimationFrame(() => {
|
|
15206
|
+
selectField(wrapper);
|
|
15207
|
+
wrapper.scrollIntoView({ block: "nearest", behavior: "smooth" });
|
|
15208
|
+
});
|
|
15209
|
+
},
|
|
15210
|
+
[persistFields, selectField]
|
|
15211
|
+
);
|
|
15212
|
+
const fieldDragRef = (0, import_react16.useRef)(null);
|
|
15213
|
+
const handleFieldDragStart = (0, import_react16.useCallback)(() => {
|
|
15214
|
+
const wrapper = fieldPickElRef.current;
|
|
15215
|
+
const form = formPickElRef.current;
|
|
15216
|
+
if (!wrapper || !form) return;
|
|
15217
|
+
fieldDragRef.current = { key: fieldKeyOf(wrapper), form };
|
|
15218
|
+
}, []);
|
|
15219
|
+
const handleFieldDragEnd = (0, import_react16.useCallback)(() => {
|
|
15220
|
+
fieldDragRef.current = null;
|
|
15221
|
+
setFieldDropIndex(null);
|
|
15222
|
+
}, []);
|
|
15223
|
+
const [fieldDropIndex, setFieldDropIndex] = (0, import_react16.useState)(null);
|
|
15224
|
+
const clearFormPickRef = (0, import_react16.useRef)(clearFormPick);
|
|
15225
|
+
clearFormPickRef.current = clearFormPick;
|
|
15226
|
+
(0, import_react16.useEffect)(() => {
|
|
15227
|
+
const el = fieldPickElRef.current;
|
|
15228
|
+
if (!el || fieldPickRect === null) return;
|
|
15229
|
+
const observer = new ResizeObserver(() => {
|
|
15230
|
+
if (fieldPickElRef.current === el) setFieldPickRect(el.getBoundingClientRect());
|
|
15231
|
+
});
|
|
15232
|
+
observer.observe(el);
|
|
15233
|
+
return () => observer.disconnect();
|
|
15234
|
+
}, [fieldPickRect !== null, fieldPickState]);
|
|
15235
|
+
(0, import_react16.useEffect)(() => {
|
|
15236
|
+
const el = formPickElRef.current;
|
|
15237
|
+
if (!el || formPickRect === null) return;
|
|
15238
|
+
const observer = new ResizeObserver(() => {
|
|
15239
|
+
if (formPickElRef.current === el) setFormPickRect(el.getBoundingClientRect());
|
|
15240
|
+
});
|
|
15241
|
+
observer.observe(el);
|
|
15242
|
+
return () => observer.disconnect();
|
|
15243
|
+
}, [formPickRect !== null, formViewState]);
|
|
14519
15244
|
const [toolbarVariant, setToolbarVariant] = (0, import_react16.useState)("none");
|
|
14520
15245
|
const toolbarVariantRef = (0, import_react16.useRef)("none");
|
|
14521
15246
|
toolbarVariantRef.current = toolbarVariant;
|
|
@@ -14537,7 +15262,7 @@ function OhhwellsBridge() {
|
|
|
14537
15262
|
(0, import_react16.useEffect)(() => {
|
|
14538
15263
|
const sync = () => {
|
|
14539
15264
|
const el = document.querySelector(
|
|
14540
|
-
|
|
15265
|
+
'[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]):not([data-ohw-editable="form"] *)'
|
|
14541
15266
|
);
|
|
14542
15267
|
const target = el && !el.closest("[data-ohw-href-key]") ? el : null;
|
|
14543
15268
|
if (!target) {
|
|
@@ -15669,6 +16394,7 @@ function OhhwellsBridge() {
|
|
|
15669
16394
|
setFloatingPanel(null);
|
|
15670
16395
|
setLogoSizeDraft(null);
|
|
15671
16396
|
}, []);
|
|
16397
|
+
closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
|
|
15672
16398
|
const closeFloatingPanelAndDeselect = (0, import_react16.useCallback)(() => {
|
|
15673
16399
|
setFloatingPanel(null);
|
|
15674
16400
|
setLogoSizeDraft(null);
|
|
@@ -15924,6 +16650,98 @@ function OhhwellsBridge() {
|
|
|
15924
16650
|
cancelled = true;
|
|
15925
16651
|
};
|
|
15926
16652
|
}, [subdomain, isEditMode]);
|
|
16653
|
+
(0, import_react16.useEffect)(() => {
|
|
16654
|
+
if (!isEditMode) return;
|
|
16655
|
+
const resolveIndex = (form, clientY) => {
|
|
16656
|
+
const wrappers = listFieldWrappers(form).filter((el) => fieldKeyOf(el) !== fieldDragRef.current?.key);
|
|
16657
|
+
for (let i = 0; i < wrappers.length; i += 1) {
|
|
16658
|
+
const rect = wrappers[i].getBoundingClientRect();
|
|
16659
|
+
if (clientY < rect.top + rect.height / 2) return i;
|
|
16660
|
+
}
|
|
16661
|
+
return wrappers.length;
|
|
16662
|
+
};
|
|
16663
|
+
const onDragOver = (e) => {
|
|
16664
|
+
const session = fieldDragRef.current;
|
|
16665
|
+
if (!session) return;
|
|
16666
|
+
e.preventDefault();
|
|
16667
|
+
e.stopPropagation();
|
|
16668
|
+
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
16669
|
+
setFieldDropIndex(resolveIndex(session.form, e.clientY));
|
|
16670
|
+
};
|
|
16671
|
+
const onDrop = (e) => {
|
|
16672
|
+
const session = fieldDragRef.current;
|
|
16673
|
+
if (!session) return;
|
|
16674
|
+
e.preventDefault();
|
|
16675
|
+
e.stopPropagation();
|
|
16676
|
+
moveField(session.form, session.key, resolveIndex(session.form, e.clientY));
|
|
16677
|
+
persistFields(session.form);
|
|
16678
|
+
const moved = listFieldWrappers(session.form).find((el) => fieldKeyOf(el) === session.key);
|
|
16679
|
+
if (moved) selectField(moved);
|
|
16680
|
+
setFormPickRect(session.form.getBoundingClientRect());
|
|
16681
|
+
fieldDragRef.current = null;
|
|
16682
|
+
setFieldDropIndex(null);
|
|
16683
|
+
};
|
|
16684
|
+
window.addEventListener("dragover", onDragOver, true);
|
|
16685
|
+
window.addEventListener("drop", onDrop, true);
|
|
16686
|
+
return () => {
|
|
16687
|
+
window.removeEventListener("dragover", onDragOver, true);
|
|
16688
|
+
window.removeEventListener("drop", onDrop, true);
|
|
16689
|
+
};
|
|
16690
|
+
}, [isEditMode, persistFields, selectField]);
|
|
16691
|
+
(0, import_react16.useEffect)(() => {
|
|
16692
|
+
if (!isEditMode) return;
|
|
16693
|
+
const mark = () => document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
|
|
16694
|
+
markFormFields(form);
|
|
16695
|
+
});
|
|
16696
|
+
mark();
|
|
16697
|
+
const observer = new MutationObserver(() => mark());
|
|
16698
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
|
|
16699
|
+
observer.observe(form, { childList: true, subtree: true, characterData: true });
|
|
16700
|
+
});
|
|
16701
|
+
return () => observer.disconnect();
|
|
16702
|
+
}, [isEditMode, fetchState, pathname]);
|
|
16703
|
+
(0, import_react16.useEffect)(() => {
|
|
16704
|
+
if (!isEditMode) return;
|
|
16705
|
+
let saveTimer = null;
|
|
16706
|
+
const onInput = (e) => {
|
|
16707
|
+
const input = e.target;
|
|
16708
|
+
if (!input || !("value" in input)) return;
|
|
16709
|
+
const wrapper = getFieldWrapper(input);
|
|
16710
|
+
if (!wrapper || wrapper !== fieldPickElRef.current) return;
|
|
16711
|
+
if (saveTimer) clearTimeout(saveTimer);
|
|
16712
|
+
saveTimer = setTimeout(() => {
|
|
16713
|
+
const form = formPickElRef.current;
|
|
16714
|
+
if (!form) return;
|
|
16715
|
+
const previous = input.getAttribute("placeholder");
|
|
16716
|
+
input.setAttribute("placeholder", input.value);
|
|
16717
|
+
persistFields(form);
|
|
16718
|
+
input.setAttribute("placeholder", previous ?? "");
|
|
16719
|
+
}, 400);
|
|
16720
|
+
};
|
|
16721
|
+
document.addEventListener("input", onInput, true);
|
|
16722
|
+
return () => document.removeEventListener("input", onInput, true);
|
|
16723
|
+
}, [isEditMode, persistFields]);
|
|
16724
|
+
(0, import_react16.useEffect)(() => {
|
|
16725
|
+
if (isEditMode || fetchState !== "done") return;
|
|
16726
|
+
const content = contentCache.get(subdomain) ?? {};
|
|
16727
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
|
|
16728
|
+
reconcileFieldsFromContent(form, content);
|
|
16729
|
+
});
|
|
16730
|
+
}, [isEditMode, fetchState, subdomain]);
|
|
16731
|
+
(0, import_react16.useEffect)(() => {
|
|
16732
|
+
if (!isEditMode) return;
|
|
16733
|
+
const swallow = (e) => {
|
|
16734
|
+
const target = e.target;
|
|
16735
|
+
if (target && getFormElement(target)) e.preventDefault();
|
|
16736
|
+
};
|
|
16737
|
+
document.addEventListener("submit", swallow, true);
|
|
16738
|
+
return () => document.removeEventListener("submit", swallow, true);
|
|
16739
|
+
}, [isEditMode]);
|
|
16740
|
+
(0, import_react16.useEffect)(() => {
|
|
16741
|
+
if (isEditMode || fetchState !== "done") return;
|
|
16742
|
+
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
16743
|
+
bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
|
|
16744
|
+
}, [isEditMode, fetchState, subdomain]);
|
|
15927
16745
|
(0, import_react16.useEffect)(() => {
|
|
15928
16746
|
if (!subdomain || isEditMode) return;
|
|
15929
16747
|
let debounceTimer = null;
|
|
@@ -16157,7 +16975,9 @@ function OhhwellsBridge() {
|
|
|
16157
16975
|
[style*="100vh"] { min-height: ${initialVh}px !important; height: ${initialVh}px !important; }
|
|
16158
16976
|
[style*="100svh"] { min-height: ${initialVh}px !important; height: ${initialVh}px !important; }
|
|
16159
16977
|
[style*="100dvh"] { min-height: ${initialVh}px !important; height: ${initialVh}px !important; }
|
|
16160
|
-
|
|
16978
|
+
/* Not the form: it is a layout container (flex/grid with gaps), and forcing block
|
|
16979
|
+
crushed its fields together (OHH-490). */
|
|
16980
|
+
[data-ohw-editable]:not([data-ohw-editable="form"]) {
|
|
16161
16981
|
display: block;
|
|
16162
16982
|
}
|
|
16163
16983
|
/* Body text (no item-action toolbar) \u2014 first click enters text edit \u2192 I-beam.
|
|
@@ -16183,6 +17003,35 @@ function OhhwellsBridge() {
|
|
|
16183
17003
|
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
16184
17004
|
[data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
|
|
16185
17005
|
[data-ohw-editable="link"], [data-ohw-editable="link"] * { cursor: pointer !important; }
|
|
17006
|
+
/* A form field is a design surface in the editor: its input takes the pointer so the
|
|
17007
|
+
field can be picked and hovered from anywhere inside it (OHH-642). */
|
|
17008
|
+
[data-ohw-editable="form"] [data-ohw-form-field] input,
|
|
17009
|
+
[data-ohw-editable="form"] [data-ohw-form-field] textarea,
|
|
17010
|
+
[data-ohw-editable="form"] [data-ohw-form-field] label {
|
|
17011
|
+
pointer-events: auto !important;
|
|
17012
|
+
cursor: pointer !important;
|
|
17013
|
+
}
|
|
17014
|
+
/* While a field is selected its placeholder is being written in the value, so the
|
|
17015
|
+
text reads as a placeholder rather than as an answer (OHH-642). */
|
|
17016
|
+
/* A field is a design surface here: dragging its corner resized it past the form and
|
|
17017
|
+
left the chrome behind. Height stays adjustable, width does not (OHH-642). */
|
|
17018
|
+
[data-ohw-editable="form"] [data-ohw-form-field] textarea {
|
|
17019
|
+
resize: vertical !important;
|
|
17020
|
+
max-width: 100% !important;
|
|
17021
|
+
}
|
|
17022
|
+
[data-ohw-editable="form"] [data-ohw-form-field] input,
|
|
17023
|
+
[data-ohw-editable="form"] [data-ohw-form-field] textarea {
|
|
17024
|
+
box-sizing: border-box !important;
|
|
17025
|
+
width: 100% !important;
|
|
17026
|
+
}
|
|
17027
|
+
/* Somewhere to click the block itself, on every side (OHH-642) \u2014 editor only. */
|
|
17028
|
+
[data-ohw-editable="form"] {
|
|
17029
|
+
padding: 18px !important;
|
|
17030
|
+
}
|
|
17031
|
+
[data-ohw-placeholder-edit] {
|
|
17032
|
+
color: color-mix(in srgb, currentColor 55%, transparent) !important;
|
|
17033
|
+
cursor: text !important;
|
|
17034
|
+
}
|
|
16186
17035
|
/* Text hover chrome is drawn by the overlay (see hoveredTextRect) \u2014 the CSS outline
|
|
16187
17036
|
that used to draw it dashes denser than the overlay border, so identical specs
|
|
16188
17037
|
still read as two different frames (OHH-695). The attribute stays: hover paths
|
|
@@ -16269,6 +17118,49 @@ function OhhwellsBridge() {
|
|
|
16269
17118
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
16270
17119
|
if (isInsideLinkEditor(target)) return;
|
|
16271
17120
|
if (isInsideFloatingPanel(target)) return;
|
|
17121
|
+
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
17122
|
+
if (target.closest(
|
|
17123
|
+
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
17124
|
+
)) {
|
|
17125
|
+
return;
|
|
17126
|
+
}
|
|
17127
|
+
{
|
|
17128
|
+
const formEl = getFormElement(target);
|
|
17129
|
+
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
17130
|
+
if (formEl && formKeyOf(formEl) && !onSuccessText) {
|
|
17131
|
+
const fieldEl = getFieldWrapper(target);
|
|
17132
|
+
if (fieldEl) {
|
|
17133
|
+
const label = target.closest("label");
|
|
17134
|
+
if (label && fieldPickElRef.current === fieldEl) return;
|
|
17135
|
+
e.preventDefault();
|
|
17136
|
+
e.stopPropagation();
|
|
17137
|
+
deactivateRef.current();
|
|
17138
|
+
deselectRef.current();
|
|
17139
|
+
formPickElRef.current = formEl;
|
|
17140
|
+
setFormPickRect(null);
|
|
17141
|
+
selectField(fieldEl);
|
|
17142
|
+
if (!label) fieldEl.querySelector("input, textarea")?.focus();
|
|
17143
|
+
return;
|
|
17144
|
+
}
|
|
17145
|
+
clearFieldPick();
|
|
17146
|
+
e.preventDefault();
|
|
17147
|
+
e.stopPropagation();
|
|
17148
|
+
deactivateRef.current();
|
|
17149
|
+
deselectRef.current();
|
|
17150
|
+
markFormFields(formEl);
|
|
17151
|
+
formHoverElRef.current = null;
|
|
17152
|
+
setFormHoverRect(null);
|
|
17153
|
+
formPickElRef.current = formEl;
|
|
17154
|
+
setFormPickRect(formEl.getBoundingClientRect());
|
|
17155
|
+
postToParentRef.current({
|
|
17156
|
+
type: "ow:form-selected",
|
|
17157
|
+
formKey: formKeyOf(formEl),
|
|
17158
|
+
hasLongText: formHasLongText(formEl)
|
|
17159
|
+
});
|
|
17160
|
+
return;
|
|
17161
|
+
}
|
|
17162
|
+
if (!formEl && formPickElRef.current) clearFormPick();
|
|
17163
|
+
}
|
|
16272
17164
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
16273
17165
|
const beneath = document.elementsFromPoint(e.clientX, e.clientY).find(
|
|
16274
17166
|
(el) => el instanceof HTMLElement && !el.closest("[data-ohw-bridge-root]") && el.closest("[data-ohw-section]") != null
|
|
@@ -16608,6 +17500,26 @@ function OhhwellsBridge() {
|
|
|
16608
17500
|
return;
|
|
16609
17501
|
}
|
|
16610
17502
|
const editable = target.closest("[data-ohw-editable]");
|
|
17503
|
+
const hoverForm = getFormElement(target);
|
|
17504
|
+
if (hoverForm) {
|
|
17505
|
+
const hoverField = getFieldWrapper(target);
|
|
17506
|
+
const hoverTarget = hoverField ?? hoverForm;
|
|
17507
|
+
const selectedHere = hoverTarget === fieldPickElRef.current || hoverTarget === formPickElRef.current;
|
|
17508
|
+
hoveredItemElRef.current = null;
|
|
17509
|
+
setHoveredItemRect(null);
|
|
17510
|
+
if (selectedHere) {
|
|
17511
|
+
formHoverElRef.current = null;
|
|
17512
|
+
setFormHoverRect(null);
|
|
17513
|
+
} else {
|
|
17514
|
+
formHoverElRef.current = hoverTarget;
|
|
17515
|
+
setFormHoverRect(hoverTarget.getBoundingClientRect());
|
|
17516
|
+
}
|
|
17517
|
+
return;
|
|
17518
|
+
}
|
|
17519
|
+
if (formHoverElRef.current) {
|
|
17520
|
+
formHoverElRef.current = null;
|
|
17521
|
+
setFormHoverRect(null);
|
|
17522
|
+
}
|
|
16611
17523
|
if (!editable) return;
|
|
16612
17524
|
const selected = selectedElRef.current;
|
|
16613
17525
|
if (selected && (selected === editable || selected.contains(editable))) return;
|
|
@@ -17244,6 +18156,13 @@ function OhhwellsBridge() {
|
|
|
17244
18156
|
setSectionGap(null);
|
|
17245
18157
|
}
|
|
17246
18158
|
};
|
|
18159
|
+
const pointOwnedByFloatingPanel = (clientX, clientY) => {
|
|
18160
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging")) return true;
|
|
18161
|
+
const panel = document.querySelector("[data-ohw-floating-panel]");
|
|
18162
|
+
if (!panel) return false;
|
|
18163
|
+
const rect = panel.getBoundingClientRect();
|
|
18164
|
+
return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
|
|
18165
|
+
};
|
|
17247
18166
|
const handleMouseMove = (e) => {
|
|
17248
18167
|
const { clientX, clientY } = e;
|
|
17249
18168
|
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
@@ -17809,6 +18728,13 @@ function OhhwellsBridge() {
|
|
|
17809
18728
|
}
|
|
17810
18729
|
}
|
|
17811
18730
|
};
|
|
18731
|
+
const handleFormCount = (e) => {
|
|
18732
|
+
if (e.data?.type !== "ow:form-count") return;
|
|
18733
|
+
const form = formPickElRef.current;
|
|
18734
|
+
if (!form || formKeyOf(form) !== e.data.formKey) return;
|
|
18735
|
+
setFormPickCount(typeof e.data.count === "number" ? e.data.count : null);
|
|
18736
|
+
};
|
|
18737
|
+
window.addEventListener("message", handleFormCount);
|
|
17812
18738
|
window.addEventListener("message", handleUiEscape);
|
|
17813
18739
|
const handleKeyDown = (e) => {
|
|
17814
18740
|
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
@@ -17828,6 +18754,11 @@ function OhhwellsBridge() {
|
|
|
17828
18754
|
closeFloatingPanelOnlyRef.current();
|
|
17829
18755
|
return;
|
|
17830
18756
|
}
|
|
18757
|
+
if (e.key === "Escape" && formPickElRef.current) {
|
|
18758
|
+
e.preventDefault();
|
|
18759
|
+
clearFormPickRef.current();
|
|
18760
|
+
return;
|
|
18761
|
+
}
|
|
17831
18762
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
17832
18763
|
if (toolbarVariantRef.current === "logo") {
|
|
17833
18764
|
deselectRef.current();
|
|
@@ -18380,6 +19311,7 @@ function OhhwellsBridge() {
|
|
|
18380
19311
|
window.removeEventListener("message", handleGetBrand);
|
|
18381
19312
|
window.removeEventListener("message", handleDeactivate);
|
|
18382
19313
|
window.removeEventListener("message", handleToastAction);
|
|
19314
|
+
window.removeEventListener("message", handleFormCount);
|
|
18383
19315
|
window.removeEventListener("message", handleUiEscape);
|
|
18384
19316
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
18385
19317
|
autoSaveTimers.current.clear();
|
|
@@ -18403,7 +19335,9 @@ function OhhwellsBridge() {
|
|
|
18403
19335
|
if (footerDragRef.current) return;
|
|
18404
19336
|
const target = e.target;
|
|
18405
19337
|
if (!target) return;
|
|
18406
|
-
if (target.closest(
|
|
19338
|
+
if (target.closest(
|
|
19339
|
+
'[data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-toolbar], [data-ohw-item-toolbar-anchor], [data-ohw-link-popover-root], [data-ohw-floating-panel], [data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"]'
|
|
19340
|
+
)) {
|
|
18407
19341
|
return;
|
|
18408
19342
|
}
|
|
18409
19343
|
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
@@ -18976,10 +19910,10 @@ function OhhwellsBridge() {
|
|
|
18976
19910
|
[postToParent2]
|
|
18977
19911
|
);
|
|
18978
19912
|
return bridgeRoot ? (0, import_react_dom4.createPortal)(
|
|
18979
|
-
/* @__PURE__ */ (0,
|
|
18980
|
-
/* @__PURE__ */ (0,
|
|
18981
|
-
isEditMode && /* @__PURE__ */ (0,
|
|
18982
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0,
|
|
19913
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
|
|
19914
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
19915
|
+
isEditMode && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
|
|
19916
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
18983
19917
|
MediaOverlay,
|
|
18984
19918
|
{
|
|
18985
19919
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -18990,7 +19924,7 @@ function OhhwellsBridge() {
|
|
|
18990
19924
|
},
|
|
18991
19925
|
`uploading-${key}`
|
|
18992
19926
|
)),
|
|
18993
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0,
|
|
19927
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
18994
19928
|
MediaOverlay,
|
|
18995
19929
|
{
|
|
18996
19930
|
hover: mediaHover,
|
|
@@ -18999,11 +19933,11 @@ function OhhwellsBridge() {
|
|
|
18999
19933
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
19000
19934
|
}
|
|
19001
19935
|
),
|
|
19002
|
-
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0,
|
|
19003
|
-
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0,
|
|
19004
|
-
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0,
|
|
19005
|
-
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0,
|
|
19006
|
-
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0,
|
|
19936
|
+
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
|
|
19937
|
+
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
19938
|
+
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
19939
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
19940
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19007
19941
|
"div",
|
|
19008
19942
|
{
|
|
19009
19943
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -19013,7 +19947,7 @@ function OhhwellsBridge() {
|
|
|
19013
19947
|
width: slot.width,
|
|
19014
19948
|
height: slot.height
|
|
19015
19949
|
},
|
|
19016
|
-
children: /* @__PURE__ */ (0,
|
|
19950
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19017
19951
|
DropIndicator,
|
|
19018
19952
|
{
|
|
19019
19953
|
direction: slot.direction,
|
|
@@ -19024,7 +19958,7 @@ function OhhwellsBridge() {
|
|
|
19024
19958
|
},
|
|
19025
19959
|
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
19026
19960
|
)),
|
|
19027
|
-
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0,
|
|
19961
|
+
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19028
19962
|
"div",
|
|
19029
19963
|
{
|
|
19030
19964
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -19034,7 +19968,7 @@ function OhhwellsBridge() {
|
|
|
19034
19968
|
width: slot.width,
|
|
19035
19969
|
height: slot.height
|
|
19036
19970
|
},
|
|
19037
|
-
children: /* @__PURE__ */ (0,
|
|
19971
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19038
19972
|
DropIndicator,
|
|
19039
19973
|
{
|
|
19040
19974
|
direction: slot.direction,
|
|
@@ -19045,11 +19979,179 @@ function OhhwellsBridge() {
|
|
|
19045
19979
|
},
|
|
19046
19980
|
`nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
|
|
19047
19981
|
)),
|
|
19048
|
-
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0,
|
|
19049
|
-
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0,
|
|
19050
|
-
hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0,
|
|
19051
|
-
|
|
19052
|
-
|
|
19982
|
+
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
19983
|
+
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
19984
|
+
hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
|
|
19985
|
+
formPickRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19986
|
+
ItemInteractionLayer,
|
|
19987
|
+
{
|
|
19988
|
+
rect: formPickRect,
|
|
19989
|
+
state: "active-top",
|
|
19990
|
+
itemDragSurface: false,
|
|
19991
|
+
toolbarAlign: "left",
|
|
19992
|
+
chromeGap: 24,
|
|
19993
|
+
toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
19994
|
+
"div",
|
|
19995
|
+
{
|
|
19996
|
+
"data-ohw-form-toolbar": "",
|
|
19997
|
+
className: "pointer-events-auto flex items-center gap-0.5 whitespace-nowrap rounded-lg border border-border bg-background p-1 shadow-md",
|
|
19998
|
+
children: [
|
|
19999
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
20000
|
+
"button",
|
|
20001
|
+
{
|
|
20002
|
+
type: "button",
|
|
20003
|
+
"aria-label": "Add field",
|
|
20004
|
+
className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
|
|
20005
|
+
onClick: () => setFieldTypePickerOpen((open) => !open),
|
|
20006
|
+
"data-ohw-add-field": "",
|
|
20007
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Plus, { size: 15, "aria-hidden": true })
|
|
20008
|
+
}
|
|
20009
|
+
),
|
|
20010
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
|
|
20011
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
20012
|
+
"button",
|
|
20013
|
+
{
|
|
20014
|
+
type: "button",
|
|
20015
|
+
className: "flex h-7 items-center gap-1.5 whitespace-nowrap rounded-md px-2 text-[13px] font-semibold text-foreground transition-colors hover:bg-muted/80",
|
|
20016
|
+
onClick: () => {
|
|
20017
|
+
const form = formPickElRef.current;
|
|
20018
|
+
if (!form) return;
|
|
20019
|
+
postToParent2({
|
|
20020
|
+
type: "ow:form-pick",
|
|
20021
|
+
formKey: formKeyOf(form),
|
|
20022
|
+
hasLongText: formHasLongText(form)
|
|
20023
|
+
});
|
|
20024
|
+
},
|
|
20025
|
+
children: [
|
|
20026
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Settings, { size: 14, "aria-hidden": true }),
|
|
20027
|
+
"Form settings",
|
|
20028
|
+
formPickCount ? (
|
|
20029
|
+
// Counter pill, per the design — not a text suffix.
|
|
20030
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
20031
|
+
"span",
|
|
20032
|
+
{
|
|
20033
|
+
"data-ohw-form-count": "",
|
|
20034
|
+
className: "ml-0.5 inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-primary px-1.5 text-[11px] font-semibold text-primary-foreground",
|
|
20035
|
+
children: formPickCount
|
|
20036
|
+
}
|
|
20037
|
+
)
|
|
20038
|
+
) : null
|
|
20039
|
+
]
|
|
20040
|
+
}
|
|
20041
|
+
),
|
|
20042
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
|
|
20043
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
20044
|
+
"button",
|
|
20045
|
+
{
|
|
20046
|
+
type: "button",
|
|
20047
|
+
className: "flex h-7 items-center gap-1.5 whitespace-nowrap rounded-md px-2 text-[13px] font-semibold text-foreground transition-colors hover:bg-muted/80",
|
|
20048
|
+
onClick: () => {
|
|
20049
|
+
const form = formPickElRef.current;
|
|
20050
|
+
if (!form) return;
|
|
20051
|
+
postToParent2({
|
|
20052
|
+
type: "ow:form-submissions",
|
|
20053
|
+
formKey: formKeyOf(form),
|
|
20054
|
+
hasLongText: formHasLongText(form)
|
|
20055
|
+
});
|
|
20056
|
+
},
|
|
20057
|
+
"data-ohw-view-submissions": "",
|
|
20058
|
+
children: [
|
|
20059
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Table, { size: 14, "aria-hidden": true }),
|
|
20060
|
+
"View submissions"
|
|
20061
|
+
]
|
|
20062
|
+
}
|
|
20063
|
+
),
|
|
20064
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
|
|
20065
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex items-center rounded-md bg-muted/70 p-0.5", children: ["default", "success"].map((state) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
20066
|
+
"button",
|
|
20067
|
+
{
|
|
20068
|
+
type: "button",
|
|
20069
|
+
"aria-pressed": formViewState === state,
|
|
20070
|
+
className: "rounded-md px-2.5 py-1 text-[13px] font-semibold capitalize transition-colors " + (formViewState === state ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"),
|
|
20071
|
+
onClick: () => {
|
|
20072
|
+
const form = formPickElRef.current;
|
|
20073
|
+
const key = form ? formKeyOf(form) : null;
|
|
20074
|
+
if (!form || !key) return;
|
|
20075
|
+
const initial = editContentRef.current[formSuccessKey(key)] ?? DEFAULT_SUCCESS_TEXT;
|
|
20076
|
+
setFormViewState(form, key, state, initial);
|
|
20077
|
+
setFormViewStateUi(state);
|
|
20078
|
+
setFormPickRect(form.getBoundingClientRect());
|
|
20079
|
+
if (state === "success") {
|
|
20080
|
+
const successEl = form.querySelector(`[${SUCCESS_TEXT_ATTR}]`);
|
|
20081
|
+
if (successEl) requestAnimationFrame(() => activateRef.current(successEl));
|
|
20082
|
+
} else {
|
|
20083
|
+
deactivateRef.current();
|
|
20084
|
+
}
|
|
20085
|
+
},
|
|
20086
|
+
children: state
|
|
20087
|
+
},
|
|
20088
|
+
state
|
|
20089
|
+
)) })
|
|
20090
|
+
]
|
|
20091
|
+
}
|
|
20092
|
+
)
|
|
20093
|
+
}
|
|
20094
|
+
),
|
|
20095
|
+
formHoverRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
20096
|
+
ItemInteractionLayer,
|
|
20097
|
+
{
|
|
20098
|
+
rect: formHoverRect,
|
|
20099
|
+
state: "hover",
|
|
20100
|
+
chromeGap: formHoverElRef.current && getFieldWrapper(formHoverElRef.current) ? 8 : 24
|
|
20101
|
+
}
|
|
20102
|
+
),
|
|
20103
|
+
fieldPickRect && fieldPickState && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
20104
|
+
ItemInteractionLayer,
|
|
20105
|
+
{
|
|
20106
|
+
rect: fieldPickRect,
|
|
20107
|
+
state: "active-top",
|
|
20108
|
+
itemDragSurface: false,
|
|
20109
|
+
toolbarAlign: "left",
|
|
20110
|
+
chromeGap: 10,
|
|
20111
|
+
showHandle: true,
|
|
20112
|
+
dragHandleLabel: "Reorder field",
|
|
20113
|
+
onDragHandleDragStart: handleFieldDragStart,
|
|
20114
|
+
onDragHandleDragEnd: handleFieldDragEnd,
|
|
20115
|
+
toolbar: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
20116
|
+
FormFieldToolbar,
|
|
20117
|
+
{
|
|
20118
|
+
type: fieldPickState.type,
|
|
20119
|
+
required: fieldPickState.required,
|
|
20120
|
+
onTypeChange: handleFieldTypeChange,
|
|
20121
|
+
onRequiredToggle: handleFieldRequiredToggle,
|
|
20122
|
+
onDuplicate: handleFieldDuplicate,
|
|
20123
|
+
onDelete: handleFieldDelete
|
|
20124
|
+
}
|
|
20125
|
+
)
|
|
20126
|
+
}
|
|
20127
|
+
),
|
|
20128
|
+
fieldDropIndex !== null && formPickElRef.current ? (() => {
|
|
20129
|
+
const wrappers = listFieldWrappers(formPickElRef.current).filter(
|
|
20130
|
+
(el) => fieldKeyOf(el) !== fieldDragRef.current?.key
|
|
20131
|
+
);
|
|
20132
|
+
const anchor = wrappers[Math.min(fieldDropIndex, wrappers.length - 1)];
|
|
20133
|
+
if (!anchor) return null;
|
|
20134
|
+
const rect = anchor.getBoundingClientRect();
|
|
20135
|
+
const atEnd = fieldDropIndex >= wrappers.length;
|
|
20136
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
20137
|
+
"div",
|
|
20138
|
+
{
|
|
20139
|
+
className: "pointer-events-none fixed z-[2147483644]",
|
|
20140
|
+
style: { top: atEnd ? rect.bottom : rect.top, left: rect.left, width: rect.width },
|
|
20141
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(DropIndicator, { direction: "horizontal", state: "dragActive" })
|
|
20142
|
+
}
|
|
20143
|
+
);
|
|
20144
|
+
})() : null,
|
|
20145
|
+
fieldTypePickerOpen && formPickRect && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
20146
|
+
"div",
|
|
20147
|
+
{
|
|
20148
|
+
className: "pointer-events-none fixed z-[2147483645]",
|
|
20149
|
+
style: { top: formPickRect.top + 16, left: formPickRect.left + 24 },
|
|
20150
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(FieldTypePicker, { onPick: handleAddField })
|
|
20151
|
+
}
|
|
20152
|
+
),
|
|
20153
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
20154
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19053
20155
|
FooterContainerChrome,
|
|
19054
20156
|
{
|
|
19055
20157
|
rect: toolbarRect,
|
|
@@ -19057,7 +20159,7 @@ function OhhwellsBridge() {
|
|
|
19057
20159
|
addDisabled: !canAddFooterColumn()
|
|
19058
20160
|
}
|
|
19059
20161
|
),
|
|
19060
|
-
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ (0,
|
|
20162
|
+
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19061
20163
|
ItemInteractionLayer,
|
|
19062
20164
|
{
|
|
19063
20165
|
rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
|
|
@@ -19072,7 +20174,7 @@ function OhhwellsBridge() {
|
|
|
19072
20174
|
onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
|
|
19073
20175
|
onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
|
|
19074
20176
|
itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection,
|
|
19075
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0,
|
|
20177
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19076
20178
|
ItemActionToolbar,
|
|
19077
20179
|
{
|
|
19078
20180
|
onEditLink: openLinkPopoverForSelected,
|
|
@@ -19108,8 +20210,8 @@ function OhhwellsBridge() {
|
|
|
19108
20210
|
) : void 0
|
|
19109
20211
|
}
|
|
19110
20212
|
),
|
|
19111
|
-
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0,
|
|
19112
|
-
/* @__PURE__ */ (0,
|
|
20213
|
+
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
|
|
20214
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19113
20215
|
EditGlowChrome,
|
|
19114
20216
|
{
|
|
19115
20217
|
rect: toolbarRect,
|
|
@@ -19119,7 +20221,7 @@ function OhhwellsBridge() {
|
|
|
19119
20221
|
hideHandle: isItemDragging
|
|
19120
20222
|
}
|
|
19121
20223
|
),
|
|
19122
|
-
/* @__PURE__ */ (0,
|
|
20224
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19123
20225
|
FloatingToolbar,
|
|
19124
20226
|
{
|
|
19125
20227
|
rect: toolbarRect,
|
|
@@ -19132,7 +20234,7 @@ function OhhwellsBridge() {
|
|
|
19132
20234
|
}
|
|
19133
20235
|
)
|
|
19134
20236
|
] }),
|
|
19135
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
20237
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
19136
20238
|
"div",
|
|
19137
20239
|
{
|
|
19138
20240
|
"data-ohw-max-badge": "",
|
|
@@ -19158,7 +20260,7 @@ function OhhwellsBridge() {
|
|
|
19158
20260
|
]
|
|
19159
20261
|
}
|
|
19160
20262
|
),
|
|
19161
|
-
toggleState && !linkPopover && /* @__PURE__ */ (0,
|
|
20263
|
+
toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19162
20264
|
StateToggle,
|
|
19163
20265
|
{
|
|
19164
20266
|
rect: toggleState.rect,
|
|
@@ -19167,15 +20269,15 @@ function OhhwellsBridge() {
|
|
|
19167
20269
|
onStateChange: handleStateChange
|
|
19168
20270
|
}
|
|
19169
20271
|
),
|
|
19170
|
-
sectionGap && !linkPopover && /* @__PURE__ */ (0,
|
|
20272
|
+
sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
19171
20273
|
"div",
|
|
19172
20274
|
{
|
|
19173
20275
|
"data-ohw-section-insert-line": "",
|
|
19174
20276
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
19175
20277
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
19176
20278
|
children: [
|
|
19177
|
-
/* @__PURE__ */ (0,
|
|
19178
|
-
/* @__PURE__ */ (0,
|
|
20279
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
20280
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19179
20281
|
Badge,
|
|
19180
20282
|
{
|
|
19181
20283
|
className: "px-8 py-1 bg-primary hover:bg-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
|
|
@@ -19192,11 +20294,11 @@ function OhhwellsBridge() {
|
|
|
19192
20294
|
children: "Add Section"
|
|
19193
20295
|
}
|
|
19194
20296
|
),
|
|
19195
|
-
/* @__PURE__ */ (0,
|
|
20297
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
19196
20298
|
]
|
|
19197
20299
|
}
|
|
19198
20300
|
),
|
|
19199
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0,
|
|
20301
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19200
20302
|
LinkPopover,
|
|
19201
20303
|
{
|
|
19202
20304
|
panelRef: linkPopoverPanelRef,
|
|
@@ -19213,7 +20315,7 @@ function OhhwellsBridge() {
|
|
|
19213
20315
|
},
|
|
19214
20316
|
linkPopover.key
|
|
19215
20317
|
) : null,
|
|
19216
|
-
floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0,
|
|
20318
|
+
floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19217
20319
|
FloatingPanel,
|
|
19218
20320
|
{
|
|
19219
20321
|
open: true,
|
|
@@ -19223,7 +20325,7 @@ function OhhwellsBridge() {
|
|
|
19223
20325
|
onPositionChange: setFloatingPanelPos,
|
|
19224
20326
|
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
19225
20327
|
onClose: closeFloatingPanelOnly,
|
|
19226
|
-
children: /* @__PURE__ */ (0,
|
|
20328
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19227
20329
|
SocialsDisplayPanel,
|
|
19228
20330
|
{
|
|
19229
20331
|
display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
|
|
@@ -19235,7 +20337,7 @@ function OhhwellsBridge() {
|
|
|
19235
20337
|
)
|
|
19236
20338
|
}
|
|
19237
20339
|
) : null,
|
|
19238
|
-
floatingPanel && floatingPanel.kind === "logo-size" && logoSizeDraft ? /* @__PURE__ */ (0,
|
|
20340
|
+
floatingPanel && floatingPanel.kind === "logo-size" && logoSizeDraft ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19239
20341
|
FloatingPanel,
|
|
19240
20342
|
{
|
|
19241
20343
|
open: true,
|
|
@@ -19245,7 +20347,7 @@ function OhhwellsBridge() {
|
|
|
19245
20347
|
onPositionChange: setFloatingPanelPos,
|
|
19246
20348
|
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
19247
20349
|
onClose: closeFloatingPanelAndDeselect,
|
|
19248
|
-
children: /* @__PURE__ */ (0,
|
|
20350
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19249
20351
|
LogoSizePanel,
|
|
19250
20352
|
{
|
|
19251
20353
|
viewport: editorViewport,
|
|
@@ -19293,10 +20395,10 @@ function OhhwellsBridge() {
|
|
|
19293
20395
|
|
|
19294
20396
|
// src/ui/EmptySection.tsx
|
|
19295
20397
|
var import_link = __toESM(require("next/link"), 1);
|
|
19296
|
-
var
|
|
20398
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
19297
20399
|
function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
|
|
19298
|
-
return /* @__PURE__ */ (0,
|
|
19299
|
-
/* @__PURE__ */ (0,
|
|
20400
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
|
|
20401
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
19300
20402
|
"p",
|
|
19301
20403
|
{
|
|
19302
20404
|
style: {
|
|
@@ -19308,10 +20410,10 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
|
|
|
19308
20410
|
color: "var(--brand-accent)",
|
|
19309
20411
|
marginBottom: "1.5rem"
|
|
19310
20412
|
},
|
|
19311
|
-
children: /* @__PURE__ */ (0,
|
|
20413
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_link.default, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
|
|
19312
20414
|
}
|
|
19313
20415
|
),
|
|
19314
|
-
/* @__PURE__ */ (0,
|
|
20416
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
19315
20417
|
"h1",
|
|
19316
20418
|
{
|
|
19317
20419
|
style: {
|
|
@@ -19326,7 +20428,7 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
|
|
|
19326
20428
|
children: title
|
|
19327
20429
|
}
|
|
19328
20430
|
),
|
|
19329
|
-
/* @__PURE__ */ (0,
|
|
20431
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
19330
20432
|
"p",
|
|
19331
20433
|
{
|
|
19332
20434
|
style: {
|