form-page-builder 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -2
- package/dist/index.cjs +344 -178
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -2
- package/dist/index.d.ts +38 -2
- package/dist/index.js +364 -200
- package/dist/index.js.map +1 -1
- package/package.json +9 -2
package/dist/index.cjs
CHANGED
|
@@ -21,6 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/index.ts
|
|
22
22
|
var index_exports = {};
|
|
23
23
|
__export(index_exports, {
|
|
24
|
+
DARK_THEME: () => DARK_THEME,
|
|
25
|
+
DEFAULT_THEME: () => DEFAULT_THEME,
|
|
24
26
|
FormBuilder: () => FormBuilder_default,
|
|
25
27
|
default: () => FormBuilder_default,
|
|
26
28
|
localStorageAdapter: () => localStorageAdapter
|
|
@@ -360,6 +362,22 @@ function withLang(val, lang, value) {
|
|
|
360
362
|
return { ...base, [lang]: value };
|
|
361
363
|
}
|
|
362
364
|
|
|
365
|
+
// src/lib/color.ts
|
|
366
|
+
function mixHex(a, b, t2) {
|
|
367
|
+
const pa = parseHex(a);
|
|
368
|
+
const pb = parseHex(b);
|
|
369
|
+
if (!pa || !pb) return a;
|
|
370
|
+
const mix = (x, y) => Math.round(x + (y - x) * t2);
|
|
371
|
+
const toHex = (n) => n.toString(16).padStart(2, "0");
|
|
372
|
+
return `#${toHex(mix(pa[0], pb[0]))}${toHex(mix(pa[1], pb[1]))}${toHex(mix(pa[2], pb[2]))}`;
|
|
373
|
+
}
|
|
374
|
+
function parseHex(hex) {
|
|
375
|
+
const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim());
|
|
376
|
+
if (!m) return null;
|
|
377
|
+
const n = parseInt(m[1], 16);
|
|
378
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
379
|
+
}
|
|
380
|
+
|
|
363
381
|
// src/lib/storage/compress.ts
|
|
364
382
|
var import_lz_string = require("lz-string");
|
|
365
383
|
function compress(raw) {
|
|
@@ -615,6 +633,37 @@ function migrateDocument(raw) {
|
|
|
615
633
|
return { title, themeOverrides, sections };
|
|
616
634
|
}
|
|
617
635
|
|
|
636
|
+
// src/lib/features.ts
|
|
637
|
+
var DEFAULT_FEATURES = {
|
|
638
|
+
naming: true,
|
|
639
|
+
templates: true,
|
|
640
|
+
newForm: true,
|
|
641
|
+
autosave: true,
|
|
642
|
+
jsonView: true,
|
|
643
|
+
previewMode: true,
|
|
644
|
+
languageSwitcher: true,
|
|
645
|
+
design: false,
|
|
646
|
+
blockStyling: true,
|
|
647
|
+
contentBlocks: true,
|
|
648
|
+
fieldTypes: true,
|
|
649
|
+
sections: true,
|
|
650
|
+
dragReorder: true
|
|
651
|
+
};
|
|
652
|
+
function resolveFeatures(features) {
|
|
653
|
+
return {
|
|
654
|
+
...DEFAULT_FEATURES,
|
|
655
|
+
...features,
|
|
656
|
+
contentBlocks: Array.isArray(features?.contentBlocks) ? new Set(features.contentBlocks) : features?.contentBlocks ?? DEFAULT_FEATURES.contentBlocks,
|
|
657
|
+
fieldTypes: Array.isArray(features?.fieldTypes) ? new Set(features.fieldTypes) : features?.fieldTypes ?? DEFAULT_FEATURES.fieldTypes
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
function isContentBlockEnabled(features, type) {
|
|
661
|
+
return features.contentBlocks === true || features.contentBlocks instanceof Set && features.contentBlocks.has(type);
|
|
662
|
+
}
|
|
663
|
+
function isFieldTypeEnabled(features, type) {
|
|
664
|
+
return features.fieldTypes === true || features.fieldTypes instanceof Set && features.fieldTypes.has(type);
|
|
665
|
+
}
|
|
666
|
+
|
|
618
667
|
// src/hooks/useTheme.ts
|
|
619
668
|
var import_react = require("react");
|
|
620
669
|
|
|
@@ -849,6 +898,7 @@ var formKey = (id) => `form-page-builder:saved:${id}`;
|
|
|
849
898
|
var MAX_TEMPLATES = 5;
|
|
850
899
|
function usePersistence({
|
|
851
900
|
storage,
|
|
901
|
+
autosave,
|
|
852
902
|
language,
|
|
853
903
|
chrome,
|
|
854
904
|
document,
|
|
@@ -910,7 +960,7 @@ function usePersistence({
|
|
|
910
960
|
refreshLibrary();
|
|
911
961
|
}, []);
|
|
912
962
|
(0, import_react3.useEffect)(() => {
|
|
913
|
-
if (!hasLoadedOnce.current) return;
|
|
963
|
+
if (!hasLoadedOnce.current || !autosave) return;
|
|
914
964
|
setSaveState("saving");
|
|
915
965
|
if (autosaveTimer.current) clearTimeout(autosaveTimer.current);
|
|
916
966
|
autosaveTimer.current = setTimeout(async () => {
|
|
@@ -1049,15 +1099,15 @@ var styles = {
|
|
|
1049
1099
|
titleInput: { border: "none", outline: "none", fontSize: 14, fontWeight: 600, background: "transparent", color: "var(--fb-ink)", padding: "4px 6px", borderRadius: 6, minWidth: 160 },
|
|
1050
1100
|
toolbarRight: { display: "flex", alignItems: "center", gap: 6, flexWrap: "wrap" },
|
|
1051
1101
|
toolbarDivider: { width: 1, height: 20, background: "var(--fb-border)", margin: "0 4px" },
|
|
1052
|
-
tabBtn: { display: "flex", alignItems: "center", gap: 6, padding: "6px 12px", borderRadius: 7, border: "1px solid transparent", background: "transparent", color: "
|
|
1102
|
+
tabBtn: { display: "flex", alignItems: "center", gap: 6, padding: "6px 12px", borderRadius: 7, border: "1px solid transparent", background: "transparent", color: "var(--fb-muted)", fontSize: 13, fontWeight: 500 },
|
|
1053
1103
|
tabBtnActive: { display: "flex", alignItems: "center", gap: 6, padding: "6px 12px", borderRadius: 7, border: "1px solid var(--fb-border)", background: "var(--fb-primary-soft)", color: "var(--fb-primary)", fontSize: 13, fontWeight: 600 },
|
|
1054
|
-
ghostBtn: { display: "flex", alignItems: "center", gap: 6, padding: "6px 12px", borderRadius: 7, border: "1px solid var(--fb-border)", background: "var(--fb-surface)", color: "
|
|
1104
|
+
ghostBtn: { display: "flex", alignItems: "center", gap: 6, padding: "6px 12px", borderRadius: 7, border: "1px solid var(--fb-border)", background: "var(--fb-surface)", color: "var(--fb-ink)", fontSize: 13, fontWeight: 500 },
|
|
1055
1105
|
primaryBtn: { display: "flex", alignItems: "center", gap: 6, padding: "6px 13px", borderRadius: 7, border: "1px solid var(--fb-primary)", background: "var(--fb-primary)", color: "#fff", fontSize: 13, fontWeight: 600 },
|
|
1056
1106
|
saveStatus: { display: "flex", alignItems: "center", gap: 5, fontSize: 12, color: "var(--fb-muted)", minWidth: 60 },
|
|
1057
1107
|
countBadge: { fontSize: 10.5, fontWeight: 700, background: "var(--fb-primary-soft)", color: "var(--fb-primary)", borderRadius: 9, padding: "1px 6px", marginLeft: 2 },
|
|
1058
1108
|
loadingScreen: { flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", color: "var(--fb-muted)" },
|
|
1059
1109
|
libraryBody: { padding: "var(--fb-space-panel)", overflowY: "auto", display: "flex", flexDirection: "column", gap: 4 },
|
|
1060
|
-
libraryRow: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10, padding: "10px 8px", borderRadius: 8, border: "1px solid
|
|
1110
|
+
libraryRow: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10, padding: "10px 8px", borderRadius: 8, border: "1px solid var(--fb-border)" },
|
|
1061
1111
|
libraryRowTitle: { fontSize: 13.5, fontWeight: 600, color: "var(--fb-ink)", display: "flex", alignItems: "center", gap: 8, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" },
|
|
1062
1112
|
libraryRowMeta: { fontSize: 11.5, color: "var(--fb-muted)", marginTop: 2 },
|
|
1063
1113
|
currentBadge: { fontSize: 10, fontWeight: 700, color: "var(--fb-primary)", background: "var(--fb-primary-soft)", padding: "2px 6px", borderRadius: 5, flexShrink: 0 },
|
|
@@ -1066,7 +1116,7 @@ var styles = {
|
|
|
1066
1116
|
panelHeading: { fontSize: 11, fontWeight: 700, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--fb-muted)", marginBottom: 10 },
|
|
1067
1117
|
activeSectionHint: { fontSize: 11.5, color: "var(--fb-muted)", marginBottom: 14, lineHeight: 1.4 },
|
|
1068
1118
|
paletteList: { display: "flex", flexDirection: "column", gap: 4 },
|
|
1069
|
-
paletteItem: { display: "flex", alignItems: "center", gap: 9, padding: "8px 9px", borderRadius: 8, border: "1px solid transparent", background: "transparent", fontSize: 13, color: "
|
|
1119
|
+
paletteItem: { display: "flex", alignItems: "center", gap: 9, padding: "8px 9px", borderRadius: 8, border: "1px solid transparent", background: "transparent", fontSize: 13, color: "var(--fb-ink)", textAlign: "left" },
|
|
1070
1120
|
canvas: { flex: 1, padding: "var(--fb-space-canvas)", overflowY: "auto", background: "var(--fb-canvas)" },
|
|
1071
1121
|
sectionBlock: { borderRadius: 12, padding: "var(--fb-space-panel)", marginBottom: "var(--fb-space-section)", transition: "border-color 0.12s" },
|
|
1072
1122
|
sectionHeader: { display: "flex", alignItems: "center", gap: 8, marginBottom: 12, flexWrap: "wrap" },
|
|
@@ -1076,7 +1126,7 @@ var styles = {
|
|
|
1076
1126
|
sectionHeaderActions: { display: "flex", alignItems: "center", gap: 6, flexWrap: "wrap", marginLeft: "auto" },
|
|
1077
1127
|
sectionEmpty: { fontSize: 12.5, color: "var(--fb-muted)", padding: "18px 4px", textAlign: "center", border: "1px dashed var(--fb-border)", borderRadius: 8 },
|
|
1078
1128
|
resetLinkBtn: { display: "flex", alignItems: "center", gap: 3, fontSize: 11, color: "var(--fb-muted)", background: "transparent", border: "none", padding: "2px 4px" },
|
|
1079
|
-
addSectionBtn: { display: "flex", alignItems: "center", justifyContent: "center", gap: 6, width: "100%", padding: "10px", borderRadius: 10, border: "1px dashed
|
|
1129
|
+
addSectionBtn: { display: "flex", alignItems: "center", justifyContent: "center", gap: 6, width: "100%", padding: "10px", borderRadius: 10, border: "1px dashed var(--fb-border)", background: "transparent", color: "var(--fb-primary)", fontSize: 13, fontWeight: 600 },
|
|
1080
1130
|
swatchRow: { display: "flex", alignItems: "center", gap: 5, flexWrap: "wrap" },
|
|
1081
1131
|
swatchBtn: { width: 20, height: 20, borderRadius: "50%", border: "1px solid var(--fb-border)", padding: 0 },
|
|
1082
1132
|
swatchBtnActive: { border: "2px solid var(--fb-primary)" },
|
|
@@ -1085,56 +1135,56 @@ var styles = {
|
|
|
1085
1135
|
ticket: { display: "flex", alignItems: "stretch", background: "var(--fb-surface)", border: "1px solid var(--fb-border)", borderRadius: 10, position: "relative", transition: "border-color 0.12s, box-shadow 0.12s" },
|
|
1086
1136
|
ticketSelected: { borderColor: "var(--fb-primary)", boxShadow: "0 0 0 3px var(--fb-primary-soft)" },
|
|
1087
1137
|
ticketDragOver: { borderColor: "var(--fb-muted)" },
|
|
1088
|
-
ticketIndex: { fontFamily: "'JetBrains Mono', monospace", fontSize: 13, fontWeight: 700, color: "
|
|
1138
|
+
ticketIndex: { fontFamily: "'JetBrains Mono', monospace", fontSize: 13, fontWeight: 700, color: "var(--fb-border)", width: 34, display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 },
|
|
1089
1139
|
ticketPerforation: { width: 0, borderLeft: "1px dashed var(--fb-border)" },
|
|
1090
1140
|
ticketBody: { flex: 1, padding: "10px var(--fb-space-ticket)", minWidth: 0 },
|
|
1091
1141
|
ticketTop: { display: "flex", alignItems: "center", gap: 7, marginBottom: 4 },
|
|
1092
1142
|
typeBadge: { fontSize: 10.5, fontFamily: "'JetBrains Mono', monospace", color: "var(--fb-muted)" },
|
|
1093
|
-
requiredBadge: { fontSize: 10, fontWeight: 700, color: "
|
|
1143
|
+
requiredBadge: { fontSize: 10, fontWeight: 700, color: "var(--fb-danger)", background: "var(--fb-danger-soft)", padding: "2px 6px", borderRadius: 5, letterSpacing: "0.02em", marginLeft: "auto" },
|
|
1094
1144
|
chipRow: { display: "flex", gap: 5, marginBottom: 7, flexWrap: "wrap" },
|
|
1095
1145
|
miniBadge: { fontSize: 10, fontWeight: 600, color: "var(--fb-primary)", background: "var(--fb-primary-soft)", padding: "2px 6px", borderRadius: 5, letterSpacing: "0.02em" },
|
|
1096
|
-
langToggleTrack: { position: "relative", display: "flex", gap: 3, background: "
|
|
1146
|
+
langToggleTrack: { position: "relative", display: "flex", gap: 3, background: "var(--fb-surface-2)", padding: 3, borderRadius: 20 },
|
|
1097
1147
|
langToggleThumb: { position: "absolute", top: 3, left: 3, bottom: 3, background: "var(--fb-primary)", borderRadius: 17, transition: "transform 0.18s ease" },
|
|
1098
|
-
langToggleBtn: { position: "relative", zIndex: 1, padding: "5px 12px", borderRadius: 17, border: "none", background: "transparent", color: "
|
|
1148
|
+
langToggleBtn: { position: "relative", zIndex: 1, padding: "5px 12px", borderRadius: 17, border: "none", background: "transparent", color: "var(--fb-muted)", fontSize: 12.5, fontWeight: 600, whiteSpace: "nowrap" },
|
|
1099
1149
|
langToggleBtnActive: { position: "relative", zIndex: 1, padding: "5px 12px", borderRadius: 17, border: "none", background: "transparent", color: "#fff", fontSize: 12.5, fontWeight: 600, whiteSpace: "nowrap" },
|
|
1100
|
-
segmented: { display: "flex", gap: 3, background: "
|
|
1101
|
-
segmentedBtn: { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", gap: 5, padding: "6px 8px", borderRadius: 6, border: "none", background: "transparent", color: "
|
|
1102
|
-
segmentedBtnActive: { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", gap: 5, padding: "6px 8px", borderRadius: 6, border: "none", background: "
|
|
1150
|
+
segmented: { display: "flex", gap: 3, background: "var(--fb-surface-2)", padding: 3, borderRadius: 8, marginBottom: 4 },
|
|
1151
|
+
segmentedBtn: { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", gap: 5, padding: "6px 8px", borderRadius: 6, border: "none", background: "transparent", color: "var(--fb-muted)", fontSize: 12.5, fontWeight: 500 },
|
|
1152
|
+
segmentedBtnActive: { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", gap: 5, padding: "6px 8px", borderRadius: 6, border: "none", background: "var(--fb-surface)", color: "var(--fb-ink)", fontSize: 12.5, fontWeight: 600, boxShadow: "0 1px 2px rgba(0,0,0,0.08)" },
|
|
1103
1153
|
iconGrid: { display: "grid", gridTemplateColumns: "repeat(6, 1fr)", gap: 5, marginTop: 6 },
|
|
1104
|
-
iconGridBtn: { width: 30, height: 30, borderRadius: 7, border: "1px solid var(--fb-border)", background: "
|
|
1154
|
+
iconGridBtn: { width: 30, height: 30, borderRadius: 7, border: "1px solid var(--fb-border)", background: "var(--fb-surface)", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--fb-muted)" },
|
|
1105
1155
|
iconGridBtnActive: { width: 30, height: 30, borderRadius: 7, border: "1px solid var(--fb-primary)", background: "var(--fb-primary-soft)", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--fb-primary)" },
|
|
1106
1156
|
styleToggleRow: { display: "flex", gap: 5, marginBottom: 4 },
|
|
1107
|
-
styleToggle: { width: 30, height: 30, borderRadius: 7, border: "1px solid var(--fb-border)", background: "
|
|
1157
|
+
styleToggle: { width: 30, height: 30, borderRadius: 7, border: "1px solid var(--fb-border)", background: "var(--fb-surface)", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--fb-muted)" },
|
|
1108
1158
|
styleToggleActive: { width: 30, height: 30, borderRadius: 7, border: "1px solid var(--fb-primary)", background: "var(--fb-primary-soft)", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--fb-primary)" },
|
|
1109
|
-
previewInput: { border: "1px solid
|
|
1110
|
-
previewRadio: { display: "flex", alignItems: "center", gap: 6, fontSize: 13, color: "
|
|
1111
|
-
ticketActions: { display: "flex", flexDirection: "column", gap: 3, padding: 8, borderLeft: "1px solid
|
|
1112
|
-
iconBtn: { width: 24, height: 24, borderRadius: 6, border: "1px solid
|
|
1159
|
+
previewInput: { border: "1px solid var(--fb-border)", borderRadius: 7, padding: "7px 10px", fontSize: 13, color: "var(--fb-muted)", background: "var(--fb-surface-2)", display: "flex", alignItems: "center", justifyContent: "space-between" },
|
|
1160
|
+
previewRadio: { display: "flex", alignItems: "center", gap: 6, fontSize: 13, color: "var(--fb-ink)" },
|
|
1161
|
+
ticketActions: { display: "flex", flexDirection: "column", gap: 3, padding: 8, borderLeft: "1px solid var(--fb-border)" },
|
|
1162
|
+
iconBtn: { width: 24, height: 24, borderRadius: 6, border: "1px solid var(--fb-border)", background: "var(--fb-surface)", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--fb-muted)" },
|
|
1113
1163
|
iconBtnDanger: { color: "var(--fb-danger)" },
|
|
1114
1164
|
inspector: { width: 270, borderLeft: "1px solid var(--fb-border)", background: "var(--fb-surface)", padding: "var(--fb-space-panel)", overflowY: "auto" },
|
|
1115
1165
|
inspectorEmpty: { fontSize: 13, color: "var(--fb-muted)", lineHeight: 1.5, marginTop: 6 },
|
|
1116
1166
|
inspectorBody: { display: "flex", flexDirection: "column", gap: 4 },
|
|
1117
1167
|
helperText: { fontSize: 11, color: "var(--fb-muted)", lineHeight: 1.4, margin: "2px 0 4px" },
|
|
1118
|
-
propLabel: { fontSize: 11.5, fontWeight: 600, color: "
|
|
1119
|
-
propInput: { border: "1px solid var(--fb-border)", borderRadius: 7, padding: "7px 9px", fontSize: 13, color: "var(--fb-ink)", outline: "none", width: "100%", boxSizing: "border-box" },
|
|
1168
|
+
propLabel: { fontSize: 11.5, fontWeight: 600, color: "var(--fb-muted)", marginTop: 12, marginBottom: 5 },
|
|
1169
|
+
propInput: { border: "1px solid var(--fb-border)", borderRadius: 7, padding: "7px 9px", fontSize: 13, color: "var(--fb-ink)", background: "var(--fb-surface)", outline: "none", width: "100%", boxSizing: "border-box" },
|
|
1120
1170
|
optionList: { display: "flex", flexDirection: "column", gap: 6 },
|
|
1121
1171
|
optionRow: { display: "flex", gap: 6, alignItems: "center" },
|
|
1122
|
-
optionInput: { flex: 1, border: "1px solid var(--fb-border)", borderRadius: 6, padding: "6px 8px", fontSize: 12.5, outline: "none", minWidth: 0, boxSizing: "border-box" },
|
|
1123
|
-
addOptionBtn: { display: "flex", alignItems: "center", gap: 5, fontSize: 12.5, color: "var(--fb-primary)", background: "transparent", border: "1px dashed
|
|
1172
|
+
optionInput: { flex: 1, border: "1px solid var(--fb-border)", borderRadius: 6, padding: "6px 8px", fontSize: 12.5, color: "var(--fb-ink)", background: "var(--fb-surface)", outline: "none", minWidth: 0, boxSizing: "border-box" },
|
|
1173
|
+
addOptionBtn: { display: "flex", alignItems: "center", gap: 5, fontSize: 12.5, color: "var(--fb-primary)", background: "transparent", border: "1px dashed var(--fb-border)", borderRadius: 7, padding: "6px 8px", justifyContent: "center", marginTop: 2 },
|
|
1124
1174
|
toggleRow: { display: "flex", alignItems: "center", gap: 8, background: "transparent", border: "none", padding: "8px 0" },
|
|
1125
1175
|
toggleTrack: { width: 30, height: 17, borderRadius: 20, position: "relative", transition: "background 0.15s", display: "inline-block" },
|
|
1126
1176
|
toggleThumb: { position: "absolute", top: 2, left: 2, width: 13, height: 13, borderRadius: "50%", background: "#fff", transition: "transform 0.15s", boxShadow: "0 1px 2px rgba(0,0,0,0.2)" },
|
|
1127
1177
|
inspectorDivider: { height: 1, background: "var(--fb-border)", margin: "14px 0 10px" },
|
|
1128
1178
|
deleteFieldBtn: { display: "flex", alignItems: "center", gap: 6, fontSize: 12.5, color: "var(--fb-danger)", background: "var(--fb-danger-soft)", border: "none", borderRadius: 7, padding: "8px 10px", justifyContent: "center" },
|
|
1129
|
-
modalOverlay: { position: "fixed", inset: 0, background: "rgba(20,22,28,0.45)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 50 },
|
|
1130
|
-
modal: { background: "
|
|
1179
|
+
modalOverlay: { position: "fixed", inset: 0, background: "rgba(20,22,28,0.45)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 50, padding: 16, boxSizing: "border-box" },
|
|
1180
|
+
modal: { background: "var(--fb-surface)", borderRadius: 12, width: "100%", maxWidth: 520, maxHeight: "70vh", display: "flex", flexDirection: "column", overflow: "hidden", boxShadow: "0 20px 60px rgba(0,0,0,0.25)", boxSizing: "border-box" },
|
|
1131
1181
|
modalHeader: { display: "flex", alignItems: "center", justifyContent: "space-between", padding: "12px 16px", borderBottom: "1px solid var(--fb-border)" },
|
|
1132
1182
|
jsonPre: { margin: 0, padding: 16, fontSize: 12, lineHeight: 1.6, overflow: "auto", background: "#14171C", color: "#D6D8E0", fontFamily: "'JetBrains Mono', monospace" },
|
|
1133
1183
|
previewWrap: { flex: 1, display: "flex", justifyContent: "center", padding: "var(--fb-space-page) 20px", overflowY: "auto", background: "var(--fb-canvas)" },
|
|
1134
1184
|
previewToolbar: { width: "100%", display: "flex", gap: 10, marginBottom: 16, justifyContent: "center" },
|
|
1135
1185
|
previewCard: { width: "100%", maxWidth: 480, background: "var(--fb-page-bg)", border: "1px solid var(--fb-border)", borderRadius: 12, padding: "var(--fb-space-page)" },
|
|
1136
1186
|
previewTitle: { fontSize: 19, fontWeight: 700, margin: "0 0 20px" },
|
|
1137
|
-
previewLabel: { display: "block", fontSize: 13, fontWeight: 600, color: "
|
|
1187
|
+
previewLabel: { display: "block", fontSize: 13, fontWeight: 600, color: "var(--fb-ink)", marginBottom: 6 },
|
|
1138
1188
|
previewGrid: { display: "flex", flexWrap: "wrap", gap: "var(--fb-space-field)" },
|
|
1139
1189
|
sectionRuntimeTitle: { fontSize: 15, fontWeight: 700, margin: "0 0 12px", color: "var(--fb-ink)" },
|
|
1140
1190
|
imagePlaceholder: { display: "flex", alignItems: "center", justifyContent: "center", border: "1px dashed var(--fb-border)" },
|
|
@@ -1144,13 +1194,13 @@ var styles = {
|
|
|
1144
1194
|
submittedRow: { display: "flex", justifyContent: "space-between", gap: 12, fontSize: 13, padding: "6px 0", borderBottom: "1px solid var(--fb-border)" },
|
|
1145
1195
|
submittedLabel: { color: "var(--fb-muted)", flexShrink: 0 },
|
|
1146
1196
|
submittedValue: { color: "var(--fb-ink)", fontWeight: 600, textAlign: "right" },
|
|
1147
|
-
realInput: { width: "100%", border: "1px solid var(--fb-border)", borderRadius: 8, padding: "9px 11px", fontSize: 13.5, outline: "none", color: "var(--fb-ink)", boxSizing: "border-box" },
|
|
1197
|
+
realInput: { width: "100%", border: "1px solid var(--fb-border)", borderRadius: 8, padding: "9px 11px", fontSize: 13.5, outline: "none", color: "var(--fb-ink)", background: "var(--fb-surface)", boxSizing: "border-box" },
|
|
1148
1198
|
realInputError: { borderColor: "var(--fb-danger)" },
|
|
1149
1199
|
submitBtn: { marginTop: 8, color: "#fff", border: "none", borderRadius: 8, fontWeight: 600, width: "100%" },
|
|
1150
1200
|
layoutPanelHeader: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 4 },
|
|
1151
1201
|
spacingRow: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, padding: "4px 0" },
|
|
1152
|
-
spacingLabel: { fontSize: 12, color: "
|
|
1153
|
-
spacingInput: { width: 60, border: "1px solid var(--fb-border)", borderRadius: 6, padding: "4px 6px", fontSize: 12, textAlign: "right", outline: "none" }
|
|
1202
|
+
spacingLabel: { fontSize: 12, color: "var(--fb-ink)" },
|
|
1203
|
+
spacingInput: { width: 60, border: "1px solid var(--fb-border)", borderRadius: 6, padding: "4px 6px", fontSize: 12, textAlign: "right", color: "var(--fb-ink)", background: "var(--fb-surface)", outline: "none" }
|
|
1154
1204
|
};
|
|
1155
1205
|
|
|
1156
1206
|
// src/components/LanguageToggle.tsx
|
|
@@ -1191,6 +1241,7 @@ function Toolbar({
|
|
|
1191
1241
|
mode,
|
|
1192
1242
|
saveState,
|
|
1193
1243
|
chrome,
|
|
1244
|
+
features,
|
|
1194
1245
|
savedFormsCount,
|
|
1195
1246
|
onTitleChange,
|
|
1196
1247
|
onLanguageChange,
|
|
@@ -1203,7 +1254,7 @@ function Toolbar({
|
|
|
1203
1254
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.toolbar, children: [
|
|
1204
1255
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.toolbarLeft, children: [
|
|
1205
1256
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.logoMark, children: "FB" }),
|
|
1206
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("input", { value: t(title, language), onChange: (e) => onTitleChange(e.target.value), style: styles.titleInput, "aria-label": "Form title" })
|
|
1257
|
+
features.naming ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("input", { value: t(title, language), onChange: (e) => onTitleChange(e.target.value), style: styles.titleInput, "aria-label": "Form title" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.titleInput, children: t(title, language) })
|
|
1207
1258
|
] }),
|
|
1208
1259
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.toolbarRight, children: [
|
|
1209
1260
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.saveStatus, children: [
|
|
@@ -1219,37 +1270,43 @@ function Toolbar({
|
|
|
1219
1270
|
chrome.saveFailed
|
|
1220
1271
|
] })
|
|
1221
1272
|
] }),
|
|
1222
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: mode === "build" ? styles.tabBtnActive : styles.tabBtn, onClick: () => onModeChange("build"), children: [
|
|
1226
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Pencil, { size: 14 }),
|
|
1227
|
-
" ",
|
|
1228
|
-
chrome.build
|
|
1273
|
+
features.languageSwitcher && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
1274
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.toolbarDivider }),
|
|
1275
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LanguageToggle, { languages, value: language, onChange: onLanguageChange })
|
|
1229
1276
|
] }),
|
|
1230
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1231
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1232
|
-
" ",
|
|
1233
|
-
|
|
1277
|
+
features.previewMode && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
1278
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.toolbarDivider }),
|
|
1279
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: mode === "build" ? styles.tabBtnActive : styles.tabBtn, onClick: () => onModeChange("build"), children: [
|
|
1280
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Pencil, { size: 14 }),
|
|
1281
|
+
" ",
|
|
1282
|
+
chrome.build
|
|
1283
|
+
] }),
|
|
1284
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: mode === "preview" ? styles.tabBtnActive : styles.tabBtn, onClick: () => onModeChange("preview"), children: [
|
|
1285
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Eye, { size: 14 }),
|
|
1286
|
+
" ",
|
|
1287
|
+
chrome.preview
|
|
1288
|
+
] })
|
|
1234
1289
|
] }),
|
|
1235
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.toolbarDivider }),
|
|
1236
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: styles.ghostBtn, onClick: onNewForm, title: chrome.startNewForm, children: [
|
|
1290
|
+
(features.newForm || features.templates) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.toolbarDivider }),
|
|
1291
|
+
features.newForm && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: styles.ghostBtn, onClick: onNewForm, title: chrome.startNewForm, children: [
|
|
1237
1292
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.FilePlus2, { size: 14 }),
|
|
1238
1293
|
" ",
|
|
1239
1294
|
chrome.newForm
|
|
1240
1295
|
] }),
|
|
1241
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1242
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
1249
|
-
|
|
1250
|
-
|
|
1296
|
+
features.templates && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
1297
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: styles.ghostBtn, onClick: onOpenLibrary, title: chrome.openTemplatesTitle, children: [
|
|
1298
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.FolderOpen, { size: 14 }),
|
|
1299
|
+
" ",
|
|
1300
|
+
chrome.templates,
|
|
1301
|
+
savedFormsCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.countBadge, children: savedFormsCount })
|
|
1302
|
+
] }),
|
|
1303
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: styles.primaryBtn, onClick: onSaveExisting, title: chrome.saveToLibraryTitle, children: [
|
|
1304
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Save, { size: 14 }),
|
|
1305
|
+
" ",
|
|
1306
|
+
chrome.save
|
|
1307
|
+
] })
|
|
1251
1308
|
] }),
|
|
1252
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: styles.ghostBtn, onClick: onOpenJson, children: [
|
|
1309
|
+
features.jsonView && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: styles.ghostBtn, onClick: onOpenJson, children: [
|
|
1253
1310
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Code2, { size: 14 }),
|
|
1254
1311
|
" ",
|
|
1255
1312
|
chrome.viewJson
|
|
@@ -1350,15 +1407,17 @@ function Palette({
|
|
|
1350
1407
|
activeSectionLabel,
|
|
1351
1408
|
chrome,
|
|
1352
1409
|
onAddField,
|
|
1353
|
-
|
|
1410
|
+
features,
|
|
1354
1411
|
theme,
|
|
1355
1412
|
updateThemeColor,
|
|
1356
1413
|
updateThemeLayout,
|
|
1357
1414
|
resetTheme
|
|
1358
1415
|
}) {
|
|
1359
1416
|
const [tab, setTab] = (0, import_react5.useState)("blocks");
|
|
1360
|
-
|
|
1361
|
-
|
|
1417
|
+
const contentTypes = CONTENT_TYPES.filter((f) => isContentBlockEnabled(features, f.type));
|
|
1418
|
+
const formTypes = FORM_TYPES.filter((f) => isFieldTypeEnabled(features, f.type));
|
|
1419
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "fb-palette", style: styles.palette, children: [
|
|
1420
|
+
features.design && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { marginBottom: 14 }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1362
1421
|
Segmented,
|
|
1363
1422
|
{
|
|
1364
1423
|
options: [
|
|
@@ -1369,7 +1428,7 @@ function Palette({
|
|
|
1369
1428
|
onChange: setTab
|
|
1370
1429
|
}
|
|
1371
1430
|
) }),
|
|
1372
|
-
tab === "design" &&
|
|
1431
|
+
tab === "design" && features.design ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1373
1432
|
DesignPanel,
|
|
1374
1433
|
{
|
|
1375
1434
|
chrome,
|
|
@@ -1384,24 +1443,28 @@ function Palette({
|
|
|
1384
1443
|
" ",
|
|
1385
1444
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: activeSectionLabel })
|
|
1386
1445
|
] }),
|
|
1387
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1403
|
-
|
|
1404
|
-
|
|
1446
|
+
contentTypes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
1447
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles.panelHeading, children: chrome.contentBlocks }),
|
|
1448
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles.paletteList, children: contentTypes.map((f) => {
|
|
1449
|
+
const Icon = f.icon;
|
|
1450
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { style: styles.paletteItem, onClick: () => onAddField(f.type), children: [
|
|
1451
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { size: 16, color: "var(--fb-primary)" }),
|
|
1452
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: chrome[FIELD_TYPE_CHROME_KEY[f.type]] }),
|
|
1453
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react5.Plus, { size: 13, color: "var(--fb-muted)", style: { marginLeft: "auto" } })
|
|
1454
|
+
] }, f.type);
|
|
1455
|
+
}) })
|
|
1456
|
+
] }),
|
|
1457
|
+
formTypes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
1458
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { ...styles.panelHeading, marginTop: 16 }, children: chrome.formFields }),
|
|
1459
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles.paletteList, children: formTypes.map((f) => {
|
|
1460
|
+
const Icon = f.icon;
|
|
1461
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { style: styles.paletteItem, onClick: () => onAddField(f.type), children: [
|
|
1462
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { size: 16, color: "var(--fb-primary)" }),
|
|
1463
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: chrome[FIELD_TYPE_CHROME_KEY[f.type]] }),
|
|
1464
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react5.Plus, { size: 13, color: "var(--fb-muted)", style: { marginLeft: "auto" } })
|
|
1465
|
+
] }, f.type);
|
|
1466
|
+
}) })
|
|
1467
|
+
] })
|
|
1405
1468
|
] })
|
|
1406
1469
|
] });
|
|
1407
1470
|
}
|
|
@@ -1530,7 +1593,7 @@ function FieldBlock({ field, lang, onFieldChange, strings, chrome, error, isBuil
|
|
|
1530
1593
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
|
|
1531
1594
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", flexDirection: isInline ? "row" : "column", alignItems: isInline ? "center" : "stretch", gap: isInline ? 10 : 6 }, children: [
|
|
1532
1595
|
showLabel && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { style: { ...styles.previewLabel, marginBottom: isInline ? 0 : 6, flexShrink: 0, width: isInline ? 120 : "auto", display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
1533
|
-
IconComp && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconComp, { size: 14, color: "
|
|
1596
|
+
IconComp && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconComp, { size: 14, color: "var(--fb-muted)" }),
|
|
1534
1597
|
labelText || (isBuild ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { fontStyle: "italic", color: "var(--fb-muted)" }, children: chrome?.untitledField || "Untitled field" }) : ""),
|
|
1535
1598
|
field.required && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: "var(--fb-danger)" }, children: " *" })
|
|
1536
1599
|
] }),
|
|
@@ -1595,14 +1658,14 @@ function renderInteractive(field, lang, onFieldChange, IconComp, hasError, strin
|
|
|
1595
1658
|
case "checkbox":
|
|
1596
1659
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { style: styles.previewRadio, children: [
|
|
1597
1660
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "checkbox", checked: !!value, onChange: (e) => set(e.target.checked), style: { accentColor: "var(--fb-primary)" } }),
|
|
1598
|
-
IconComp && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconComp, { size: 14, color: "
|
|
1661
|
+
IconComp && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconComp, { size: 14, color: "var(--fb-muted)" }),
|
|
1599
1662
|
t(field.label, lang),
|
|
1600
1663
|
field.required && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: "var(--fb-danger)" }, children: " *" })
|
|
1601
1664
|
] });
|
|
1602
1665
|
case "toggle":
|
|
1603
1666
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { style: styles.previewRadio, children: [
|
|
1604
1667
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "checkbox", checked: !!value, onChange: (e) => set(e.target.checked), style: { accentColor: "var(--fb-primary)" } }),
|
|
1605
|
-
IconComp && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconComp, { size: 14, color: "
|
|
1668
|
+
IconComp && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconComp, { size: 14, color: "var(--fb-muted)" }),
|
|
1606
1669
|
t(field.label, lang)
|
|
1607
1670
|
] });
|
|
1608
1671
|
default:
|
|
@@ -1620,6 +1683,7 @@ function FieldTicket({
|
|
|
1620
1683
|
chrome,
|
|
1621
1684
|
strings,
|
|
1622
1685
|
language,
|
|
1686
|
+
dragEnabled,
|
|
1623
1687
|
onSelect,
|
|
1624
1688
|
onFieldChange,
|
|
1625
1689
|
onMoveField,
|
|
@@ -1649,7 +1713,7 @@ function FieldTicket({
|
|
|
1649
1713
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: styles.ticketPerforation }),
|
|
1650
1714
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: styles.ticketBody, children: [
|
|
1651
1715
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: styles.ticketTop, children: [
|
|
1652
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { ...dragHandleProps, style: { cursor: "grab", display: "flex" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react10.GripVertical, { size: 14, color: "
|
|
1716
|
+
dragEnabled && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { ...dragHandleProps, style: { cursor: "grab", display: "flex" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react10.GripVertical, { size: 14, color: "var(--fb-muted)" }) }),
|
|
1653
1717
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon, { size: 13, color: "var(--fb-primary)" }),
|
|
1654
1718
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: styles.typeBadge, children: [
|
|
1655
1719
|
chrome[FIELD_TYPE_CHROME_KEY[field.type]] || field.type,
|
|
@@ -1692,6 +1756,7 @@ function SectionCard({
|
|
|
1692
1756
|
chrome,
|
|
1693
1757
|
strings,
|
|
1694
1758
|
language,
|
|
1759
|
+
features,
|
|
1695
1760
|
onActivate,
|
|
1696
1761
|
onToggleCollapse,
|
|
1697
1762
|
onUpdateTitle,
|
|
@@ -1731,14 +1796,16 @@ function SectionCard({
|
|
|
1731
1796
|
),
|
|
1732
1797
|
section.collapsed && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: styles.miniBadge, children: chrome.fieldsCount(section.fields.length) }),
|
|
1733
1798
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: styles.sectionHeaderActions, onClick: (e) => e.stopPropagation(), children: [
|
|
1734
|
-
!section.collapsed && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: styles.swatchRow, children: [
|
|
1799
|
+
features.sections && !section.collapsed && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: styles.swatchRow, children: [
|
|
1735
1800
|
SECTION_BG_SWATCHES.map((c) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", title: c || chrome.none, style: { ...styles.swatchBtn, background: c || "var(--fb-canvas)", ...section.background === c ? styles.swatchBtnActive : {} }, onClick: () => onUpdateBackground(c) }, c || "none")),
|
|
1736
1801
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "color", title: chrome.customColor, value: /^#/.test(section.background) ? section.background : "#ffffff", onChange: (e) => onUpdateBackground(e.target.value), style: styles.colorPickerInput })
|
|
1737
1802
|
] }),
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1803
|
+
features.sections && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1804
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { style: styles.iconBtn, title: chrome.duplicate, onClick: onDuplicateSection, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react11.Copy, { size: 13 }) }),
|
|
1805
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { style: styles.iconBtn, title: chrome.moveUp, disabled: sIdx === 0, onClick: () => onMoveSection(-1), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react11.ArrowUp, { size: 13 }) }),
|
|
1806
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { style: styles.iconBtn, title: chrome.moveDown, disabled: sIdx === sectionsLength - 1, onClick: () => onMoveSection(1), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react11.ArrowDown, { size: 13 }) }),
|
|
1807
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { style: { ...styles.iconBtn, ...styles.iconBtnDanger }, title: chrome.deleteSection, disabled: sectionsLength <= 1, onClick: onDeleteSection, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react11.Trash2, { size: 13 }) })
|
|
1808
|
+
] })
|
|
1742
1809
|
] })
|
|
1743
1810
|
] }),
|
|
1744
1811
|
!section.collapsed && (section.fields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: styles.sectionEmpty, children: chrome.noFieldsInSection }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: styles.fieldList, children: section.fields.map((field, idx) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
@@ -1752,6 +1819,7 @@ function SectionCard({
|
|
|
1752
1819
|
chrome,
|
|
1753
1820
|
strings,
|
|
1754
1821
|
language,
|
|
1822
|
+
dragEnabled: features.dragReorder,
|
|
1755
1823
|
onSelect: () => onSelectField(field.id),
|
|
1756
1824
|
onFieldChange,
|
|
1757
1825
|
onMoveField,
|
|
@@ -1777,6 +1845,7 @@ function Canvas({
|
|
|
1777
1845
|
chrome,
|
|
1778
1846
|
strings,
|
|
1779
1847
|
language,
|
|
1848
|
+
features,
|
|
1780
1849
|
onActivateSection,
|
|
1781
1850
|
onToggleSectionCollapse,
|
|
1782
1851
|
onUpdateSectionTitle,
|
|
@@ -1793,7 +1862,7 @@ function Canvas({
|
|
|
1793
1862
|
getDropZoneHandlers,
|
|
1794
1863
|
getDragHandleProps
|
|
1795
1864
|
}) {
|
|
1796
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: styles.canvas, children: [
|
|
1865
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "fb-canvas", style: styles.canvas, children: [
|
|
1797
1866
|
sections.map((section, sIdx) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1798
1867
|
SectionCard,
|
|
1799
1868
|
{
|
|
@@ -1806,6 +1875,7 @@ function Canvas({
|
|
|
1806
1875
|
chrome,
|
|
1807
1876
|
strings,
|
|
1808
1877
|
language,
|
|
1878
|
+
features,
|
|
1809
1879
|
onActivate: () => onActivateSection(section.id),
|
|
1810
1880
|
onToggleCollapse: () => onToggleSectionCollapse(section.id),
|
|
1811
1881
|
onUpdateTitle: (value) => onUpdateSectionTitle(section.id, value),
|
|
@@ -1823,7 +1893,7 @@ function Canvas({
|
|
|
1823
1893
|
},
|
|
1824
1894
|
section.id
|
|
1825
1895
|
)),
|
|
1826
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("button", { style: styles.addSectionBtn, onClick: onAddSection, children: [
|
|
1896
|
+
features.sections && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("button", { style: styles.addSectionBtn, onClick: onAddSection, children: [
|
|
1827
1897
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react12.Layers, { size: 14 }),
|
|
1828
1898
|
" ",
|
|
1829
1899
|
chrome.addSection
|
|
@@ -1844,7 +1914,7 @@ function DefaultValueEditor({ field, meta, lang, chrome, onChange }) {
|
|
|
1844
1914
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("label", { style: styles.propLabel, children: chrome.defaultValue }),
|
|
1845
1915
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { style: styles.toggleRow, onClick: () => onChange({ defaultValue: !f.defaultValue }), children: [
|
|
1846
1916
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { ...styles.toggleTrack, background: f.defaultValue ? "var(--fb-primary)" : "var(--fb-border)" }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { ...styles.toggleThumb, transform: f.defaultValue ? "translateX(16px)" : "translateX(0)" } }) }),
|
|
1847
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { fontSize: 13, color: "
|
|
1917
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { fontSize: 13, color: "var(--fb-ink)" }, children: f.defaultValue ? chrome.checked : chrome.unchecked })
|
|
1848
1918
|
] })
|
|
1849
1919
|
] });
|
|
1850
1920
|
}
|
|
@@ -1882,8 +1952,8 @@ function DefaultValueEditor({ field, meta, lang, chrome, onChange }) {
|
|
|
1882
1952
|
|
|
1883
1953
|
// src/components/Inspector.tsx
|
|
1884
1954
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1885
|
-
function Inspector({ selected, language, chrome, onUpdateField, onDeleteField, onUpdateOption, onAddOption, onRemoveOption }) {
|
|
1886
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: styles.inspector, children: [
|
|
1955
|
+
function Inspector({ selected, language, chrome, features, onUpdateField, onDeleteField, onUpdateOption, onAddOption, onRemoveOption }) {
|
|
1956
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "fb-inspector", style: styles.inspector, children: [
|
|
1887
1957
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.panelHeading, children: chrome.properties }),
|
|
1888
1958
|
!selected ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.inspectorEmpty, children: chrome.selectFieldHint }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1889
1959
|
InspectorBody,
|
|
@@ -1891,6 +1961,7 @@ function Inspector({ selected, language, chrome, onUpdateField, onDeleteField, o
|
|
|
1891
1961
|
selected,
|
|
1892
1962
|
language,
|
|
1893
1963
|
chrome,
|
|
1964
|
+
features,
|
|
1894
1965
|
onUpdateField,
|
|
1895
1966
|
onDeleteField,
|
|
1896
1967
|
onUpdateOption,
|
|
@@ -1900,7 +1971,7 @@ function Inspector({ selected, language, chrome, onUpdateField, onDeleteField, o
|
|
|
1900
1971
|
)
|
|
1901
1972
|
] });
|
|
1902
1973
|
}
|
|
1903
|
-
function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteField, onUpdateOption, onAddOption, onRemoveOption }) {
|
|
1974
|
+
function InspectorBody({ selected, language, chrome, features, onUpdateField, onDeleteField, onUpdateOption, onAddOption, onRemoveOption }) {
|
|
1904
1975
|
const meta = getMeta(selected.type);
|
|
1905
1976
|
const f = selected;
|
|
1906
1977
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: styles.inspectorBody, children: [
|
|
@@ -1909,7 +1980,7 @@ function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteFiel
|
|
|
1909
1980
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { style: styles.propInput, value: t(selected.label, language), onChange: (e) => onUpdateField({ label: withLang(selected.label, language, e.target.value) }) }),
|
|
1910
1981
|
!meta.isContent && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { style: styles.toggleRow, children: [
|
|
1911
1982
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { type: "checkbox", checked: !!selected.hideLabel, onChange: (e) => onUpdateField({ hideLabel: e.target.checked }), style: { width: 15, height: 15, accentColor: "var(--fb-primary)" } }),
|
|
1912
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: 13, color: "
|
|
1983
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: 13, color: "var(--fb-ink)" }, children: chrome.hideLabel })
|
|
1913
1984
|
] })
|
|
1914
1985
|
] }),
|
|
1915
1986
|
meta.hasSubtype && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
@@ -1919,23 +1990,25 @@ function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteFiel
|
|
|
1919
1990
|
selected.type === "paragraph" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1920
1991
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.content }),
|
|
1921
1992
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("textarea", { style: { ...styles.propInput, minHeight: 70, resize: "vertical" }, value: t(selected.content, language), onChange: (e) => onUpdateField({ content: withLang(selected.content, language, e.target.value) }) }),
|
|
1922
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1993
|
+
features.blockStyling && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1994
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.inspectorDivider }),
|
|
1995
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.panelHeading, children: chrome.typography }),
|
|
1996
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.headingStyle }),
|
|
1997
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Segmented, { options: PARAGRAPH_TAG_OPTIONS.map((v) => ({ value: v, label: TAG_CHROME_KEY[v] ? chrome[TAG_CHROME_KEY[v]] : v.toUpperCase() })), value: selected.tag || "p", onChange: (v) => onUpdateField({ tag: v, ...TAG_PRESETS[v] }) }),
|
|
1998
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.width }),
|
|
1999
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Segmented, { options: FONT_SIZE_OPTIONS, value: selected.fontSize || "md", onChange: (v) => onUpdateField({ fontSize: v }) }),
|
|
2000
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.style }),
|
|
2001
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: styles.styleToggleRow, children: [
|
|
2002
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", style: selected.fontWeight === "bold" ? styles.styleToggleActive : styles.styleToggle, onClick: () => onUpdateField({ fontWeight: selected.fontWeight === "bold" ? "normal" : "bold" }), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react13.Bold, { size: 14 }) }),
|
|
2003
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", style: selected.fontStyle === "italic" ? styles.styleToggleActive : styles.styleToggle, onClick: () => onUpdateField({ fontStyle: selected.fontStyle === "italic" ? "normal" : "italic" }), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react13.Italic, { size: 14 }) })
|
|
2004
|
+
] }),
|
|
2005
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.align }),
|
|
2006
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Segmented, { options: TEXT_ALIGN_OPTIONS, value: selected.textAlign || "left", onChange: (v) => onUpdateField({ textAlign: v }) }),
|
|
2007
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.color }),
|
|
2008
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: styles.swatchRow, children: [
|
|
2009
|
+
COLOR_SWATCHES.map((c) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", title: c || chrome.none, style: { ...styles.swatchBtn, background: c || "var(--fb-ink)", ...selected.color === c ? styles.swatchBtnActive : {} }, onClick: () => onUpdateField({ color: c }) }, c || "default")),
|
|
2010
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { type: "color", value: selected.color || "#1B1E24", onChange: (e) => onUpdateField({ color: e.target.value }), style: styles.colorPickerInput })
|
|
2011
|
+
] })
|
|
1939
2012
|
] })
|
|
1940
2013
|
] }),
|
|
1941
2014
|
selected.type === "image" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
@@ -1964,13 +2037,15 @@ function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteFiel
|
|
|
1964
2037
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.submitScope }),
|
|
1965
2038
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Segmented, { options: [{ value: "section", label: chrome.thisSection }, { value: "form", label: chrome.wholeForm }], value: selected.submitScope || "form", onChange: (v) => onUpdateField({ submitScope: v }) })
|
|
1966
2039
|
] }),
|
|
1967
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
2040
|
+
features.blockStyling && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
2041
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.color }),
|
|
2042
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: styles.swatchRow, children: [
|
|
2043
|
+
BUTTON_COLOR_SWATCHES.map((c) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", title: c || chrome.none, style: { ...styles.swatchBtn, background: c || "var(--fb-primary)", ...(selected.buttonStyle?.color || "") === c ? styles.swatchBtnActive : {} }, onClick: () => onUpdateField({ buttonStyle: { ...selected.buttonStyle, color: c } }) }, c || "default")),
|
|
2044
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { type: "color", value: selected.buttonStyle?.color || "#5B5FEF", onChange: (e) => onUpdateField({ buttonStyle: { ...selected.buttonStyle, color: e.target.value } }), style: styles.colorPickerInput })
|
|
2045
|
+
] }),
|
|
2046
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.buttonSize }),
|
|
2047
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Segmented, { options: SUBMIT_SIZE_OPTIONS, value: selected.buttonStyle?.size || "md", onChange: (v) => onUpdateField({ buttonStyle: { ...selected.buttonStyle, size: v } }) })
|
|
2048
|
+
] })
|
|
1974
2049
|
] }),
|
|
1975
2050
|
meta.placeholder && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1976
2051
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.placeholder }),
|
|
@@ -2007,7 +2082,7 @@ function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteFiel
|
|
|
2007
2082
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DefaultValueEditor, { field: selected, meta, lang: language, chrome, onChange: onUpdateField }),
|
|
2008
2083
|
!meta.isContent && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { style: styles.toggleRow, children: [
|
|
2009
2084
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { type: "checkbox", checked: !!selected.required, onChange: (e) => onUpdateField({ required: e.target.checked }), style: { width: 15, height: 15, accentColor: "var(--fb-primary)" } }),
|
|
2010
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: 13, color: "
|
|
2085
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: 13, color: "var(--fb-ink)" }, children: chrome.requiredField })
|
|
2011
2086
|
] }),
|
|
2012
2087
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.inspectorDivider }),
|
|
2013
2088
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.panelHeading, children: chrome.layout }),
|
|
@@ -2024,7 +2099,7 @@ function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteFiel
|
|
|
2024
2099
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.panelHeading, children: chrome.icon }),
|
|
2025
2100
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { style: styles.toggleRow, children: [
|
|
2026
2101
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { type: "checkbox", checked: !!selected.showIcon, onChange: (e) => onUpdateField({ showIcon: e.target.checked }), style: { width: 15, height: 15, accentColor: "var(--fb-primary)" } }),
|
|
2027
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: 13, color: "
|
|
2102
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: 13, color: "var(--fb-ink)" }, children: chrome.showIcon })
|
|
2028
2103
|
] }),
|
|
2029
2104
|
selected.showIcon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.iconGrid, children: Object.keys(ICON_LIBRARY).map((key) => {
|
|
2030
2105
|
const IconComp = ICON_LIBRARY[key];
|
|
@@ -2176,7 +2251,7 @@ function PreviewPane({ title, sections, onFieldChange, language, strings, chrome
|
|
|
2176
2251
|
})
|
|
2177
2252
|
] })
|
|
2178
2253
|
] }),
|
|
2179
|
-
submitted && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: styles.modalOverlay, onClick: () => setSubmitted(null), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { ...styles.modal,
|
|
2254
|
+
submitted && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: styles.modalOverlay, onClick: () => setSubmitted(null), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { ...styles.modal, maxWidth: 420 }, onClick: (e) => e.stopPropagation(), children: [
|
|
2180
2255
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: styles.modalHeader, children: [
|
|
2181
2256
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { style: { fontWeight: 600, fontSize: 14, display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
2182
2257
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react14.PartyPopper, { size: 15, color: "var(--fb-primary)" }),
|
|
@@ -2251,7 +2326,7 @@ var import_lucide_react17 = require("lucide-react");
|
|
|
2251
2326
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2252
2327
|
function SaveAsModal({ chrome, suggestedName, onSave, onClose }) {
|
|
2253
2328
|
const [name, setName] = (0, import_react7.useState)(suggestedName);
|
|
2254
|
-
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: styles.modalOverlay, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { ...styles.modal,
|
|
2329
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: styles.modalOverlay, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { ...styles.modal, maxWidth: 380 }, onClick: (e) => e.stopPropagation(), children: [
|
|
2255
2330
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: styles.modalHeader, children: [
|
|
2256
2331
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { fontWeight: 600, fontSize: 14 }, children: chrome.saveForm }),
|
|
2257
2332
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { style: styles.iconBtn, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react17.X, { size: 16 }) })
|
|
@@ -2281,6 +2356,36 @@ var css = `
|
|
|
2281
2356
|
that support it (mobile browser chrome resizing the viewport), and is
|
|
2282
2357
|
simply ignored by ones that don't. */
|
|
2283
2358
|
.fb-root { max-height: 100vh; max-height: 100dvh; }
|
|
2359
|
+
|
|
2360
|
+
/* Below this width the fixed 200px Palette + 270px Inspector columns
|
|
2361
|
+
don't leave room for a usable Canvas, so instead of stacking all
|
|
2362
|
+
three in flow (which buries Canvas under a tall Palette), Palette
|
|
2363
|
+
and Inspector become narrow drawers over Canvas (which stays
|
|
2364
|
+
partially visible behind them), toggled by .fb-mobile-bar's two
|
|
2365
|
+
buttons, tracked by .fb-work-area's data-mobile-panel attribute,
|
|
2366
|
+
and dismissible via .fb-mobile-backdrop. */
|
|
2367
|
+
.fb-mobile-bar { display: none; align-items: center; gap: 6px; padding: 6px 10px; border-bottom: 1px solid var(--fb-border); background: var(--fb-surface); flex-shrink: 0; }
|
|
2368
|
+
.fb-mobile-btn { display: flex; align-items: center; gap: 6px; padding: 6px 10px; border-radius: 7px; border: 1px solid var(--fb-border); background: var(--fb-surface); color: var(--fb-muted); font-size: 12.5px; font-weight: 600; }
|
|
2369
|
+
.fb-mobile-btn[aria-pressed="true"] { border-color: var(--fb-primary); background: var(--fb-primary-soft); color: var(--fb-primary); }
|
|
2370
|
+
.fb-mobile-backdrop { display: none; }
|
|
2371
|
+
@media (max-width: 720px) {
|
|
2372
|
+
.fb-mobile-bar { display: flex; }
|
|
2373
|
+
.fb-work-area { flex-direction: column !important; min-height: 0; }
|
|
2374
|
+
.fb-canvas-area { position: relative; overflow: hidden; }
|
|
2375
|
+
.fb-canvas { width: 100%; }
|
|
2376
|
+
.fb-mobile-backdrop { display: block; position: absolute; inset: 0; z-index: 6; background: rgba(15,16,20,0.35); }
|
|
2377
|
+
.fb-palette, .fb-inspector {
|
|
2378
|
+
position: absolute; top: 0; bottom: 0; z-index: 7;
|
|
2379
|
+
width: min(260px, 80vw) !important; max-height: none !important;
|
|
2380
|
+
border: none !important;
|
|
2381
|
+
box-shadow: 0 0 24px rgba(0,0,0,0.18);
|
|
2382
|
+
transition: transform 0.18s ease;
|
|
2383
|
+
}
|
|
2384
|
+
.fb-palette { left: 0; transform: translateX(-100%); }
|
|
2385
|
+
.fb-inspector { right: 0; transform: translateX(100%); }
|
|
2386
|
+
.fb-work-area[data-mobile-panel="palette"] .fb-palette,
|
|
2387
|
+
.fb-work-area[data-mobile-panel="inspector"] .fb-inspector { transform: translateX(0); }
|
|
2388
|
+
}
|
|
2284
2389
|
`;
|
|
2285
2390
|
|
|
2286
2391
|
// src/FormBuilder.tsx
|
|
@@ -2291,11 +2396,12 @@ var FormBuilder = (0, import_react8.forwardRef)(function FormBuilder2({
|
|
|
2291
2396
|
languages = DEFAULT_LANGUAGES,
|
|
2292
2397
|
strings: stringsOverride,
|
|
2293
2398
|
chrome: chromeOverride,
|
|
2294
|
-
|
|
2399
|
+
features: featuresProp,
|
|
2295
2400
|
storage: storageProp,
|
|
2296
2401
|
onSubmit,
|
|
2297
2402
|
initialDocument
|
|
2298
2403
|
}, ref) {
|
|
2404
|
+
const features = resolveFeatures(featuresProp);
|
|
2299
2405
|
const storage = storageProp ?? localStorageAdapter;
|
|
2300
2406
|
const { theme, updateThemeColor, updateThemeLayout, resetTheme, replaceThemeOverrides, themeOverrides } = useTheme(themeOverrideProp);
|
|
2301
2407
|
const [language, setLanguage] = (0, import_react8.useState)(languageOverride || languages[0]?.code || "en");
|
|
@@ -2307,8 +2413,10 @@ var FormBuilder = (0, import_react8.forwardRef)(function FormBuilder2({
|
|
|
2307
2413
|
const [showJson, setShowJson] = (0, import_react8.useState)(false);
|
|
2308
2414
|
const [showLibrary, setShowLibrary] = (0, import_react8.useState)(false);
|
|
2309
2415
|
const [copied, setCopied] = (0, import_react8.useState)(false);
|
|
2416
|
+
const [mobilePanel, setMobilePanel] = (0, import_react8.useState)("none");
|
|
2310
2417
|
const persistence = usePersistence({
|
|
2311
2418
|
storage,
|
|
2419
|
+
autosave: features.autosave,
|
|
2312
2420
|
language,
|
|
2313
2421
|
chrome,
|
|
2314
2422
|
document: { title: doc.title, themeOverrides, sections: doc.sections },
|
|
@@ -2362,6 +2470,7 @@ var FormBuilder = (0, import_react8.forwardRef)(function FormBuilder2({
|
|
|
2362
2470
|
"--fb-surface": theme.surface,
|
|
2363
2471
|
"--fb-canvas": theme.canvas,
|
|
2364
2472
|
"--fb-page-bg": theme.pageBackground,
|
|
2473
|
+
"--fb-surface-2": mixHex(theme.surface, theme.ink, 0.06),
|
|
2365
2474
|
"--fb-space-page": `${theme.layout.pagePadding}px`,
|
|
2366
2475
|
"--fb-space-canvas": `${theme.layout.canvasPadding}px`,
|
|
2367
2476
|
"--fb-space-section": `${theme.layout.sectionGap}px`,
|
|
@@ -2381,6 +2490,7 @@ var FormBuilder = (0, import_react8.forwardRef)(function FormBuilder2({
|
|
|
2381
2490
|
mode,
|
|
2382
2491
|
saveState: persistence.saveState,
|
|
2383
2492
|
chrome,
|
|
2493
|
+
features,
|
|
2384
2494
|
savedFormsCount: persistence.savedForms.length,
|
|
2385
2495
|
onTitleChange: doc.updateTitle,
|
|
2386
2496
|
onLanguageChange: setLanguage,
|
|
@@ -2394,63 +2504,102 @@ var FormBuilder = (0, import_react8.forwardRef)(function FormBuilder2({
|
|
|
2394
2504
|
persistence.loadingDraft ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: styles.loadingScreen, children: [
|
|
2395
2505
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react18.Loader2, { size: 20, className: "spin" }),
|
|
2396
2506
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { marginTop: 8, fontSize: 13, color: "var(--fb-muted)" }, children: chrome.loadingDraft })
|
|
2397
|
-
] }) : mode === "build" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: styles.workArea, children: [
|
|
2398
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2507
|
+
] }) : mode === "build" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "fb-work-area", style: styles.workArea, "data-mobile-panel": mobilePanel, children: [
|
|
2508
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "fb-mobile-bar", children: [
|
|
2509
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
2510
|
+
"button",
|
|
2511
|
+
{
|
|
2512
|
+
type: "button",
|
|
2513
|
+
className: "fb-mobile-btn",
|
|
2514
|
+
"aria-pressed": mobilePanel === "palette",
|
|
2515
|
+
onClick: () => setMobilePanel((p) => p === "palette" ? "none" : "palette"),
|
|
2516
|
+
children: [
|
|
2517
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react18.Menu, { size: 14 }),
|
|
2518
|
+
" ",
|
|
2519
|
+
chrome.paletteTabBlocks
|
|
2520
|
+
]
|
|
2521
|
+
}
|
|
2522
|
+
),
|
|
2523
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
2524
|
+
"button",
|
|
2525
|
+
{
|
|
2526
|
+
type: "button",
|
|
2527
|
+
className: "fb-mobile-btn",
|
|
2528
|
+
"aria-pressed": mobilePanel === "inspector",
|
|
2529
|
+
onClick: () => setMobilePanel((p) => p === "inspector" ? "none" : "inspector"),
|
|
2530
|
+
children: [
|
|
2531
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react18.SlidersHorizontal, { size: 14 }),
|
|
2532
|
+
" ",
|
|
2533
|
+
chrome.properties
|
|
2534
|
+
]
|
|
2535
|
+
}
|
|
2536
|
+
)
|
|
2537
|
+
] }),
|
|
2538
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "fb-canvas-area", style: styles.workArea, children: [
|
|
2539
|
+
mobilePanel !== "none" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "fb-mobile-backdrop", onClick: () => setMobilePanel("none") }),
|
|
2540
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2541
|
+
Palette,
|
|
2542
|
+
{
|
|
2543
|
+
activeSectionLabel,
|
|
2544
|
+
chrome,
|
|
2545
|
+
onAddField: (type) => {
|
|
2546
|
+
doc.addField(type);
|
|
2547
|
+
setMobilePanel("none");
|
|
2548
|
+
},
|
|
2549
|
+
features,
|
|
2550
|
+
theme,
|
|
2551
|
+
updateThemeColor,
|
|
2552
|
+
updateThemeLayout,
|
|
2553
|
+
resetTheme
|
|
2554
|
+
}
|
|
2555
|
+
),
|
|
2556
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2557
|
+
Canvas,
|
|
2558
|
+
{
|
|
2559
|
+
sections: doc.sections,
|
|
2560
|
+
activeSectionId: doc.activeSectionId,
|
|
2561
|
+
selectedId: doc.selectedId,
|
|
2562
|
+
dragOverKey: drag.dragOverKey,
|
|
2563
|
+
chrome,
|
|
2564
|
+
strings,
|
|
2565
|
+
language,
|
|
2566
|
+
features,
|
|
2567
|
+
onActivateSection: doc.setActiveSectionId,
|
|
2568
|
+
onToggleSectionCollapse: doc.toggleSectionCollapse,
|
|
2569
|
+
onUpdateSectionTitle: doc.updateSectionTitle,
|
|
2570
|
+
onUpdateSectionBackground: doc.updateSectionBackground,
|
|
2571
|
+
onDuplicateSection: doc.duplicateSection,
|
|
2572
|
+
onMoveSection: doc.moveSection,
|
|
2573
|
+
onDeleteSection: doc.deleteSection,
|
|
2574
|
+
onAddSection: doc.addSection,
|
|
2575
|
+
onSelectField: (sectionId, fieldId) => {
|
|
2576
|
+
doc.setSelectedId(fieldId);
|
|
2577
|
+
doc.setActiveSectionId(sectionId);
|
|
2578
|
+
setMobilePanel("inspector");
|
|
2579
|
+
},
|
|
2580
|
+
onFieldChange: doc.updateField,
|
|
2581
|
+
onMoveField: doc.moveField,
|
|
2582
|
+
onDuplicateField: doc.duplicateField,
|
|
2583
|
+
onDeleteField: doc.deleteField,
|
|
2584
|
+
getDropZoneHandlers: drag.getDropZoneHandlers,
|
|
2585
|
+
getDragHandleProps: drag.getDragHandleProps
|
|
2586
|
+
}
|
|
2587
|
+
),
|
|
2588
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2589
|
+
Inspector,
|
|
2590
|
+
{
|
|
2591
|
+
selected: doc.selected,
|
|
2592
|
+
language,
|
|
2593
|
+
chrome,
|
|
2594
|
+
features,
|
|
2595
|
+
onUpdateField: (patch) => doc.selected && doc.updateField(doc.selected.id, patch),
|
|
2596
|
+
onDeleteField: () => doc.selected && doc.deleteField(doc.selected.id),
|
|
2597
|
+
onUpdateOption: (optIdx, patch) => doc.selected && doc.updateOption(doc.selected.id, optIdx, patch),
|
|
2598
|
+
onAddOption: () => doc.selected && doc.addOption(doc.selected.id),
|
|
2599
|
+
onRemoveOption: (optIdx) => doc.selected && doc.removeOption(doc.selected.id, optIdx)
|
|
2600
|
+
}
|
|
2601
|
+
)
|
|
2602
|
+
] })
|
|
2454
2603
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2455
2604
|
PreviewPane,
|
|
2456
2605
|
{
|
|
@@ -2491,8 +2640,25 @@ var FormBuilder = (0, import_react8.forwardRef)(function FormBuilder2({
|
|
|
2491
2640
|
] });
|
|
2492
2641
|
});
|
|
2493
2642
|
var FormBuilder_default = FormBuilder;
|
|
2643
|
+
|
|
2644
|
+
// src/theme/darkTheme.ts
|
|
2645
|
+
var DARK_THEME = {
|
|
2646
|
+
primary: "#8B8FF5",
|
|
2647
|
+
primarySoft: "#262A45",
|
|
2648
|
+
danger: "#F0715B",
|
|
2649
|
+
dangerSoft: "#3A2420",
|
|
2650
|
+
ink: "#EDEEF2",
|
|
2651
|
+
muted: "#9096A8",
|
|
2652
|
+
border: "#2E313D",
|
|
2653
|
+
surface: "#1A1B23",
|
|
2654
|
+
canvas: "#121319",
|
|
2655
|
+
pageBackground: "#1A1B23",
|
|
2656
|
+
layout: DEFAULT_THEME.layout
|
|
2657
|
+
};
|
|
2494
2658
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2495
2659
|
0 && (module.exports = {
|
|
2660
|
+
DARK_THEME,
|
|
2661
|
+
DEFAULT_THEME,
|
|
2496
2662
|
FormBuilder,
|
|
2497
2663
|
localStorageAdapter
|
|
2498
2664
|
});
|