@ohhwells/bridge 0.1.63-next.175 → 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 +1367 -262
- 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 +1351 -246
- package/dist/index.js.map +1 -1
- package/dist/styles.css +92 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -252,7 +252,10 @@ var BRAND_VAR_PREFIX = "--ohw-brand-";
|
|
|
252
252
|
var BRAND_VAR_NAMES = ["primary", "accent", "light", "dark", "surface", "border", "muted"].map(
|
|
253
253
|
(role) => `${BRAND_VAR_PREFIX}${role}`
|
|
254
254
|
);
|
|
255
|
-
var FONT_VARS = {
|
|
255
|
+
var FONT_VARS = {
|
|
256
|
+
heading: ["--font-heading", "--font-display", "--brand-font-heading"],
|
|
257
|
+
body: ["--font-body", "--brand-font-body"]
|
|
258
|
+
};
|
|
256
259
|
var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
|
|
257
260
|
function brandColorVars(kit) {
|
|
258
261
|
const { dark, primary, accent, light } = kit.palette;
|
|
@@ -6586,6 +6589,7 @@ function getChromeStyle(state) {
|
|
|
6586
6589
|
}
|
|
6587
6590
|
function ClampedToolbarSlot({
|
|
6588
6591
|
placement,
|
|
6592
|
+
align = "center",
|
|
6589
6593
|
children
|
|
6590
6594
|
}) {
|
|
6591
6595
|
const slotRef = (0, import_react7.useRef)(null);
|
|
@@ -6607,7 +6611,7 @@ function ClampedToolbarSlot({
|
|
|
6607
6611
|
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN - half)
|
|
6608
6612
|
);
|
|
6609
6613
|
const offsetX = clampedCenter - centerX;
|
|
6610
|
-
slot.style.transform = `translateX(calc(-50% + ${offsetX}px))`;
|
|
6614
|
+
slot.style.transform = align === "left" ? "none" : `translateX(calc(-50% + ${offsetX}px))`;
|
|
6611
6615
|
};
|
|
6612
6616
|
clamp();
|
|
6613
6617
|
const ro = new ResizeObserver(clamp);
|
|
@@ -6618,19 +6622,20 @@ function ClampedToolbarSlot({
|
|
|
6618
6622
|
ro.disconnect();
|
|
6619
6623
|
window.removeEventListener("resize", clamp);
|
|
6620
6624
|
};
|
|
6621
|
-
}, [placement, children]);
|
|
6625
|
+
}, [placement, children, align]);
|
|
6622
6626
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
6623
6627
|
"div",
|
|
6624
6628
|
{
|
|
6625
6629
|
ref: slotRef,
|
|
6626
6630
|
className: cn(
|
|
6627
|
-
"pointer-events-auto absolute
|
|
6631
|
+
"pointer-events-auto absolute",
|
|
6632
|
+
align === "left" ? "left-0" : "left-1/2",
|
|
6628
6633
|
placement === "top" ? "bottom-full" : "top-full"
|
|
6629
6634
|
),
|
|
6630
6635
|
style: {
|
|
6631
6636
|
marginBottom: placement === "top" ? TOOLBAR_STROKE_GAP : void 0,
|
|
6632
6637
|
marginTop: placement === "bottom" ? TOOLBAR_STROKE_GAP : void 0,
|
|
6633
|
-
transform: "translateX(-50%)"
|
|
6638
|
+
transform: align === "left" ? "none" : "translateX(-50%)"
|
|
6634
6639
|
},
|
|
6635
6640
|
"data-ohw-item-toolbar-anchor": placement,
|
|
6636
6641
|
children
|
|
@@ -6699,6 +6704,7 @@ function ItemInteractionLayer({
|
|
|
6699
6704
|
onItemClick,
|
|
6700
6705
|
itemDragSurface = true,
|
|
6701
6706
|
chromeGap,
|
|
6707
|
+
toolbarAlign = "center",
|
|
6702
6708
|
className
|
|
6703
6709
|
}) {
|
|
6704
6710
|
if (state === "default") return null;
|
|
@@ -6786,8 +6792,8 @@ function ItemInteractionLayer({
|
|
|
6786
6792
|
)
|
|
6787
6793
|
}
|
|
6788
6794
|
),
|
|
6789
|
-
showToolbar && state === "active-top" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ClampedToolbarSlot, { placement: "top", children: toolbar }),
|
|
6790
|
-
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 }),
|
|
6791
6797
|
useDetachedBelowToolbar && toolbarBelowRect ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
6792
6798
|
DetachedBelowToolbarSlot,
|
|
6793
6799
|
{
|
|
@@ -6801,14 +6807,580 @@ function ItemInteractionLayer({
|
|
|
6801
6807
|
);
|
|
6802
6808
|
}
|
|
6803
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
|
+
|
|
6804
7376
|
// src/ui/MediaOverlay.tsx
|
|
6805
7377
|
var React7 = __toESM(require("react"), 1);
|
|
6806
|
-
var
|
|
7378
|
+
var import_lucide_react5 = require("lucide-react");
|
|
6807
7379
|
|
|
6808
7380
|
// src/ui/button.tsx
|
|
6809
7381
|
var React6 = __toESM(require("react"), 1);
|
|
6810
7382
|
var import_radix_ui5 = require("radix-ui");
|
|
6811
|
-
var
|
|
7383
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
6812
7384
|
var buttonVariants = cva(
|
|
6813
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",
|
|
6814
7386
|
{
|
|
@@ -6832,7 +7404,7 @@ var buttonVariants = cva(
|
|
|
6832
7404
|
var Button = React6.forwardRef(
|
|
6833
7405
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
6834
7406
|
const Comp = asChild ? import_radix_ui5.Slot.Root : "button";
|
|
6835
|
-
return /* @__PURE__ */ (0,
|
|
7407
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
6836
7408
|
Comp,
|
|
6837
7409
|
{
|
|
6838
7410
|
ref,
|
|
@@ -6846,7 +7418,7 @@ var Button = React6.forwardRef(
|
|
|
6846
7418
|
Button.displayName = "Button";
|
|
6847
7419
|
|
|
6848
7420
|
// src/ui/MediaOverlay.tsx
|
|
6849
|
-
var
|
|
7421
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
6850
7422
|
var MEDIA_UPLOAD_FADE_MS = 300;
|
|
6851
7423
|
var VIDEO_SETTINGS_BAR_INSET = 8;
|
|
6852
7424
|
var OVERLAY_BUTTON_STYLE = {
|
|
@@ -6904,7 +7476,7 @@ function MediaOverlay({
|
|
|
6904
7476
|
return () => anim.cancel();
|
|
6905
7477
|
}, [isUploading, fadingOut, onFadeOutComplete, hover.key]);
|
|
6906
7478
|
if (isUploading) {
|
|
6907
|
-
return /* @__PURE__ */ (0,
|
|
7479
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
6908
7480
|
"div",
|
|
6909
7481
|
{
|
|
6910
7482
|
ref: skeletonRef,
|
|
@@ -6913,11 +7485,11 @@ function MediaOverlay({
|
|
|
6913
7485
|
"data-ohw-media-skeleton": "",
|
|
6914
7486
|
"aria-hidden": true,
|
|
6915
7487
|
style: { ...box, pointerEvents: "none" },
|
|
6916
|
-
children: /* @__PURE__ */ (0,
|
|
7488
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("style", { children: SKELETON_CSS })
|
|
6917
7489
|
}
|
|
6918
7490
|
);
|
|
6919
7491
|
}
|
|
6920
|
-
const settingsBar = isVideo && !hover.isDragOver ? /* @__PURE__ */ (0,
|
|
7492
|
+
const settingsBar = isVideo && !hover.isDragOver ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
6921
7493
|
"div",
|
|
6922
7494
|
{
|
|
6923
7495
|
"data-ohw-bridge": "",
|
|
@@ -6933,7 +7505,7 @@ function MediaOverlay({
|
|
|
6933
7505
|
},
|
|
6934
7506
|
onClick: (e) => e.stopPropagation(),
|
|
6935
7507
|
children: [
|
|
6936
|
-
/* @__PURE__ */ (0,
|
|
7508
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
6937
7509
|
Button,
|
|
6938
7510
|
{
|
|
6939
7511
|
"data-ohw-media-overlay": "",
|
|
@@ -6948,10 +7520,10 @@ function MediaOverlay({
|
|
|
6948
7520
|
e.stopPropagation();
|
|
6949
7521
|
onVideoSettingsChange?.(hover.key, { autoplay: !autoplay });
|
|
6950
7522
|
},
|
|
6951
|
-
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 })
|
|
6952
7524
|
}
|
|
6953
7525
|
),
|
|
6954
|
-
/* @__PURE__ */ (0,
|
|
7526
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
6955
7527
|
Button,
|
|
6956
7528
|
{
|
|
6957
7529
|
"data-ohw-media-overlay": "",
|
|
@@ -6966,15 +7538,15 @@ function MediaOverlay({
|
|
|
6966
7538
|
e.stopPropagation();
|
|
6967
7539
|
onVideoSettingsChange?.(hover.key, { muted: !muted });
|
|
6968
7540
|
},
|
|
6969
|
-
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 })
|
|
6970
7542
|
}
|
|
6971
7543
|
)
|
|
6972
7544
|
]
|
|
6973
7545
|
}
|
|
6974
7546
|
) : null;
|
|
6975
|
-
return /* @__PURE__ */ (0,
|
|
7547
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
6976
7548
|
settingsBar,
|
|
6977
|
-
/* @__PURE__ */ (0,
|
|
7549
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
6978
7550
|
"div",
|
|
6979
7551
|
{
|
|
6980
7552
|
"data-ohw-bridge": "",
|
|
@@ -6991,7 +7563,7 @@ function MediaOverlay({
|
|
|
6991
7563
|
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
6992
7564
|
},
|
|
6993
7565
|
onClick: () => onReplace(hover.key),
|
|
6994
|
-
children: /* @__PURE__ */ (0,
|
|
7566
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
6995
7567
|
Button,
|
|
6996
7568
|
{
|
|
6997
7569
|
"data-ohw-media-overlay": "",
|
|
@@ -7009,7 +7581,7 @@ function MediaOverlay({
|
|
|
7009
7581
|
onReplace(hover.key);
|
|
7010
7582
|
},
|
|
7011
7583
|
children: [
|
|
7012
|
-
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 }),
|
|
7013
7585
|
isVideo ? "Replace video" : "Replace image"
|
|
7014
7586
|
]
|
|
7015
7587
|
}
|
|
@@ -7020,8 +7592,8 @@ function MediaOverlay({
|
|
|
7020
7592
|
}
|
|
7021
7593
|
|
|
7022
7594
|
// src/ui/CarouselOverlay.tsx
|
|
7023
|
-
var
|
|
7024
|
-
var
|
|
7595
|
+
var import_lucide_react6 = require("lucide-react");
|
|
7596
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
7025
7597
|
var OVERLAY_BUTTON_STYLE2 = {
|
|
7026
7598
|
pointerEvents: "auto",
|
|
7027
7599
|
fontFamily: "Inter, sans-serif",
|
|
@@ -7033,7 +7605,7 @@ function CarouselOverlay({
|
|
|
7033
7605
|
onEdit
|
|
7034
7606
|
}) {
|
|
7035
7607
|
const { rect } = hover;
|
|
7036
|
-
return /* @__PURE__ */ (0,
|
|
7608
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
7037
7609
|
"div",
|
|
7038
7610
|
{
|
|
7039
7611
|
"data-ohw-bridge": "",
|
|
@@ -7051,7 +7623,7 @@ function CarouselOverlay({
|
|
|
7051
7623
|
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
7052
7624
|
},
|
|
7053
7625
|
onClick: () => onEdit(hover.key),
|
|
7054
|
-
children: /* @__PURE__ */ (0,
|
|
7626
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
7055
7627
|
Button,
|
|
7056
7628
|
{
|
|
7057
7629
|
"data-ohw-carousel-overlay": "",
|
|
@@ -7065,7 +7637,7 @@ function CarouselOverlay({
|
|
|
7065
7637
|
onEdit(hover.key);
|
|
7066
7638
|
},
|
|
7067
7639
|
children: [
|
|
7068
|
-
/* @__PURE__ */ (0,
|
|
7640
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react6.GalleryHorizontal, { size: 14 }),
|
|
7069
7641
|
"Edit gallery"
|
|
7070
7642
|
]
|
|
7071
7643
|
}
|
|
@@ -7076,7 +7648,7 @@ function CarouselOverlay({
|
|
|
7076
7648
|
|
|
7077
7649
|
// src/ui/ai-section/AiSectionOverlay.tsx
|
|
7078
7650
|
var import_react8 = require("react");
|
|
7079
|
-
var
|
|
7651
|
+
var import_lucide_react7 = require("lucide-react");
|
|
7080
7652
|
|
|
7081
7653
|
// src/lib/sections.ts
|
|
7082
7654
|
var LINK_PICKER_EXCLUDED_IDS = /* @__PURE__ */ new Set(["navbar", "footer"]);
|
|
@@ -7106,7 +7678,7 @@ function parseSectionsFromHtml(html) {
|
|
|
7106
7678
|
}
|
|
7107
7679
|
|
|
7108
7680
|
// src/ui/ai-section/AiSectionOverlay.tsx
|
|
7109
|
-
var
|
|
7681
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
7110
7682
|
function findSectionElement(instanceId) {
|
|
7111
7683
|
const escaped = CSS.escape(instanceId);
|
|
7112
7684
|
return document.querySelector(`[data-ohw-instance="${escaped}"]`) ?? document.querySelector(`[data-ohw-section="${escaped}"]:not([data-ohw-instance])`);
|
|
@@ -7174,8 +7746,8 @@ function ReviewButton({
|
|
|
7174
7746
|
color
|
|
7175
7747
|
}) {
|
|
7176
7748
|
const [hover, setHover] = (0, import_react8.useState)(false);
|
|
7177
|
-
return /* @__PURE__ */ (0,
|
|
7178
|
-
/* @__PURE__ */ (0,
|
|
7749
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { position: "relative" }, children: [
|
|
7750
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7179
7751
|
"button",
|
|
7180
7752
|
{
|
|
7181
7753
|
type: "button",
|
|
@@ -7199,7 +7771,7 @@ function ReviewButton({
|
|
|
7199
7771
|
children
|
|
7200
7772
|
}
|
|
7201
7773
|
),
|
|
7202
|
-
hover && /* @__PURE__ */ (0,
|
|
7774
|
+
hover && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7203
7775
|
"div",
|
|
7204
7776
|
{
|
|
7205
7777
|
style: {
|
|
@@ -7365,8 +7937,8 @@ function AiSectionOverlay({
|
|
|
7365
7937
|
isLast
|
|
7366
7938
|
});
|
|
7367
7939
|
}, [activeSelectionId, selectionRect, postToParent2]);
|
|
7368
|
-
return /* @__PURE__ */ (0,
|
|
7369
|
-
hoverRect && /* @__PURE__ */ (0,
|
|
7940
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
7941
|
+
hoverRect && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7370
7942
|
"div",
|
|
7371
7943
|
{
|
|
7372
7944
|
"data-ohw-ai-section-hover": "",
|
|
@@ -7384,7 +7956,7 @@ function AiSectionOverlay({
|
|
|
7384
7956
|
}
|
|
7385
7957
|
}
|
|
7386
7958
|
),
|
|
7387
|
-
selectionRect && /* @__PURE__ */ (0,
|
|
7959
|
+
selectionRect && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7388
7960
|
"div",
|
|
7389
7961
|
{
|
|
7390
7962
|
"data-ohw-ai-section-selected": "",
|
|
@@ -7402,7 +7974,7 @@ function AiSectionOverlay({
|
|
|
7402
7974
|
}
|
|
7403
7975
|
}
|
|
7404
7976
|
),
|
|
7405
|
-
reviewRect && /* @__PURE__ */ (0,
|
|
7977
|
+
reviewRect && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
7406
7978
|
"div",
|
|
7407
7979
|
{
|
|
7408
7980
|
"data-ohw-ai-review": "",
|
|
@@ -7424,7 +7996,7 @@ function AiSectionOverlay({
|
|
|
7424
7996
|
cursor: "default"
|
|
7425
7997
|
},
|
|
7426
7998
|
onClick: (e) => e.stopPropagation(),
|
|
7427
|
-
children: !reviewButtonsHidden && /* @__PURE__ */ (0,
|
|
7999
|
+
children: !reviewButtonsHidden && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
7428
8000
|
"div",
|
|
7429
8001
|
{
|
|
7430
8002
|
style: {
|
|
@@ -7437,8 +8009,8 @@ function AiSectionOverlay({
|
|
|
7437
8009
|
paddingTop: 12
|
|
7438
8010
|
},
|
|
7439
8011
|
children: [
|
|
7440
|
-
/* @__PURE__ */ (0,
|
|
7441
|
-
/* @__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 }) })
|
|
7442
8014
|
]
|
|
7443
8015
|
}
|
|
7444
8016
|
)
|
|
@@ -7797,23 +8369,23 @@ var import_react12 = require("react");
|
|
|
7797
8369
|
// src/ui/dialog.tsx
|
|
7798
8370
|
var React8 = __toESM(require("react"), 1);
|
|
7799
8371
|
var import_radix_ui6 = require("radix-ui");
|
|
7800
|
-
var
|
|
7801
|
-
var
|
|
8372
|
+
var import_lucide_react8 = require("lucide-react");
|
|
8373
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
7802
8374
|
function Dialog2({
|
|
7803
8375
|
...props
|
|
7804
8376
|
}) {
|
|
7805
|
-
return /* @__PURE__ */ (0,
|
|
8377
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
7806
8378
|
}
|
|
7807
8379
|
function DialogPortal({
|
|
7808
8380
|
...props
|
|
7809
8381
|
}) {
|
|
7810
|
-
return /* @__PURE__ */ (0,
|
|
8382
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
|
|
7811
8383
|
}
|
|
7812
8384
|
function DialogOverlay({
|
|
7813
8385
|
className,
|
|
7814
8386
|
...props
|
|
7815
8387
|
}) {
|
|
7816
|
-
return /* @__PURE__ */ (0,
|
|
8388
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
7817
8389
|
import_radix_ui6.Dialog.Overlay,
|
|
7818
8390
|
{
|
|
7819
8391
|
"data-slot": "dialog-overlay",
|
|
@@ -7826,9 +8398,9 @@ function DialogOverlay({
|
|
|
7826
8398
|
var DialogContent = React8.forwardRef(
|
|
7827
8399
|
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
7828
8400
|
const positionMode = container ? "absolute" : "fixed";
|
|
7829
|
-
return /* @__PURE__ */ (0,
|
|
7830
|
-
/* @__PURE__ */ (0,
|
|
7831
|
-
/* @__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)(
|
|
7832
8404
|
import_radix_ui6.Dialog.Content,
|
|
7833
8405
|
{
|
|
7834
8406
|
ref,
|
|
@@ -7844,13 +8416,13 @@ var DialogContent = React8.forwardRef(
|
|
|
7844
8416
|
...props,
|
|
7845
8417
|
children: [
|
|
7846
8418
|
children,
|
|
7847
|
-
showCloseButton ? /* @__PURE__ */ (0,
|
|
8419
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
7848
8420
|
import_radix_ui6.Dialog.Close,
|
|
7849
8421
|
{
|
|
7850
8422
|
type: "button",
|
|
7851
8423
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
7852
8424
|
"aria-label": "Close",
|
|
7853
|
-
children: /* @__PURE__ */ (0,
|
|
8425
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.X, { size: 16, "aria-hidden": true })
|
|
7854
8426
|
}
|
|
7855
8427
|
) : null
|
|
7856
8428
|
]
|
|
@@ -7864,13 +8436,13 @@ function DialogHeader({
|
|
|
7864
8436
|
className,
|
|
7865
8437
|
...props
|
|
7866
8438
|
}) {
|
|
7867
|
-
return /* @__PURE__ */ (0,
|
|
8439
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
7868
8440
|
}
|
|
7869
8441
|
function DialogFooter({
|
|
7870
8442
|
className,
|
|
7871
8443
|
...props
|
|
7872
8444
|
}) {
|
|
7873
|
-
return /* @__PURE__ */ (0,
|
|
8445
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
7874
8446
|
"div",
|
|
7875
8447
|
{
|
|
7876
8448
|
className: cn("flex items-center justify-end gap-2", className),
|
|
@@ -7878,7 +8450,7 @@ function DialogFooter({
|
|
|
7878
8450
|
}
|
|
7879
8451
|
);
|
|
7880
8452
|
}
|
|
7881
|
-
var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
8453
|
+
var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
7882
8454
|
import_radix_ui6.Dialog.Title,
|
|
7883
8455
|
{
|
|
7884
8456
|
ref,
|
|
@@ -7890,7 +8462,7 @@ var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
7890
8462
|
}
|
|
7891
8463
|
));
|
|
7892
8464
|
DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
|
|
7893
|
-
var DialogDescription = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
8465
|
+
var DialogDescription = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
7894
8466
|
import_radix_ui6.Dialog.Description,
|
|
7895
8467
|
{
|
|
7896
8468
|
ref,
|
|
@@ -7902,63 +8474,63 @@ DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
|
|
|
7902
8474
|
var DialogClose = import_radix_ui6.Dialog.Close;
|
|
7903
8475
|
|
|
7904
8476
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
7905
|
-
var
|
|
8477
|
+
var import_lucide_react12 = require("lucide-react");
|
|
7906
8478
|
|
|
7907
8479
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
7908
|
-
var
|
|
7909
|
-
var
|
|
8480
|
+
var import_lucide_react9 = require("lucide-react");
|
|
8481
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
7910
8482
|
function DestinationBreadcrumb({
|
|
7911
8483
|
pageTitle,
|
|
7912
8484
|
sectionLabel
|
|
7913
8485
|
}) {
|
|
7914
|
-
return /* @__PURE__ */ (0,
|
|
7915
|
-
/* @__PURE__ */ (0,
|
|
7916
|
-
/* @__PURE__ */ (0,
|
|
7917
|
-
/* @__PURE__ */ (0,
|
|
7918
|
-
/* @__PURE__ */ (0,
|
|
7919
|
-
/* @__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 })
|
|
7920
8492
|
] }),
|
|
7921
|
-
/* @__PURE__ */ (0,
|
|
7922
|
-
|
|
8493
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
8494
|
+
import_lucide_react9.ArrowRight,
|
|
7923
8495
|
{
|
|
7924
8496
|
size: 16,
|
|
7925
8497
|
className: "shrink-0 text-muted-foreground",
|
|
7926
8498
|
"aria-hidden": true
|
|
7927
8499
|
}
|
|
7928
8500
|
),
|
|
7929
|
-
/* @__PURE__ */ (0,
|
|
7930
|
-
/* @__PURE__ */ (0,
|
|
7931
|
-
|
|
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,
|
|
7932
8504
|
{
|
|
7933
8505
|
size: 16,
|
|
7934
8506
|
className: "shrink-0 text-foreground",
|
|
7935
8507
|
"aria-hidden": true
|
|
7936
8508
|
}
|
|
7937
8509
|
),
|
|
7938
|
-
/* @__PURE__ */ (0,
|
|
8510
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
7939
8511
|
] })
|
|
7940
8512
|
] })
|
|
7941
8513
|
] });
|
|
7942
8514
|
}
|
|
7943
8515
|
|
|
7944
8516
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
7945
|
-
var
|
|
7946
|
-
var
|
|
8517
|
+
var import_lucide_react10 = require("lucide-react");
|
|
8518
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
7947
8519
|
function SectionTreeItem({
|
|
7948
8520
|
section,
|
|
7949
8521
|
onSelect,
|
|
7950
8522
|
selected
|
|
7951
8523
|
}) {
|
|
7952
8524
|
const interactive = Boolean(onSelect);
|
|
7953
|
-
return /* @__PURE__ */ (0,
|
|
7954
|
-
/* @__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)(
|
|
7955
8527
|
"div",
|
|
7956
8528
|
{
|
|
7957
8529
|
className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
7958
8530
|
"aria-hidden": true
|
|
7959
8531
|
}
|
|
7960
8532
|
),
|
|
7961
|
-
/* @__PURE__ */ (0,
|
|
8533
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
7962
8534
|
"div",
|
|
7963
8535
|
{
|
|
7964
8536
|
role: interactive ? "button" : void 0,
|
|
@@ -7976,15 +8548,15 @@ function SectionTreeItem({
|
|
|
7976
8548
|
interactive && selected && "border-primary"
|
|
7977
8549
|
),
|
|
7978
8550
|
children: [
|
|
7979
|
-
/* @__PURE__ */ (0,
|
|
7980
|
-
|
|
8551
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
8552
|
+
import_lucide_react10.GalleryVertical,
|
|
7981
8553
|
{
|
|
7982
8554
|
size: 16,
|
|
7983
8555
|
className: "shrink-0 text-foreground",
|
|
7984
8556
|
"aria-hidden": true
|
|
7985
8557
|
}
|
|
7986
8558
|
),
|
|
7987
|
-
/* @__PURE__ */ (0,
|
|
8559
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
7988
8560
|
]
|
|
7989
8561
|
}
|
|
7990
8562
|
)
|
|
@@ -7996,10 +8568,10 @@ var import_react9 = require("react");
|
|
|
7996
8568
|
|
|
7997
8569
|
// src/ui/input.tsx
|
|
7998
8570
|
var React9 = __toESM(require("react"), 1);
|
|
7999
|
-
var
|
|
8571
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
8000
8572
|
var Input = React9.forwardRef(
|
|
8001
8573
|
({ className, type, ...props }, ref) => {
|
|
8002
|
-
return /* @__PURE__ */ (0,
|
|
8574
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
8003
8575
|
"input",
|
|
8004
8576
|
{
|
|
8005
8577
|
type,
|
|
@@ -8018,9 +8590,9 @@ Input.displayName = "Input";
|
|
|
8018
8590
|
|
|
8019
8591
|
// src/ui/label.tsx
|
|
8020
8592
|
var import_radix_ui7 = require("radix-ui");
|
|
8021
|
-
var
|
|
8593
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
8022
8594
|
function Label({ className, ...props }) {
|
|
8023
|
-
return /* @__PURE__ */ (0,
|
|
8595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8024
8596
|
import_radix_ui7.Label.Root,
|
|
8025
8597
|
{
|
|
8026
8598
|
"data-slot": "label",
|
|
@@ -8031,12 +8603,12 @@ function Label({ className, ...props }) {
|
|
|
8031
8603
|
}
|
|
8032
8604
|
|
|
8033
8605
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
8034
|
-
var
|
|
8035
|
-
var
|
|
8606
|
+
var import_lucide_react11 = require("lucide-react");
|
|
8607
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
8036
8608
|
function FieldChevron({
|
|
8037
8609
|
onClick
|
|
8038
8610
|
}) {
|
|
8039
|
-
return /* @__PURE__ */ (0,
|
|
8611
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8040
8612
|
"button",
|
|
8041
8613
|
{
|
|
8042
8614
|
type: "button",
|
|
@@ -8044,7 +8616,7 @@ function FieldChevron({
|
|
|
8044
8616
|
onClick,
|
|
8045
8617
|
"aria-label": "Open page list",
|
|
8046
8618
|
tabIndex: -1,
|
|
8047
|
-
children: /* @__PURE__ */ (0,
|
|
8619
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.ChevronDown, { size: 16 })
|
|
8048
8620
|
}
|
|
8049
8621
|
);
|
|
8050
8622
|
}
|
|
@@ -8105,19 +8677,19 @@ function UrlOrPageInput({
|
|
|
8105
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]",
|
|
8106
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"
|
|
8107
8679
|
);
|
|
8108
|
-
return /* @__PURE__ */ (0,
|
|
8109
|
-
/* @__PURE__ */ (0,
|
|
8110
|
-
/* @__PURE__ */ (0,
|
|
8111
|
-
/* @__PURE__ */ (0,
|
|
8112
|
-
selectedPage ? /* @__PURE__ */ (0,
|
|
8113
|
-
|
|
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,
|
|
8114
8686
|
{
|
|
8115
8687
|
size: 16,
|
|
8116
8688
|
className: "shrink-0 text-foreground",
|
|
8117
8689
|
"aria-hidden": true
|
|
8118
8690
|
}
|
|
8119
8691
|
) }) : null,
|
|
8120
|
-
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)(
|
|
8121
8693
|
Input,
|
|
8122
8694
|
{
|
|
8123
8695
|
ref: inputRef,
|
|
@@ -8143,7 +8715,7 @@ function UrlOrPageInput({
|
|
|
8143
8715
|
)
|
|
8144
8716
|
}
|
|
8145
8717
|
),
|
|
8146
|
-
selectedPage && !readOnly ? /* @__PURE__ */ (0,
|
|
8718
|
+
selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8147
8719
|
"button",
|
|
8148
8720
|
{
|
|
8149
8721
|
type: "button",
|
|
@@ -8151,26 +8723,26 @@ function UrlOrPageInput({
|
|
|
8151
8723
|
onMouseDown: clearSelection,
|
|
8152
8724
|
"aria-label": "Clear selected page",
|
|
8153
8725
|
tabIndex: -1,
|
|
8154
|
-
children: /* @__PURE__ */ (0,
|
|
8726
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.X, { size: 16, "aria-hidden": true })
|
|
8155
8727
|
}
|
|
8156
8728
|
) : null,
|
|
8157
|
-
!readOnly ? /* @__PURE__ */ (0,
|
|
8729
|
+
!readOnly ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
|
|
8158
8730
|
] }),
|
|
8159
|
-
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0,
|
|
8731
|
+
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8160
8732
|
"div",
|
|
8161
8733
|
{
|
|
8162
8734
|
"data-ohw-link-page-dropdown": "",
|
|
8163
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",
|
|
8164
8736
|
onMouseDown: (e) => e.preventDefault(),
|
|
8165
|
-
children: filteredPages.map((page) => /* @__PURE__ */ (0,
|
|
8737
|
+
children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8166
8738
|
"button",
|
|
8167
8739
|
{
|
|
8168
8740
|
type: "button",
|
|
8169
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",
|
|
8170
8742
|
onClick: () => onPageSelect(page),
|
|
8171
8743
|
children: [
|
|
8172
|
-
/* @__PURE__ */ (0,
|
|
8173
|
-
/* @__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 })
|
|
8174
8746
|
]
|
|
8175
8747
|
},
|
|
8176
8748
|
page.path
|
|
@@ -8178,34 +8750,34 @@ function UrlOrPageInput({
|
|
|
8178
8750
|
}
|
|
8179
8751
|
) : null
|
|
8180
8752
|
] }),
|
|
8181
|
-
urlError ? /* @__PURE__ */ (0,
|
|
8753
|
+
urlError ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
|
|
8182
8754
|
] });
|
|
8183
8755
|
}
|
|
8184
8756
|
|
|
8185
8757
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
8186
|
-
var
|
|
8758
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
8187
8759
|
function LinkEditorPanel({ state, onClose }) {
|
|
8188
8760
|
const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
|
|
8189
|
-
return /* @__PURE__ */ (0,
|
|
8190
|
-
/* @__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)(
|
|
8191
8763
|
"button",
|
|
8192
8764
|
{
|
|
8193
8765
|
type: "button",
|
|
8194
8766
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
|
|
8195
8767
|
"aria-label": "Close",
|
|
8196
8768
|
onClick: onClose,
|
|
8197
|
-
children: /* @__PURE__ */ (0,
|
|
8769
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react12.X, { size: 16, "aria-hidden": true })
|
|
8198
8770
|
}
|
|
8199
8771
|
) }),
|
|
8200
|
-
/* @__PURE__ */ (0,
|
|
8201
|
-
/* @__PURE__ */ (0,
|
|
8202
|
-
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)(
|
|
8203
8775
|
DestinationBreadcrumb,
|
|
8204
8776
|
{
|
|
8205
8777
|
pageTitle: state.selectedPage.title,
|
|
8206
8778
|
sectionLabel: state.selectedSection.label
|
|
8207
8779
|
}
|
|
8208
|
-
) : /* @__PURE__ */ (0,
|
|
8780
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
8209
8781
|
UrlOrPageInput,
|
|
8210
8782
|
{
|
|
8211
8783
|
value: state.searchValue,
|
|
@@ -8218,8 +8790,8 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
8218
8790
|
urlError: state.urlError
|
|
8219
8791
|
}
|
|
8220
8792
|
),
|
|
8221
|
-
state.showChooseSection ? /* @__PURE__ */ (0,
|
|
8222
|
-
/* @__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)(
|
|
8223
8795
|
Button,
|
|
8224
8796
|
{
|
|
8225
8797
|
type: "button",
|
|
@@ -8230,15 +8802,15 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
8230
8802
|
children: "Choose a section"
|
|
8231
8803
|
}
|
|
8232
8804
|
),
|
|
8233
|
-
/* @__PURE__ */ (0,
|
|
8234
|
-
/* @__PURE__ */ (0,
|
|
8235
|
-
/* @__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." })
|
|
8236
8808
|
] })
|
|
8237
8809
|
] }) : null,
|
|
8238
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0,
|
|
8810
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
8239
8811
|
] }),
|
|
8240
|
-
/* @__PURE__ */ (0,
|
|
8241
|
-
/* @__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)(
|
|
8242
8814
|
Button,
|
|
8243
8815
|
{
|
|
8244
8816
|
type: "button",
|
|
@@ -8253,7 +8825,7 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
8253
8825
|
children: state.secondaryLabel
|
|
8254
8826
|
}
|
|
8255
8827
|
),
|
|
8256
|
-
/* @__PURE__ */ (0,
|
|
8828
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
8257
8829
|
Button,
|
|
8258
8830
|
{
|
|
8259
8831
|
type: "button",
|
|
@@ -8274,9 +8846,9 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
8274
8846
|
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
8275
8847
|
var import_react10 = require("react");
|
|
8276
8848
|
var import_react_dom2 = require("react-dom");
|
|
8277
|
-
var
|
|
8849
|
+
var import_lucide_react13 = require("lucide-react");
|
|
8278
8850
|
var import_navigation2 = require("next/navigation");
|
|
8279
|
-
var
|
|
8851
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
8280
8852
|
var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
|
|
8281
8853
|
function rectsEqual(a, b) {
|
|
8282
8854
|
if (a.size !== b.size) return false;
|
|
@@ -8505,7 +9077,7 @@ function SectionPickerOverlay({
|
|
|
8505
9077
|
const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
|
|
8506
9078
|
if (!portalRoot) return null;
|
|
8507
9079
|
return (0, import_react_dom2.createPortal)(
|
|
8508
|
-
/* @__PURE__ */ (0,
|
|
9080
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
8509
9081
|
"div",
|
|
8510
9082
|
{
|
|
8511
9083
|
"data-ohw-section-picker": "",
|
|
@@ -8515,12 +9087,12 @@ function SectionPickerOverlay({
|
|
|
8515
9087
|
role: "dialog",
|
|
8516
9088
|
"aria-label": "Choose a section",
|
|
8517
9089
|
children: [
|
|
8518
|
-
/* @__PURE__ */ (0,
|
|
9090
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8519
9091
|
"div",
|
|
8520
9092
|
{
|
|
8521
9093
|
className: "pointer-events-auto fixed left-5 z-[2]",
|
|
8522
9094
|
style: { top: chromeClip.top + 20 },
|
|
8523
|
-
children: /* @__PURE__ */ (0,
|
|
9095
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
8524
9096
|
Button,
|
|
8525
9097
|
{
|
|
8526
9098
|
type: "button",
|
|
@@ -8529,14 +9101,14 @@ function SectionPickerOverlay({
|
|
|
8529
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",
|
|
8530
9102
|
onClick: onBack,
|
|
8531
9103
|
children: [
|
|
8532
|
-
/* @__PURE__ */ (0,
|
|
9104
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react13.ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
8533
9105
|
"Back"
|
|
8534
9106
|
]
|
|
8535
9107
|
}
|
|
8536
9108
|
)
|
|
8537
9109
|
}
|
|
8538
9110
|
),
|
|
8539
|
-
/* @__PURE__ */ (0,
|
|
9111
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8540
9112
|
"div",
|
|
8541
9113
|
{
|
|
8542
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",
|
|
@@ -8549,7 +9121,7 @@ function SectionPickerOverlay({
|
|
|
8549
9121
|
children: "Click on section to select"
|
|
8550
9122
|
}
|
|
8551
9123
|
),
|
|
8552
|
-
!isOnTargetPage ? /* @__PURE__ */ (0,
|
|
9124
|
+
!isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8553
9125
|
"div",
|
|
8554
9126
|
{
|
|
8555
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",
|
|
@@ -8557,14 +9129,14 @@ function SectionPickerOverlay({
|
|
|
8557
9129
|
children: "Loading page preview\u2026"
|
|
8558
9130
|
}
|
|
8559
9131
|
) : null,
|
|
8560
|
-
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,
|
|
8561
9133
|
isOnTargetPage ? liveSections.map((section) => {
|
|
8562
9134
|
const rect = rects.get(section.id);
|
|
8563
9135
|
if (!rect || rect.width <= 0 || rect.height <= 0) return null;
|
|
8564
9136
|
const isSelected = selectedId === section.id;
|
|
8565
9137
|
const isHovered = hoveredId === section.id;
|
|
8566
9138
|
const isLit = isSelected || isHovered;
|
|
8567
|
-
return /* @__PURE__ */ (0,
|
|
9139
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
8568
9140
|
"button",
|
|
8569
9141
|
{
|
|
8570
9142
|
type: "button",
|
|
@@ -8579,7 +9151,7 @@ function SectionPickerOverlay({
|
|
|
8579
9151
|
"aria-label": `Select section ${section.label}`,
|
|
8580
9152
|
onClick: () => handleSelect(section),
|
|
8581
9153
|
children: [
|
|
8582
|
-
isLit ? /* @__PURE__ */ (0,
|
|
9154
|
+
isLit ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8583
9155
|
"span",
|
|
8584
9156
|
{
|
|
8585
9157
|
className: "pointer-events-none absolute",
|
|
@@ -8592,13 +9164,13 @@ function SectionPickerOverlay({
|
|
|
8592
9164
|
"aria-hidden": true
|
|
8593
9165
|
}
|
|
8594
9166
|
) : null,
|
|
8595
|
-
isSelected ? /* @__PURE__ */ (0,
|
|
9167
|
+
isSelected ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8596
9168
|
"span",
|
|
8597
9169
|
{
|
|
8598
9170
|
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
8599
9171
|
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
8600
9172
|
"aria-hidden": true,
|
|
8601
|
-
children: /* @__PURE__ */ (0,
|
|
9173
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react13.Check, { className: "size-5" })
|
|
8602
9174
|
}
|
|
8603
9175
|
) : null
|
|
8604
9176
|
]
|
|
@@ -8778,7 +9350,7 @@ function useLinkModalState({
|
|
|
8778
9350
|
}
|
|
8779
9351
|
|
|
8780
9352
|
// src/ui/link-modal/LinkPopover.tsx
|
|
8781
|
-
var
|
|
9353
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
8782
9354
|
function postToParent(data) {
|
|
8783
9355
|
window.parent?.postMessage(data, "*");
|
|
8784
9356
|
}
|
|
@@ -8874,15 +9446,15 @@ function LinkPopover({
|
|
|
8874
9446
|
);
|
|
8875
9447
|
};
|
|
8876
9448
|
}, [open, sectionPickerActive]);
|
|
8877
|
-
return /* @__PURE__ */ (0,
|
|
8878
|
-
/* @__PURE__ */ (0,
|
|
9449
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
9450
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
8879
9451
|
Dialog2,
|
|
8880
9452
|
{
|
|
8881
9453
|
open: open && !sectionPickerActive,
|
|
8882
9454
|
onOpenChange: (next) => {
|
|
8883
9455
|
if (!next) onClose?.();
|
|
8884
9456
|
},
|
|
8885
|
-
children: /* @__PURE__ */ (0,
|
|
9457
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
8886
9458
|
DialogContent,
|
|
8887
9459
|
{
|
|
8888
9460
|
ref: panelRef,
|
|
@@ -8892,12 +9464,12 @@ function LinkPopover({
|
|
|
8892
9464
|
"data-ohw-bridge": "",
|
|
8893
9465
|
showCloseButton: false,
|
|
8894
9466
|
className: "gap-0 p-0 w-full max-w-[448px] pointer-events-auto z-[2147483646] overflow-visible",
|
|
8895
|
-
children: /* @__PURE__ */ (0,
|
|
9467
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(LinkEditorPanel, { state, onClose })
|
|
8896
9468
|
}
|
|
8897
9469
|
)
|
|
8898
9470
|
}
|
|
8899
9471
|
),
|
|
8900
|
-
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0,
|
|
9472
|
+
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
8901
9473
|
SectionPickerOverlay,
|
|
8902
9474
|
{
|
|
8903
9475
|
pagePath: state.selectedPage.path,
|
|
@@ -10123,13 +10695,14 @@ function listSocialItems(row) {
|
|
|
10123
10695
|
return isSocialItem(anchor) ? anchor : null;
|
|
10124
10696
|
}).filter((item) => item !== null);
|
|
10125
10697
|
}
|
|
10126
|
-
function socialRowUnit(item) {
|
|
10127
|
-
const row = findSocialsRow(item);
|
|
10698
|
+
function socialRowUnit(item, knownRow) {
|
|
10699
|
+
const row = knownRow ?? findSocialsRow(item);
|
|
10700
|
+
if (!row || !row.contains(item)) return null;
|
|
10128
10701
|
let node = item;
|
|
10129
10702
|
while (node.parentElement && node.parentElement !== row) {
|
|
10130
10703
|
node = node.parentElement;
|
|
10131
10704
|
}
|
|
10132
|
-
return node;
|
|
10705
|
+
return node.parentElement === row ? node : null;
|
|
10133
10706
|
}
|
|
10134
10707
|
function listSocialsRows(root = document) {
|
|
10135
10708
|
const rows = /* @__PURE__ */ new Set();
|
|
@@ -10148,7 +10721,8 @@ function markSocialsRows(root = document) {
|
|
|
10148
10721
|
listSocialsRows(root).forEach((row) => {
|
|
10149
10722
|
row.setAttribute(SOCIALS_ROW_ATTR, "");
|
|
10150
10723
|
const items = listSocialItems(row);
|
|
10151
|
-
|
|
10724
|
+
const firstUnit = items[0] ? socialRowUnit(items[0], row) : null;
|
|
10725
|
+
if (firstUnit) rowTemplates.set(rowKeyOf(row), firstUnit.outerHTML);
|
|
10152
10726
|
items.forEach((item, index) => {
|
|
10153
10727
|
item.setAttribute(SOCIALS_ITEM_ATTR, String(index));
|
|
10154
10728
|
const iconKey = socialIconKey(item);
|
|
@@ -10292,7 +10866,8 @@ function removeSocialItem(item, content) {
|
|
|
10292
10866
|
const previousContent = Object.fromEntries(
|
|
10293
10867
|
removedKeys.filter((key) => key in content).map((key) => [key, content[key]])
|
|
10294
10868
|
);
|
|
10295
|
-
const unit = socialRowUnit(item);
|
|
10869
|
+
const unit = socialRowUnit(item, row);
|
|
10870
|
+
if (!unit) return null;
|
|
10296
10871
|
const nextSibling = unit.nextElementSibling;
|
|
10297
10872
|
unit.remove();
|
|
10298
10873
|
markSocialsRows(row.ownerDocument);
|
|
@@ -10315,7 +10890,9 @@ function applySocialsOrder(order, root = document) {
|
|
|
10315
10890
|
const byKey = new Map(listSocialItems(row).map((item) => [socialHrefKey(item), item]));
|
|
10316
10891
|
wanted.forEach((key) => {
|
|
10317
10892
|
const item = byKey.get(key);
|
|
10318
|
-
if (item)
|
|
10893
|
+
if (!item) return;
|
|
10894
|
+
const unit = socialRowUnit(item, row);
|
|
10895
|
+
if (unit) row.appendChild(unit);
|
|
10319
10896
|
});
|
|
10320
10897
|
});
|
|
10321
10898
|
markSocialsRows(root);
|
|
@@ -10345,7 +10922,7 @@ function reconcileSocialsFromContent(content, root = document) {
|
|
|
10345
10922
|
});
|
|
10346
10923
|
if (surviving.length) {
|
|
10347
10924
|
present.forEach((item) => {
|
|
10348
|
-
if (!surviving.includes(item)) socialRowUnit(item)
|
|
10925
|
+
if (!surviving.includes(item)) socialRowUnit(item)?.remove();
|
|
10349
10926
|
});
|
|
10350
10927
|
}
|
|
10351
10928
|
});
|
|
@@ -11681,8 +12258,8 @@ function addFooterColumnWithPersist({
|
|
|
11681
12258
|
|
|
11682
12259
|
// src/ui/FloatingPanel.tsx
|
|
11683
12260
|
var import_react13 = require("react");
|
|
11684
|
-
var
|
|
11685
|
-
var
|
|
12261
|
+
var import_lucide_react14 = require("lucide-react");
|
|
12262
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
11686
12263
|
var PANEL_WIDTH = 256;
|
|
11687
12264
|
var EDGE_MARGIN = 16;
|
|
11688
12265
|
function getVisibleClip(parentScroll) {
|
|
@@ -11797,7 +12374,7 @@ function FloatingPanel({
|
|
|
11797
12374
|
}, [open]);
|
|
11798
12375
|
(0, import_react13.useEffect)(() => () => document.documentElement.removeAttribute("data-ohw-panel-dragging"), []);
|
|
11799
12376
|
if (!open) return null;
|
|
11800
|
-
return /* @__PURE__ */ (0,
|
|
12377
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
11801
12378
|
"div",
|
|
11802
12379
|
{
|
|
11803
12380
|
ref: panelRef,
|
|
@@ -11814,7 +12391,7 @@ function FloatingPanel({
|
|
|
11814
12391
|
onPointerDown: (e) => e.stopPropagation(),
|
|
11815
12392
|
onClick: (e) => e.stopPropagation(),
|
|
11816
12393
|
children: [
|
|
11817
|
-
/* @__PURE__ */ (0,
|
|
12394
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
11818
12395
|
"div",
|
|
11819
12396
|
{
|
|
11820
12397
|
"data-ohw-floating-panel-header": "",
|
|
@@ -11824,14 +12401,14 @@ function FloatingPanel({
|
|
|
11824
12401
|
onPointerUp: endDrag,
|
|
11825
12402
|
onPointerCancel: endDrag,
|
|
11826
12403
|
children: [
|
|
11827
|
-
/* @__PURE__ */ (0,
|
|
11828
|
-
/* @__PURE__ */ (0,
|
|
11829
|
-
icon ? /* @__PURE__ */ (0,
|
|
11830
|
-
/* @__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 })
|
|
11831
12408
|
] }),
|
|
11832
|
-
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
|
|
11833
12410
|
] }),
|
|
11834
|
-
/* @__PURE__ */ (0,
|
|
12411
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
11835
12412
|
"button",
|
|
11836
12413
|
{
|
|
11837
12414
|
type: "button",
|
|
@@ -11843,13 +12420,13 @@ function FloatingPanel({
|
|
|
11843
12420
|
onClose();
|
|
11844
12421
|
},
|
|
11845
12422
|
onPointerDown: (e) => e.stopPropagation(),
|
|
11846
|
-
children: /* @__PURE__ */ (0,
|
|
12423
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.X, { size: 16, "aria-hidden": true })
|
|
11847
12424
|
}
|
|
11848
12425
|
)
|
|
11849
12426
|
]
|
|
11850
12427
|
}
|
|
11851
12428
|
),
|
|
11852
|
-
/* @__PURE__ */ (0,
|
|
12429
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
11853
12430
|
"div",
|
|
11854
12431
|
{
|
|
11855
12432
|
"data-ohw-floating-panel-body": "",
|
|
@@ -11863,30 +12440,30 @@ function FloatingPanel({
|
|
|
11863
12440
|
}
|
|
11864
12441
|
|
|
11865
12442
|
// src/ui/logo-size-panel.tsx
|
|
11866
|
-
var
|
|
11867
|
-
var
|
|
12443
|
+
var import_lucide_react15 = require("lucide-react");
|
|
12444
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
11868
12445
|
function SizeSlider({
|
|
11869
12446
|
value,
|
|
11870
12447
|
onChange
|
|
11871
12448
|
}) {
|
|
11872
12449
|
const pct = (value - LOGO_SIZE_MIN) / (LOGO_SIZE_MAX - LOGO_SIZE_MIN) * 100;
|
|
11873
|
-
return /* @__PURE__ */ (0,
|
|
11874
|
-
/* @__PURE__ */ (0,
|
|
11875
|
-
/* @__PURE__ */ (0,
|
|
11876
|
-
/* @__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: [
|
|
11877
12454
|
value,
|
|
11878
12455
|
" px"
|
|
11879
12456
|
] })
|
|
11880
12457
|
] }),
|
|
11881
|
-
/* @__PURE__ */ (0,
|
|
11882
|
-
/* @__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)(
|
|
11883
12460
|
"div",
|
|
11884
12461
|
{
|
|
11885
12462
|
className: "absolute inset-y-0 left-0 rounded-full bg-primary",
|
|
11886
12463
|
style: { width: `${pct}%` }
|
|
11887
12464
|
}
|
|
11888
12465
|
),
|
|
11889
|
-
/* @__PURE__ */ (0,
|
|
12466
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11890
12467
|
"input",
|
|
11891
12468
|
{
|
|
11892
12469
|
type: "range",
|
|
@@ -11923,14 +12500,14 @@ function LogoSizePanel({
|
|
|
11923
12500
|
const showFollowing = viewport === "mobile" && mobileFollowing;
|
|
11924
12501
|
const showMobileSlider = viewport === "mobile" && !mobileFollowing;
|
|
11925
12502
|
const showDesktopSlider = viewport === "desktop";
|
|
11926
|
-
return /* @__PURE__ */ (0,
|
|
11927
|
-
showFollowing ? /* @__PURE__ */ (0,
|
|
11928
|
-
/* @__PURE__ */ (0,
|
|
11929
|
-
/* @__PURE__ */ (0,
|
|
11930
|
-
/* @__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" })
|
|
11931
12508
|
] }),
|
|
11932
|
-
/* @__PURE__ */ (0,
|
|
11933
|
-
/* @__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)(
|
|
11934
12511
|
Button,
|
|
11935
12512
|
{
|
|
11936
12513
|
type: "button",
|
|
@@ -11942,8 +12519,8 @@ function LogoSizePanel({
|
|
|
11942
12519
|
}
|
|
11943
12520
|
)
|
|
11944
12521
|
] }) : null,
|
|
11945
|
-
showDesktopSlider || showMobileSlider ? /* @__PURE__ */ (0,
|
|
11946
|
-
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)(
|
|
11947
12524
|
Button,
|
|
11948
12525
|
{
|
|
11949
12526
|
type: "button",
|
|
@@ -11954,8 +12531,8 @@ function LogoSizePanel({
|
|
|
11954
12531
|
children: "Reset to desktop size"
|
|
11955
12532
|
}
|
|
11956
12533
|
) : null,
|
|
11957
|
-
/* @__PURE__ */ (0,
|
|
11958
|
-
/* @__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)(
|
|
11959
12536
|
Button,
|
|
11960
12537
|
{
|
|
11961
12538
|
type: "button",
|
|
@@ -11965,24 +12542,24 @@ function LogoSizePanel({
|
|
|
11965
12542
|
onClick: onUpdateEverywhere,
|
|
11966
12543
|
children: [
|
|
11967
12544
|
"Update logo everywhere",
|
|
11968
|
-
/* @__PURE__ */ (0,
|
|
12545
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react15.ArrowUpRight, { size: 16, "aria-hidden": true })
|
|
11969
12546
|
]
|
|
11970
12547
|
}
|
|
11971
12548
|
),
|
|
11972
|
-
/* @__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." })
|
|
11973
12550
|
] });
|
|
11974
12551
|
}
|
|
11975
12552
|
|
|
11976
12553
|
// src/ui/socials-display-panel.tsx
|
|
11977
|
-
var
|
|
12554
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
11978
12555
|
function DisplaySwitch({
|
|
11979
12556
|
label,
|
|
11980
12557
|
checked,
|
|
11981
12558
|
disabled,
|
|
11982
12559
|
onChange
|
|
11983
12560
|
}) {
|
|
11984
|
-
return /* @__PURE__ */ (0,
|
|
11985
|
-
/* @__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)(
|
|
11986
12563
|
"span",
|
|
11987
12564
|
{
|
|
11988
12565
|
className: cn(
|
|
@@ -11992,7 +12569,7 @@ function DisplaySwitch({
|
|
|
11992
12569
|
children: label
|
|
11993
12570
|
}
|
|
11994
12571
|
),
|
|
11995
|
-
/* @__PURE__ */ (0,
|
|
12572
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
11996
12573
|
"button",
|
|
11997
12574
|
{
|
|
11998
12575
|
type: "button",
|
|
@@ -12006,7 +12583,7 @@ function DisplaySwitch({
|
|
|
12006
12583
|
checked ? "bg-primary" : "bg-primary-50",
|
|
12007
12584
|
disabled ? "cursor-default opacity-50" : "cursor-pointer"
|
|
12008
12585
|
),
|
|
12009
|
-
children: /* @__PURE__ */ (0,
|
|
12586
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
12010
12587
|
"span",
|
|
12011
12588
|
{
|
|
12012
12589
|
className: cn(
|
|
@@ -12020,8 +12597,8 @@ function DisplaySwitch({
|
|
|
12020
12597
|
] });
|
|
12021
12598
|
}
|
|
12022
12599
|
function SocialsDisplayPanel({ display, onChange, className }) {
|
|
12023
|
-
return /* @__PURE__ */ (0,
|
|
12024
|
-
/* @__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)(
|
|
12025
12602
|
DisplaySwitch,
|
|
12026
12603
|
{
|
|
12027
12604
|
label: "Text",
|
|
@@ -12030,7 +12607,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
|
|
|
12030
12607
|
onChange: (text) => onChange({ ...display, text })
|
|
12031
12608
|
}
|
|
12032
12609
|
),
|
|
12033
|
-
/* @__PURE__ */ (0,
|
|
12610
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
12034
12611
|
DisplaySwitch,
|
|
12035
12612
|
{
|
|
12036
12613
|
label: "Icon",
|
|
@@ -12590,8 +13167,8 @@ function useNavItemDrag({
|
|
|
12590
13167
|
}
|
|
12591
13168
|
|
|
12592
13169
|
// src/ui/footer-container-chrome.tsx
|
|
12593
|
-
var
|
|
12594
|
-
var
|
|
13170
|
+
var import_lucide_react16 = require("lucide-react");
|
|
13171
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
12595
13172
|
function FooterContainerChrome({
|
|
12596
13173
|
rect,
|
|
12597
13174
|
onAdd,
|
|
@@ -12599,7 +13176,7 @@ function FooterContainerChrome({
|
|
|
12599
13176
|
}) {
|
|
12600
13177
|
const chromeGap = 6;
|
|
12601
13178
|
const buttonMargin = 7;
|
|
12602
|
-
return /* @__PURE__ */ (0,
|
|
13179
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
12603
13180
|
"div",
|
|
12604
13181
|
{
|
|
12605
13182
|
"data-ohw-footer-container-chrome": "",
|
|
@@ -12611,8 +13188,8 @@ function FooterContainerChrome({
|
|
|
12611
13188
|
width: rect.width + chromeGap * 2,
|
|
12612
13189
|
height: rect.height + chromeGap * 2
|
|
12613
13190
|
},
|
|
12614
|
-
children: /* @__PURE__ */ (0,
|
|
12615
|
-
/* @__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)(
|
|
12616
13193
|
"button",
|
|
12617
13194
|
{
|
|
12618
13195
|
type: "button",
|
|
@@ -12631,10 +13208,10 @@ function FooterContainerChrome({
|
|
|
12631
13208
|
if (addDisabled) return;
|
|
12632
13209
|
onAdd();
|
|
12633
13210
|
},
|
|
12634
|
-
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 })
|
|
12635
13212
|
}
|
|
12636
13213
|
) }),
|
|
12637
|
-
/* @__PURE__ */ (0,
|
|
13214
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
|
|
12638
13215
|
] })
|
|
12639
13216
|
}
|
|
12640
13217
|
) });
|
|
@@ -13094,14 +13671,14 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
13094
13671
|
}
|
|
13095
13672
|
|
|
13096
13673
|
// src/ui/navbar-container-chrome.tsx
|
|
13097
|
-
var
|
|
13098
|
-
var
|
|
13674
|
+
var import_lucide_react17 = require("lucide-react");
|
|
13675
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
13099
13676
|
function NavbarContainerChrome({
|
|
13100
13677
|
rect,
|
|
13101
13678
|
onAdd
|
|
13102
13679
|
}) {
|
|
13103
13680
|
const chromeGap = 6;
|
|
13104
|
-
return /* @__PURE__ */ (0,
|
|
13681
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
13105
13682
|
"div",
|
|
13106
13683
|
{
|
|
13107
13684
|
"data-ohw-navbar-container-chrome": "",
|
|
@@ -13113,7 +13690,7 @@ function NavbarContainerChrome({
|
|
|
13113
13690
|
width: rect.width + chromeGap * 2,
|
|
13114
13691
|
height: rect.height + chromeGap * 2
|
|
13115
13692
|
},
|
|
13116
|
-
children: /* @__PURE__ */ (0,
|
|
13693
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
13117
13694
|
"button",
|
|
13118
13695
|
{
|
|
13119
13696
|
type: "button",
|
|
@@ -13130,7 +13707,7 @@ function NavbarContainerChrome({
|
|
|
13130
13707
|
e.stopPropagation();
|
|
13131
13708
|
onAdd();
|
|
13132
13709
|
},
|
|
13133
|
-
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 })
|
|
13134
13711
|
}
|
|
13135
13712
|
)
|
|
13136
13713
|
}
|
|
@@ -13139,7 +13716,7 @@ function NavbarContainerChrome({
|
|
|
13139
13716
|
|
|
13140
13717
|
// src/ui/drop-indicator.tsx
|
|
13141
13718
|
var React10 = __toESM(require("react"), 1);
|
|
13142
|
-
var
|
|
13719
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
13143
13720
|
var dropIndicatorVariants = cva(
|
|
13144
13721
|
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
13145
13722
|
{
|
|
@@ -13163,7 +13740,7 @@ var dropIndicatorVariants = cva(
|
|
|
13163
13740
|
);
|
|
13164
13741
|
var DropIndicator = React10.forwardRef(
|
|
13165
13742
|
({ className, direction, state, ...props }, ref) => {
|
|
13166
|
-
return /* @__PURE__ */ (0,
|
|
13743
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
13167
13744
|
"div",
|
|
13168
13745
|
{
|
|
13169
13746
|
ref,
|
|
@@ -13180,7 +13757,7 @@ var DropIndicator = React10.forwardRef(
|
|
|
13180
13757
|
DropIndicator.displayName = "DropIndicator";
|
|
13181
13758
|
|
|
13182
13759
|
// src/ui/badge.tsx
|
|
13183
|
-
var
|
|
13760
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
13184
13761
|
var badgeVariants = cva(
|
|
13185
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",
|
|
13186
13763
|
{
|
|
@@ -13198,12 +13775,12 @@ var badgeVariants = cva(
|
|
|
13198
13775
|
}
|
|
13199
13776
|
);
|
|
13200
13777
|
function Badge({ className, variant, ...props }) {
|
|
13201
|
-
return /* @__PURE__ */ (0,
|
|
13778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
13202
13779
|
}
|
|
13203
13780
|
|
|
13204
13781
|
// src/OhhwellsBridge.tsx
|
|
13205
|
-
var
|
|
13206
|
-
var
|
|
13782
|
+
var import_lucide_react18 = require("lucide-react");
|
|
13783
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
13207
13784
|
var PRIMARY3 = "#0885FE";
|
|
13208
13785
|
var IMAGE_FADE_MS = 300;
|
|
13209
13786
|
function runOpacityFade(el, onDone) {
|
|
@@ -13372,7 +13949,7 @@ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, be
|
|
|
13372
13949
|
const root = (0, import_client2.createRoot)(container);
|
|
13373
13950
|
(0, import_react_dom3.flushSync)(() => {
|
|
13374
13951
|
root.render(
|
|
13375
|
-
/* @__PURE__ */ (0,
|
|
13952
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
13376
13953
|
SchedulingWidget,
|
|
13377
13954
|
{
|
|
13378
13955
|
notifyOnConnect,
|
|
@@ -13487,7 +14064,7 @@ function isIconEditable(el) {
|
|
|
13487
14064
|
return el.dataset.ohwEditable === "icon";
|
|
13488
14065
|
}
|
|
13489
14066
|
var MEDIA_SELECTOR = '[data-ohw-editable="image"], [data-ohw-editable="bg-image"], [data-ohw-editable="video"]';
|
|
13490
|
-
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"])';
|
|
13491
14068
|
function getVideoEl2(el) {
|
|
13492
14069
|
return el instanceof HTMLVideoElement ? el : el.querySelector("video");
|
|
13493
14070
|
}
|
|
@@ -14048,7 +14625,7 @@ function EditGlowChrome({
|
|
|
14048
14625
|
hideHandle = false
|
|
14049
14626
|
}) {
|
|
14050
14627
|
const GAP = SELECTION_CHROME_GAP2;
|
|
14051
|
-
return /* @__PURE__ */ (0,
|
|
14628
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
14052
14629
|
"div",
|
|
14053
14630
|
{
|
|
14054
14631
|
ref: elRef,
|
|
@@ -14063,7 +14640,7 @@ function EditGlowChrome({
|
|
|
14063
14640
|
zIndex: 2147483646
|
|
14064
14641
|
},
|
|
14065
14642
|
children: [
|
|
14066
|
-
/* @__PURE__ */ (0,
|
|
14643
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14067
14644
|
"div",
|
|
14068
14645
|
{
|
|
14069
14646
|
style: {
|
|
@@ -14076,7 +14653,7 @@ function EditGlowChrome({
|
|
|
14076
14653
|
}
|
|
14077
14654
|
}
|
|
14078
14655
|
),
|
|
14079
|
-
reorderHrefKey && !hideHandle && /* @__PURE__ */ (0,
|
|
14656
|
+
reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14080
14657
|
"div",
|
|
14081
14658
|
{
|
|
14082
14659
|
"data-ohw-drag-handle-container": "",
|
|
@@ -14088,7 +14665,7 @@ function EditGlowChrome({
|
|
|
14088
14665
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
14089
14666
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
14090
14667
|
},
|
|
14091
|
-
children: /* @__PURE__ */ (0,
|
|
14668
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14092
14669
|
DragHandle,
|
|
14093
14670
|
{
|
|
14094
14671
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -14298,7 +14875,7 @@ function FloatingToolbar({
|
|
|
14298
14875
|
return () => ro.disconnect();
|
|
14299
14876
|
}, [showEditLink, activeCommands]);
|
|
14300
14877
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
|
|
14301
|
-
return /* @__PURE__ */ (0,
|
|
14878
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14302
14879
|
"div",
|
|
14303
14880
|
{
|
|
14304
14881
|
ref: setRefs,
|
|
@@ -14310,12 +14887,12 @@ function FloatingToolbar({
|
|
|
14310
14887
|
zIndex: 2147483647,
|
|
14311
14888
|
pointerEvents: "auto"
|
|
14312
14889
|
},
|
|
14313
|
-
children: /* @__PURE__ */ (0,
|
|
14314
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0,
|
|
14315
|
-
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, {}),
|
|
14316
14893
|
btns.map((btn) => {
|
|
14317
14894
|
const isActive = activeCommands.has(btn.cmd);
|
|
14318
|
-
return /* @__PURE__ */ (0,
|
|
14895
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14319
14896
|
CustomToolbarButton,
|
|
14320
14897
|
{
|
|
14321
14898
|
title: btn.title,
|
|
@@ -14324,7 +14901,7 @@ function FloatingToolbar({
|
|
|
14324
14901
|
e.preventDefault();
|
|
14325
14902
|
onCommand(btn.cmd);
|
|
14326
14903
|
},
|
|
14327
|
-
children: /* @__PURE__ */ (0,
|
|
14904
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14328
14905
|
"svg",
|
|
14329
14906
|
{
|
|
14330
14907
|
width: "16",
|
|
@@ -14345,7 +14922,7 @@ function FloatingToolbar({
|
|
|
14345
14922
|
);
|
|
14346
14923
|
})
|
|
14347
14924
|
] }, gi)),
|
|
14348
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
14925
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14349
14926
|
CustomToolbarButton,
|
|
14350
14927
|
{
|
|
14351
14928
|
type: "button",
|
|
@@ -14359,7 +14936,7 @@ function FloatingToolbar({
|
|
|
14359
14936
|
e.preventDefault();
|
|
14360
14937
|
e.stopPropagation();
|
|
14361
14938
|
},
|
|
14362
|
-
children: /* @__PURE__ */ (0,
|
|
14939
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
14363
14940
|
}
|
|
14364
14941
|
) : null
|
|
14365
14942
|
] })
|
|
@@ -14376,7 +14953,7 @@ function StateToggle({
|
|
|
14376
14953
|
states,
|
|
14377
14954
|
onStateChange
|
|
14378
14955
|
}) {
|
|
14379
|
-
return /* @__PURE__ */ (0,
|
|
14956
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
14380
14957
|
ToggleGroup,
|
|
14381
14958
|
{
|
|
14382
14959
|
"data-ohw-state-toggle": "",
|
|
@@ -14390,7 +14967,7 @@ function StateToggle({
|
|
|
14390
14967
|
left: rect.right - 8,
|
|
14391
14968
|
transform: "translateX(-100%)"
|
|
14392
14969
|
},
|
|
14393
|
-
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))
|
|
14394
14971
|
}
|
|
14395
14972
|
);
|
|
14396
14973
|
}
|
|
@@ -14513,6 +15090,157 @@ function OhhwellsBridge() {
|
|
|
14513
15090
|
const sectionsLoadedRef = (0, import_react16.useRef)(false);
|
|
14514
15091
|
const pendingScheduleConfigRequests = (0, import_react16.useRef)([]);
|
|
14515
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]);
|
|
14516
15244
|
const [toolbarVariant, setToolbarVariant] = (0, import_react16.useState)("none");
|
|
14517
15245
|
const toolbarVariantRef = (0, import_react16.useRef)("none");
|
|
14518
15246
|
toolbarVariantRef.current = toolbarVariant;
|
|
@@ -14534,7 +15262,7 @@ function OhhwellsBridge() {
|
|
|
14534
15262
|
(0, import_react16.useEffect)(() => {
|
|
14535
15263
|
const sync = () => {
|
|
14536
15264
|
const el = document.querySelector(
|
|
14537
|
-
|
|
15265
|
+
'[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]):not([data-ohw-editable="form"] *)'
|
|
14538
15266
|
);
|
|
14539
15267
|
const target = el && !el.closest("[data-ohw-href-key]") ? el : null;
|
|
14540
15268
|
if (!target) {
|
|
@@ -15666,6 +16394,7 @@ function OhhwellsBridge() {
|
|
|
15666
16394
|
setFloatingPanel(null);
|
|
15667
16395
|
setLogoSizeDraft(null);
|
|
15668
16396
|
}, []);
|
|
16397
|
+
closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
|
|
15669
16398
|
const closeFloatingPanelAndDeselect = (0, import_react16.useCallback)(() => {
|
|
15670
16399
|
setFloatingPanel(null);
|
|
15671
16400
|
setLogoSizeDraft(null);
|
|
@@ -15921,6 +16650,98 @@ function OhhwellsBridge() {
|
|
|
15921
16650
|
cancelled = true;
|
|
15922
16651
|
};
|
|
15923
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]);
|
|
15924
16745
|
(0, import_react16.useEffect)(() => {
|
|
15925
16746
|
if (!subdomain || isEditMode) return;
|
|
15926
16747
|
let debounceTimer = null;
|
|
@@ -16154,7 +16975,9 @@ function OhhwellsBridge() {
|
|
|
16154
16975
|
[style*="100vh"] { min-height: ${initialVh}px !important; height: ${initialVh}px !important; }
|
|
16155
16976
|
[style*="100svh"] { min-height: ${initialVh}px !important; height: ${initialVh}px !important; }
|
|
16156
16977
|
[style*="100dvh"] { min-height: ${initialVh}px !important; height: ${initialVh}px !important; }
|
|
16157
|
-
|
|
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"]) {
|
|
16158
16981
|
display: block;
|
|
16159
16982
|
}
|
|
16160
16983
|
/* Body text (no item-action toolbar) \u2014 first click enters text edit \u2192 I-beam.
|
|
@@ -16180,6 +17003,35 @@ function OhhwellsBridge() {
|
|
|
16180
17003
|
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
16181
17004
|
[data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
|
|
16182
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
|
+
}
|
|
16183
17035
|
/* Text hover chrome is drawn by the overlay (see hoveredTextRect) \u2014 the CSS outline
|
|
16184
17036
|
that used to draw it dashes denser than the overlay border, so identical specs
|
|
16185
17037
|
still read as two different frames (OHH-695). The attribute stays: hover paths
|
|
@@ -16266,6 +17118,49 @@ function OhhwellsBridge() {
|
|
|
16266
17118
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
16267
17119
|
if (isInsideLinkEditor(target)) return;
|
|
16268
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
|
+
}
|
|
16269
17164
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
16270
17165
|
const beneath = document.elementsFromPoint(e.clientX, e.clientY).find(
|
|
16271
17166
|
(el) => el instanceof HTMLElement && !el.closest("[data-ohw-bridge-root]") && el.closest("[data-ohw-section]") != null
|
|
@@ -16605,6 +17500,26 @@ function OhhwellsBridge() {
|
|
|
16605
17500
|
return;
|
|
16606
17501
|
}
|
|
16607
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
|
+
}
|
|
16608
17523
|
if (!editable) return;
|
|
16609
17524
|
const selected = selectedElRef.current;
|
|
16610
17525
|
if (selected && (selected === editable || selected.contains(editable))) return;
|
|
@@ -17241,6 +18156,13 @@ function OhhwellsBridge() {
|
|
|
17241
18156
|
setSectionGap(null);
|
|
17242
18157
|
}
|
|
17243
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
|
+
};
|
|
17244
18166
|
const handleMouseMove = (e) => {
|
|
17245
18167
|
const { clientX, clientY } = e;
|
|
17246
18168
|
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
@@ -17806,6 +18728,13 @@ function OhhwellsBridge() {
|
|
|
17806
18728
|
}
|
|
17807
18729
|
}
|
|
17808
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);
|
|
17809
18738
|
window.addEventListener("message", handleUiEscape);
|
|
17810
18739
|
const handleKeyDown = (e) => {
|
|
17811
18740
|
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
@@ -17825,6 +18754,11 @@ function OhhwellsBridge() {
|
|
|
17825
18754
|
closeFloatingPanelOnlyRef.current();
|
|
17826
18755
|
return;
|
|
17827
18756
|
}
|
|
18757
|
+
if (e.key === "Escape" && formPickElRef.current) {
|
|
18758
|
+
e.preventDefault();
|
|
18759
|
+
clearFormPickRef.current();
|
|
18760
|
+
return;
|
|
18761
|
+
}
|
|
17828
18762
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
17829
18763
|
if (toolbarVariantRef.current === "logo") {
|
|
17830
18764
|
deselectRef.current();
|
|
@@ -18377,6 +19311,7 @@ function OhhwellsBridge() {
|
|
|
18377
19311
|
window.removeEventListener("message", handleGetBrand);
|
|
18378
19312
|
window.removeEventListener("message", handleDeactivate);
|
|
18379
19313
|
window.removeEventListener("message", handleToastAction);
|
|
19314
|
+
window.removeEventListener("message", handleFormCount);
|
|
18380
19315
|
window.removeEventListener("message", handleUiEscape);
|
|
18381
19316
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
18382
19317
|
autoSaveTimers.current.clear();
|
|
@@ -18400,7 +19335,9 @@ function OhhwellsBridge() {
|
|
|
18400
19335
|
if (footerDragRef.current) return;
|
|
18401
19336
|
const target = e.target;
|
|
18402
19337
|
if (!target) return;
|
|
18403
|
-
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
|
+
)) {
|
|
18404
19341
|
return;
|
|
18405
19342
|
}
|
|
18406
19343
|
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
@@ -18578,7 +19515,7 @@ function OhhwellsBridge() {
|
|
|
18578
19515
|
postToParent2({
|
|
18579
19516
|
type: "ow:ready",
|
|
18580
19517
|
version: "1",
|
|
18581
|
-
bridgeVersion: "0.1.
|
|
19518
|
+
bridgeVersion: "0.1.64",
|
|
18582
19519
|
path: pathname,
|
|
18583
19520
|
nodes: collectEditableNodes(editContentRef.current),
|
|
18584
19521
|
sections
|
|
@@ -18973,10 +19910,10 @@ function OhhwellsBridge() {
|
|
|
18973
19910
|
[postToParent2]
|
|
18974
19911
|
);
|
|
18975
19912
|
return bridgeRoot ? (0, import_react_dom4.createPortal)(
|
|
18976
|
-
/* @__PURE__ */ (0,
|
|
18977
|
-
/* @__PURE__ */ (0,
|
|
18978
|
-
isEditMode && /* @__PURE__ */ (0,
|
|
18979
|
-
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)(
|
|
18980
19917
|
MediaOverlay,
|
|
18981
19918
|
{
|
|
18982
19919
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -18987,7 +19924,7 @@ function OhhwellsBridge() {
|
|
|
18987
19924
|
},
|
|
18988
19925
|
`uploading-${key}`
|
|
18989
19926
|
)),
|
|
18990
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0,
|
|
19927
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
18991
19928
|
MediaOverlay,
|
|
18992
19929
|
{
|
|
18993
19930
|
hover: mediaHover,
|
|
@@ -18996,11 +19933,11 @@ function OhhwellsBridge() {
|
|
|
18996
19933
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
18997
19934
|
}
|
|
18998
19935
|
),
|
|
18999
|
-
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0,
|
|
19000
|
-
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0,
|
|
19001
|
-
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0,
|
|
19002
|
-
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0,
|
|
19003
|
-
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)(
|
|
19004
19941
|
"div",
|
|
19005
19942
|
{
|
|
19006
19943
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -19010,7 +19947,7 @@ function OhhwellsBridge() {
|
|
|
19010
19947
|
width: slot.width,
|
|
19011
19948
|
height: slot.height
|
|
19012
19949
|
},
|
|
19013
|
-
children: /* @__PURE__ */ (0,
|
|
19950
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19014
19951
|
DropIndicator,
|
|
19015
19952
|
{
|
|
19016
19953
|
direction: slot.direction,
|
|
@@ -19021,7 +19958,7 @@ function OhhwellsBridge() {
|
|
|
19021
19958
|
},
|
|
19022
19959
|
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
19023
19960
|
)),
|
|
19024
|
-
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0,
|
|
19961
|
+
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19025
19962
|
"div",
|
|
19026
19963
|
{
|
|
19027
19964
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -19031,7 +19968,7 @@ function OhhwellsBridge() {
|
|
|
19031
19968
|
width: slot.width,
|
|
19032
19969
|
height: slot.height
|
|
19033
19970
|
},
|
|
19034
|
-
children: /* @__PURE__ */ (0,
|
|
19971
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19035
19972
|
DropIndicator,
|
|
19036
19973
|
{
|
|
19037
19974
|
direction: slot.direction,
|
|
@@ -19042,11 +19979,179 @@ function OhhwellsBridge() {
|
|
|
19042
19979
|
},
|
|
19043
19980
|
`nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
|
|
19044
19981
|
)),
|
|
19045
|
-
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0,
|
|
19046
|
-
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0,
|
|
19047
|
-
hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0,
|
|
19048
|
-
|
|
19049
|
-
|
|
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)(
|
|
19050
20155
|
FooterContainerChrome,
|
|
19051
20156
|
{
|
|
19052
20157
|
rect: toolbarRect,
|
|
@@ -19054,7 +20159,7 @@ function OhhwellsBridge() {
|
|
|
19054
20159
|
addDisabled: !canAddFooterColumn()
|
|
19055
20160
|
}
|
|
19056
20161
|
),
|
|
19057
|
-
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)(
|
|
19058
20163
|
ItemInteractionLayer,
|
|
19059
20164
|
{
|
|
19060
20165
|
rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
|
|
@@ -19069,7 +20174,7 @@ function OhhwellsBridge() {
|
|
|
19069
20174
|
onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
|
|
19070
20175
|
onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
|
|
19071
20176
|
itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection,
|
|
19072
|
-
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)(
|
|
19073
20178
|
ItemActionToolbar,
|
|
19074
20179
|
{
|
|
19075
20180
|
onEditLink: openLinkPopoverForSelected,
|
|
@@ -19105,8 +20210,8 @@ function OhhwellsBridge() {
|
|
|
19105
20210
|
) : void 0
|
|
19106
20211
|
}
|
|
19107
20212
|
),
|
|
19108
|
-
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0,
|
|
19109
|
-
/* @__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)(
|
|
19110
20215
|
EditGlowChrome,
|
|
19111
20216
|
{
|
|
19112
20217
|
rect: toolbarRect,
|
|
@@ -19116,7 +20221,7 @@ function OhhwellsBridge() {
|
|
|
19116
20221
|
hideHandle: isItemDragging
|
|
19117
20222
|
}
|
|
19118
20223
|
),
|
|
19119
|
-
/* @__PURE__ */ (0,
|
|
20224
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19120
20225
|
FloatingToolbar,
|
|
19121
20226
|
{
|
|
19122
20227
|
rect: toolbarRect,
|
|
@@ -19129,7 +20234,7 @@ function OhhwellsBridge() {
|
|
|
19129
20234
|
}
|
|
19130
20235
|
)
|
|
19131
20236
|
] }),
|
|
19132
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
20237
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
19133
20238
|
"div",
|
|
19134
20239
|
{
|
|
19135
20240
|
"data-ohw-max-badge": "",
|
|
@@ -19155,7 +20260,7 @@ function OhhwellsBridge() {
|
|
|
19155
20260
|
]
|
|
19156
20261
|
}
|
|
19157
20262
|
),
|
|
19158
|
-
toggleState && !linkPopover && /* @__PURE__ */ (0,
|
|
20263
|
+
toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19159
20264
|
StateToggle,
|
|
19160
20265
|
{
|
|
19161
20266
|
rect: toggleState.rect,
|
|
@@ -19164,15 +20269,15 @@ function OhhwellsBridge() {
|
|
|
19164
20269
|
onStateChange: handleStateChange
|
|
19165
20270
|
}
|
|
19166
20271
|
),
|
|
19167
|
-
sectionGap && !linkPopover && /* @__PURE__ */ (0,
|
|
20272
|
+
sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
19168
20273
|
"div",
|
|
19169
20274
|
{
|
|
19170
20275
|
"data-ohw-section-insert-line": "",
|
|
19171
20276
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
19172
20277
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
19173
20278
|
children: [
|
|
19174
|
-
/* @__PURE__ */ (0,
|
|
19175
|
-
/* @__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)(
|
|
19176
20281
|
Badge,
|
|
19177
20282
|
{
|
|
19178
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",
|
|
@@ -19189,11 +20294,11 @@ function OhhwellsBridge() {
|
|
|
19189
20294
|
children: "Add Section"
|
|
19190
20295
|
}
|
|
19191
20296
|
),
|
|
19192
|
-
/* @__PURE__ */ (0,
|
|
20297
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
19193
20298
|
]
|
|
19194
20299
|
}
|
|
19195
20300
|
),
|
|
19196
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0,
|
|
20301
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19197
20302
|
LinkPopover,
|
|
19198
20303
|
{
|
|
19199
20304
|
panelRef: linkPopoverPanelRef,
|
|
@@ -19210,7 +20315,7 @@ function OhhwellsBridge() {
|
|
|
19210
20315
|
},
|
|
19211
20316
|
linkPopover.key
|
|
19212
20317
|
) : null,
|
|
19213
|
-
floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0,
|
|
20318
|
+
floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19214
20319
|
FloatingPanel,
|
|
19215
20320
|
{
|
|
19216
20321
|
open: true,
|
|
@@ -19220,7 +20325,7 @@ function OhhwellsBridge() {
|
|
|
19220
20325
|
onPositionChange: setFloatingPanelPos,
|
|
19221
20326
|
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
19222
20327
|
onClose: closeFloatingPanelOnly,
|
|
19223
|
-
children: /* @__PURE__ */ (0,
|
|
20328
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19224
20329
|
SocialsDisplayPanel,
|
|
19225
20330
|
{
|
|
19226
20331
|
display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
|
|
@@ -19232,7 +20337,7 @@ function OhhwellsBridge() {
|
|
|
19232
20337
|
)
|
|
19233
20338
|
}
|
|
19234
20339
|
) : null,
|
|
19235
|
-
floatingPanel && floatingPanel.kind === "logo-size" && logoSizeDraft ? /* @__PURE__ */ (0,
|
|
20340
|
+
floatingPanel && floatingPanel.kind === "logo-size" && logoSizeDraft ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19236
20341
|
FloatingPanel,
|
|
19237
20342
|
{
|
|
19238
20343
|
open: true,
|
|
@@ -19242,7 +20347,7 @@ function OhhwellsBridge() {
|
|
|
19242
20347
|
onPositionChange: setFloatingPanelPos,
|
|
19243
20348
|
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
19244
20349
|
onClose: closeFloatingPanelAndDeselect,
|
|
19245
|
-
children: /* @__PURE__ */ (0,
|
|
20350
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19246
20351
|
LogoSizePanel,
|
|
19247
20352
|
{
|
|
19248
20353
|
viewport: editorViewport,
|
|
@@ -19290,10 +20395,10 @@ function OhhwellsBridge() {
|
|
|
19290
20395
|
|
|
19291
20396
|
// src/ui/EmptySection.tsx
|
|
19292
20397
|
var import_link = __toESM(require("next/link"), 1);
|
|
19293
|
-
var
|
|
20398
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
19294
20399
|
function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
|
|
19295
|
-
return /* @__PURE__ */ (0,
|
|
19296
|
-
/* @__PURE__ */ (0,
|
|
20400
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
|
|
20401
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
19297
20402
|
"p",
|
|
19298
20403
|
{
|
|
19299
20404
|
style: {
|
|
@@ -19305,10 +20410,10 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
|
|
|
19305
20410
|
color: "var(--brand-accent)",
|
|
19306
20411
|
marginBottom: "1.5rem"
|
|
19307
20412
|
},
|
|
19308
|
-
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" }) })
|
|
19309
20414
|
}
|
|
19310
20415
|
),
|
|
19311
|
-
/* @__PURE__ */ (0,
|
|
20416
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
19312
20417
|
"h1",
|
|
19313
20418
|
{
|
|
19314
20419
|
style: {
|
|
@@ -19323,7 +20428,7 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
|
|
|
19323
20428
|
children: title
|
|
19324
20429
|
}
|
|
19325
20430
|
),
|
|
19326
|
-
/* @__PURE__ */ (0,
|
|
20431
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
19327
20432
|
"p",
|
|
19328
20433
|
{
|
|
19329
20434
|
style: {
|