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.js
CHANGED
|
@@ -1,8 +1,69 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/FormBuilder.tsx
|
|
4
|
-
import { forwardRef, useImperativeHandle, useState as useState8 } from "react";
|
|
5
|
-
import { Loader2 as Loader22 } from "lucide-react";
|
|
4
|
+
import { forwardRef, useEffect as useEffect2, useImperativeHandle, useState as useState8 } from "react";
|
|
5
|
+
import { Loader2 as Loader22, Menu, SlidersHorizontal } from "lucide-react";
|
|
6
|
+
|
|
7
|
+
// src/constants/fieldTypes.ts
|
|
8
|
+
import {
|
|
9
|
+
Type,
|
|
10
|
+
AlignLeft,
|
|
11
|
+
ChevronDown,
|
|
12
|
+
Circle,
|
|
13
|
+
ListChecks,
|
|
14
|
+
CheckSquare,
|
|
15
|
+
ToggleLeft,
|
|
16
|
+
FileText,
|
|
17
|
+
Image as ImageIcon,
|
|
18
|
+
MousePointerClick
|
|
19
|
+
} from "lucide-react";
|
|
20
|
+
var FIELD_TYPES = [
|
|
21
|
+
{ type: "paragraph", icon: FileText, isContent: true, defaultIcon: "FileText" },
|
|
22
|
+
{ type: "image", icon: ImageIcon, isContent: true, isImage: true, defaultIcon: "Type" },
|
|
23
|
+
{ type: "button", icon: MousePointerClick, isContent: true, defaultIcon: "Type" },
|
|
24
|
+
{ type: "input", icon: Type, placeholder: true, hasSubtype: true, defaultIcon: "Type" },
|
|
25
|
+
{ type: "textarea", icon: AlignLeft, placeholder: true, defaultIcon: "AlignLeft" },
|
|
26
|
+
{ type: "select", icon: ChevronDown, options: true, defaultIcon: "ChevronDown" },
|
|
27
|
+
{ type: "radio", icon: Circle, options: true, defaultIcon: "Circle" },
|
|
28
|
+
{ type: "checkboxGroup", icon: ListChecks, options: true, multiValue: true, defaultIcon: "ListChecks" },
|
|
29
|
+
{ type: "checkbox", icon: CheckSquare, boolean: true, defaultIcon: "CheckSquare" },
|
|
30
|
+
{ type: "toggle", icon: ToggleLeft, boolean: true, defaultIcon: "ToggleLeft" }
|
|
31
|
+
];
|
|
32
|
+
var TYPE_MAP = Object.fromEntries(FIELD_TYPES.map((f) => [f.type, f]));
|
|
33
|
+
var CONTENT_TYPES = FIELD_TYPES.filter((f) => f.isContent);
|
|
34
|
+
var FORM_TYPES = FIELD_TYPES.filter((f) => !f.isContent);
|
|
35
|
+
function getMeta(type) {
|
|
36
|
+
return TYPE_MAP[type] || TYPE_MAP.input;
|
|
37
|
+
}
|
|
38
|
+
var LEGACY_INPUT_TYPES = ["text", "email", "phone", "number", "password", "date"];
|
|
39
|
+
var INPUT_SUBTYPES = ["text", "email", "phone", "number", "password", "date", "time"];
|
|
40
|
+
var IMAGE_SHAPES = ["square", "circle", "banner"];
|
|
41
|
+
var FIELD_TYPE_CHROME_KEY = {
|
|
42
|
+
paragraph: "fieldTypeParagraph",
|
|
43
|
+
image: "fieldTypeImage",
|
|
44
|
+
button: "fieldTypeButton",
|
|
45
|
+
input: "fieldTypeInput",
|
|
46
|
+
textarea: "fieldTypeTextarea",
|
|
47
|
+
select: "fieldTypeSelect",
|
|
48
|
+
radio: "fieldTypeRadio",
|
|
49
|
+
checkboxGroup: "fieldTypeCheckboxGroup",
|
|
50
|
+
checkbox: "fieldTypeCheckbox",
|
|
51
|
+
toggle: "fieldTypeToggle"
|
|
52
|
+
};
|
|
53
|
+
var INPUT_SUBTYPE_CHROME_KEY = {
|
|
54
|
+
text: "subtypeText",
|
|
55
|
+
email: "subtypeEmail",
|
|
56
|
+
phone: "subtypePhone",
|
|
57
|
+
number: "subtypeNumber",
|
|
58
|
+
password: "subtypePassword",
|
|
59
|
+
date: "subtypeDate",
|
|
60
|
+
time: "subtypeTime"
|
|
61
|
+
};
|
|
62
|
+
var IMAGE_SHAPE_CHROME_KEY = {
|
|
63
|
+
square: "shapeSquare",
|
|
64
|
+
circle: "shapeCircle",
|
|
65
|
+
banner: "shapeBanner"
|
|
66
|
+
};
|
|
6
67
|
|
|
7
68
|
// src/i18n/languages.ts
|
|
8
69
|
var DEFAULT_LANGUAGES = [
|
|
@@ -333,6 +394,22 @@ function withLang(val, lang, value) {
|
|
|
333
394
|
return { ...base, [lang]: value };
|
|
334
395
|
}
|
|
335
396
|
|
|
397
|
+
// src/lib/color.ts
|
|
398
|
+
function mixHex(a, b, t2) {
|
|
399
|
+
const pa = parseHex(a);
|
|
400
|
+
const pb = parseHex(b);
|
|
401
|
+
if (!pa || !pb) return a;
|
|
402
|
+
const mix = (x, y) => Math.round(x + (y - x) * t2);
|
|
403
|
+
const toHex = (n) => n.toString(16).padStart(2, "0");
|
|
404
|
+
return `#${toHex(mix(pa[0], pb[0]))}${toHex(mix(pa[1], pb[1]))}${toHex(mix(pa[2], pb[2]))}`;
|
|
405
|
+
}
|
|
406
|
+
function parseHex(hex) {
|
|
407
|
+
const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim());
|
|
408
|
+
if (!m) return null;
|
|
409
|
+
const n = parseInt(m[1], 16);
|
|
410
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
411
|
+
}
|
|
412
|
+
|
|
336
413
|
// src/lib/storage/compress.ts
|
|
337
414
|
import { compressToUTF16, decompressFromUTF16 } from "lz-string";
|
|
338
415
|
function compress(raw) {
|
|
@@ -375,67 +452,6 @@ var localStorageAdapter = {
|
|
|
375
452
|
}
|
|
376
453
|
};
|
|
377
454
|
|
|
378
|
-
// src/constants/fieldTypes.ts
|
|
379
|
-
import {
|
|
380
|
-
Type,
|
|
381
|
-
AlignLeft,
|
|
382
|
-
ChevronDown,
|
|
383
|
-
Circle,
|
|
384
|
-
ListChecks,
|
|
385
|
-
CheckSquare,
|
|
386
|
-
ToggleLeft,
|
|
387
|
-
FileText,
|
|
388
|
-
Image as ImageIcon,
|
|
389
|
-
MousePointerClick
|
|
390
|
-
} from "lucide-react";
|
|
391
|
-
var FIELD_TYPES = [
|
|
392
|
-
{ type: "paragraph", icon: FileText, isContent: true, defaultIcon: "FileText" },
|
|
393
|
-
{ type: "image", icon: ImageIcon, isContent: true, isImage: true, defaultIcon: "Type" },
|
|
394
|
-
{ type: "button", icon: MousePointerClick, isContent: true, defaultIcon: "Type" },
|
|
395
|
-
{ type: "input", icon: Type, placeholder: true, hasSubtype: true, defaultIcon: "Type" },
|
|
396
|
-
{ type: "textarea", icon: AlignLeft, placeholder: true, defaultIcon: "AlignLeft" },
|
|
397
|
-
{ type: "select", icon: ChevronDown, options: true, defaultIcon: "ChevronDown" },
|
|
398
|
-
{ type: "radio", icon: Circle, options: true, defaultIcon: "Circle" },
|
|
399
|
-
{ type: "checkboxGroup", icon: ListChecks, options: true, multiValue: true, defaultIcon: "ListChecks" },
|
|
400
|
-
{ type: "checkbox", icon: CheckSquare, boolean: true, defaultIcon: "CheckSquare" },
|
|
401
|
-
{ type: "toggle", icon: ToggleLeft, boolean: true, defaultIcon: "ToggleLeft" }
|
|
402
|
-
];
|
|
403
|
-
var TYPE_MAP = Object.fromEntries(FIELD_TYPES.map((f) => [f.type, f]));
|
|
404
|
-
var CONTENT_TYPES = FIELD_TYPES.filter((f) => f.isContent);
|
|
405
|
-
var FORM_TYPES = FIELD_TYPES.filter((f) => !f.isContent);
|
|
406
|
-
function getMeta(type) {
|
|
407
|
-
return TYPE_MAP[type] || TYPE_MAP.input;
|
|
408
|
-
}
|
|
409
|
-
var LEGACY_INPUT_TYPES = ["text", "email", "phone", "number", "password", "date"];
|
|
410
|
-
var INPUT_SUBTYPES = ["text", "email", "phone", "number", "password", "date", "time"];
|
|
411
|
-
var IMAGE_SHAPES = ["square", "circle", "banner"];
|
|
412
|
-
var FIELD_TYPE_CHROME_KEY = {
|
|
413
|
-
paragraph: "fieldTypeParagraph",
|
|
414
|
-
image: "fieldTypeImage",
|
|
415
|
-
button: "fieldTypeButton",
|
|
416
|
-
input: "fieldTypeInput",
|
|
417
|
-
textarea: "fieldTypeTextarea",
|
|
418
|
-
select: "fieldTypeSelect",
|
|
419
|
-
radio: "fieldTypeRadio",
|
|
420
|
-
checkboxGroup: "fieldTypeCheckboxGroup",
|
|
421
|
-
checkbox: "fieldTypeCheckbox",
|
|
422
|
-
toggle: "fieldTypeToggle"
|
|
423
|
-
};
|
|
424
|
-
var INPUT_SUBTYPE_CHROME_KEY = {
|
|
425
|
-
text: "subtypeText",
|
|
426
|
-
email: "subtypeEmail",
|
|
427
|
-
phone: "subtypePhone",
|
|
428
|
-
number: "subtypeNumber",
|
|
429
|
-
password: "subtypePassword",
|
|
430
|
-
date: "subtypeDate",
|
|
431
|
-
time: "subtypeTime"
|
|
432
|
-
};
|
|
433
|
-
var IMAGE_SHAPE_CHROME_KEY = {
|
|
434
|
-
square: "shapeSquare",
|
|
435
|
-
circle: "shapeCircle",
|
|
436
|
-
banner: "shapeBanner"
|
|
437
|
-
};
|
|
438
|
-
|
|
439
455
|
// src/lib/id.ts
|
|
440
456
|
var genFormId = () => `form_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;
|
|
441
457
|
var genSectionId = () => `section_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;
|
|
@@ -599,6 +615,38 @@ function migrateDocument(raw) {
|
|
|
599
615
|
return { title, themeOverrides, sections };
|
|
600
616
|
}
|
|
601
617
|
|
|
618
|
+
// src/lib/features.ts
|
|
619
|
+
var DEFAULT_FEATURES = {
|
|
620
|
+
naming: true,
|
|
621
|
+
templates: true,
|
|
622
|
+
newForm: true,
|
|
623
|
+
autosave: true,
|
|
624
|
+
jsonView: true,
|
|
625
|
+
previewMode: true,
|
|
626
|
+
languageSwitcher: true,
|
|
627
|
+
design: false,
|
|
628
|
+
blockStyling: true,
|
|
629
|
+
contentBlocks: true,
|
|
630
|
+
fieldTypes: true,
|
|
631
|
+
sections: true,
|
|
632
|
+
dragReorder: true,
|
|
633
|
+
deviceToggle: true
|
|
634
|
+
};
|
|
635
|
+
function resolveFeatures(features) {
|
|
636
|
+
return {
|
|
637
|
+
...DEFAULT_FEATURES,
|
|
638
|
+
...features,
|
|
639
|
+
contentBlocks: Array.isArray(features?.contentBlocks) ? new Set(features.contentBlocks) : features?.contentBlocks ?? DEFAULT_FEATURES.contentBlocks,
|
|
640
|
+
fieldTypes: Array.isArray(features?.fieldTypes) ? new Set(features.fieldTypes) : features?.fieldTypes ?? DEFAULT_FEATURES.fieldTypes
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
function isContentBlockEnabled(features, type) {
|
|
644
|
+
return features.contentBlocks === true || features.contentBlocks instanceof Set && features.contentBlocks.has(type);
|
|
645
|
+
}
|
|
646
|
+
function isFieldTypeEnabled(features, type) {
|
|
647
|
+
return features.fieldTypes === true || features.fieldTypes instanceof Set && features.fieldTypes.has(type);
|
|
648
|
+
}
|
|
649
|
+
|
|
602
650
|
// src/hooks/useTheme.ts
|
|
603
651
|
import { useState } from "react";
|
|
604
652
|
|
|
@@ -833,6 +881,7 @@ var formKey = (id) => `form-page-builder:saved:${id}`;
|
|
|
833
881
|
var MAX_TEMPLATES = 5;
|
|
834
882
|
function usePersistence({
|
|
835
883
|
storage,
|
|
884
|
+
autosave,
|
|
836
885
|
language,
|
|
837
886
|
chrome,
|
|
838
887
|
document,
|
|
@@ -894,7 +943,7 @@ function usePersistence({
|
|
|
894
943
|
refreshLibrary();
|
|
895
944
|
}, []);
|
|
896
945
|
useEffect(() => {
|
|
897
|
-
if (!hasLoadedOnce.current) return;
|
|
946
|
+
if (!hasLoadedOnce.current || !autosave) return;
|
|
898
947
|
setSaveState("saving");
|
|
899
948
|
if (autosaveTimer.current) clearTimeout(autosaveTimer.current);
|
|
900
949
|
autosaveTimer.current = setTimeout(async () => {
|
|
@@ -1033,15 +1082,15 @@ var styles = {
|
|
|
1033
1082
|
titleInput: { border: "none", outline: "none", fontSize: 14, fontWeight: 600, background: "transparent", color: "var(--fb-ink)", padding: "4px 6px", borderRadius: 6, minWidth: 160 },
|
|
1034
1083
|
toolbarRight: { display: "flex", alignItems: "center", gap: 6, flexWrap: "wrap" },
|
|
1035
1084
|
toolbarDivider: { width: 1, height: 20, background: "var(--fb-border)", margin: "0 4px" },
|
|
1036
|
-
tabBtn: { display: "flex", alignItems: "center", gap: 6, padding: "6px 12px", borderRadius: 7, border: "1px solid transparent", background: "transparent", color: "
|
|
1085
|
+
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 },
|
|
1037
1086
|
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 },
|
|
1038
|
-
ghostBtn: { display: "flex", alignItems: "center", gap: 6, padding: "6px 12px", borderRadius: 7, border: "1px solid var(--fb-border)", background: "var(--fb-surface)", color: "
|
|
1087
|
+
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 },
|
|
1039
1088
|
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 },
|
|
1040
1089
|
saveStatus: { display: "flex", alignItems: "center", gap: 5, fontSize: 12, color: "var(--fb-muted)", minWidth: 60 },
|
|
1041
1090
|
countBadge: { fontSize: 10.5, fontWeight: 700, background: "var(--fb-primary-soft)", color: "var(--fb-primary)", borderRadius: 9, padding: "1px 6px", marginLeft: 2 },
|
|
1042
1091
|
loadingScreen: { flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", color: "var(--fb-muted)" },
|
|
1043
1092
|
libraryBody: { padding: "var(--fb-space-panel)", overflowY: "auto", display: "flex", flexDirection: "column", gap: 4 },
|
|
1044
|
-
libraryRow: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10, padding: "10px 8px", borderRadius: 8, border: "1px solid
|
|
1093
|
+
libraryRow: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10, padding: "10px 8px", borderRadius: 8, border: "1px solid var(--fb-border)" },
|
|
1045
1094
|
libraryRowTitle: { fontSize: 13.5, fontWeight: 600, color: "var(--fb-ink)", display: "flex", alignItems: "center", gap: 8, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" },
|
|
1046
1095
|
libraryRowMeta: { fontSize: 11.5, color: "var(--fb-muted)", marginTop: 2 },
|
|
1047
1096
|
currentBadge: { fontSize: 10, fontWeight: 700, color: "var(--fb-primary)", background: "var(--fb-primary-soft)", padding: "2px 6px", borderRadius: 5, flexShrink: 0 },
|
|
@@ -1050,7 +1099,7 @@ var styles = {
|
|
|
1050
1099
|
panelHeading: { fontSize: 11, fontWeight: 700, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--fb-muted)", marginBottom: 10 },
|
|
1051
1100
|
activeSectionHint: { fontSize: 11.5, color: "var(--fb-muted)", marginBottom: 14, lineHeight: 1.4 },
|
|
1052
1101
|
paletteList: { display: "flex", flexDirection: "column", gap: 4 },
|
|
1053
|
-
paletteItem: { display: "flex", alignItems: "center", gap: 9, padding: "8px 9px", borderRadius: 8, border: "1px solid transparent", background: "transparent", fontSize: 13, color: "
|
|
1102
|
+
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" },
|
|
1054
1103
|
canvas: { flex: 1, padding: "var(--fb-space-canvas)", overflowY: "auto", background: "var(--fb-canvas)" },
|
|
1055
1104
|
sectionBlock: { borderRadius: 12, padding: "var(--fb-space-panel)", marginBottom: "var(--fb-space-section)", transition: "border-color 0.12s" },
|
|
1056
1105
|
sectionHeader: { display: "flex", alignItems: "center", gap: 8, marginBottom: 12, flexWrap: "wrap" },
|
|
@@ -1060,7 +1109,7 @@ var styles = {
|
|
|
1060
1109
|
sectionHeaderActions: { display: "flex", alignItems: "center", gap: 6, flexWrap: "wrap", marginLeft: "auto" },
|
|
1061
1110
|
sectionEmpty: { fontSize: 12.5, color: "var(--fb-muted)", padding: "18px 4px", textAlign: "center", border: "1px dashed var(--fb-border)", borderRadius: 8 },
|
|
1062
1111
|
resetLinkBtn: { display: "flex", alignItems: "center", gap: 3, fontSize: 11, color: "var(--fb-muted)", background: "transparent", border: "none", padding: "2px 4px" },
|
|
1063
|
-
addSectionBtn: { display: "flex", alignItems: "center", justifyContent: "center", gap: 6, width: "100%", padding: "10px", borderRadius: 10, border: "1px dashed
|
|
1112
|
+
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 },
|
|
1064
1113
|
swatchRow: { display: "flex", alignItems: "center", gap: 5, flexWrap: "wrap" },
|
|
1065
1114
|
swatchBtn: { width: 20, height: 20, borderRadius: "50%", border: "1px solid var(--fb-border)", padding: 0 },
|
|
1066
1115
|
swatchBtnActive: { border: "2px solid var(--fb-primary)" },
|
|
@@ -1069,56 +1118,56 @@ var styles = {
|
|
|
1069
1118
|
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" },
|
|
1070
1119
|
ticketSelected: { borderColor: "var(--fb-primary)", boxShadow: "0 0 0 3px var(--fb-primary-soft)" },
|
|
1071
1120
|
ticketDragOver: { borderColor: "var(--fb-muted)" },
|
|
1072
|
-
ticketIndex: { fontFamily: "'JetBrains Mono', monospace", fontSize: 13, fontWeight: 700, color: "
|
|
1121
|
+
ticketIndex: { fontFamily: "'JetBrains Mono', monospace", fontSize: 13, fontWeight: 700, color: "var(--fb-border)", width: 34, display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 },
|
|
1073
1122
|
ticketPerforation: { width: 0, borderLeft: "1px dashed var(--fb-border)" },
|
|
1074
1123
|
ticketBody: { flex: 1, padding: "10px var(--fb-space-ticket)", minWidth: 0 },
|
|
1075
1124
|
ticketTop: { display: "flex", alignItems: "center", gap: 7, marginBottom: 4 },
|
|
1076
1125
|
typeBadge: { fontSize: 10.5, fontFamily: "'JetBrains Mono', monospace", color: "var(--fb-muted)" },
|
|
1077
|
-
requiredBadge: { fontSize: 10, fontWeight: 700, color: "
|
|
1126
|
+
requiredBadge: { fontSize: 10, fontWeight: 700, color: "var(--fb-danger)", background: "var(--fb-danger-soft)", padding: "2px 6px", borderRadius: 5, letterSpacing: "0.02em", marginLeft: "auto" },
|
|
1078
1127
|
chipRow: { display: "flex", gap: 5, marginBottom: 7, flexWrap: "wrap" },
|
|
1079
1128
|
miniBadge: { fontSize: 10, fontWeight: 600, color: "var(--fb-primary)", background: "var(--fb-primary-soft)", padding: "2px 6px", borderRadius: 5, letterSpacing: "0.02em" },
|
|
1080
|
-
langToggleTrack: { position: "relative", display: "flex", gap: 3, background: "
|
|
1129
|
+
langToggleTrack: { position: "relative", display: "flex", gap: 3, background: "var(--fb-surface-2)", padding: 3, borderRadius: 20 },
|
|
1081
1130
|
langToggleThumb: { position: "absolute", top: 3, left: 3, bottom: 3, background: "var(--fb-primary)", borderRadius: 17, transition: "transform 0.18s ease" },
|
|
1082
|
-
langToggleBtn: { position: "relative", zIndex: 1, padding: "5px 12px", borderRadius: 17, border: "none", background: "transparent", color: "
|
|
1131
|
+
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" },
|
|
1083
1132
|
langToggleBtnActive: { position: "relative", zIndex: 1, padding: "5px 12px", borderRadius: 17, border: "none", background: "transparent", color: "#fff", fontSize: 12.5, fontWeight: 600, whiteSpace: "nowrap" },
|
|
1084
|
-
segmented: { display: "flex", gap: 3, background: "
|
|
1085
|
-
segmentedBtn: { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", gap: 5, padding: "6px 8px", borderRadius: 6, border: "none", background: "transparent", color: "
|
|
1086
|
-
segmentedBtnActive: { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", gap: 5, padding: "6px 8px", borderRadius: 6, border: "none", background: "
|
|
1133
|
+
segmented: { display: "flex", gap: 3, background: "var(--fb-surface-2)", padding: 3, borderRadius: 8, marginBottom: 4 },
|
|
1134
|
+
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 },
|
|
1135
|
+
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)" },
|
|
1087
1136
|
iconGrid: { display: "grid", gridTemplateColumns: "repeat(6, 1fr)", gap: 5, marginTop: 6 },
|
|
1088
|
-
iconGridBtn: { width: 30, height: 30, borderRadius: 7, border: "1px solid var(--fb-border)", background: "
|
|
1137
|
+
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)" },
|
|
1089
1138
|
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)" },
|
|
1090
1139
|
styleToggleRow: { display: "flex", gap: 5, marginBottom: 4 },
|
|
1091
|
-
styleToggle: { width: 30, height: 30, borderRadius: 7, border: "1px solid var(--fb-border)", background: "
|
|
1140
|
+
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)" },
|
|
1092
1141
|
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)" },
|
|
1093
|
-
previewInput: { border: "1px solid
|
|
1094
|
-
previewRadio: { display: "flex", alignItems: "center", gap: 6, fontSize: 13, color: "
|
|
1095
|
-
ticketActions: { display: "flex", flexDirection: "column", gap: 3, padding: 8, borderLeft: "1px solid
|
|
1096
|
-
iconBtn: { width: 24, height: 24, borderRadius: 6, border: "1px solid
|
|
1142
|
+
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" },
|
|
1143
|
+
previewRadio: { display: "flex", alignItems: "center", gap: 6, fontSize: 13, color: "var(--fb-ink)" },
|
|
1144
|
+
ticketActions: { display: "flex", flexDirection: "column", gap: 3, padding: 8, borderLeft: "1px solid var(--fb-border)" },
|
|
1145
|
+
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)" },
|
|
1097
1146
|
iconBtnDanger: { color: "var(--fb-danger)" },
|
|
1098
1147
|
inspector: { width: 270, borderLeft: "1px solid var(--fb-border)", background: "var(--fb-surface)", padding: "var(--fb-space-panel)", overflowY: "auto" },
|
|
1099
1148
|
inspectorEmpty: { fontSize: 13, color: "var(--fb-muted)", lineHeight: 1.5, marginTop: 6 },
|
|
1100
1149
|
inspectorBody: { display: "flex", flexDirection: "column", gap: 4 },
|
|
1101
1150
|
helperText: { fontSize: 11, color: "var(--fb-muted)", lineHeight: 1.4, margin: "2px 0 4px" },
|
|
1102
|
-
propLabel: { fontSize: 11.5, fontWeight: 600, color: "
|
|
1103
|
-
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" },
|
|
1151
|
+
propLabel: { fontSize: 11.5, fontWeight: 600, color: "var(--fb-muted)", marginTop: 12, marginBottom: 5 },
|
|
1152
|
+
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" },
|
|
1104
1153
|
optionList: { display: "flex", flexDirection: "column", gap: 6 },
|
|
1105
1154
|
optionRow: { display: "flex", gap: 6, alignItems: "center" },
|
|
1106
|
-
optionInput: { flex: 1, border: "1px solid var(--fb-border)", borderRadius: 6, padding: "6px 8px", fontSize: 12.5, outline: "none", minWidth: 0, boxSizing: "border-box" },
|
|
1107
|
-
addOptionBtn: { display: "flex", alignItems: "center", gap: 5, fontSize: 12.5, color: "var(--fb-primary)", background: "transparent", border: "1px dashed
|
|
1155
|
+
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" },
|
|
1156
|
+
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 },
|
|
1108
1157
|
toggleRow: { display: "flex", alignItems: "center", gap: 8, background: "transparent", border: "none", padding: "8px 0" },
|
|
1109
1158
|
toggleTrack: { width: 30, height: 17, borderRadius: 20, position: "relative", transition: "background 0.15s", display: "inline-block" },
|
|
1110
1159
|
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)" },
|
|
1111
1160
|
inspectorDivider: { height: 1, background: "var(--fb-border)", margin: "14px 0 10px" },
|
|
1112
1161
|
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" },
|
|
1113
|
-
modalOverlay: { position: "fixed", inset: 0, background: "rgba(20,22,28,0.45)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 50 },
|
|
1114
|
-
modal: { background: "
|
|
1162
|
+
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" },
|
|
1163
|
+
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" },
|
|
1115
1164
|
modalHeader: { display: "flex", alignItems: "center", justifyContent: "space-between", padding: "12px 16px", borderBottom: "1px solid var(--fb-border)" },
|
|
1116
1165
|
jsonPre: { margin: 0, padding: 16, fontSize: 12, lineHeight: 1.6, overflow: "auto", background: "#14171C", color: "#D6D8E0", fontFamily: "'JetBrains Mono', monospace" },
|
|
1117
1166
|
previewWrap: { flex: 1, display: "flex", justifyContent: "center", padding: "var(--fb-space-page) 20px", overflowY: "auto", background: "var(--fb-canvas)" },
|
|
1118
1167
|
previewToolbar: { width: "100%", display: "flex", gap: 10, marginBottom: 16, justifyContent: "center" },
|
|
1119
1168
|
previewCard: { width: "100%", maxWidth: 480, background: "var(--fb-page-bg)", border: "1px solid var(--fb-border)", borderRadius: 12, padding: "var(--fb-space-page)" },
|
|
1120
1169
|
previewTitle: { fontSize: 19, fontWeight: 700, margin: "0 0 20px" },
|
|
1121
|
-
previewLabel: { display: "block", fontSize: 13, fontWeight: 600, color: "
|
|
1170
|
+
previewLabel: { display: "block", fontSize: 13, fontWeight: 600, color: "var(--fb-ink)", marginBottom: 6 },
|
|
1122
1171
|
previewGrid: { display: "flex", flexWrap: "wrap", gap: "var(--fb-space-field)" },
|
|
1123
1172
|
sectionRuntimeTitle: { fontSize: 15, fontWeight: 700, margin: "0 0 12px", color: "var(--fb-ink)" },
|
|
1124
1173
|
imagePlaceholder: { display: "flex", alignItems: "center", justifyContent: "center", border: "1px dashed var(--fb-border)" },
|
|
@@ -1128,13 +1177,13 @@ var styles = {
|
|
|
1128
1177
|
submittedRow: { display: "flex", justifyContent: "space-between", gap: 12, fontSize: 13, padding: "6px 0", borderBottom: "1px solid var(--fb-border)" },
|
|
1129
1178
|
submittedLabel: { color: "var(--fb-muted)", flexShrink: 0 },
|
|
1130
1179
|
submittedValue: { color: "var(--fb-ink)", fontWeight: 600, textAlign: "right" },
|
|
1131
|
-
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" },
|
|
1180
|
+
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" },
|
|
1132
1181
|
realInputError: { borderColor: "var(--fb-danger)" },
|
|
1133
1182
|
submitBtn: { marginTop: 8, color: "#fff", border: "none", borderRadius: 8, fontWeight: 600, width: "100%" },
|
|
1134
1183
|
layoutPanelHeader: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 4 },
|
|
1135
1184
|
spacingRow: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, padding: "4px 0" },
|
|
1136
|
-
spacingLabel: { fontSize: 12, color: "
|
|
1137
|
-
spacingInput: { width: 60, border: "1px solid var(--fb-border)", borderRadius: 6, padding: "4px 6px", fontSize: 12, textAlign: "right", outline: "none" }
|
|
1185
|
+
spacingLabel: { fontSize: 12, color: "var(--fb-ink)" },
|
|
1186
|
+
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" }
|
|
1138
1187
|
};
|
|
1139
1188
|
|
|
1140
1189
|
// src/components/LanguageToggle.tsx
|
|
@@ -1175,6 +1224,7 @@ function Toolbar({
|
|
|
1175
1224
|
mode,
|
|
1176
1225
|
saveState,
|
|
1177
1226
|
chrome,
|
|
1227
|
+
features,
|
|
1178
1228
|
savedFormsCount,
|
|
1179
1229
|
onTitleChange,
|
|
1180
1230
|
onLanguageChange,
|
|
@@ -1187,7 +1237,7 @@ function Toolbar({
|
|
|
1187
1237
|
return /* @__PURE__ */ jsxs2("div", { style: styles.toolbar, children: [
|
|
1188
1238
|
/* @__PURE__ */ jsxs2("div", { style: styles.toolbarLeft, children: [
|
|
1189
1239
|
/* @__PURE__ */ jsx2("div", { style: styles.logoMark, children: "FB" }),
|
|
1190
|
-
/* @__PURE__ */ jsx2("input", { value: t(title, language), onChange: (e) => onTitleChange(e.target.value), style: styles.titleInput, "aria-label": "Form title" })
|
|
1240
|
+
features.naming ? /* @__PURE__ */ jsx2("input", { value: t(title, language), onChange: (e) => onTitleChange(e.target.value), style: styles.titleInput, "aria-label": "Form title" }) : /* @__PURE__ */ jsx2("span", { style: styles.titleInput, children: t(title, language) })
|
|
1191
1241
|
] }),
|
|
1192
1242
|
/* @__PURE__ */ jsxs2("div", { style: styles.toolbarRight, children: [
|
|
1193
1243
|
/* @__PURE__ */ jsxs2("span", { style: styles.saveStatus, children: [
|
|
@@ -1203,37 +1253,43 @@ function Toolbar({
|
|
|
1203
1253
|
chrome.saveFailed
|
|
1204
1254
|
] })
|
|
1205
1255
|
] }),
|
|
1206
|
-
/* @__PURE__ */
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
/* @__PURE__ */ jsxs2("button", { style: mode === "build" ? styles.tabBtnActive : styles.tabBtn, onClick: () => onModeChange("build"), children: [
|
|
1210
|
-
/* @__PURE__ */ jsx2(Pencil, { size: 14 }),
|
|
1211
|
-
" ",
|
|
1212
|
-
chrome.build
|
|
1256
|
+
features.languageSwitcher && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
1257
|
+
/* @__PURE__ */ jsx2("div", { style: styles.toolbarDivider }),
|
|
1258
|
+
/* @__PURE__ */ jsx2(LanguageToggle, { languages, value: language, onChange: onLanguageChange })
|
|
1213
1259
|
] }),
|
|
1214
|
-
/* @__PURE__ */ jsxs2(
|
|
1215
|
-
/* @__PURE__ */ jsx2(
|
|
1216
|
-
" ",
|
|
1217
|
-
|
|
1260
|
+
features.previewMode && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
1261
|
+
/* @__PURE__ */ jsx2("div", { style: styles.toolbarDivider }),
|
|
1262
|
+
/* @__PURE__ */ jsxs2("button", { style: mode === "build" ? styles.tabBtnActive : styles.tabBtn, onClick: () => onModeChange("build"), children: [
|
|
1263
|
+
/* @__PURE__ */ jsx2(Pencil, { size: 14 }),
|
|
1264
|
+
" ",
|
|
1265
|
+
chrome.build
|
|
1266
|
+
] }),
|
|
1267
|
+
/* @__PURE__ */ jsxs2("button", { style: mode === "preview" ? styles.tabBtnActive : styles.tabBtn, onClick: () => onModeChange("preview"), children: [
|
|
1268
|
+
/* @__PURE__ */ jsx2(Eye, { size: 14 }),
|
|
1269
|
+
" ",
|
|
1270
|
+
chrome.preview
|
|
1271
|
+
] })
|
|
1218
1272
|
] }),
|
|
1219
|
-
/* @__PURE__ */ jsx2("div", { style: styles.toolbarDivider }),
|
|
1220
|
-
/* @__PURE__ */ jsxs2("button", { style: styles.ghostBtn, onClick: onNewForm, title: chrome.startNewForm, children: [
|
|
1273
|
+
(features.newForm || features.templates) && /* @__PURE__ */ jsx2("div", { style: styles.toolbarDivider }),
|
|
1274
|
+
features.newForm && /* @__PURE__ */ jsxs2("button", { style: styles.ghostBtn, onClick: onNewForm, title: chrome.startNewForm, children: [
|
|
1221
1275
|
/* @__PURE__ */ jsx2(FilePlus2, { size: 14 }),
|
|
1222
1276
|
" ",
|
|
1223
1277
|
chrome.newForm
|
|
1224
1278
|
] }),
|
|
1225
|
-
/* @__PURE__ */ jsxs2(
|
|
1226
|
-
/* @__PURE__ */
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
/* @__PURE__ */
|
|
1233
|
-
|
|
1234
|
-
|
|
1279
|
+
features.templates && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
1280
|
+
/* @__PURE__ */ jsxs2("button", { style: styles.ghostBtn, onClick: onOpenLibrary, title: chrome.openTemplatesTitle, children: [
|
|
1281
|
+
/* @__PURE__ */ jsx2(FolderOpen, { size: 14 }),
|
|
1282
|
+
" ",
|
|
1283
|
+
chrome.templates,
|
|
1284
|
+
savedFormsCount > 0 && /* @__PURE__ */ jsx2("span", { style: styles.countBadge, children: savedFormsCount })
|
|
1285
|
+
] }),
|
|
1286
|
+
/* @__PURE__ */ jsxs2("button", { style: styles.primaryBtn, onClick: onSaveExisting, title: chrome.saveToLibraryTitle, children: [
|
|
1287
|
+
/* @__PURE__ */ jsx2(Save, { size: 14 }),
|
|
1288
|
+
" ",
|
|
1289
|
+
chrome.save
|
|
1290
|
+
] })
|
|
1235
1291
|
] }),
|
|
1236
|
-
/* @__PURE__ */ jsxs2("button", { style: styles.ghostBtn, onClick: onOpenJson, children: [
|
|
1292
|
+
features.jsonView && /* @__PURE__ */ jsxs2("button", { style: styles.ghostBtn, onClick: onOpenJson, children: [
|
|
1237
1293
|
/* @__PURE__ */ jsx2(Code2, { size: 14 }),
|
|
1238
1294
|
" ",
|
|
1239
1295
|
chrome.viewJson
|
|
@@ -1334,15 +1390,19 @@ function Palette({
|
|
|
1334
1390
|
activeSectionLabel,
|
|
1335
1391
|
chrome,
|
|
1336
1392
|
onAddField,
|
|
1337
|
-
|
|
1393
|
+
features,
|
|
1338
1394
|
theme,
|
|
1339
1395
|
updateThemeColor,
|
|
1340
1396
|
updateThemeLayout,
|
|
1341
|
-
resetTheme
|
|
1397
|
+
resetTheme,
|
|
1398
|
+
fieldCount
|
|
1342
1399
|
}) {
|
|
1343
1400
|
const [tab, setTab] = useState5("blocks");
|
|
1344
|
-
|
|
1345
|
-
|
|
1401
|
+
const contentTypes = CONTENT_TYPES.filter((f) => isContentBlockEnabled(features, f.type));
|
|
1402
|
+
const formTypes = FORM_TYPES.filter((f) => isFieldTypeEnabled(features, f.type));
|
|
1403
|
+
const atFieldCap = typeof features.maxFields === "number" && fieldCount >= features.maxFields;
|
|
1404
|
+
return /* @__PURE__ */ jsxs5("div", { className: "fb-palette", style: styles.palette, children: [
|
|
1405
|
+
features.design && /* @__PURE__ */ jsx5("div", { style: { marginBottom: 14 }, children: /* @__PURE__ */ jsx5(
|
|
1346
1406
|
Segmented,
|
|
1347
1407
|
{
|
|
1348
1408
|
options: [
|
|
@@ -1353,7 +1413,7 @@ function Palette({
|
|
|
1353
1413
|
onChange: setTab
|
|
1354
1414
|
}
|
|
1355
1415
|
) }),
|
|
1356
|
-
tab === "design" &&
|
|
1416
|
+
tab === "design" && features.design ? /* @__PURE__ */ jsx5(
|
|
1357
1417
|
DesignPanel,
|
|
1358
1418
|
{
|
|
1359
1419
|
chrome,
|
|
@@ -1368,24 +1428,29 @@ function Palette({
|
|
|
1368
1428
|
" ",
|
|
1369
1429
|
/* @__PURE__ */ jsx5("strong", { children: activeSectionLabel })
|
|
1370
1430
|
] }),
|
|
1371
|
-
/* @__PURE__ */
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
/* @__PURE__ */
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1431
|
+
contentTypes.length > 0 && /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1432
|
+
/* @__PURE__ */ jsx5("div", { style: styles.panelHeading, children: chrome.contentBlocks }),
|
|
1433
|
+
/* @__PURE__ */ jsx5("div", { style: styles.paletteList, children: contentTypes.map((f) => {
|
|
1434
|
+
const Icon = f.icon;
|
|
1435
|
+
return /* @__PURE__ */ jsxs5("button", { style: styles.paletteItem, onClick: () => onAddField(f.type), children: [
|
|
1436
|
+
/* @__PURE__ */ jsx5(Icon, { size: 16, color: "var(--fb-primary)" }),
|
|
1437
|
+
/* @__PURE__ */ jsx5("span", { children: chrome[FIELD_TYPE_CHROME_KEY[f.type]] }),
|
|
1438
|
+
/* @__PURE__ */ jsx5(Plus, { size: 13, color: "var(--fb-muted)", style: { marginLeft: "auto" } })
|
|
1439
|
+
] }, f.type);
|
|
1440
|
+
}) })
|
|
1441
|
+
] }),
|
|
1442
|
+
formTypes.length > 0 && /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1443
|
+
/* @__PURE__ */ jsx5("div", { style: { ...styles.panelHeading, marginTop: 16 }, children: chrome.formFields }),
|
|
1444
|
+
/* @__PURE__ */ jsx5("div", { style: styles.paletteList, children: formTypes.map((f) => {
|
|
1445
|
+
const Icon = f.icon;
|
|
1446
|
+
const itemStyle = atFieldCap ? { ...styles.paletteItem, opacity: 0.45, cursor: "not-allowed" } : styles.paletteItem;
|
|
1447
|
+
return /* @__PURE__ */ jsxs5("button", { type: "button", disabled: atFieldCap, style: itemStyle, onClick: () => onAddField(f.type), children: [
|
|
1448
|
+
/* @__PURE__ */ jsx5(Icon, { size: 16, color: "var(--fb-primary)" }),
|
|
1449
|
+
/* @__PURE__ */ jsx5("span", { children: chrome[FIELD_TYPE_CHROME_KEY[f.type]] }),
|
|
1450
|
+
/* @__PURE__ */ jsx5(Plus, { size: 13, color: "var(--fb-muted)", style: { marginLeft: "auto" } })
|
|
1451
|
+
] }, f.type);
|
|
1452
|
+
}) })
|
|
1453
|
+
] })
|
|
1389
1454
|
] })
|
|
1390
1455
|
] });
|
|
1391
1456
|
}
|
|
@@ -1538,7 +1603,7 @@ function FieldBlock({ field, lang, onFieldChange, strings, chrome, error, isBuil
|
|
|
1538
1603
|
return /* @__PURE__ */ jsxs6("div", { children: [
|
|
1539
1604
|
/* @__PURE__ */ jsxs6("div", { style: { display: "flex", flexDirection: isInline ? "row" : "column", alignItems: isInline ? "center" : "stretch", gap: isInline ? 10 : 6 }, children: [
|
|
1540
1605
|
showLabel && /* @__PURE__ */ jsxs6("label", { style: { ...styles.previewLabel, marginBottom: isInline ? 0 : 6, flexShrink: 0, width: isInline ? 120 : "auto", display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
1541
|
-
IconComp && /* @__PURE__ */ jsx8(IconComp, { size: 14, color: "
|
|
1606
|
+
IconComp && /* @__PURE__ */ jsx8(IconComp, { size: 14, color: "var(--fb-muted)" }),
|
|
1542
1607
|
labelText || (isBuild ? /* @__PURE__ */ jsx8("span", { style: { fontStyle: "italic", color: "var(--fb-muted)" }, children: chrome?.untitledField || "Untitled field" }) : ""),
|
|
1543
1608
|
field.required && /* @__PURE__ */ jsx8("span", { style: { color: "var(--fb-danger)" }, children: " *" })
|
|
1544
1609
|
] }),
|
|
@@ -1603,14 +1668,14 @@ function renderInteractive(field, lang, onFieldChange, IconComp, hasError, strin
|
|
|
1603
1668
|
case "checkbox":
|
|
1604
1669
|
return /* @__PURE__ */ jsxs6("label", { style: styles.previewRadio, children: [
|
|
1605
1670
|
/* @__PURE__ */ jsx8("input", { type: "checkbox", checked: !!value, onChange: (e) => set(e.target.checked), style: { accentColor: "var(--fb-primary)" } }),
|
|
1606
|
-
IconComp && /* @__PURE__ */ jsx8(IconComp, { size: 14, color: "
|
|
1671
|
+
IconComp && /* @__PURE__ */ jsx8(IconComp, { size: 14, color: "var(--fb-muted)" }),
|
|
1607
1672
|
t(field.label, lang),
|
|
1608
1673
|
field.required && /* @__PURE__ */ jsx8("span", { style: { color: "var(--fb-danger)" }, children: " *" })
|
|
1609
1674
|
] });
|
|
1610
1675
|
case "toggle":
|
|
1611
1676
|
return /* @__PURE__ */ jsxs6("label", { style: styles.previewRadio, children: [
|
|
1612
1677
|
/* @__PURE__ */ jsx8("input", { type: "checkbox", checked: !!value, onChange: (e) => set(e.target.checked), style: { accentColor: "var(--fb-primary)" } }),
|
|
1613
|
-
IconComp && /* @__PURE__ */ jsx8(IconComp, { size: 14, color: "
|
|
1678
|
+
IconComp && /* @__PURE__ */ jsx8(IconComp, { size: 14, color: "var(--fb-muted)" }),
|
|
1614
1679
|
t(field.label, lang)
|
|
1615
1680
|
] });
|
|
1616
1681
|
default:
|
|
@@ -1628,6 +1693,7 @@ function FieldTicket({
|
|
|
1628
1693
|
chrome,
|
|
1629
1694
|
strings,
|
|
1630
1695
|
language,
|
|
1696
|
+
dragEnabled,
|
|
1631
1697
|
onSelect,
|
|
1632
1698
|
onFieldChange,
|
|
1633
1699
|
onMoveField,
|
|
@@ -1657,7 +1723,7 @@ function FieldTicket({
|
|
|
1657
1723
|
/* @__PURE__ */ jsx9("div", { style: styles.ticketPerforation }),
|
|
1658
1724
|
/* @__PURE__ */ jsxs7("div", { style: styles.ticketBody, children: [
|
|
1659
1725
|
/* @__PURE__ */ jsxs7("div", { style: styles.ticketTop, children: [
|
|
1660
|
-
/* @__PURE__ */ jsx9("span", { ...dragHandleProps, style: { cursor: "grab", display: "flex" }, children: /* @__PURE__ */ jsx9(GripVertical, { size: 14, color: "
|
|
1726
|
+
dragEnabled && /* @__PURE__ */ jsx9("span", { ...dragHandleProps, style: { cursor: "grab", display: "flex" }, children: /* @__PURE__ */ jsx9(GripVertical, { size: 14, color: "var(--fb-muted)" }) }),
|
|
1661
1727
|
/* @__PURE__ */ jsx9(Icon, { size: 13, color: "var(--fb-primary)" }),
|
|
1662
1728
|
/* @__PURE__ */ jsxs7("span", { style: styles.typeBadge, children: [
|
|
1663
1729
|
chrome[FIELD_TYPE_CHROME_KEY[field.type]] || field.type,
|
|
@@ -1689,7 +1755,7 @@ function FieldTicket({
|
|
|
1689
1755
|
}
|
|
1690
1756
|
|
|
1691
1757
|
// src/components/SectionCard.tsx
|
|
1692
|
-
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1758
|
+
import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1693
1759
|
function SectionCard({
|
|
1694
1760
|
section,
|
|
1695
1761
|
sIdx,
|
|
@@ -1700,6 +1766,7 @@ function SectionCard({
|
|
|
1700
1766
|
chrome,
|
|
1701
1767
|
strings,
|
|
1702
1768
|
language,
|
|
1769
|
+
features,
|
|
1703
1770
|
onActivate,
|
|
1704
1771
|
onToggleCollapse,
|
|
1705
1772
|
onUpdateTitle,
|
|
@@ -1739,14 +1806,16 @@ function SectionCard({
|
|
|
1739
1806
|
),
|
|
1740
1807
|
section.collapsed && /* @__PURE__ */ jsx10("span", { style: styles.miniBadge, children: chrome.fieldsCount(section.fields.length) }),
|
|
1741
1808
|
/* @__PURE__ */ jsxs8("div", { style: styles.sectionHeaderActions, onClick: (e) => e.stopPropagation(), children: [
|
|
1742
|
-
!section.collapsed && /* @__PURE__ */ jsxs8("div", { style: styles.swatchRow, children: [
|
|
1809
|
+
features.sections && !section.collapsed && /* @__PURE__ */ jsxs8("div", { style: styles.swatchRow, children: [
|
|
1743
1810
|
SECTION_BG_SWATCHES.map((c) => /* @__PURE__ */ jsx10("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")),
|
|
1744
1811
|
/* @__PURE__ */ jsx10("input", { type: "color", title: chrome.customColor, value: /^#/.test(section.background) ? section.background : "#ffffff", onChange: (e) => onUpdateBackground(e.target.value), style: styles.colorPickerInput })
|
|
1745
1812
|
] }),
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1813
|
+
features.sections && /* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
1814
|
+
/* @__PURE__ */ jsx10("button", { style: styles.iconBtn, title: chrome.duplicate, onClick: onDuplicateSection, children: /* @__PURE__ */ jsx10(Copy2, { size: 13 }) }),
|
|
1815
|
+
/* @__PURE__ */ jsx10("button", { style: styles.iconBtn, title: chrome.moveUp, disabled: sIdx === 0, onClick: () => onMoveSection(-1), children: /* @__PURE__ */ jsx10(ArrowUp2, { size: 13 }) }),
|
|
1816
|
+
/* @__PURE__ */ jsx10("button", { style: styles.iconBtn, title: chrome.moveDown, disabled: sIdx === sectionsLength - 1, onClick: () => onMoveSection(1), children: /* @__PURE__ */ jsx10(ArrowDown2, { size: 13 }) }),
|
|
1817
|
+
/* @__PURE__ */ jsx10("button", { style: { ...styles.iconBtn, ...styles.iconBtnDanger }, title: chrome.deleteSection, disabled: sectionsLength <= 1, onClick: onDeleteSection, children: /* @__PURE__ */ jsx10(Trash22, { size: 13 }) })
|
|
1818
|
+
] })
|
|
1750
1819
|
] })
|
|
1751
1820
|
] }),
|
|
1752
1821
|
!section.collapsed && (section.fields.length === 0 ? /* @__PURE__ */ jsx10("div", { style: styles.sectionEmpty, children: chrome.noFieldsInSection }) : /* @__PURE__ */ jsx10("div", { style: styles.fieldList, children: section.fields.map((field, idx) => /* @__PURE__ */ jsx10(
|
|
@@ -1760,6 +1829,7 @@ function SectionCard({
|
|
|
1760
1829
|
chrome,
|
|
1761
1830
|
strings,
|
|
1762
1831
|
language,
|
|
1832
|
+
dragEnabled: features.dragReorder,
|
|
1763
1833
|
onSelect: () => onSelectField(field.id),
|
|
1764
1834
|
onFieldChange,
|
|
1765
1835
|
onMoveField,
|
|
@@ -1785,6 +1855,7 @@ function Canvas({
|
|
|
1785
1855
|
chrome,
|
|
1786
1856
|
strings,
|
|
1787
1857
|
language,
|
|
1858
|
+
features,
|
|
1788
1859
|
onActivateSection,
|
|
1789
1860
|
onToggleSectionCollapse,
|
|
1790
1861
|
onUpdateSectionTitle,
|
|
@@ -1801,7 +1872,7 @@ function Canvas({
|
|
|
1801
1872
|
getDropZoneHandlers,
|
|
1802
1873
|
getDragHandleProps
|
|
1803
1874
|
}) {
|
|
1804
|
-
return /* @__PURE__ */ jsxs9("div", { style: styles.canvas, children: [
|
|
1875
|
+
return /* @__PURE__ */ jsxs9("div", { className: "fb-canvas", style: styles.canvas, children: [
|
|
1805
1876
|
sections.map((section, sIdx) => /* @__PURE__ */ jsx11(
|
|
1806
1877
|
SectionCard,
|
|
1807
1878
|
{
|
|
@@ -1814,6 +1885,7 @@ function Canvas({
|
|
|
1814
1885
|
chrome,
|
|
1815
1886
|
strings,
|
|
1816
1887
|
language,
|
|
1888
|
+
features,
|
|
1817
1889
|
onActivate: () => onActivateSection(section.id),
|
|
1818
1890
|
onToggleCollapse: () => onToggleSectionCollapse(section.id),
|
|
1819
1891
|
onUpdateTitle: (value) => onUpdateSectionTitle(section.id, value),
|
|
@@ -1831,7 +1903,7 @@ function Canvas({
|
|
|
1831
1903
|
},
|
|
1832
1904
|
section.id
|
|
1833
1905
|
)),
|
|
1834
|
-
/* @__PURE__ */ jsxs9("button", { style: styles.addSectionBtn, onClick: onAddSection, children: [
|
|
1906
|
+
features.sections && /* @__PURE__ */ jsxs9("button", { style: styles.addSectionBtn, onClick: onAddSection, children: [
|
|
1835
1907
|
/* @__PURE__ */ jsx11(Layers, { size: 14 }),
|
|
1836
1908
|
" ",
|
|
1837
1909
|
chrome.addSection
|
|
@@ -1843,22 +1915,22 @@ function Canvas({
|
|
|
1843
1915
|
import { Bold, Italic, X, Plus as Plus2, Trash2 as Trash23 } from "lucide-react";
|
|
1844
1916
|
|
|
1845
1917
|
// src/components/fields/DefaultValueEditor.tsx
|
|
1846
|
-
import { Fragment as
|
|
1918
|
+
import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1847
1919
|
function DefaultValueEditor({ field, meta, lang, chrome, onChange }) {
|
|
1848
1920
|
if (meta.isContent) return null;
|
|
1849
1921
|
const f = field;
|
|
1850
1922
|
if (meta.boolean) {
|
|
1851
|
-
return /* @__PURE__ */ jsxs10(
|
|
1923
|
+
return /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
1852
1924
|
/* @__PURE__ */ jsx12("label", { style: styles.propLabel, children: chrome.defaultValue }),
|
|
1853
1925
|
/* @__PURE__ */ jsxs10("button", { style: styles.toggleRow, onClick: () => onChange({ defaultValue: !f.defaultValue }), children: [
|
|
1854
1926
|
/* @__PURE__ */ jsx12("span", { style: { ...styles.toggleTrack, background: f.defaultValue ? "var(--fb-primary)" : "var(--fb-border)" }, children: /* @__PURE__ */ jsx12("span", { style: { ...styles.toggleThumb, transform: f.defaultValue ? "translateX(16px)" : "translateX(0)" } }) }),
|
|
1855
|
-
/* @__PURE__ */ jsx12("span", { style: { fontSize: 13, color: "
|
|
1927
|
+
/* @__PURE__ */ jsx12("span", { style: { fontSize: 13, color: "var(--fb-ink)" }, children: f.defaultValue ? chrome.checked : chrome.unchecked })
|
|
1856
1928
|
] })
|
|
1857
1929
|
] });
|
|
1858
1930
|
}
|
|
1859
1931
|
if (meta.multiValue) {
|
|
1860
1932
|
const selectedVals = f.defaultValue || [];
|
|
1861
|
-
return /* @__PURE__ */ jsxs10(
|
|
1933
|
+
return /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
1862
1934
|
/* @__PURE__ */ jsx12("label", { style: styles.propLabel, children: chrome.defaultChecked }),
|
|
1863
1935
|
/* @__PURE__ */ jsx12("div", { style: styles.optionList, children: (f.options || []).map((o) => {
|
|
1864
1936
|
const checked = selectedVals.includes(o.value);
|
|
@@ -1873,7 +1945,7 @@ function DefaultValueEditor({ field, meta, lang, chrome, onChange }) {
|
|
|
1873
1945
|
] });
|
|
1874
1946
|
}
|
|
1875
1947
|
if (meta.options) {
|
|
1876
|
-
return /* @__PURE__ */ jsxs10(
|
|
1948
|
+
return /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
1877
1949
|
/* @__PURE__ */ jsx12("label", { style: styles.propLabel, children: chrome.defaultValue }),
|
|
1878
1950
|
/* @__PURE__ */ jsxs10("select", { style: styles.propInput, value: f.defaultValue || "", onChange: (e) => onChange({ defaultValue: e.target.value }), children: [
|
|
1879
1951
|
/* @__PURE__ */ jsx12("option", { value: "", children: chrome.none }),
|
|
@@ -1882,16 +1954,16 @@ function DefaultValueEditor({ field, meta, lang, chrome, onChange }) {
|
|
|
1882
1954
|
] });
|
|
1883
1955
|
}
|
|
1884
1956
|
const htmlType = field.type === "input" && field.inputType === "number" ? "number" : field.type === "input" && field.inputType === "date" ? "date" : field.type === "input" && field.inputType === "time" ? "time" : "text";
|
|
1885
|
-
return /* @__PURE__ */ jsxs10(
|
|
1957
|
+
return /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
1886
1958
|
/* @__PURE__ */ jsx12("label", { style: styles.propLabel, children: chrome.defaultValue }),
|
|
1887
1959
|
/* @__PURE__ */ jsx12("input", { type: htmlType, style: styles.propInput, value: f.defaultValue || "", onChange: (e) => onChange({ defaultValue: e.target.value }) })
|
|
1888
1960
|
] });
|
|
1889
1961
|
}
|
|
1890
1962
|
|
|
1891
1963
|
// src/components/Inspector.tsx
|
|
1892
|
-
import { Fragment as
|
|
1893
|
-
function Inspector({ selected, language, chrome, onUpdateField, onDeleteField, onUpdateOption, onAddOption, onRemoveOption }) {
|
|
1894
|
-
return /* @__PURE__ */ jsxs11("div", { style: styles.inspector, children: [
|
|
1964
|
+
import { Fragment as Fragment5, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1965
|
+
function Inspector({ selected, language, chrome, features, onUpdateField, onDeleteField, onUpdateOption, onAddOption, onRemoveOption }) {
|
|
1966
|
+
return /* @__PURE__ */ jsxs11("div", { className: "fb-inspector", style: styles.inspector, children: [
|
|
1895
1967
|
/* @__PURE__ */ jsx13("div", { style: styles.panelHeading, children: chrome.properties }),
|
|
1896
1968
|
!selected ? /* @__PURE__ */ jsx13("div", { style: styles.inspectorEmpty, children: chrome.selectFieldHint }) : /* @__PURE__ */ jsx13(
|
|
1897
1969
|
InspectorBody,
|
|
@@ -1899,6 +1971,7 @@ function Inspector({ selected, language, chrome, onUpdateField, onDeleteField, o
|
|
|
1899
1971
|
selected,
|
|
1900
1972
|
language,
|
|
1901
1973
|
chrome,
|
|
1974
|
+
features,
|
|
1902
1975
|
onUpdateField,
|
|
1903
1976
|
onDeleteField,
|
|
1904
1977
|
onUpdateOption,
|
|
@@ -1908,45 +1981,47 @@ function Inspector({ selected, language, chrome, onUpdateField, onDeleteField, o
|
|
|
1908
1981
|
)
|
|
1909
1982
|
] });
|
|
1910
1983
|
}
|
|
1911
|
-
function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteField, onUpdateOption, onAddOption, onRemoveOption }) {
|
|
1984
|
+
function InspectorBody({ selected, language, chrome, features, onUpdateField, onDeleteField, onUpdateOption, onAddOption, onRemoveOption }) {
|
|
1912
1985
|
const meta = getMeta(selected.type);
|
|
1913
1986
|
const f = selected;
|
|
1914
1987
|
return /* @__PURE__ */ jsxs11("div", { style: styles.inspectorBody, children: [
|
|
1915
|
-
(!meta.isContent || selected.type === "button") && /* @__PURE__ */ jsxs11(
|
|
1988
|
+
(!meta.isContent || selected.type === "button") && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
1916
1989
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: selected.type === "button" ? chrome.buttonText : chrome.label }),
|
|
1917
1990
|
/* @__PURE__ */ jsx13("input", { style: styles.propInput, value: t(selected.label, language), onChange: (e) => onUpdateField({ label: withLang(selected.label, language, e.target.value) }) }),
|
|
1918
1991
|
!meta.isContent && /* @__PURE__ */ jsxs11("label", { style: styles.toggleRow, children: [
|
|
1919
1992
|
/* @__PURE__ */ jsx13("input", { type: "checkbox", checked: !!selected.hideLabel, onChange: (e) => onUpdateField({ hideLabel: e.target.checked }), style: { width: 15, height: 15, accentColor: "var(--fb-primary)" } }),
|
|
1920
|
-
/* @__PURE__ */ jsx13("span", { style: { fontSize: 13, color: "
|
|
1993
|
+
/* @__PURE__ */ jsx13("span", { style: { fontSize: 13, color: "var(--fb-ink)" }, children: chrome.hideLabel })
|
|
1921
1994
|
] })
|
|
1922
1995
|
] }),
|
|
1923
|
-
meta.hasSubtype && /* @__PURE__ */ jsxs11(
|
|
1996
|
+
meta.hasSubtype && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
1924
1997
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.inputType }),
|
|
1925
1998
|
/* @__PURE__ */ jsx13("select", { style: styles.propInput, value: f.inputType || "text", onChange: (e) => onUpdateField({ inputType: e.target.value }), children: INPUT_SUBTYPES.map((s) => /* @__PURE__ */ jsx13("option", { value: s, children: chrome[INPUT_SUBTYPE_CHROME_KEY[s]] }, s)) })
|
|
1926
1999
|
] }),
|
|
1927
|
-
selected.type === "paragraph" && /* @__PURE__ */ jsxs11(
|
|
2000
|
+
selected.type === "paragraph" && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
1928
2001
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.content }),
|
|
1929
2002
|
/* @__PURE__ */ jsx13("textarea", { style: { ...styles.propInput, minHeight: 70, resize: "vertical" }, value: t(selected.content, language), onChange: (e) => onUpdateField({ content: withLang(selected.content, language, e.target.value) }) }),
|
|
1930
|
-
/* @__PURE__ */
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
/* @__PURE__ */
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
2003
|
+
features.blockStyling && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
2004
|
+
/* @__PURE__ */ jsx13("div", { style: styles.inspectorDivider }),
|
|
2005
|
+
/* @__PURE__ */ jsx13("div", { style: styles.panelHeading, children: chrome.typography }),
|
|
2006
|
+
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.headingStyle }),
|
|
2007
|
+
/* @__PURE__ */ jsx13(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] }) }),
|
|
2008
|
+
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.width }),
|
|
2009
|
+
/* @__PURE__ */ jsx13(Segmented, { options: FONT_SIZE_OPTIONS, value: selected.fontSize || "md", onChange: (v) => onUpdateField({ fontSize: v }) }),
|
|
2010
|
+
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.style }),
|
|
2011
|
+
/* @__PURE__ */ jsxs11("div", { style: styles.styleToggleRow, children: [
|
|
2012
|
+
/* @__PURE__ */ jsx13("button", { type: "button", style: selected.fontWeight === "bold" ? styles.styleToggleActive : styles.styleToggle, onClick: () => onUpdateField({ fontWeight: selected.fontWeight === "bold" ? "normal" : "bold" }), children: /* @__PURE__ */ jsx13(Bold, { size: 14 }) }),
|
|
2013
|
+
/* @__PURE__ */ jsx13("button", { type: "button", style: selected.fontStyle === "italic" ? styles.styleToggleActive : styles.styleToggle, onClick: () => onUpdateField({ fontStyle: selected.fontStyle === "italic" ? "normal" : "italic" }), children: /* @__PURE__ */ jsx13(Italic, { size: 14 }) })
|
|
2014
|
+
] }),
|
|
2015
|
+
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.align }),
|
|
2016
|
+
/* @__PURE__ */ jsx13(Segmented, { options: TEXT_ALIGN_OPTIONS, value: selected.textAlign || "left", onChange: (v) => onUpdateField({ textAlign: v }) }),
|
|
2017
|
+
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.color }),
|
|
2018
|
+
/* @__PURE__ */ jsxs11("div", { style: styles.swatchRow, children: [
|
|
2019
|
+
COLOR_SWATCHES.map((c) => /* @__PURE__ */ jsx13("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")),
|
|
2020
|
+
/* @__PURE__ */ jsx13("input", { type: "color", value: selected.color || "#1B1E24", onChange: (e) => onUpdateField({ color: e.target.value }), style: styles.colorPickerInput })
|
|
2021
|
+
] })
|
|
1947
2022
|
] })
|
|
1948
2023
|
] }),
|
|
1949
|
-
selected.type === "image" && /* @__PURE__ */ jsxs11(
|
|
2024
|
+
selected.type === "image" && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
1950
2025
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.imageUrl }),
|
|
1951
2026
|
/* @__PURE__ */ jsx13("input", { style: styles.propInput, placeholder: "https://...", value: selected.src || "", onChange: (e) => onUpdateField({ src: e.target.value }) }),
|
|
1952
2027
|
/* @__PURE__ */ jsx13("p", { style: styles.helperText, children: chrome.imageUrlHelper }),
|
|
@@ -1958,47 +2033,49 @@ function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteFiel
|
|
|
1958
2033
|
/* @__PURE__ */ jsx13(Segmented, { options: IMAGE_SHAPES.map((v) => ({ value: v, label: chrome[IMAGE_SHAPE_CHROME_KEY[v]] })), value: selected.shape || "square", onChange: (v) => onUpdateField({ shape: v }) }),
|
|
1959
2034
|
/* @__PURE__ */ jsx13("p", { style: styles.helperText, children: "Fills the field's own width (set below under Layout) and scales height automatically \u2014 always responsive, never overflows." })
|
|
1960
2035
|
] }),
|
|
1961
|
-
selected.type === "button" && /* @__PURE__ */ jsxs11(
|
|
2036
|
+
selected.type === "button" && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
1962
2037
|
/* @__PURE__ */ jsx13("div", { style: styles.inspectorDivider }),
|
|
1963
2038
|
/* @__PURE__ */ jsx13("div", { style: styles.panelHeading, children: chrome.buttonActionTitle }),
|
|
1964
2039
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.buttonAction }),
|
|
1965
2040
|
/* @__PURE__ */ jsx13(Segmented, { options: [{ value: "link", label: chrome.actionLink }, { value: "submit", label: chrome.actionSubmit }], value: selected.action || "submit", onChange: (v) => onUpdateField({ action: v }) }),
|
|
1966
|
-
selected.action === "link" ? /* @__PURE__ */ jsxs11(
|
|
2041
|
+
selected.action === "link" ? /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
1967
2042
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.linkOptional }),
|
|
1968
2043
|
/* @__PURE__ */ jsx13("input", { style: styles.propInput, placeholder: "https://...", value: selected.href || "", onChange: (e) => onUpdateField({ href: e.target.value }) }),
|
|
1969
2044
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.openIn }),
|
|
1970
2045
|
/* @__PURE__ */ jsx13(Segmented, { options: [{ value: "_self", label: chrome.sameTab }, { value: "_blank", label: chrome.newTab }], value: selected.target || "_self", onChange: (v) => onUpdateField({ target: v }) })
|
|
1971
|
-
] }) : /* @__PURE__ */ jsxs11(
|
|
2046
|
+
] }) : /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
1972
2047
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.submitScope }),
|
|
1973
2048
|
/* @__PURE__ */ jsx13(Segmented, { options: [{ value: "section", label: chrome.thisSection }, { value: "form", label: chrome.wholeForm }], value: selected.submitScope || "form", onChange: (v) => onUpdateField({ submitScope: v }) })
|
|
1974
2049
|
] }),
|
|
1975
|
-
/* @__PURE__ */
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
2050
|
+
features.blockStyling && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
2051
|
+
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.color }),
|
|
2052
|
+
/* @__PURE__ */ jsxs11("div", { style: styles.swatchRow, children: [
|
|
2053
|
+
BUTTON_COLOR_SWATCHES.map((c) => /* @__PURE__ */ jsx13("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")),
|
|
2054
|
+
/* @__PURE__ */ jsx13("input", { type: "color", value: selected.buttonStyle?.color || "#5B5FEF", onChange: (e) => onUpdateField({ buttonStyle: { ...selected.buttonStyle, color: e.target.value } }), style: styles.colorPickerInput })
|
|
2055
|
+
] }),
|
|
2056
|
+
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.buttonSize }),
|
|
2057
|
+
/* @__PURE__ */ jsx13(Segmented, { options: SUBMIT_SIZE_OPTIONS, value: selected.buttonStyle?.size || "md", onChange: (v) => onUpdateField({ buttonStyle: { ...selected.buttonStyle, size: v } }) })
|
|
2058
|
+
] })
|
|
1982
2059
|
] }),
|
|
1983
|
-
meta.placeholder && /* @__PURE__ */ jsxs11(
|
|
2060
|
+
meta.placeholder && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
1984
2061
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.placeholder }),
|
|
1985
2062
|
/* @__PURE__ */ jsx13("input", { style: styles.propInput, value: t(f.placeholder, language), onChange: (e) => onUpdateField({ placeholder: withLang(f.placeholder, language, e.target.value) }) })
|
|
1986
2063
|
] }),
|
|
1987
|
-
selected.type === "input" && (selected.inputType === "text" || selected.inputType === "password" || !selected.inputType) && /* @__PURE__ */ jsxs11(
|
|
2064
|
+
selected.type === "input" && (selected.inputType === "text" || selected.inputType === "password" || !selected.inputType) && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
1988
2065
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.maxLength }),
|
|
1989
2066
|
/* @__PURE__ */ jsx13("input", { type: "number", style: styles.propInput, placeholder: chrome.noLimit, value: selected.maxLength || "", onChange: (e) => onUpdateField({ maxLength: e.target.value ? Number(e.target.value) : null }) })
|
|
1990
2067
|
] }),
|
|
1991
|
-
selected.type === "input" && selected.inputType === "number" && /* @__PURE__ */ jsxs11(
|
|
2068
|
+
selected.type === "input" && selected.inputType === "number" && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
1992
2069
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.minValue }),
|
|
1993
2070
|
/* @__PURE__ */ jsx13("input", { type: "number", style: styles.propInput, value: selected.min ?? "", onChange: (e) => onUpdateField({ min: e.target.value === "" ? null : Number(e.target.value) }) }),
|
|
1994
2071
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.maxValue }),
|
|
1995
2072
|
/* @__PURE__ */ jsx13("input", { type: "number", style: styles.propInput, value: selected.max ?? "", onChange: (e) => onUpdateField({ max: e.target.value === "" ? null : Number(e.target.value) }) })
|
|
1996
2073
|
] }),
|
|
1997
|
-
selected.type === "textarea" && /* @__PURE__ */ jsxs11(
|
|
2074
|
+
selected.type === "textarea" && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
1998
2075
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.maxLength }),
|
|
1999
2076
|
/* @__PURE__ */ jsx13("input", { type: "number", style: styles.propInput, placeholder: chrome.noLimit, value: selected.maxLength || "", onChange: (e) => onUpdateField({ maxLength: e.target.value ? Number(e.target.value) : null }) })
|
|
2000
2077
|
] }),
|
|
2001
|
-
meta.options && /* @__PURE__ */ jsxs11(
|
|
2078
|
+
meta.options && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
2002
2079
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.options }),
|
|
2003
2080
|
/* @__PURE__ */ jsxs11("div", { style: styles.optionList, children: [
|
|
2004
2081
|
(f.options || []).map((opt, i) => /* @__PURE__ */ jsxs11("div", { style: styles.optionRow, children: [
|
|
@@ -2015,7 +2092,7 @@ function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteFiel
|
|
|
2015
2092
|
/* @__PURE__ */ jsx13(DefaultValueEditor, { field: selected, meta, lang: language, chrome, onChange: onUpdateField }),
|
|
2016
2093
|
!meta.isContent && /* @__PURE__ */ jsxs11("label", { style: styles.toggleRow, children: [
|
|
2017
2094
|
/* @__PURE__ */ jsx13("input", { type: "checkbox", checked: !!selected.required, onChange: (e) => onUpdateField({ required: e.target.checked }), style: { width: 15, height: 15, accentColor: "var(--fb-primary)" } }),
|
|
2018
|
-
/* @__PURE__ */ jsx13("span", { style: { fontSize: 13, color: "
|
|
2095
|
+
/* @__PURE__ */ jsx13("span", { style: { fontSize: 13, color: "var(--fb-ink)" }, children: chrome.requiredField })
|
|
2019
2096
|
] }),
|
|
2020
2097
|
/* @__PURE__ */ jsx13("div", { style: styles.inspectorDivider }),
|
|
2021
2098
|
/* @__PURE__ */ jsx13("div", { style: styles.panelHeading, children: chrome.layout }),
|
|
@@ -2023,16 +2100,16 @@ function InspectorBody({ selected, language, chrome, onUpdateField, onDeleteFiel
|
|
|
2023
2100
|
/* @__PURE__ */ jsx13(Segmented, { options: WIDTH_OPTIONS.map((o) => ({ ...o, label: o.labelKey ? chrome[o.labelKey] : o.label || "" })), value: selected.width || "1/1", onChange: (v) => onUpdateField({ width: v }) }),
|
|
2024
2101
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.verticalAlign }),
|
|
2025
2102
|
/* @__PURE__ */ jsx13(Segmented, { options: [{ value: "top", label: chrome.top }, { value: "middle", label: chrome.middle }, { value: "bottom", label: chrome.bottom }], value: selected.verticalAlign || "top", onChange: (v) => onUpdateField({ verticalAlign: v }) }),
|
|
2026
|
-
!meta.boolean && !meta.isContent && /* @__PURE__ */ jsxs11(
|
|
2103
|
+
!meta.boolean && !meta.isContent && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
2027
2104
|
/* @__PURE__ */ jsx13("label", { style: styles.propLabel, children: chrome.labelPosition }),
|
|
2028
2105
|
/* @__PURE__ */ jsx13(Segmented, { options: [{ value: "top", label: chrome.above }, { value: "inline", label: chrome.inline }], value: selected.labelPosition || "top", onChange: (v) => onUpdateField({ labelPosition: v }) })
|
|
2029
2106
|
] }),
|
|
2030
|
-
!meta.isContent && /* @__PURE__ */ jsxs11(
|
|
2107
|
+
!meta.isContent && /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
2031
2108
|
/* @__PURE__ */ jsx13("div", { style: styles.inspectorDivider }),
|
|
2032
2109
|
/* @__PURE__ */ jsx13("div", { style: styles.panelHeading, children: chrome.icon }),
|
|
2033
2110
|
/* @__PURE__ */ jsxs11("label", { style: styles.toggleRow, children: [
|
|
2034
2111
|
/* @__PURE__ */ jsx13("input", { type: "checkbox", checked: !!selected.showIcon, onChange: (e) => onUpdateField({ showIcon: e.target.checked }), style: { width: 15, height: 15, accentColor: "var(--fb-primary)" } }),
|
|
2035
|
-
/* @__PURE__ */ jsx13("span", { style: { fontSize: 13, color: "
|
|
2112
|
+
/* @__PURE__ */ jsx13("span", { style: { fontSize: 13, color: "var(--fb-ink)" }, children: chrome.showIcon })
|
|
2036
2113
|
] }),
|
|
2037
2114
|
selected.showIcon && /* @__PURE__ */ jsx13("div", { style: styles.iconGrid, children: Object.keys(ICON_LIBRARY).map((key) => {
|
|
2038
2115
|
const IconComp = ICON_LIBRARY[key];
|
|
@@ -2098,7 +2175,7 @@ function collectFieldValues(fields) {
|
|
|
2098
2175
|
|
|
2099
2176
|
// src/components/PreviewPane.tsx
|
|
2100
2177
|
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2101
|
-
function PreviewPane({ title, sections, onFieldChange, language, strings, chrome, baseMaxWidth, onSubmit }) {
|
|
2178
|
+
function PreviewPane({ title, sections, onFieldChange, language, strings, chrome, baseMaxWidth, features, onSubmit }) {
|
|
2102
2179
|
const [device, setDevice] = useState6("laptop");
|
|
2103
2180
|
const [errors, setErrors] = useState6({});
|
|
2104
2181
|
const [submitted, setSubmitted] = useState6(null);
|
|
@@ -2161,7 +2238,7 @@ function PreviewPane({ title, sections, onFieldChange, language, strings, chrome
|
|
|
2161
2238
|
}
|
|
2162
2239
|
return /* @__PURE__ */ jsxs12("div", { style: styles.previewWrap, children: [
|
|
2163
2240
|
/* @__PURE__ */ jsxs12("div", { style: { width: "100%", maxWidth, display: "flex", flexDirection: "column", alignItems: "center" }, children: [
|
|
2164
|
-
/* @__PURE__ */ jsx14("div", { style: styles.previewToolbar, children: /* @__PURE__ */ jsx14(Segmented, { options: deviceOptions, value: device, onChange: setDevice }) }),
|
|
2241
|
+
features.deviceToggle && /* @__PURE__ */ jsx14("div", { style: styles.previewToolbar, children: /* @__PURE__ */ jsx14(Segmented, { options: deviceOptions, value: device, onChange: setDevice }) }),
|
|
2165
2242
|
/* @__PURE__ */ jsxs12("div", { style: { ...styles.previewCard, maxWidth, width: "100%" }, children: [
|
|
2166
2243
|
/* @__PURE__ */ jsx14("h2", { style: styles.previewTitle, children: t(title, language) }),
|
|
2167
2244
|
allFields.length === 0 && /* @__PURE__ */ jsx14("p", { style: { color: "var(--fb-muted)", fontSize: 14 }, children: strings.addFieldsHint }),
|
|
@@ -2184,7 +2261,7 @@ function PreviewPane({ title, sections, onFieldChange, language, strings, chrome
|
|
|
2184
2261
|
})
|
|
2185
2262
|
] })
|
|
2186
2263
|
] }),
|
|
2187
|
-
submitted && /* @__PURE__ */ jsx14("div", { style: styles.modalOverlay, onClick: () => setSubmitted(null), children: /* @__PURE__ */ jsxs12("div", { style: { ...styles.modal,
|
|
2264
|
+
submitted && /* @__PURE__ */ jsx14("div", { style: styles.modalOverlay, onClick: () => setSubmitted(null), children: /* @__PURE__ */ jsxs12("div", { style: { ...styles.modal, maxWidth: 420 }, onClick: (e) => e.stopPropagation(), children: [
|
|
2188
2265
|
/* @__PURE__ */ jsxs12("div", { style: styles.modalHeader, children: [
|
|
2189
2266
|
/* @__PURE__ */ jsxs12("span", { style: { fontWeight: 600, fontSize: 14, display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
2190
2267
|
/* @__PURE__ */ jsx14(PartyPopper, { size: 15, color: "var(--fb-primary)" }),
|
|
@@ -2259,7 +2336,7 @@ import { Save as Save2, X as X5 } from "lucide-react";
|
|
|
2259
2336
|
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2260
2337
|
function SaveAsModal({ chrome, suggestedName, onSave, onClose }) {
|
|
2261
2338
|
const [name, setName] = useState7(suggestedName);
|
|
2262
|
-
return /* @__PURE__ */ jsx17("div", { style: styles.modalOverlay, onClick: onClose, children: /* @__PURE__ */ jsxs15("div", { style: { ...styles.modal,
|
|
2339
|
+
return /* @__PURE__ */ jsx17("div", { style: styles.modalOverlay, onClick: onClose, children: /* @__PURE__ */ jsxs15("div", { style: { ...styles.modal, maxWidth: 380 }, onClick: (e) => e.stopPropagation(), children: [
|
|
2263
2340
|
/* @__PURE__ */ jsxs15("div", { style: styles.modalHeader, children: [
|
|
2264
2341
|
/* @__PURE__ */ jsx17("span", { style: { fontWeight: 600, fontSize: 14 }, children: chrome.saveForm }),
|
|
2265
2342
|
/* @__PURE__ */ jsx17("button", { style: styles.iconBtn, onClick: onClose, children: /* @__PURE__ */ jsx17(X5, { size: 16 }) })
|
|
@@ -2289,6 +2366,36 @@ var css = `
|
|
|
2289
2366
|
that support it (mobile browser chrome resizing the viewport), and is
|
|
2290
2367
|
simply ignored by ones that don't. */
|
|
2291
2368
|
.fb-root { max-height: 100vh; max-height: 100dvh; }
|
|
2369
|
+
|
|
2370
|
+
/* Below this width the fixed 200px Palette + 270px Inspector columns
|
|
2371
|
+
don't leave room for a usable Canvas, so instead of stacking all
|
|
2372
|
+
three in flow (which buries Canvas under a tall Palette), Palette
|
|
2373
|
+
and Inspector become narrow drawers over Canvas (which stays
|
|
2374
|
+
partially visible behind them), toggled by .fb-mobile-bar's two
|
|
2375
|
+
buttons, tracked by .fb-work-area's data-mobile-panel attribute,
|
|
2376
|
+
and dismissible via .fb-mobile-backdrop. */
|
|
2377
|
+
.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; }
|
|
2378
|
+
.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; }
|
|
2379
|
+
.fb-mobile-btn[aria-pressed="true"] { border-color: var(--fb-primary); background: var(--fb-primary-soft); color: var(--fb-primary); }
|
|
2380
|
+
.fb-mobile-backdrop { display: none; }
|
|
2381
|
+
@media (max-width: 720px) {
|
|
2382
|
+
.fb-mobile-bar { display: flex; }
|
|
2383
|
+
.fb-work-area { flex-direction: column !important; min-height: 0; }
|
|
2384
|
+
.fb-canvas-area { position: relative; overflow: hidden; }
|
|
2385
|
+
.fb-canvas { width: 100%; }
|
|
2386
|
+
.fb-mobile-backdrop { display: block; position: absolute; inset: 0; z-index: 6; background: rgba(15,16,20,0.35); }
|
|
2387
|
+
.fb-palette, .fb-inspector {
|
|
2388
|
+
position: absolute; top: 0; bottom: 0; z-index: 7;
|
|
2389
|
+
width: min(260px, 80vw) !important; max-height: none !important;
|
|
2390
|
+
border: none !important;
|
|
2391
|
+
box-shadow: 0 0 24px rgba(0,0,0,0.18);
|
|
2392
|
+
transition: transform 0.18s ease;
|
|
2393
|
+
}
|
|
2394
|
+
.fb-palette { left: 0; transform: translateX(-100%); }
|
|
2395
|
+
.fb-inspector { right: 0; transform: translateX(100%); }
|
|
2396
|
+
.fb-work-area[data-mobile-panel="palette"] .fb-palette,
|
|
2397
|
+
.fb-work-area[data-mobile-panel="inspector"] .fb-inspector { transform: translateX(0); }
|
|
2398
|
+
}
|
|
2292
2399
|
`;
|
|
2293
2400
|
|
|
2294
2401
|
// src/FormBuilder.tsx
|
|
@@ -2299,11 +2406,14 @@ var FormBuilder = forwardRef(function FormBuilder2({
|
|
|
2299
2406
|
languages = DEFAULT_LANGUAGES,
|
|
2300
2407
|
strings: stringsOverride,
|
|
2301
2408
|
chrome: chromeOverride,
|
|
2302
|
-
|
|
2409
|
+
features: featuresProp,
|
|
2303
2410
|
storage: storageProp,
|
|
2304
2411
|
onSubmit,
|
|
2305
|
-
initialDocument
|
|
2412
|
+
initialDocument,
|
|
2413
|
+
initialMode,
|
|
2414
|
+
onModeChange
|
|
2306
2415
|
}, ref) {
|
|
2416
|
+
const features = resolveFeatures(featuresProp);
|
|
2307
2417
|
const storage = storageProp ?? localStorageAdapter;
|
|
2308
2418
|
const { theme, updateThemeColor, updateThemeLayout, resetTheme, replaceThemeOverrides, themeOverrides } = useTheme(themeOverrideProp);
|
|
2309
2419
|
const [language, setLanguage] = useState8(languageOverride || languages[0]?.code || "en");
|
|
@@ -2311,12 +2421,21 @@ var FormBuilder = forwardRef(function FormBuilder2({
|
|
|
2311
2421
|
const chrome = { ...CHROME[language] || CHROME.en, ...chromeOverride && chromeOverride[language] || {} };
|
|
2312
2422
|
const doc = useFormDocument({ language, chrome });
|
|
2313
2423
|
const drag = useDragReorder(doc.reorderWithinSection);
|
|
2314
|
-
const [mode,
|
|
2424
|
+
const [mode, setModeState] = useState8(initialMode ?? "build");
|
|
2425
|
+
const setMode = (next) => {
|
|
2426
|
+
setModeState(next);
|
|
2427
|
+
onModeChange?.(next);
|
|
2428
|
+
};
|
|
2429
|
+
useEffect2(() => {
|
|
2430
|
+
onModeChange?.(mode);
|
|
2431
|
+
}, []);
|
|
2315
2432
|
const [showJson, setShowJson] = useState8(false);
|
|
2316
2433
|
const [showLibrary, setShowLibrary] = useState8(false);
|
|
2317
2434
|
const [copied, setCopied] = useState8(false);
|
|
2435
|
+
const [mobilePanel, setMobilePanel] = useState8("none");
|
|
2318
2436
|
const persistence = usePersistence({
|
|
2319
2437
|
storage,
|
|
2438
|
+
autosave: features.autosave,
|
|
2320
2439
|
language,
|
|
2321
2440
|
chrome,
|
|
2322
2441
|
document: { title: doc.title, themeOverrides, sections: doc.sections },
|
|
@@ -2356,6 +2475,7 @@ var FormBuilder = forwardRef(function FormBuilder2({
|
|
|
2356
2475
|
}
|
|
2357
2476
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2358
2477
|
}), [jsonDoc, jsonString]);
|
|
2478
|
+
const fieldCount = doc.sections.reduce((n, s) => n + s.fields.filter((f) => !getMeta(f.type).isContent).length, 0);
|
|
2359
2479
|
const activeSectionIdx = doc.sections.findIndex((s) => s.id === doc.activeSection?.id);
|
|
2360
2480
|
const activeSectionLabel = t(doc.activeSection?.title, language) || `#${activeSectionIdx + 1}`;
|
|
2361
2481
|
const rootStyle = {
|
|
@@ -2370,6 +2490,7 @@ var FormBuilder = forwardRef(function FormBuilder2({
|
|
|
2370
2490
|
"--fb-surface": theme.surface,
|
|
2371
2491
|
"--fb-canvas": theme.canvas,
|
|
2372
2492
|
"--fb-page-bg": theme.pageBackground,
|
|
2493
|
+
"--fb-surface-2": mixHex(theme.surface, theme.ink, 0.06),
|
|
2373
2494
|
"--fb-space-page": `${theme.layout.pagePadding}px`,
|
|
2374
2495
|
"--fb-space-canvas": `${theme.layout.canvasPadding}px`,
|
|
2375
2496
|
"--fb-space-section": `${theme.layout.sectionGap}px`,
|
|
@@ -2389,6 +2510,7 @@ var FormBuilder = forwardRef(function FormBuilder2({
|
|
|
2389
2510
|
mode,
|
|
2390
2511
|
saveState: persistence.saveState,
|
|
2391
2512
|
chrome,
|
|
2513
|
+
features,
|
|
2392
2514
|
savedFormsCount: persistence.savedForms.length,
|
|
2393
2515
|
onTitleChange: doc.updateTitle,
|
|
2394
2516
|
onLanguageChange: setLanguage,
|
|
@@ -2402,63 +2524,103 @@ var FormBuilder = forwardRef(function FormBuilder2({
|
|
|
2402
2524
|
persistence.loadingDraft ? /* @__PURE__ */ jsxs16("div", { style: styles.loadingScreen, children: [
|
|
2403
2525
|
/* @__PURE__ */ jsx18(Loader22, { size: 20, className: "spin" }),
|
|
2404
2526
|
/* @__PURE__ */ jsx18("span", { style: { marginTop: 8, fontSize: 13, color: "var(--fb-muted)" }, children: chrome.loadingDraft })
|
|
2405
|
-
] }) : mode === "build" ? /* @__PURE__ */ jsxs16("div", { style: styles.workArea, children: [
|
|
2406
|
-
/* @__PURE__ */
|
|
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
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2527
|
+
] }) : mode === "build" ? /* @__PURE__ */ jsxs16("div", { className: "fb-work-area", style: styles.workArea, "data-mobile-panel": mobilePanel, children: [
|
|
2528
|
+
/* @__PURE__ */ jsxs16("div", { className: "fb-mobile-bar", children: [
|
|
2529
|
+
/* @__PURE__ */ jsxs16(
|
|
2530
|
+
"button",
|
|
2531
|
+
{
|
|
2532
|
+
type: "button",
|
|
2533
|
+
className: "fb-mobile-btn",
|
|
2534
|
+
"aria-pressed": mobilePanel === "palette",
|
|
2535
|
+
onClick: () => setMobilePanel((p) => p === "palette" ? "none" : "palette"),
|
|
2536
|
+
children: [
|
|
2537
|
+
/* @__PURE__ */ jsx18(Menu, { size: 14 }),
|
|
2538
|
+
" ",
|
|
2539
|
+
chrome.paletteTabBlocks
|
|
2540
|
+
]
|
|
2541
|
+
}
|
|
2542
|
+
),
|
|
2543
|
+
/* @__PURE__ */ jsxs16(
|
|
2544
|
+
"button",
|
|
2545
|
+
{
|
|
2546
|
+
type: "button",
|
|
2547
|
+
className: "fb-mobile-btn",
|
|
2548
|
+
"aria-pressed": mobilePanel === "inspector",
|
|
2549
|
+
onClick: () => setMobilePanel((p) => p === "inspector" ? "none" : "inspector"),
|
|
2550
|
+
children: [
|
|
2551
|
+
/* @__PURE__ */ jsx18(SlidersHorizontal, { size: 14 }),
|
|
2552
|
+
" ",
|
|
2553
|
+
chrome.properties
|
|
2554
|
+
]
|
|
2555
|
+
}
|
|
2556
|
+
)
|
|
2557
|
+
] }),
|
|
2558
|
+
/* @__PURE__ */ jsxs16("div", { className: "fb-canvas-area", style: styles.workArea, children: [
|
|
2559
|
+
mobilePanel !== "none" && /* @__PURE__ */ jsx18("div", { className: "fb-mobile-backdrop", onClick: () => setMobilePanel("none") }),
|
|
2560
|
+
/* @__PURE__ */ jsx18(
|
|
2561
|
+
Palette,
|
|
2562
|
+
{
|
|
2563
|
+
activeSectionLabel,
|
|
2564
|
+
chrome,
|
|
2565
|
+
onAddField: (type) => {
|
|
2566
|
+
doc.addField(type);
|
|
2567
|
+
setMobilePanel("none");
|
|
2568
|
+
},
|
|
2569
|
+
features,
|
|
2570
|
+
fieldCount,
|
|
2571
|
+
theme,
|
|
2572
|
+
updateThemeColor,
|
|
2573
|
+
updateThemeLayout,
|
|
2574
|
+
resetTheme
|
|
2575
|
+
}
|
|
2576
|
+
),
|
|
2577
|
+
/* @__PURE__ */ jsx18(
|
|
2578
|
+
Canvas,
|
|
2579
|
+
{
|
|
2580
|
+
sections: doc.sections,
|
|
2581
|
+
activeSectionId: doc.activeSectionId,
|
|
2582
|
+
selectedId: doc.selectedId,
|
|
2583
|
+
dragOverKey: drag.dragOverKey,
|
|
2584
|
+
chrome,
|
|
2585
|
+
strings,
|
|
2586
|
+
language,
|
|
2587
|
+
features,
|
|
2588
|
+
onActivateSection: doc.setActiveSectionId,
|
|
2589
|
+
onToggleSectionCollapse: doc.toggleSectionCollapse,
|
|
2590
|
+
onUpdateSectionTitle: doc.updateSectionTitle,
|
|
2591
|
+
onUpdateSectionBackground: doc.updateSectionBackground,
|
|
2592
|
+
onDuplicateSection: doc.duplicateSection,
|
|
2593
|
+
onMoveSection: doc.moveSection,
|
|
2594
|
+
onDeleteSection: doc.deleteSection,
|
|
2595
|
+
onAddSection: doc.addSection,
|
|
2596
|
+
onSelectField: (sectionId, fieldId) => {
|
|
2597
|
+
doc.setSelectedId(fieldId);
|
|
2598
|
+
doc.setActiveSectionId(sectionId);
|
|
2599
|
+
setMobilePanel("inspector");
|
|
2600
|
+
},
|
|
2601
|
+
onFieldChange: doc.updateField,
|
|
2602
|
+
onMoveField: doc.moveField,
|
|
2603
|
+
onDuplicateField: doc.duplicateField,
|
|
2604
|
+
onDeleteField: doc.deleteField,
|
|
2605
|
+
getDropZoneHandlers: drag.getDropZoneHandlers,
|
|
2606
|
+
getDragHandleProps: drag.getDragHandleProps
|
|
2607
|
+
}
|
|
2608
|
+
),
|
|
2609
|
+
/* @__PURE__ */ jsx18(
|
|
2610
|
+
Inspector,
|
|
2611
|
+
{
|
|
2612
|
+
selected: doc.selected,
|
|
2613
|
+
language,
|
|
2614
|
+
chrome,
|
|
2615
|
+
features,
|
|
2616
|
+
onUpdateField: (patch) => doc.selected && doc.updateField(doc.selected.id, patch),
|
|
2617
|
+
onDeleteField: () => doc.selected && doc.deleteField(doc.selected.id),
|
|
2618
|
+
onUpdateOption: (optIdx, patch) => doc.selected && doc.updateOption(doc.selected.id, optIdx, patch),
|
|
2619
|
+
onAddOption: () => doc.selected && doc.addOption(doc.selected.id),
|
|
2620
|
+
onRemoveOption: (optIdx) => doc.selected && doc.removeOption(doc.selected.id, optIdx)
|
|
2621
|
+
}
|
|
2622
|
+
)
|
|
2623
|
+
] })
|
|
2462
2624
|
] }) : /* @__PURE__ */ jsx18(
|
|
2463
2625
|
PreviewPane,
|
|
2464
2626
|
{
|
|
@@ -2469,6 +2631,7 @@ var FormBuilder = forwardRef(function FormBuilder2({
|
|
|
2469
2631
|
strings,
|
|
2470
2632
|
chrome,
|
|
2471
2633
|
baseMaxWidth: theme.layout.maxWidth,
|
|
2634
|
+
features,
|
|
2472
2635
|
onSubmit
|
|
2473
2636
|
}
|
|
2474
2637
|
),
|
|
@@ -2499,7 +2662,24 @@ var FormBuilder = forwardRef(function FormBuilder2({
|
|
|
2499
2662
|
] });
|
|
2500
2663
|
});
|
|
2501
2664
|
var FormBuilder_default = FormBuilder;
|
|
2665
|
+
|
|
2666
|
+
// src/theme/darkTheme.ts
|
|
2667
|
+
var DARK_THEME = {
|
|
2668
|
+
primary: "#8B8FF5",
|
|
2669
|
+
primarySoft: "#262A45",
|
|
2670
|
+
danger: "#F0715B",
|
|
2671
|
+
dangerSoft: "#3A2420",
|
|
2672
|
+
ink: "#EDEEF2",
|
|
2673
|
+
muted: "#9096A8",
|
|
2674
|
+
border: "#2E313D",
|
|
2675
|
+
surface: "#1A1B23",
|
|
2676
|
+
canvas: "#121319",
|
|
2677
|
+
pageBackground: "#1A1B23",
|
|
2678
|
+
layout: DEFAULT_THEME.layout
|
|
2679
|
+
};
|
|
2502
2680
|
export {
|
|
2681
|
+
DARK_THEME,
|
|
2682
|
+
DEFAULT_THEME,
|
|
2503
2683
|
FormBuilder_default as FormBuilder,
|
|
2504
2684
|
FormBuilder_default as default,
|
|
2505
2685
|
localStorageAdapter
|