form-page-builder 1.0.0 → 2.1.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 +88 -2
- package/dist/index.cjs +415 -233
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -2
- package/dist/index.d.ts +46 -2
- package/dist/index.js +447 -267
- 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
|
|
@@ -31,6 +33,56 @@ module.exports = __toCommonJS(index_exports);
|
|
|
31
33
|
var import_react8 = require("react");
|
|
32
34
|
var import_lucide_react18 = require("lucide-react");
|
|
33
35
|
|
|
36
|
+
// src/constants/fieldTypes.ts
|
|
37
|
+
var import_lucide_react = require("lucide-react");
|
|
38
|
+
var FIELD_TYPES = [
|
|
39
|
+
{ type: "paragraph", icon: import_lucide_react.FileText, isContent: true, defaultIcon: "FileText" },
|
|
40
|
+
{ type: "image", icon: import_lucide_react.Image, isContent: true, isImage: true, defaultIcon: "Type" },
|
|
41
|
+
{ type: "button", icon: import_lucide_react.MousePointerClick, isContent: true, defaultIcon: "Type" },
|
|
42
|
+
{ type: "input", icon: import_lucide_react.Type, placeholder: true, hasSubtype: true, defaultIcon: "Type" },
|
|
43
|
+
{ type: "textarea", icon: import_lucide_react.AlignLeft, placeholder: true, defaultIcon: "AlignLeft" },
|
|
44
|
+
{ type: "select", icon: import_lucide_react.ChevronDown, options: true, defaultIcon: "ChevronDown" },
|
|
45
|
+
{ type: "radio", icon: import_lucide_react.Circle, options: true, defaultIcon: "Circle" },
|
|
46
|
+
{ type: "checkboxGroup", icon: import_lucide_react.ListChecks, options: true, multiValue: true, defaultIcon: "ListChecks" },
|
|
47
|
+
{ type: "checkbox", icon: import_lucide_react.CheckSquare, boolean: true, defaultIcon: "CheckSquare" },
|
|
48
|
+
{ type: "toggle", icon: import_lucide_react.ToggleLeft, boolean: true, defaultIcon: "ToggleLeft" }
|
|
49
|
+
];
|
|
50
|
+
var TYPE_MAP = Object.fromEntries(FIELD_TYPES.map((f) => [f.type, f]));
|
|
51
|
+
var CONTENT_TYPES = FIELD_TYPES.filter((f) => f.isContent);
|
|
52
|
+
var FORM_TYPES = FIELD_TYPES.filter((f) => !f.isContent);
|
|
53
|
+
function getMeta(type) {
|
|
54
|
+
return TYPE_MAP[type] || TYPE_MAP.input;
|
|
55
|
+
}
|
|
56
|
+
var LEGACY_INPUT_TYPES = ["text", "email", "phone", "number", "password", "date"];
|
|
57
|
+
var INPUT_SUBTYPES = ["text", "email", "phone", "number", "password", "date", "time"];
|
|
58
|
+
var IMAGE_SHAPES = ["square", "circle", "banner"];
|
|
59
|
+
var FIELD_TYPE_CHROME_KEY = {
|
|
60
|
+
paragraph: "fieldTypeParagraph",
|
|
61
|
+
image: "fieldTypeImage",
|
|
62
|
+
button: "fieldTypeButton",
|
|
63
|
+
input: "fieldTypeInput",
|
|
64
|
+
textarea: "fieldTypeTextarea",
|
|
65
|
+
select: "fieldTypeSelect",
|
|
66
|
+
radio: "fieldTypeRadio",
|
|
67
|
+
checkboxGroup: "fieldTypeCheckboxGroup",
|
|
68
|
+
checkbox: "fieldTypeCheckbox",
|
|
69
|
+
toggle: "fieldTypeToggle"
|
|
70
|
+
};
|
|
71
|
+
var INPUT_SUBTYPE_CHROME_KEY = {
|
|
72
|
+
text: "subtypeText",
|
|
73
|
+
email: "subtypeEmail",
|
|
74
|
+
phone: "subtypePhone",
|
|
75
|
+
number: "subtypeNumber",
|
|
76
|
+
password: "subtypePassword",
|
|
77
|
+
date: "subtypeDate",
|
|
78
|
+
time: "subtypeTime"
|
|
79
|
+
};
|
|
80
|
+
var IMAGE_SHAPE_CHROME_KEY = {
|
|
81
|
+
square: "shapeSquare",
|
|
82
|
+
circle: "shapeCircle",
|
|
83
|
+
banner: "shapeBanner"
|
|
84
|
+
};
|
|
85
|
+
|
|
34
86
|
// src/i18n/languages.ts
|
|
35
87
|
var DEFAULT_LANGUAGES = [
|
|
36
88
|
{ code: "en", label: "EN" },
|
|
@@ -360,6 +412,22 @@ function withLang(val, lang, value) {
|
|
|
360
412
|
return { ...base, [lang]: value };
|
|
361
413
|
}
|
|
362
414
|
|
|
415
|
+
// src/lib/color.ts
|
|
416
|
+
function mixHex(a, b, t2) {
|
|
417
|
+
const pa = parseHex(a);
|
|
418
|
+
const pb = parseHex(b);
|
|
419
|
+
if (!pa || !pb) return a;
|
|
420
|
+
const mix = (x, y) => Math.round(x + (y - x) * t2);
|
|
421
|
+
const toHex = (n) => n.toString(16).padStart(2, "0");
|
|
422
|
+
return `#${toHex(mix(pa[0], pb[0]))}${toHex(mix(pa[1], pb[1]))}${toHex(mix(pa[2], pb[2]))}`;
|
|
423
|
+
}
|
|
424
|
+
function parseHex(hex) {
|
|
425
|
+
const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim());
|
|
426
|
+
if (!m) return null;
|
|
427
|
+
const n = parseInt(m[1], 16);
|
|
428
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
429
|
+
}
|
|
430
|
+
|
|
363
431
|
// src/lib/storage/compress.ts
|
|
364
432
|
var import_lz_string = require("lz-string");
|
|
365
433
|
function compress(raw) {
|
|
@@ -402,56 +470,6 @@ var localStorageAdapter = {
|
|
|
402
470
|
}
|
|
403
471
|
};
|
|
404
472
|
|
|
405
|
-
// src/constants/fieldTypes.ts
|
|
406
|
-
var import_lucide_react = require("lucide-react");
|
|
407
|
-
var FIELD_TYPES = [
|
|
408
|
-
{ type: "paragraph", icon: import_lucide_react.FileText, isContent: true, defaultIcon: "FileText" },
|
|
409
|
-
{ type: "image", icon: import_lucide_react.Image, isContent: true, isImage: true, defaultIcon: "Type" },
|
|
410
|
-
{ type: "button", icon: import_lucide_react.MousePointerClick, isContent: true, defaultIcon: "Type" },
|
|
411
|
-
{ type: "input", icon: import_lucide_react.Type, placeholder: true, hasSubtype: true, defaultIcon: "Type" },
|
|
412
|
-
{ type: "textarea", icon: import_lucide_react.AlignLeft, placeholder: true, defaultIcon: "AlignLeft" },
|
|
413
|
-
{ type: "select", icon: import_lucide_react.ChevronDown, options: true, defaultIcon: "ChevronDown" },
|
|
414
|
-
{ type: "radio", icon: import_lucide_react.Circle, options: true, defaultIcon: "Circle" },
|
|
415
|
-
{ type: "checkboxGroup", icon: import_lucide_react.ListChecks, options: true, multiValue: true, defaultIcon: "ListChecks" },
|
|
416
|
-
{ type: "checkbox", icon: import_lucide_react.CheckSquare, boolean: true, defaultIcon: "CheckSquare" },
|
|
417
|
-
{ type: "toggle", icon: import_lucide_react.ToggleLeft, boolean: true, defaultIcon: "ToggleLeft" }
|
|
418
|
-
];
|
|
419
|
-
var TYPE_MAP = Object.fromEntries(FIELD_TYPES.map((f) => [f.type, f]));
|
|
420
|
-
var CONTENT_TYPES = FIELD_TYPES.filter((f) => f.isContent);
|
|
421
|
-
var FORM_TYPES = FIELD_TYPES.filter((f) => !f.isContent);
|
|
422
|
-
function getMeta(type) {
|
|
423
|
-
return TYPE_MAP[type] || TYPE_MAP.input;
|
|
424
|
-
}
|
|
425
|
-
var LEGACY_INPUT_TYPES = ["text", "email", "phone", "number", "password", "date"];
|
|
426
|
-
var INPUT_SUBTYPES = ["text", "email", "phone", "number", "password", "date", "time"];
|
|
427
|
-
var IMAGE_SHAPES = ["square", "circle", "banner"];
|
|
428
|
-
var FIELD_TYPE_CHROME_KEY = {
|
|
429
|
-
paragraph: "fieldTypeParagraph",
|
|
430
|
-
image: "fieldTypeImage",
|
|
431
|
-
button: "fieldTypeButton",
|
|
432
|
-
input: "fieldTypeInput",
|
|
433
|
-
textarea: "fieldTypeTextarea",
|
|
434
|
-
select: "fieldTypeSelect",
|
|
435
|
-
radio: "fieldTypeRadio",
|
|
436
|
-
checkboxGroup: "fieldTypeCheckboxGroup",
|
|
437
|
-
checkbox: "fieldTypeCheckbox",
|
|
438
|
-
toggle: "fieldTypeToggle"
|
|
439
|
-
};
|
|
440
|
-
var INPUT_SUBTYPE_CHROME_KEY = {
|
|
441
|
-
text: "subtypeText",
|
|
442
|
-
email: "subtypeEmail",
|
|
443
|
-
phone: "subtypePhone",
|
|
444
|
-
number: "subtypeNumber",
|
|
445
|
-
password: "subtypePassword",
|
|
446
|
-
date: "subtypeDate",
|
|
447
|
-
time: "subtypeTime"
|
|
448
|
-
};
|
|
449
|
-
var IMAGE_SHAPE_CHROME_KEY = {
|
|
450
|
-
square: "shapeSquare",
|
|
451
|
-
circle: "shapeCircle",
|
|
452
|
-
banner: "shapeBanner"
|
|
453
|
-
};
|
|
454
|
-
|
|
455
473
|
// src/lib/id.ts
|
|
456
474
|
var genFormId = () => `form_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;
|
|
457
475
|
var genSectionId = () => `section_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;
|
|
@@ -615,6 +633,38 @@ 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
|
+
deviceToggle: true
|
|
652
|
+
};
|
|
653
|
+
function resolveFeatures(features) {
|
|
654
|
+
return {
|
|
655
|
+
...DEFAULT_FEATURES,
|
|
656
|
+
...features,
|
|
657
|
+
contentBlocks: Array.isArray(features?.contentBlocks) ? new Set(features.contentBlocks) : features?.contentBlocks ?? DEFAULT_FEATURES.contentBlocks,
|
|
658
|
+
fieldTypes: Array.isArray(features?.fieldTypes) ? new Set(features.fieldTypes) : features?.fieldTypes ?? DEFAULT_FEATURES.fieldTypes
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
function isContentBlockEnabled(features, type) {
|
|
662
|
+
return features.contentBlocks === true || features.contentBlocks instanceof Set && features.contentBlocks.has(type);
|
|
663
|
+
}
|
|
664
|
+
function isFieldTypeEnabled(features, type) {
|
|
665
|
+
return features.fieldTypes === true || features.fieldTypes instanceof Set && features.fieldTypes.has(type);
|
|
666
|
+
}
|
|
667
|
+
|
|
618
668
|
// src/hooks/useTheme.ts
|
|
619
669
|
var import_react = require("react");
|
|
620
670
|
|
|
@@ -849,6 +899,7 @@ var formKey = (id) => `form-page-builder:saved:${id}`;
|
|
|
849
899
|
var MAX_TEMPLATES = 5;
|
|
850
900
|
function usePersistence({
|
|
851
901
|
storage,
|
|
902
|
+
autosave,
|
|
852
903
|
language,
|
|
853
904
|
chrome,
|
|
854
905
|
document,
|
|
@@ -910,7 +961,7 @@ function usePersistence({
|
|
|
910
961
|
refreshLibrary();
|
|
911
962
|
}, []);
|
|
912
963
|
(0, import_react3.useEffect)(() => {
|
|
913
|
-
if (!hasLoadedOnce.current) return;
|
|
964
|
+
if (!hasLoadedOnce.current || !autosave) return;
|
|
914
965
|
setSaveState("saving");
|
|
915
966
|
if (autosaveTimer.current) clearTimeout(autosaveTimer.current);
|
|
916
967
|
autosaveTimer.current = setTimeout(async () => {
|
|
@@ -1049,15 +1100,15 @@ var styles = {
|
|
|
1049
1100
|
titleInput: { border: "none", outline: "none", fontSize: 14, fontWeight: 600, background: "transparent", color: "var(--fb-ink)", padding: "4px 6px", borderRadius: 6, minWidth: 160 },
|
|
1050
1101
|
toolbarRight: { display: "flex", alignItems: "center", gap: 6, flexWrap: "wrap" },
|
|
1051
1102
|
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: "
|
|
1103
|
+
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
1104
|
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: "
|
|
1105
|
+
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
1106
|
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
1107
|
saveStatus: { display: "flex", alignItems: "center", gap: 5, fontSize: 12, color: "var(--fb-muted)", minWidth: 60 },
|
|
1057
1108
|
countBadge: { fontSize: 10.5, fontWeight: 700, background: "var(--fb-primary-soft)", color: "var(--fb-primary)", borderRadius: 9, padding: "1px 6px", marginLeft: 2 },
|
|
1058
1109
|
loadingScreen: { flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", color: "var(--fb-muted)" },
|
|
1059
1110
|
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
|
|
1111
|
+
libraryRow: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10, padding: "10px 8px", borderRadius: 8, border: "1px solid var(--fb-border)" },
|
|
1061
1112
|
libraryRowTitle: { fontSize: 13.5, fontWeight: 600, color: "var(--fb-ink)", display: "flex", alignItems: "center", gap: 8, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" },
|
|
1062
1113
|
libraryRowMeta: { fontSize: 11.5, color: "var(--fb-muted)", marginTop: 2 },
|
|
1063
1114
|
currentBadge: { fontSize: 10, fontWeight: 700, color: "var(--fb-primary)", background: "var(--fb-primary-soft)", padding: "2px 6px", borderRadius: 5, flexShrink: 0 },
|
|
@@ -1066,7 +1117,7 @@ var styles = {
|
|
|
1066
1117
|
panelHeading: { fontSize: 11, fontWeight: 700, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--fb-muted)", marginBottom: 10 },
|
|
1067
1118
|
activeSectionHint: { fontSize: 11.5, color: "var(--fb-muted)", marginBottom: 14, lineHeight: 1.4 },
|
|
1068
1119
|
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: "
|
|
1120
|
+
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
1121
|
canvas: { flex: 1, padding: "var(--fb-space-canvas)", overflowY: "auto", background: "var(--fb-canvas)" },
|
|
1071
1122
|
sectionBlock: { borderRadius: 12, padding: "var(--fb-space-panel)", marginBottom: "var(--fb-space-section)", transition: "border-color 0.12s" },
|
|
1072
1123
|
sectionHeader: { display: "flex", alignItems: "center", gap: 8, marginBottom: 12, flexWrap: "wrap" },
|
|
@@ -1076,7 +1127,7 @@ var styles = {
|
|
|
1076
1127
|
sectionHeaderActions: { display: "flex", alignItems: "center", gap: 6, flexWrap: "wrap", marginLeft: "auto" },
|
|
1077
1128
|
sectionEmpty: { fontSize: 12.5, color: "var(--fb-muted)", padding: "18px 4px", textAlign: "center", border: "1px dashed var(--fb-border)", borderRadius: 8 },
|
|
1078
1129
|
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
|
|
1130
|
+
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
1131
|
swatchRow: { display: "flex", alignItems: "center", gap: 5, flexWrap: "wrap" },
|
|
1081
1132
|
swatchBtn: { width: 20, height: 20, borderRadius: "50%", border: "1px solid var(--fb-border)", padding: 0 },
|
|
1082
1133
|
swatchBtnActive: { border: "2px solid var(--fb-primary)" },
|
|
@@ -1085,56 +1136,56 @@ var styles = {
|
|
|
1085
1136
|
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
1137
|
ticketSelected: { borderColor: "var(--fb-primary)", boxShadow: "0 0 0 3px var(--fb-primary-soft)" },
|
|
1087
1138
|
ticketDragOver: { borderColor: "var(--fb-muted)" },
|
|
1088
|
-
ticketIndex: { fontFamily: "'JetBrains Mono', monospace", fontSize: 13, fontWeight: 700, color: "
|
|
1139
|
+
ticketIndex: { fontFamily: "'JetBrains Mono', monospace", fontSize: 13, fontWeight: 700, color: "var(--fb-border)", width: 34, display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 },
|
|
1089
1140
|
ticketPerforation: { width: 0, borderLeft: "1px dashed var(--fb-border)" },
|
|
1090
1141
|
ticketBody: { flex: 1, padding: "10px var(--fb-space-ticket)", minWidth: 0 },
|
|
1091
1142
|
ticketTop: { display: "flex", alignItems: "center", gap: 7, marginBottom: 4 },
|
|
1092
1143
|
typeBadge: { fontSize: 10.5, fontFamily: "'JetBrains Mono', monospace", color: "var(--fb-muted)" },
|
|
1093
|
-
requiredBadge: { fontSize: 10, fontWeight: 700, color: "
|
|
1144
|
+
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
1145
|
chipRow: { display: "flex", gap: 5, marginBottom: 7, flexWrap: "wrap" },
|
|
1095
1146
|
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: "
|
|
1147
|
+
langToggleTrack: { position: "relative", display: "flex", gap: 3, background: "var(--fb-surface-2)", padding: 3, borderRadius: 20 },
|
|
1097
1148
|
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: "
|
|
1149
|
+
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
1150
|
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: "
|
|
1151
|
+
segmented: { display: "flex", gap: 3, background: "var(--fb-surface-2)", padding: 3, borderRadius: 8, marginBottom: 4 },
|
|
1152
|
+
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 },
|
|
1153
|
+
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
1154
|
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: "
|
|
1155
|
+
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
1156
|
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
1157
|
styleToggleRow: { display: "flex", gap: 5, marginBottom: 4 },
|
|
1107
|
-
styleToggle: { width: 30, height: 30, borderRadius: 7, border: "1px solid var(--fb-border)", background: "
|
|
1158
|
+
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
1159
|
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
|
|
1160
|
+
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" },
|
|
1161
|
+
previewRadio: { display: "flex", alignItems: "center", gap: 6, fontSize: 13, color: "var(--fb-ink)" },
|
|
1162
|
+
ticketActions: { display: "flex", flexDirection: "column", gap: 3, padding: 8, borderLeft: "1px solid var(--fb-border)" },
|
|
1163
|
+
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
1164
|
iconBtnDanger: { color: "var(--fb-danger)" },
|
|
1114
1165
|
inspector: { width: 270, borderLeft: "1px solid var(--fb-border)", background: "var(--fb-surface)", padding: "var(--fb-space-panel)", overflowY: "auto" },
|
|
1115
1166
|
inspectorEmpty: { fontSize: 13, color: "var(--fb-muted)", lineHeight: 1.5, marginTop: 6 },
|
|
1116
1167
|
inspectorBody: { display: "flex", flexDirection: "column", gap: 4 },
|
|
1117
1168
|
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" },
|
|
1169
|
+
propLabel: { fontSize: 11.5, fontWeight: 600, color: "var(--fb-muted)", marginTop: 12, marginBottom: 5 },
|
|
1170
|
+
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
1171
|
optionList: { display: "flex", flexDirection: "column", gap: 6 },
|
|
1121
1172
|
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
|
|
1173
|
+
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" },
|
|
1174
|
+
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
1175
|
toggleRow: { display: "flex", alignItems: "center", gap: 8, background: "transparent", border: "none", padding: "8px 0" },
|
|
1125
1176
|
toggleTrack: { width: 30, height: 17, borderRadius: 20, position: "relative", transition: "background 0.15s", display: "inline-block" },
|
|
1126
1177
|
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
1178
|
inspectorDivider: { height: 1, background: "var(--fb-border)", margin: "14px 0 10px" },
|
|
1128
1179
|
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: "
|
|
1180
|
+
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" },
|
|
1181
|
+
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
1182
|
modalHeader: { display: "flex", alignItems: "center", justifyContent: "space-between", padding: "12px 16px", borderBottom: "1px solid var(--fb-border)" },
|
|
1132
1183
|
jsonPre: { margin: 0, padding: 16, fontSize: 12, lineHeight: 1.6, overflow: "auto", background: "#14171C", color: "#D6D8E0", fontFamily: "'JetBrains Mono', monospace" },
|
|
1133
1184
|
previewWrap: { flex: 1, display: "flex", justifyContent: "center", padding: "var(--fb-space-page) 20px", overflowY: "auto", background: "var(--fb-canvas)" },
|
|
1134
1185
|
previewToolbar: { width: "100%", display: "flex", gap: 10, marginBottom: 16, justifyContent: "center" },
|
|
1135
1186
|
previewCard: { width: "100%", maxWidth: 480, background: "var(--fb-page-bg)", border: "1px solid var(--fb-border)", borderRadius: 12, padding: "var(--fb-space-page)" },
|
|
1136
1187
|
previewTitle: { fontSize: 19, fontWeight: 700, margin: "0 0 20px" },
|
|
1137
|
-
previewLabel: { display: "block", fontSize: 13, fontWeight: 600, color: "
|
|
1188
|
+
previewLabel: { display: "block", fontSize: 13, fontWeight: 600, color: "var(--fb-ink)", marginBottom: 6 },
|
|
1138
1189
|
previewGrid: { display: "flex", flexWrap: "wrap", gap: "var(--fb-space-field)" },
|
|
1139
1190
|
sectionRuntimeTitle: { fontSize: 15, fontWeight: 700, margin: "0 0 12px", color: "var(--fb-ink)" },
|
|
1140
1191
|
imagePlaceholder: { display: "flex", alignItems: "center", justifyContent: "center", border: "1px dashed var(--fb-border)" },
|
|
@@ -1144,13 +1195,13 @@ var styles = {
|
|
|
1144
1195
|
submittedRow: { display: "flex", justifyContent: "space-between", gap: 12, fontSize: 13, padding: "6px 0", borderBottom: "1px solid var(--fb-border)" },
|
|
1145
1196
|
submittedLabel: { color: "var(--fb-muted)", flexShrink: 0 },
|
|
1146
1197
|
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" },
|
|
1198
|
+
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
1199
|
realInputError: { borderColor: "var(--fb-danger)" },
|
|
1149
1200
|
submitBtn: { marginTop: 8, color: "#fff", border: "none", borderRadius: 8, fontWeight: 600, width: "100%" },
|
|
1150
1201
|
layoutPanelHeader: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 4 },
|
|
1151
1202
|
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" }
|
|
1203
|
+
spacingLabel: { fontSize: 12, color: "var(--fb-ink)" },
|
|
1204
|
+
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
1205
|
};
|
|
1155
1206
|
|
|
1156
1207
|
// src/components/LanguageToggle.tsx
|
|
@@ -1191,6 +1242,7 @@ function Toolbar({
|
|
|
1191
1242
|
mode,
|
|
1192
1243
|
saveState,
|
|
1193
1244
|
chrome,
|
|
1245
|
+
features,
|
|
1194
1246
|
savedFormsCount,
|
|
1195
1247
|
onTitleChange,
|
|
1196
1248
|
onLanguageChange,
|
|
@@ -1203,7 +1255,7 @@ function Toolbar({
|
|
|
1203
1255
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.toolbar, children: [
|
|
1204
1256
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.toolbarLeft, children: [
|
|
1205
1257
|
/* @__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" })
|
|
1258
|
+
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
1259
|
] }),
|
|
1208
1260
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.toolbarRight, children: [
|
|
1209
1261
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.saveStatus, children: [
|
|
@@ -1219,37 +1271,43 @@ function Toolbar({
|
|
|
1219
1271
|
chrome.saveFailed
|
|
1220
1272
|
] })
|
|
1221
1273
|
] }),
|
|
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
|
|
1274
|
+
features.languageSwitcher && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
1275
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.toolbarDivider }),
|
|
1276
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LanguageToggle, { languages, value: language, onChange: onLanguageChange })
|
|
1229
1277
|
] }),
|
|
1230
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1231
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1232
|
-
" ",
|
|
1233
|
-
|
|
1278
|
+
features.previewMode && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
1279
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.toolbarDivider }),
|
|
1280
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: mode === "build" ? styles.tabBtnActive : styles.tabBtn, onClick: () => onModeChange("build"), children: [
|
|
1281
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Pencil, { size: 14 }),
|
|
1282
|
+
" ",
|
|
1283
|
+
chrome.build
|
|
1284
|
+
] }),
|
|
1285
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: mode === "preview" ? styles.tabBtnActive : styles.tabBtn, onClick: () => onModeChange("preview"), children: [
|
|
1286
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Eye, { size: 14 }),
|
|
1287
|
+
" ",
|
|
1288
|
+
chrome.preview
|
|
1289
|
+
] })
|
|
1234
1290
|
] }),
|
|
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: [
|
|
1291
|
+
(features.newForm || features.templates) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.toolbarDivider }),
|
|
1292
|
+
features.newForm && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: styles.ghostBtn, onClick: onNewForm, title: chrome.startNewForm, children: [
|
|
1237
1293
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.FilePlus2, { size: 14 }),
|
|
1238
1294
|
" ",
|
|
1239
1295
|
chrome.newForm
|
|
1240
1296
|
] }),
|
|
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
|
-
|
|
1297
|
+
features.templates && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
1298
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: styles.ghostBtn, onClick: onOpenLibrary, title: chrome.openTemplatesTitle, children: [
|
|
1299
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.FolderOpen, { size: 14 }),
|
|
1300
|
+
" ",
|
|
1301
|
+
chrome.templates,
|
|
1302
|
+
savedFormsCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.countBadge, children: savedFormsCount })
|
|
1303
|
+
] }),
|
|
1304
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: styles.primaryBtn, onClick: onSaveExisting, title: chrome.saveToLibraryTitle, children: [
|
|
1305
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Save, { size: 14 }),
|
|
1306
|
+
" ",
|
|
1307
|
+
chrome.save
|
|
1308
|
+
] })
|
|
1251
1309
|
] }),
|
|
1252
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: styles.ghostBtn, onClick: onOpenJson, children: [
|
|
1310
|
+
features.jsonView && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { style: styles.ghostBtn, onClick: onOpenJson, children: [
|
|
1253
1311
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Code2, { size: 14 }),
|
|
1254
1312
|
" ",
|
|
1255
1313
|
chrome.viewJson
|
|
@@ -1350,15 +1408,19 @@ function Palette({
|
|
|
1350
1408
|
activeSectionLabel,
|
|
1351
1409
|
chrome,
|
|
1352
1410
|
onAddField,
|
|
1353
|
-
|
|
1411
|
+
features,
|
|
1354
1412
|
theme,
|
|
1355
1413
|
updateThemeColor,
|
|
1356
1414
|
updateThemeLayout,
|
|
1357
|
-
resetTheme
|
|
1415
|
+
resetTheme,
|
|
1416
|
+
fieldCount
|
|
1358
1417
|
}) {
|
|
1359
1418
|
const [tab, setTab] = (0, import_react5.useState)("blocks");
|
|
1360
|
-
|
|
1361
|
-
|
|
1419
|
+
const contentTypes = CONTENT_TYPES.filter((f) => isContentBlockEnabled(features, f.type));
|
|
1420
|
+
const formTypes = FORM_TYPES.filter((f) => isFieldTypeEnabled(features, f.type));
|
|
1421
|
+
const atFieldCap = typeof features.maxFields === "number" && fieldCount >= features.maxFields;
|
|
1422
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "fb-palette", style: styles.palette, children: [
|
|
1423
|
+
features.design && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { marginBottom: 14 }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1362
1424
|
Segmented,
|
|
1363
1425
|
{
|
|
1364
1426
|
options: [
|
|
@@ -1369,7 +1431,7 @@ function Palette({
|
|
|
1369
1431
|
onChange: setTab
|
|
1370
1432
|
}
|
|
1371
1433
|
) }),
|
|
1372
|
-
tab === "design" &&
|
|
1434
|
+
tab === "design" && features.design ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1373
1435
|
DesignPanel,
|
|
1374
1436
|
{
|
|
1375
1437
|
chrome,
|
|
@@ -1384,24 +1446,29 @@ function Palette({
|
|
|
1384
1446
|
" ",
|
|
1385
1447
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: activeSectionLabel })
|
|
1386
1448
|
] }),
|
|
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
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1449
|
+
contentTypes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
1450
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles.panelHeading, children: chrome.contentBlocks }),
|
|
1451
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles.paletteList, children: contentTypes.map((f) => {
|
|
1452
|
+
const Icon = f.icon;
|
|
1453
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { style: styles.paletteItem, onClick: () => onAddField(f.type), children: [
|
|
1454
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { size: 16, color: "var(--fb-primary)" }),
|
|
1455
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: chrome[FIELD_TYPE_CHROME_KEY[f.type]] }),
|
|
1456
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react5.Plus, { size: 13, color: "var(--fb-muted)", style: { marginLeft: "auto" } })
|
|
1457
|
+
] }, f.type);
|
|
1458
|
+
}) })
|
|
1459
|
+
] }),
|
|
1460
|
+
formTypes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
1461
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { ...styles.panelHeading, marginTop: 16 }, children: chrome.formFields }),
|
|
1462
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles.paletteList, children: formTypes.map((f) => {
|
|
1463
|
+
const Icon = f.icon;
|
|
1464
|
+
const itemStyle = atFieldCap ? { ...styles.paletteItem, opacity: 0.45, cursor: "not-allowed" } : styles.paletteItem;
|
|
1465
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", disabled: atFieldCap, style: itemStyle, onClick: () => onAddField(f.type), children: [
|
|
1466
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { size: 16, color: "var(--fb-primary)" }),
|
|
1467
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: chrome[FIELD_TYPE_CHROME_KEY[f.type]] }),
|
|
1468
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react5.Plus, { size: 13, color: "var(--fb-muted)", style: { marginLeft: "auto" } })
|
|
1469
|
+
] }, f.type);
|
|
1470
|
+
}) })
|
|
1471
|
+
] })
|
|
1405
1472
|
] })
|
|
1406
1473
|
] });
|
|
1407
1474
|
}
|
|
@@ -1530,7 +1597,7 @@ function FieldBlock({ field, lang, onFieldChange, strings, chrome, error, isBuil
|
|
|
1530
1597
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
|
|
1531
1598
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", flexDirection: isInline ? "row" : "column", alignItems: isInline ? "center" : "stretch", gap: isInline ? 10 : 6 }, children: [
|
|
1532
1599
|
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: "
|
|
1600
|
+
IconComp && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconComp, { size: 14, color: "var(--fb-muted)" }),
|
|
1534
1601
|
labelText || (isBuild ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { fontStyle: "italic", color: "var(--fb-muted)" }, children: chrome?.untitledField || "Untitled field" }) : ""),
|
|
1535
1602
|
field.required && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: "var(--fb-danger)" }, children: " *" })
|
|
1536
1603
|
] }),
|
|
@@ -1595,14 +1662,14 @@ function renderInteractive(field, lang, onFieldChange, IconComp, hasError, strin
|
|
|
1595
1662
|
case "checkbox":
|
|
1596
1663
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { style: styles.previewRadio, children: [
|
|
1597
1664
|
/* @__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: "
|
|
1665
|
+
IconComp && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconComp, { size: 14, color: "var(--fb-muted)" }),
|
|
1599
1666
|
t(field.label, lang),
|
|
1600
1667
|
field.required && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: "var(--fb-danger)" }, children: " *" })
|
|
1601
1668
|
] });
|
|
1602
1669
|
case "toggle":
|
|
1603
1670
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { style: styles.previewRadio, children: [
|
|
1604
1671
|
/* @__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: "
|
|
1672
|
+
IconComp && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconComp, { size: 14, color: "var(--fb-muted)" }),
|
|
1606
1673
|
t(field.label, lang)
|
|
1607
1674
|
] });
|
|
1608
1675
|
default:
|
|
@@ -1620,6 +1687,7 @@ function FieldTicket({
|
|
|
1620
1687
|
chrome,
|
|
1621
1688
|
strings,
|
|
1622
1689
|
language,
|
|
1690
|
+
dragEnabled,
|
|
1623
1691
|
onSelect,
|
|
1624
1692
|
onFieldChange,
|
|
1625
1693
|
onMoveField,
|
|
@@ -1649,7 +1717,7 @@ function FieldTicket({
|
|
|
1649
1717
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: styles.ticketPerforation }),
|
|
1650
1718
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: styles.ticketBody, children: [
|
|
1651
1719
|
/* @__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: "
|
|
1720
|
+
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
1721
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon, { size: 13, color: "var(--fb-primary)" }),
|
|
1654
1722
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: styles.typeBadge, children: [
|
|
1655
1723
|
chrome[FIELD_TYPE_CHROME_KEY[field.type]] || field.type,
|
|
@@ -1692,6 +1760,7 @@ function SectionCard({
|
|
|
1692
1760
|
chrome,
|
|
1693
1761
|
strings,
|
|
1694
1762
|
language,
|
|
1763
|
+
features,
|
|
1695
1764
|
onActivate,
|
|
1696
1765
|
onToggleCollapse,
|
|
1697
1766
|
onUpdateTitle,
|
|
@@ -1731,14 +1800,16 @@ function SectionCard({
|
|
|
1731
1800
|
),
|
|
1732
1801
|
section.collapsed && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: styles.miniBadge, children: chrome.fieldsCount(section.fields.length) }),
|
|
1733
1802
|
/* @__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: [
|
|
1803
|
+
features.sections && !section.collapsed && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: styles.swatchRow, children: [
|
|
1735
1804
|
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
1805
|
/* @__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
1806
|
] }),
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1807
|
+
features.sections && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1808
|
+
/* @__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 }) }),
|
|
1809
|
+
/* @__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 }) }),
|
|
1810
|
+
/* @__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 }) }),
|
|
1811
|
+
/* @__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 }) })
|
|
1812
|
+
] })
|
|
1742
1813
|
] })
|
|
1743
1814
|
] }),
|
|
1744
1815
|
!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 +1823,7 @@ function SectionCard({
|
|
|
1752
1823
|
chrome,
|
|
1753
1824
|
strings,
|
|
1754
1825
|
language,
|
|
1826
|
+
dragEnabled: features.dragReorder,
|
|
1755
1827
|
onSelect: () => onSelectField(field.id),
|
|
1756
1828
|
onFieldChange,
|
|
1757
1829
|
onMoveField,
|
|
@@ -1777,6 +1849,7 @@ function Canvas({
|
|
|
1777
1849
|
chrome,
|
|
1778
1850
|
strings,
|
|
1779
1851
|
language,
|
|
1852
|
+
features,
|
|
1780
1853
|
onActivateSection,
|
|
1781
1854
|
onToggleSectionCollapse,
|
|
1782
1855
|
onUpdateSectionTitle,
|
|
@@ -1793,7 +1866,7 @@ function Canvas({
|
|
|
1793
1866
|
getDropZoneHandlers,
|
|
1794
1867
|
getDragHandleProps
|
|
1795
1868
|
}) {
|
|
1796
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: styles.canvas, children: [
|
|
1869
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "fb-canvas", style: styles.canvas, children: [
|
|
1797
1870
|
sections.map((section, sIdx) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1798
1871
|
SectionCard,
|
|
1799
1872
|
{
|
|
@@ -1806,6 +1879,7 @@ function Canvas({
|
|
|
1806
1879
|
chrome,
|
|
1807
1880
|
strings,
|
|
1808
1881
|
language,
|
|
1882
|
+
features,
|
|
1809
1883
|
onActivate: () => onActivateSection(section.id),
|
|
1810
1884
|
onToggleCollapse: () => onToggleSectionCollapse(section.id),
|
|
1811
1885
|
onUpdateTitle: (value) => onUpdateSectionTitle(section.id, value),
|
|
@@ -1823,7 +1897,7 @@ function Canvas({
|
|
|
1823
1897
|
},
|
|
1824
1898
|
section.id
|
|
1825
1899
|
)),
|
|
1826
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("button", { style: styles.addSectionBtn, onClick: onAddSection, children: [
|
|
1900
|
+
features.sections && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("button", { style: styles.addSectionBtn, onClick: onAddSection, children: [
|
|
1827
1901
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react12.Layers, { size: 14 }),
|
|
1828
1902
|
" ",
|
|
1829
1903
|
chrome.addSection
|
|
@@ -1844,7 +1918,7 @@ function DefaultValueEditor({ field, meta, lang, chrome, onChange }) {
|
|
|
1844
1918
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("label", { style: styles.propLabel, children: chrome.defaultValue }),
|
|
1845
1919
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { style: styles.toggleRow, onClick: () => onChange({ defaultValue: !f.defaultValue }), children: [
|
|
1846
1920
|
/* @__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: "
|
|
1921
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { fontSize: 13, color: "var(--fb-ink)" }, children: f.defaultValue ? chrome.checked : chrome.unchecked })
|
|
1848
1922
|
] })
|
|
1849
1923
|
] });
|
|
1850
1924
|
}
|
|
@@ -1882,8 +1956,8 @@ function DefaultValueEditor({ field, meta, lang, chrome, onChange }) {
|
|
|
1882
1956
|
|
|
1883
1957
|
// src/components/Inspector.tsx
|
|
1884
1958
|
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: [
|
|
1959
|
+
function Inspector({ selected, language, chrome, features, onUpdateField, onDeleteField, onUpdateOption, onAddOption, onRemoveOption }) {
|
|
1960
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "fb-inspector", style: styles.inspector, children: [
|
|
1887
1961
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.panelHeading, children: chrome.properties }),
|
|
1888
1962
|
!selected ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.inspectorEmpty, children: chrome.selectFieldHint }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1889
1963
|
InspectorBody,
|
|
@@ -1891,6 +1965,7 @@ function Inspector({ selected, language, chrome, onUpdateField, onDeleteField, o
|
|
|
1891
1965
|
selected,
|
|
1892
1966
|
language,
|
|
1893
1967
|
chrome,
|
|
1968
|
+
features,
|
|
1894
1969
|
onUpdateField,
|
|
1895
1970
|
onDeleteField,
|
|
1896
1971
|
onUpdateOption,
|
|
@@ -1900,7 +1975,7 @@ function Inspector({ selected, language, chrome, onUpdateField, onDeleteField, o
|
|
|
1900
1975
|
)
|
|
1901
1976
|
] });
|
|
1902
1977
|
}
|
|
1903
|
-
function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteField, onUpdateOption, onAddOption, onRemoveOption }) {
|
|
1978
|
+
function InspectorBody({ selected, language, chrome, features, onUpdateField, onDeleteField, onUpdateOption, onAddOption, onRemoveOption }) {
|
|
1904
1979
|
const meta = getMeta(selected.type);
|
|
1905
1980
|
const f = selected;
|
|
1906
1981
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: styles.inspectorBody, children: [
|
|
@@ -1909,7 +1984,7 @@ function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteFiel
|
|
|
1909
1984
|
/* @__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
1985
|
!meta.isContent && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { style: styles.toggleRow, children: [
|
|
1911
1986
|
/* @__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: "
|
|
1987
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: 13, color: "var(--fb-ink)" }, children: chrome.hideLabel })
|
|
1913
1988
|
] })
|
|
1914
1989
|
] }),
|
|
1915
1990
|
meta.hasSubtype && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
@@ -1919,23 +1994,25 @@ function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteFiel
|
|
|
1919
1994
|
selected.type === "paragraph" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1920
1995
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.content }),
|
|
1921
1996
|
/* @__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
|
-
|
|
1997
|
+
features.blockStyling && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1998
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.inspectorDivider }),
|
|
1999
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.panelHeading, children: chrome.typography }),
|
|
2000
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.headingStyle }),
|
|
2001
|
+
/* @__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] }) }),
|
|
2002
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.width }),
|
|
2003
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Segmented, { options: FONT_SIZE_OPTIONS, value: selected.fontSize || "md", onChange: (v) => onUpdateField({ fontSize: v }) }),
|
|
2004
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.style }),
|
|
2005
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: styles.styleToggleRow, children: [
|
|
2006
|
+
/* @__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 }) }),
|
|
2007
|
+
/* @__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 }) })
|
|
2008
|
+
] }),
|
|
2009
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.align }),
|
|
2010
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Segmented, { options: TEXT_ALIGN_OPTIONS, value: selected.textAlign || "left", onChange: (v) => onUpdateField({ textAlign: v }) }),
|
|
2011
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.color }),
|
|
2012
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: styles.swatchRow, children: [
|
|
2013
|
+
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")),
|
|
2014
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { type: "color", value: selected.color || "#1B1E24", onChange: (e) => onUpdateField({ color: e.target.value }), style: styles.colorPickerInput })
|
|
2015
|
+
] })
|
|
1939
2016
|
] })
|
|
1940
2017
|
] }),
|
|
1941
2018
|
selected.type === "image" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
@@ -1964,13 +2041,15 @@ function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteFiel
|
|
|
1964
2041
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.submitScope }),
|
|
1965
2042
|
/* @__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
2043
|
] }),
|
|
1967
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
2044
|
+
features.blockStyling && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
2045
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.color }),
|
|
2046
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: styles.swatchRow, children: [
|
|
2047
|
+
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")),
|
|
2048
|
+
/* @__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 })
|
|
2049
|
+
] }),
|
|
2050
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.buttonSize }),
|
|
2051
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Segmented, { options: SUBMIT_SIZE_OPTIONS, value: selected.buttonStyle?.size || "md", onChange: (v) => onUpdateField({ buttonStyle: { ...selected.buttonStyle, size: v } }) })
|
|
2052
|
+
] })
|
|
1974
2053
|
] }),
|
|
1975
2054
|
meta.placeholder && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1976
2055
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { style: styles.propLabel, children: chrome.placeholder }),
|
|
@@ -2007,7 +2086,7 @@ function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteFiel
|
|
|
2007
2086
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DefaultValueEditor, { field: selected, meta, lang: language, chrome, onChange: onUpdateField }),
|
|
2008
2087
|
!meta.isContent && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { style: styles.toggleRow, children: [
|
|
2009
2088
|
/* @__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: "
|
|
2089
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: 13, color: "var(--fb-ink)" }, children: chrome.requiredField })
|
|
2011
2090
|
] }),
|
|
2012
2091
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.inspectorDivider }),
|
|
2013
2092
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.panelHeading, children: chrome.layout }),
|
|
@@ -2024,7 +2103,7 @@ function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteFiel
|
|
|
2024
2103
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.panelHeading, children: chrome.icon }),
|
|
2025
2104
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { style: styles.toggleRow, children: [
|
|
2026
2105
|
/* @__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: "
|
|
2106
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: 13, color: "var(--fb-ink)" }, children: chrome.showIcon })
|
|
2028
2107
|
] }),
|
|
2029
2108
|
selected.showIcon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: styles.iconGrid, children: Object.keys(ICON_LIBRARY).map((key) => {
|
|
2030
2109
|
const IconComp = ICON_LIBRARY[key];
|
|
@@ -2090,7 +2169,7 @@ function collectFieldValues(fields) {
|
|
|
2090
2169
|
|
|
2091
2170
|
// src/components/PreviewPane.tsx
|
|
2092
2171
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2093
|
-
function PreviewPane({ title, sections, onFieldChange, language, strings, chrome, baseMaxWidth, onSubmit }) {
|
|
2172
|
+
function PreviewPane({ title, sections, onFieldChange, language, strings, chrome, baseMaxWidth, features, onSubmit }) {
|
|
2094
2173
|
const [device, setDevice] = (0, import_react6.useState)("laptop");
|
|
2095
2174
|
const [errors, setErrors] = (0, import_react6.useState)({});
|
|
2096
2175
|
const [submitted, setSubmitted] = (0, import_react6.useState)(null);
|
|
@@ -2153,7 +2232,7 @@ function PreviewPane({ title, sections, onFieldChange, language, strings, chrome
|
|
|
2153
2232
|
}
|
|
2154
2233
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: styles.previewWrap, children: [
|
|
2155
2234
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { width: "100%", maxWidth, display: "flex", flexDirection: "column", alignItems: "center" }, children: [
|
|
2156
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: styles.previewToolbar, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Segmented, { options: deviceOptions, value: device, onChange: setDevice }) }),
|
|
2235
|
+
features.deviceToggle && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: styles.previewToolbar, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Segmented, { options: deviceOptions, value: device, onChange: setDevice }) }),
|
|
2157
2236
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { ...styles.previewCard, maxWidth, width: "100%" }, children: [
|
|
2158
2237
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h2", { style: styles.previewTitle, children: t(title, language) }),
|
|
2159
2238
|
allFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { style: { color: "var(--fb-muted)", fontSize: 14 }, children: strings.addFieldsHint }),
|
|
@@ -2176,7 +2255,7 @@ function PreviewPane({ title, sections, onFieldChange, language, strings, chrome
|
|
|
2176
2255
|
})
|
|
2177
2256
|
] })
|
|
2178
2257
|
] }),
|
|
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,
|
|
2258
|
+
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
2259
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: styles.modalHeader, children: [
|
|
2181
2260
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { style: { fontWeight: 600, fontSize: 14, display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
2182
2261
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react14.PartyPopper, { size: 15, color: "var(--fb-primary)" }),
|
|
@@ -2251,7 +2330,7 @@ var import_lucide_react17 = require("lucide-react");
|
|
|
2251
2330
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2252
2331
|
function SaveAsModal({ chrome, suggestedName, onSave, onClose }) {
|
|
2253
2332
|
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,
|
|
2333
|
+
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
2334
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: styles.modalHeader, children: [
|
|
2256
2335
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { fontWeight: 600, fontSize: 14 }, children: chrome.saveForm }),
|
|
2257
2336
|
/* @__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 +2360,36 @@ var css = `
|
|
|
2281
2360
|
that support it (mobile browser chrome resizing the viewport), and is
|
|
2282
2361
|
simply ignored by ones that don't. */
|
|
2283
2362
|
.fb-root { max-height: 100vh; max-height: 100dvh; }
|
|
2363
|
+
|
|
2364
|
+
/* Below this width the fixed 200px Palette + 270px Inspector columns
|
|
2365
|
+
don't leave room for a usable Canvas, so instead of stacking all
|
|
2366
|
+
three in flow (which buries Canvas under a tall Palette), Palette
|
|
2367
|
+
and Inspector become narrow drawers over Canvas (which stays
|
|
2368
|
+
partially visible behind them), toggled by .fb-mobile-bar's two
|
|
2369
|
+
buttons, tracked by .fb-work-area's data-mobile-panel attribute,
|
|
2370
|
+
and dismissible via .fb-mobile-backdrop. */
|
|
2371
|
+
.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; }
|
|
2372
|
+
.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; }
|
|
2373
|
+
.fb-mobile-btn[aria-pressed="true"] { border-color: var(--fb-primary); background: var(--fb-primary-soft); color: var(--fb-primary); }
|
|
2374
|
+
.fb-mobile-backdrop { display: none; }
|
|
2375
|
+
@media (max-width: 720px) {
|
|
2376
|
+
.fb-mobile-bar { display: flex; }
|
|
2377
|
+
.fb-work-area { flex-direction: column !important; min-height: 0; }
|
|
2378
|
+
.fb-canvas-area { position: relative; overflow: hidden; }
|
|
2379
|
+
.fb-canvas { width: 100%; }
|
|
2380
|
+
.fb-mobile-backdrop { display: block; position: absolute; inset: 0; z-index: 6; background: rgba(15,16,20,0.35); }
|
|
2381
|
+
.fb-palette, .fb-inspector {
|
|
2382
|
+
position: absolute; top: 0; bottom: 0; z-index: 7;
|
|
2383
|
+
width: min(260px, 80vw) !important; max-height: none !important;
|
|
2384
|
+
border: none !important;
|
|
2385
|
+
box-shadow: 0 0 24px rgba(0,0,0,0.18);
|
|
2386
|
+
transition: transform 0.18s ease;
|
|
2387
|
+
}
|
|
2388
|
+
.fb-palette { left: 0; transform: translateX(-100%); }
|
|
2389
|
+
.fb-inspector { right: 0; transform: translateX(100%); }
|
|
2390
|
+
.fb-work-area[data-mobile-panel="palette"] .fb-palette,
|
|
2391
|
+
.fb-work-area[data-mobile-panel="inspector"] .fb-inspector { transform: translateX(0); }
|
|
2392
|
+
}
|
|
2284
2393
|
`;
|
|
2285
2394
|
|
|
2286
2395
|
// src/FormBuilder.tsx
|
|
@@ -2291,11 +2400,14 @@ var FormBuilder = (0, import_react8.forwardRef)(function FormBuilder2({
|
|
|
2291
2400
|
languages = DEFAULT_LANGUAGES,
|
|
2292
2401
|
strings: stringsOverride,
|
|
2293
2402
|
chrome: chromeOverride,
|
|
2294
|
-
|
|
2403
|
+
features: featuresProp,
|
|
2295
2404
|
storage: storageProp,
|
|
2296
2405
|
onSubmit,
|
|
2297
|
-
initialDocument
|
|
2406
|
+
initialDocument,
|
|
2407
|
+
initialMode,
|
|
2408
|
+
onModeChange
|
|
2298
2409
|
}, ref) {
|
|
2410
|
+
const features = resolveFeatures(featuresProp);
|
|
2299
2411
|
const storage = storageProp ?? localStorageAdapter;
|
|
2300
2412
|
const { theme, updateThemeColor, updateThemeLayout, resetTheme, replaceThemeOverrides, themeOverrides } = useTheme(themeOverrideProp);
|
|
2301
2413
|
const [language, setLanguage] = (0, import_react8.useState)(languageOverride || languages[0]?.code || "en");
|
|
@@ -2303,12 +2415,21 @@ var FormBuilder = (0, import_react8.forwardRef)(function FormBuilder2({
|
|
|
2303
2415
|
const chrome = { ...CHROME[language] || CHROME.en, ...chromeOverride && chromeOverride[language] || {} };
|
|
2304
2416
|
const doc = useFormDocument({ language, chrome });
|
|
2305
2417
|
const drag = useDragReorder(doc.reorderWithinSection);
|
|
2306
|
-
const [mode,
|
|
2418
|
+
const [mode, setModeState] = (0, import_react8.useState)(initialMode ?? "build");
|
|
2419
|
+
const setMode = (next) => {
|
|
2420
|
+
setModeState(next);
|
|
2421
|
+
onModeChange?.(next);
|
|
2422
|
+
};
|
|
2423
|
+
(0, import_react8.useEffect)(() => {
|
|
2424
|
+
onModeChange?.(mode);
|
|
2425
|
+
}, []);
|
|
2307
2426
|
const [showJson, setShowJson] = (0, import_react8.useState)(false);
|
|
2308
2427
|
const [showLibrary, setShowLibrary] = (0, import_react8.useState)(false);
|
|
2309
2428
|
const [copied, setCopied] = (0, import_react8.useState)(false);
|
|
2429
|
+
const [mobilePanel, setMobilePanel] = (0, import_react8.useState)("none");
|
|
2310
2430
|
const persistence = usePersistence({
|
|
2311
2431
|
storage,
|
|
2432
|
+
autosave: features.autosave,
|
|
2312
2433
|
language,
|
|
2313
2434
|
chrome,
|
|
2314
2435
|
document: { title: doc.title, themeOverrides, sections: doc.sections },
|
|
@@ -2348,6 +2469,7 @@ var FormBuilder = (0, import_react8.forwardRef)(function FormBuilder2({
|
|
|
2348
2469
|
}
|
|
2349
2470
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2350
2471
|
}), [jsonDoc, jsonString]);
|
|
2472
|
+
const fieldCount = doc.sections.reduce((n, s) => n + s.fields.filter((f) => !getMeta(f.type).isContent).length, 0);
|
|
2351
2473
|
const activeSectionIdx = doc.sections.findIndex((s) => s.id === doc.activeSection?.id);
|
|
2352
2474
|
const activeSectionLabel = t(doc.activeSection?.title, language) || `#${activeSectionIdx + 1}`;
|
|
2353
2475
|
const rootStyle = {
|
|
@@ -2362,6 +2484,7 @@ var FormBuilder = (0, import_react8.forwardRef)(function FormBuilder2({
|
|
|
2362
2484
|
"--fb-surface": theme.surface,
|
|
2363
2485
|
"--fb-canvas": theme.canvas,
|
|
2364
2486
|
"--fb-page-bg": theme.pageBackground,
|
|
2487
|
+
"--fb-surface-2": mixHex(theme.surface, theme.ink, 0.06),
|
|
2365
2488
|
"--fb-space-page": `${theme.layout.pagePadding}px`,
|
|
2366
2489
|
"--fb-space-canvas": `${theme.layout.canvasPadding}px`,
|
|
2367
2490
|
"--fb-space-section": `${theme.layout.sectionGap}px`,
|
|
@@ -2381,6 +2504,7 @@ var FormBuilder = (0, import_react8.forwardRef)(function FormBuilder2({
|
|
|
2381
2504
|
mode,
|
|
2382
2505
|
saveState: persistence.saveState,
|
|
2383
2506
|
chrome,
|
|
2507
|
+
features,
|
|
2384
2508
|
savedFormsCount: persistence.savedForms.length,
|
|
2385
2509
|
onTitleChange: doc.updateTitle,
|
|
2386
2510
|
onLanguageChange: setLanguage,
|
|
@@ -2394,63 +2518,103 @@ var FormBuilder = (0, import_react8.forwardRef)(function FormBuilder2({
|
|
|
2394
2518
|
persistence.loadingDraft ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: styles.loadingScreen, children: [
|
|
2395
2519
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react18.Loader2, { size: 20, className: "spin" }),
|
|
2396
2520
|
/* @__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
|
-
|
|
2521
|
+
] }) : mode === "build" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "fb-work-area", style: styles.workArea, "data-mobile-panel": mobilePanel, children: [
|
|
2522
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "fb-mobile-bar", children: [
|
|
2523
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
2524
|
+
"button",
|
|
2525
|
+
{
|
|
2526
|
+
type: "button",
|
|
2527
|
+
className: "fb-mobile-btn",
|
|
2528
|
+
"aria-pressed": mobilePanel === "palette",
|
|
2529
|
+
onClick: () => setMobilePanel((p) => p === "palette" ? "none" : "palette"),
|
|
2530
|
+
children: [
|
|
2531
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react18.Menu, { size: 14 }),
|
|
2532
|
+
" ",
|
|
2533
|
+
chrome.paletteTabBlocks
|
|
2534
|
+
]
|
|
2535
|
+
}
|
|
2536
|
+
),
|
|
2537
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
2538
|
+
"button",
|
|
2539
|
+
{
|
|
2540
|
+
type: "button",
|
|
2541
|
+
className: "fb-mobile-btn",
|
|
2542
|
+
"aria-pressed": mobilePanel === "inspector",
|
|
2543
|
+
onClick: () => setMobilePanel((p) => p === "inspector" ? "none" : "inspector"),
|
|
2544
|
+
children: [
|
|
2545
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react18.SlidersHorizontal, { size: 14 }),
|
|
2546
|
+
" ",
|
|
2547
|
+
chrome.properties
|
|
2548
|
+
]
|
|
2549
|
+
}
|
|
2550
|
+
)
|
|
2551
|
+
] }),
|
|
2552
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "fb-canvas-area", style: styles.workArea, children: [
|
|
2553
|
+
mobilePanel !== "none" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "fb-mobile-backdrop", onClick: () => setMobilePanel("none") }),
|
|
2554
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2555
|
+
Palette,
|
|
2556
|
+
{
|
|
2557
|
+
activeSectionLabel,
|
|
2558
|
+
chrome,
|
|
2559
|
+
onAddField: (type) => {
|
|
2560
|
+
doc.addField(type);
|
|
2561
|
+
setMobilePanel("none");
|
|
2562
|
+
},
|
|
2563
|
+
features,
|
|
2564
|
+
fieldCount,
|
|
2565
|
+
theme,
|
|
2566
|
+
updateThemeColor,
|
|
2567
|
+
updateThemeLayout,
|
|
2568
|
+
resetTheme
|
|
2569
|
+
}
|
|
2570
|
+
),
|
|
2571
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2572
|
+
Canvas,
|
|
2573
|
+
{
|
|
2574
|
+
sections: doc.sections,
|
|
2575
|
+
activeSectionId: doc.activeSectionId,
|
|
2576
|
+
selectedId: doc.selectedId,
|
|
2577
|
+
dragOverKey: drag.dragOverKey,
|
|
2578
|
+
chrome,
|
|
2579
|
+
strings,
|
|
2580
|
+
language,
|
|
2581
|
+
features,
|
|
2582
|
+
onActivateSection: doc.setActiveSectionId,
|
|
2583
|
+
onToggleSectionCollapse: doc.toggleSectionCollapse,
|
|
2584
|
+
onUpdateSectionTitle: doc.updateSectionTitle,
|
|
2585
|
+
onUpdateSectionBackground: doc.updateSectionBackground,
|
|
2586
|
+
onDuplicateSection: doc.duplicateSection,
|
|
2587
|
+
onMoveSection: doc.moveSection,
|
|
2588
|
+
onDeleteSection: doc.deleteSection,
|
|
2589
|
+
onAddSection: doc.addSection,
|
|
2590
|
+
onSelectField: (sectionId, fieldId) => {
|
|
2591
|
+
doc.setSelectedId(fieldId);
|
|
2592
|
+
doc.setActiveSectionId(sectionId);
|
|
2593
|
+
setMobilePanel("inspector");
|
|
2594
|
+
},
|
|
2595
|
+
onFieldChange: doc.updateField,
|
|
2596
|
+
onMoveField: doc.moveField,
|
|
2597
|
+
onDuplicateField: doc.duplicateField,
|
|
2598
|
+
onDeleteField: doc.deleteField,
|
|
2599
|
+
getDropZoneHandlers: drag.getDropZoneHandlers,
|
|
2600
|
+
getDragHandleProps: drag.getDragHandleProps
|
|
2601
|
+
}
|
|
2602
|
+
),
|
|
2603
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2604
|
+
Inspector,
|
|
2605
|
+
{
|
|
2606
|
+
selected: doc.selected,
|
|
2607
|
+
language,
|
|
2608
|
+
chrome,
|
|
2609
|
+
features,
|
|
2610
|
+
onUpdateField: (patch) => doc.selected && doc.updateField(doc.selected.id, patch),
|
|
2611
|
+
onDeleteField: () => doc.selected && doc.deleteField(doc.selected.id),
|
|
2612
|
+
onUpdateOption: (optIdx, patch) => doc.selected && doc.updateOption(doc.selected.id, optIdx, patch),
|
|
2613
|
+
onAddOption: () => doc.selected && doc.addOption(doc.selected.id),
|
|
2614
|
+
onRemoveOption: (optIdx) => doc.selected && doc.removeOption(doc.selected.id, optIdx)
|
|
2615
|
+
}
|
|
2616
|
+
)
|
|
2617
|
+
] })
|
|
2454
2618
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2455
2619
|
PreviewPane,
|
|
2456
2620
|
{
|
|
@@ -2461,6 +2625,7 @@ var FormBuilder = (0, import_react8.forwardRef)(function FormBuilder2({
|
|
|
2461
2625
|
strings,
|
|
2462
2626
|
chrome,
|
|
2463
2627
|
baseMaxWidth: theme.layout.maxWidth,
|
|
2628
|
+
features,
|
|
2464
2629
|
onSubmit
|
|
2465
2630
|
}
|
|
2466
2631
|
),
|
|
@@ -2491,8 +2656,25 @@ var FormBuilder = (0, import_react8.forwardRef)(function FormBuilder2({
|
|
|
2491
2656
|
] });
|
|
2492
2657
|
});
|
|
2493
2658
|
var FormBuilder_default = FormBuilder;
|
|
2659
|
+
|
|
2660
|
+
// src/theme/darkTheme.ts
|
|
2661
|
+
var DARK_THEME = {
|
|
2662
|
+
primary: "#8B8FF5",
|
|
2663
|
+
primarySoft: "#262A45",
|
|
2664
|
+
danger: "#F0715B",
|
|
2665
|
+
dangerSoft: "#3A2420",
|
|
2666
|
+
ink: "#EDEEF2",
|
|
2667
|
+
muted: "#9096A8",
|
|
2668
|
+
border: "#2E313D",
|
|
2669
|
+
surface: "#1A1B23",
|
|
2670
|
+
canvas: "#121319",
|
|
2671
|
+
pageBackground: "#1A1B23",
|
|
2672
|
+
layout: DEFAULT_THEME.layout
|
|
2673
|
+
};
|
|
2494
2674
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2495
2675
|
0 && (module.exports = {
|
|
2676
|
+
DARK_THEME,
|
|
2677
|
+
DEFAULT_THEME,
|
|
2496
2678
|
FormBuilder,
|
|
2497
2679
|
localStorageAdapter
|
|
2498
2680
|
});
|