config-driven-form 1.2.0 → 1.3.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/dist/index.js CHANGED
@@ -7,6 +7,10 @@ var jsxRuntime = require('react/jsx-runtime');
7
7
  var lucideReact = require('lucide-react');
8
8
  var react$1 = require('@tiptap/react');
9
9
  var StarterKit = require('@tiptap/starter-kit');
10
+ var core = require('@dnd-kit/core');
11
+ var sortable = require('@dnd-kit/sortable');
12
+ var uuid = require('uuid');
13
+ var utilities = require('@dnd-kit/utilities');
10
14
 
11
15
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
16
 
@@ -696,7 +700,1436 @@ var SchemaForm = ({
696
700
  ] }) });
697
701
  };
698
702
 
703
+ // src/builder/types.ts
704
+ var FIELD_TEMPLATES = {
705
+ text: {
706
+ type: "text",
707
+ schema: { type: "string", title: "New Text Field" }
708
+ },
709
+ number: {
710
+ type: "number",
711
+ schema: { type: "number", title: "New Number Field" }
712
+ },
713
+ email: {
714
+ type: "email",
715
+ schema: { type: "string", format: "email", title: "Email Address" }
716
+ },
717
+ password: {
718
+ type: "password",
719
+ schema: { type: "string", format: "password", title: "Password" }
720
+ },
721
+ "rich-text": {
722
+ type: "rich-text",
723
+ schema: { type: "string", format: "rich-text", title: "Rich Text" }
724
+ },
725
+ file: {
726
+ type: "file",
727
+ schema: { type: "string", format: "data-url", title: "File Upload" }
728
+ },
729
+ checkbox: {
730
+ type: "checkbox",
731
+ schema: { type: "boolean", title: "Checkbox" }
732
+ },
733
+ checkboxes: {
734
+ type: "checkboxes",
735
+ schema: {
736
+ type: "array",
737
+ title: "Multiple Checkboxes",
738
+ items: { type: "string", enum: ["Option 1", "Option 2"] }
739
+ }
740
+ },
741
+ select: {
742
+ type: "select",
743
+ schema: { type: "string", title: "Dropdown", enum: ["Option 1", "Option 2"] }
744
+ },
745
+ radio: {
746
+ type: "radio",
747
+ schema: { type: "string", title: "Radio Buttons", enum: ["Option 1", "Option 2"] },
748
+ uiSchema: { "ui:widget": "radio" }
749
+ }
750
+ };
751
+
752
+ // src/builder/useFormBuilder.ts
753
+ var useFormBuilder = (initialSchema, initialUiSchema, initialColumns, initialTheme) => {
754
+ const [fields, setFields] = react.useState(() => {
755
+ if (!initialSchema || !initialSchema.properties) return [];
756
+ return Object.entries(initialSchema.properties).map(([key, propSchema]) => {
757
+ var _a;
758
+ let type = "text";
759
+ if (propSchema.type === "string") {
760
+ if (propSchema.format === "email") type = "email";
761
+ else if (propSchema.format === "password") type = "password";
762
+ else if (propSchema.format === "data-url") type = "file";
763
+ else if (propSchema.format === "rich-text") type = "rich-text";
764
+ else if (propSchema.enum) type = "select";
765
+ } else if (propSchema.type === "number" || propSchema.type === "integer") {
766
+ type = "number";
767
+ } else if (propSchema.type === "boolean") {
768
+ type = "checkbox";
769
+ } else if (propSchema.type === "array") {
770
+ type = "checkboxes";
771
+ }
772
+ const uiSchema = initialUiSchema == null ? void 0 : initialUiSchema[key];
773
+ if (propSchema.enum && (uiSchema == null ? void 0 : uiSchema["ui:widget"]) === "radio") {
774
+ type = "radio";
775
+ }
776
+ return {
777
+ id: uuid.v4(),
778
+ key,
779
+ type,
780
+ schema: propSchema,
781
+ uiSchema,
782
+ isRequired: (_a = initialSchema.required) == null ? void 0 : _a.includes(key)
783
+ };
784
+ });
785
+ });
786
+ const [selectedFieldId, setSelectedFieldId] = react.useState(null);
787
+ const addField = react.useCallback((type, index) => {
788
+ const template = FIELD_TEMPLATES[type];
789
+ const newField = {
790
+ id: uuid.v4(),
791
+ key: `field_${Date.now()}`,
792
+ type,
793
+ // Deep clone template schemas
794
+ schema: JSON.parse(JSON.stringify(template.schema)),
795
+ uiSchema: template.uiSchema ? JSON.parse(JSON.stringify(template.uiSchema)) : void 0
796
+ };
797
+ setFields((prev) => {
798
+ if (typeof index === "number") {
799
+ const newFields = [...prev];
800
+ newFields.splice(index, 0, newField);
801
+ return newFields;
802
+ }
803
+ return [...prev, newField];
804
+ });
805
+ setSelectedFieldId(newField.id);
806
+ }, []);
807
+ const removeField = react.useCallback(
808
+ (id) => {
809
+ setFields((prev) => prev.filter((f) => f.id !== id));
810
+ if (selectedFieldId === id) setSelectedFieldId(null);
811
+ },
812
+ [selectedFieldId]
813
+ );
814
+ const updateField = react.useCallback((id, updates) => {
815
+ setFields((prev) => prev.map((f) => f.id === id ? { ...f, ...updates } : f));
816
+ }, []);
817
+ const reorderFields = react.useCallback((activeId, overId) => {
818
+ setFields((prev) => {
819
+ const oldIndex = prev.findIndex((f) => f.id === activeId);
820
+ const newIndex = prev.findIndex((f) => f.id === overId);
821
+ return sortable.arrayMove(prev, oldIndex, newIndex);
822
+ });
823
+ }, []);
824
+ const selectedField = react.useMemo(
825
+ () => fields.find((f) => f.id === selectedFieldId),
826
+ [fields, selectedFieldId]
827
+ );
828
+ const compileSchemas = react.useCallback(() => {
829
+ var _a;
830
+ const finalSchema = {
831
+ type: "object",
832
+ title: (initialSchema == null ? void 0 : initialSchema.title) || "Generated Form",
833
+ description: (initialSchema == null ? void 0 : initialSchema.description) || "",
834
+ properties: {},
835
+ required: []
836
+ };
837
+ const finalUiSchema = {};
838
+ fields.forEach((field) => {
839
+ if (finalSchema.properties) {
840
+ finalSchema.properties[field.key] = field.schema;
841
+ }
842
+ if (field.isRequired && finalSchema.required) {
843
+ finalSchema.required.push(field.key);
844
+ }
845
+ if (field.uiSchema) {
846
+ finalUiSchema[field.key] = field.uiSchema;
847
+ }
848
+ });
849
+ if (((_a = finalSchema.required) == null ? void 0 : _a.length) === 0) {
850
+ delete finalSchema.required;
851
+ }
852
+ return { schema: finalSchema, uiSchema: finalUiSchema };
853
+ }, [fields, initialSchema]);
854
+ const [formSettings, setFormSettings] = react.useState({
855
+ columns: initialColumns || 1,
856
+ theme: initialTheme || {}
857
+ });
858
+ const updateFormSettings = react.useCallback((updates) => {
859
+ setFormSettings((prev) => ({
860
+ ...prev,
861
+ ...updates,
862
+ theme: { ...prev.theme, ...updates.theme || {} }
863
+ }));
864
+ }, []);
865
+ return {
866
+ fields,
867
+ selectedFieldId,
868
+ setSelectedFieldId,
869
+ selectedField,
870
+ addField,
871
+ removeField,
872
+ updateField,
873
+ reorderFields,
874
+ compileSchemas,
875
+ formSettings,
876
+ updateFormSettings
877
+ };
878
+ };
879
+ var TOOLS = [
880
+ { type: "text", label: "Text Field", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Type, { size: 18 }) },
881
+ { type: "number", label: "Number", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Hash, { size: 18 }) },
882
+ { type: "email", label: "Email", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Mail, { size: 18 }) },
883
+ { type: "password", label: "Password", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Key, { size: 18 }) },
884
+ { type: "rich-text", label: "Rich Text", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlignLeft, { size: 18 }) },
885
+ { type: "select", label: "Dropdown", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { size: 18 }) },
886
+ { type: "radio", label: "Radio Group", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { size: 18 }) },
887
+ { type: "checkbox", label: "Checkbox", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckSquare, { size: 18 }) },
888
+ { type: "checkboxes", label: "Checkbox Group", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.List, { size: 18 }) },
889
+ { type: "file", label: "File Upload", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileUp, { size: 18 }) }
890
+ ];
891
+ var DraggableTool = ({
892
+ type,
893
+ label,
894
+ icon
895
+ }) => {
896
+ const { attributes, listeners, setNodeRef, isDragging } = core.useDraggable({
897
+ id: `toolbox-${type}`,
898
+ data: {
899
+ type: "ToolboxItem",
900
+ fieldType: type
901
+ }
902
+ });
903
+ return /* @__PURE__ */ jsxRuntime.jsxs(
904
+ "div",
905
+ {
906
+ ref: setNodeRef,
907
+ ...listeners,
908
+ ...attributes,
909
+ style: {
910
+ display: "flex",
911
+ alignItems: "center",
912
+ gap: "0.75rem",
913
+ padding: "0.75rem",
914
+ backgroundColor: "white",
915
+ border: "1px solid #e5e7eb",
916
+ borderRadius: "0.5rem",
917
+ cursor: isDragging ? "grabbing" : "grab",
918
+ opacity: isDragging ? 0.5 : 1,
919
+ marginBottom: "0.5rem",
920
+ boxShadow: "0 1px 2px rgba(0,0,0,0.05)",
921
+ transition: "all 0.2s"
922
+ },
923
+ onMouseEnter: (e) => {
924
+ e.currentTarget.style.borderColor = "#6366f1";
925
+ e.currentTarget.style.boxShadow = "0 4px 6px rgba(99, 102, 241, 0.1)";
926
+ },
927
+ onMouseLeave: (e) => {
928
+ e.currentTarget.style.borderColor = "#e5e7eb";
929
+ e.currentTarget.style.boxShadow = "0 1px 2px rgba(0,0,0,0.05)";
930
+ },
931
+ children: [
932
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#6b7280" }, children: icon }),
933
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: label })
934
+ ]
935
+ }
936
+ );
937
+ };
938
+ var Toolbox = () => {
939
+ return /* @__PURE__ */ jsxRuntime.jsxs(
940
+ "div",
941
+ {
942
+ style: {
943
+ padding: "1.5rem",
944
+ width: "280px",
945
+ borderRight: "1px solid #e5e7eb",
946
+ backgroundColor: "#f9fafb",
947
+ height: "100%",
948
+ overflowY: "auto"
949
+ },
950
+ children: [
951
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { fontSize: "1rem", fontWeight: 600, color: "#111827", marginBottom: "1rem" }, children: "Form Elements" }),
952
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.875rem", color: "#6b7280", marginBottom: "1.5rem" }, children: "Drag and drop fields onto the canvas to build your form." }),
953
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: TOOLS.map((tool) => /* @__PURE__ */ jsxRuntime.jsx(DraggableTool, { ...tool }, tool.type)) })
954
+ ]
955
+ }
956
+ );
957
+ };
958
+ var SortableField = ({
959
+ field,
960
+ isSelected,
961
+ onClick,
962
+ onRemove,
963
+ onDuplicate
964
+ }) => {
965
+ var _a, _b;
966
+ const { attributes, listeners, setNodeRef, transform, transition, isDragging } = sortable.useSortable({
967
+ id: field.id,
968
+ data: {
969
+ type: "SortableField",
970
+ field
971
+ }
972
+ });
973
+ const style = {
974
+ transform: utilities.CSS.Transform.toString(transform),
975
+ transition,
976
+ opacity: isDragging ? 0.6 : 1,
977
+ position: "relative",
978
+ zIndex: isDragging ? 10 : 1,
979
+ padding: "2rem 1.5rem 1.5rem",
980
+ // Extra top padding for drag handle
981
+ backgroundColor: "white",
982
+ borderRadius: "0.75rem",
983
+ border: `2px solid ${isSelected ? "#6366f1" : "#e5e7eb"}`,
984
+ boxShadow: isSelected ? "0 4px 12px rgba(99, 102, 241, 0.15)" : "0 1px 3px rgba(0,0,0,0.05)",
985
+ marginBottom: "1rem",
986
+ cursor: "pointer",
987
+ gridColumn: `span ${((_a = field.uiSchema) == null ? void 0 : _a["ui:columnSpan"]) || 1} / span ${((_b = field.uiSchema) == null ? void 0 : _b["ui:columnSpan"]) || 1}`
988
+ };
989
+ const methods = reactHookForm.useForm();
990
+ return /* @__PURE__ */ jsxRuntime.jsxs(
991
+ "div",
992
+ {
993
+ ref: setNodeRef,
994
+ style,
995
+ onClick: (e) => {
996
+ e.stopPropagation();
997
+ onClick();
998
+ },
999
+ children: [
1000
+ /* @__PURE__ */ jsxRuntime.jsx(
1001
+ "div",
1002
+ {
1003
+ ...attributes,
1004
+ ...listeners,
1005
+ style: {
1006
+ position: "absolute",
1007
+ top: "0",
1008
+ left: "50%",
1009
+ transform: "translateX(-50%)",
1010
+ width: "40px",
1011
+ height: "24px",
1012
+ backgroundColor: isSelected ? "#eef2ff" : "#f3f4f6",
1013
+ borderBottomLeftRadius: "8px",
1014
+ borderBottomRightRadius: "8px",
1015
+ display: "flex",
1016
+ alignItems: "center",
1017
+ justifyContent: "center",
1018
+ cursor: isDragging ? "grabbing" : "grab",
1019
+ color: isSelected ? "#6366f1" : "#9ca3af",
1020
+ zIndex: 2
1021
+ },
1022
+ onClick: (e) => e.stopPropagation(),
1023
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GripVertical, { size: 16 })
1024
+ }
1025
+ ),
1026
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
1027
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "absolute", inset: 0, zIndex: 1, cursor: "pointer" } }),
1028
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { pointerEvents: "none" }, children: /* @__PURE__ */ jsxRuntime.jsx(reactHookForm.FormProvider, { ...methods, children: /* @__PURE__ */ jsxRuntime.jsx("form", { children: /* @__PURE__ */ jsxRuntime.jsx(
1029
+ FieldRenderer,
1030
+ {
1031
+ name: field.key,
1032
+ schema: field.schema,
1033
+ uiSchema: field.uiSchema,
1034
+ isRequired: field.isRequired
1035
+ }
1036
+ ) }) }) })
1037
+ ] }),
1038
+ isSelected && /* @__PURE__ */ jsxRuntime.jsxs(
1039
+ "div",
1040
+ {
1041
+ style: {
1042
+ position: "absolute",
1043
+ top: "-12px",
1044
+ right: "1rem",
1045
+ display: "flex",
1046
+ gap: "0.25rem",
1047
+ backgroundColor: "#ffffff",
1048
+ border: "1px solid #e5e7eb",
1049
+ padding: "0.25rem",
1050
+ borderRadius: "0.5rem",
1051
+ boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1)",
1052
+ zIndex: 10
1053
+ },
1054
+ children: [
1055
+ /* @__PURE__ */ jsxRuntime.jsx(
1056
+ "button",
1057
+ {
1058
+ onClick: (e) => {
1059
+ e.stopPropagation();
1060
+ onDuplicate();
1061
+ },
1062
+ style: {
1063
+ color: "#4f46e5",
1064
+ backgroundColor: "#eef2ff",
1065
+ border: "none",
1066
+ cursor: "pointer",
1067
+ padding: "0.375rem",
1068
+ borderRadius: "0.375rem",
1069
+ display: "flex",
1070
+ alignItems: "center",
1071
+ justifyContent: "center"
1072
+ },
1073
+ title: "Duplicate Field",
1074
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { size: 14 })
1075
+ }
1076
+ ),
1077
+ /* @__PURE__ */ jsxRuntime.jsx(
1078
+ "button",
1079
+ {
1080
+ onClick: (e) => {
1081
+ e.stopPropagation();
1082
+ onRemove();
1083
+ },
1084
+ style: {
1085
+ color: "#ef4444",
1086
+ backgroundColor: "#fef2f2",
1087
+ border: "none",
1088
+ cursor: "pointer",
1089
+ padding: "0.375rem",
1090
+ borderRadius: "0.375rem",
1091
+ display: "flex",
1092
+ alignItems: "center",
1093
+ justifyContent: "center"
1094
+ },
1095
+ title: "Remove Field",
1096
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { size: 14 })
1097
+ }
1098
+ )
1099
+ ]
1100
+ }
1101
+ )
1102
+ ]
1103
+ }
1104
+ );
1105
+ };
1106
+ var Canvas = ({
1107
+ fields,
1108
+ selectedFieldId,
1109
+ onSelectField,
1110
+ onRemoveField,
1111
+ onDuplicateField
1112
+ }) => {
1113
+ const { setNodeRef, isOver } = core.useDroppable({
1114
+ id: "canvas-droppable",
1115
+ data: {
1116
+ type: "Canvas"
1117
+ }
1118
+ });
1119
+ return /* @__PURE__ */ jsxRuntime.jsx(
1120
+ "div",
1121
+ {
1122
+ style: {
1123
+ flex: 1,
1124
+ padding: "2rem",
1125
+ backgroundColor: "#f3f4f6",
1126
+ overflowY: "auto",
1127
+ display: "flex",
1128
+ flexDirection: "column",
1129
+ alignItems: "center"
1130
+ },
1131
+ onClick: () => onSelectField(""),
1132
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1133
+ "div",
1134
+ {
1135
+ ref: setNodeRef,
1136
+ style: {
1137
+ width: "100%",
1138
+ maxWidth: "800px",
1139
+ minHeight: "400px",
1140
+ backgroundColor: fields.length === 0 ? "transparent" : "white",
1141
+ border: fields.length === 0 ? "2px dashed #d1d5db" : "1px solid #e5e7eb",
1142
+ borderRadius: "0.75rem",
1143
+ padding: fields.length === 0 ? "0" : "2rem",
1144
+ display: "flex",
1145
+ flexDirection: "column",
1146
+ boxShadow: fields.length === 0 ? "none" : "0 10px 15px -3px rgba(0, 0, 0, 0.1)",
1147
+ transition: "all 0.2s ease",
1148
+ ...isOver && fields.length === 0 ? { backgroundColor: "#eef2ff", borderColor: "#6366f1" } : {}
1149
+ },
1150
+ children: fields.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { margin: "auto", textAlign: "center", color: "#6b7280" }, children: [
1151
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "1.125rem", fontWeight: 500, marginBottom: "0.5rem" }, children: "Your form is empty" }),
1152
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.875rem" }, children: "Drag and drop a field from the left panel to get started." })
1153
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: "1rem" }, children: /* @__PURE__ */ jsxRuntime.jsx(sortable.SortableContext, { items: fields.map((f) => f.id), strategy: sortable.verticalListSortingStrategy, children: fields.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
1154
+ SortableField,
1155
+ {
1156
+ field,
1157
+ isSelected: selectedFieldId === field.id,
1158
+ onClick: () => onSelectField(field.id),
1159
+ onRemove: () => onRemoveField(field.id),
1160
+ onDuplicate: () => onDuplicateField(field)
1161
+ },
1162
+ field.id
1163
+ )) }) })
1164
+ }
1165
+ )
1166
+ }
1167
+ );
1168
+ };
1169
+ var PropertiesPanel = ({
1170
+ field,
1171
+ formSettings,
1172
+ onUpdate,
1173
+ onUpdateSettings
1174
+ }) => {
1175
+ var _a, _b, _c, _d, _e, _f, _g;
1176
+ const [activeTab, setActiveTab] = react.useState("general");
1177
+ if (!field) {
1178
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1179
+ "div",
1180
+ {
1181
+ style: {
1182
+ width: "320px",
1183
+ borderLeft: "1px solid #e5e7eb",
1184
+ backgroundColor: "white",
1185
+ display: "flex",
1186
+ flexDirection: "column",
1187
+ height: "100%",
1188
+ overflowY: "auto"
1189
+ },
1190
+ children: [
1191
+ /* @__PURE__ */ jsxRuntime.jsxs(
1192
+ "div",
1193
+ {
1194
+ style: {
1195
+ padding: "1.5rem",
1196
+ borderBottom: "1px solid #e5e7eb",
1197
+ backgroundColor: "#f9fafb"
1198
+ },
1199
+ children: [
1200
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { fontSize: "1.125rem", fontWeight: 600, color: "#111827", margin: 0 }, children: "Global Form Settings" }),
1201
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.875rem", color: "#6b7280", margin: "0.25rem 0 0" }, children: "Click a field to edit its properties, or configure global form settings here." })
1202
+ ]
1203
+ }
1204
+ ),
1205
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "1.5rem", display: "flex", flexDirection: "column", gap: "1.5rem" }, children: [
1206
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1207
+ /* @__PURE__ */ jsxRuntime.jsxs(
1208
+ "h4",
1209
+ {
1210
+ style: {
1211
+ fontSize: "0.875rem",
1212
+ fontWeight: 600,
1213
+ color: "#374151",
1214
+ marginBottom: "0.75rem",
1215
+ display: "flex",
1216
+ alignItems: "center",
1217
+ gap: "0.375rem"
1218
+ },
1219
+ children: [
1220
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LayoutTemplate, { size: 16 }),
1221
+ " Layout Options"
1222
+ ]
1223
+ }
1224
+ ),
1225
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1226
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: "0.75rem", fontWeight: 500, color: "#6b7280" }, children: "Global Columns" }),
1227
+ /* @__PURE__ */ jsxRuntime.jsxs(
1228
+ "select",
1229
+ {
1230
+ value: formSettings.columns,
1231
+ onChange: (e) => onUpdateSettings({ columns: Number(e.target.value) }),
1232
+ style: {
1233
+ width: "100%",
1234
+ padding: "0.5rem",
1235
+ border: "1px solid #d1d5db",
1236
+ borderRadius: "0.375rem",
1237
+ fontSize: "0.875rem"
1238
+ },
1239
+ children: [
1240
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: 1, children: "1 Column" }),
1241
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: 2, children: "2 Columns" }),
1242
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: 3, children: "3 Columns" }),
1243
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: 4, children: "4 Columns" })
1244
+ ]
1245
+ }
1246
+ )
1247
+ ] })
1248
+ ] }),
1249
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1250
+ /* @__PURE__ */ jsxRuntime.jsxs(
1251
+ "h4",
1252
+ {
1253
+ style: {
1254
+ fontSize: "0.875rem",
1255
+ fontWeight: 600,
1256
+ color: "#374151",
1257
+ marginBottom: "0.75rem",
1258
+ display: "flex",
1259
+ alignItems: "center",
1260
+ gap: "0.375rem"
1261
+ },
1262
+ children: [
1263
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Palette, { size: 16 }),
1264
+ " Theme Colors"
1265
+ ]
1266
+ }
1267
+ ),
1268
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
1269
+ /* @__PURE__ */ jsxRuntime.jsxs(
1270
+ "div",
1271
+ {
1272
+ style: {
1273
+ display: "flex",
1274
+ alignItems: "center",
1275
+ justifyContent: "space-between",
1276
+ gap: "0.5rem"
1277
+ },
1278
+ children: [
1279
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#4b5563" }, children: "Primary Color" }),
1280
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1281
+ /* @__PURE__ */ jsxRuntime.jsx(
1282
+ "input",
1283
+ {
1284
+ type: "color",
1285
+ value: formSettings.theme.primary || "#6366f1",
1286
+ onChange: (e) => onUpdateSettings({
1287
+ theme: { ...formSettings.theme, primary: e.target.value }
1288
+ }),
1289
+ style: {
1290
+ width: "28px",
1291
+ height: "28px",
1292
+ padding: "0",
1293
+ border: "none",
1294
+ borderRadius: "4px",
1295
+ cursor: "pointer"
1296
+ }
1297
+ }
1298
+ ),
1299
+ /* @__PURE__ */ jsxRuntime.jsx(
1300
+ "input",
1301
+ {
1302
+ type: "text",
1303
+ value: formSettings.theme.primary || "",
1304
+ placeholder: "#6366f1",
1305
+ onChange: (e) => onUpdateSettings({
1306
+ theme: { ...formSettings.theme, primary: e.target.value }
1307
+ }),
1308
+ style: {
1309
+ width: "80px",
1310
+ padding: "0.25rem 0.5rem",
1311
+ border: "1px solid #d1d5db",
1312
+ borderRadius: "0.25rem",
1313
+ fontSize: "0.75rem",
1314
+ fontFamily: "monospace"
1315
+ }
1316
+ }
1317
+ )
1318
+ ] })
1319
+ ]
1320
+ }
1321
+ ),
1322
+ /* @__PURE__ */ jsxRuntime.jsxs(
1323
+ "div",
1324
+ {
1325
+ style: {
1326
+ display: "flex",
1327
+ alignItems: "center",
1328
+ justifyContent: "space-between",
1329
+ gap: "0.5rem"
1330
+ },
1331
+ children: [
1332
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#4b5563" }, children: "Background Color" }),
1333
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1334
+ /* @__PURE__ */ jsxRuntime.jsx(
1335
+ "input",
1336
+ {
1337
+ type: "color",
1338
+ value: formSettings.theme.background || "#ffffff",
1339
+ onChange: (e) => onUpdateSettings({
1340
+ theme: { ...formSettings.theme, background: e.target.value }
1341
+ }),
1342
+ style: {
1343
+ width: "28px",
1344
+ height: "28px",
1345
+ padding: "0",
1346
+ border: "none",
1347
+ borderRadius: "4px",
1348
+ cursor: "pointer"
1349
+ }
1350
+ }
1351
+ ),
1352
+ /* @__PURE__ */ jsxRuntime.jsx(
1353
+ "input",
1354
+ {
1355
+ type: "text",
1356
+ value: formSettings.theme.background || "",
1357
+ placeholder: "#ffffff",
1358
+ onChange: (e) => onUpdateSettings({
1359
+ theme: { ...formSettings.theme, background: e.target.value }
1360
+ }),
1361
+ style: {
1362
+ width: "80px",
1363
+ padding: "0.25rem 0.5rem",
1364
+ border: "1px solid #d1d5db",
1365
+ borderRadius: "0.25rem",
1366
+ fontSize: "0.75rem",
1367
+ fontFamily: "monospace"
1368
+ }
1369
+ }
1370
+ )
1371
+ ] })
1372
+ ]
1373
+ }
1374
+ )
1375
+ ] })
1376
+ ] })
1377
+ ] })
1378
+ ]
1379
+ }
1380
+ );
1381
+ }
1382
+ const handleSchemaChange = (key, value) => {
1383
+ onUpdate(field.id, {
1384
+ schema: { ...field.schema, [key]: value }
1385
+ });
1386
+ };
1387
+ const handleUiSchemaChange = (key, value) => {
1388
+ onUpdate(field.id, {
1389
+ uiSchema: { ...field.uiSchema || {}, [key]: value }
1390
+ });
1391
+ };
1392
+ const handleClassNamesChange = (element, value) => {
1393
+ var _a2;
1394
+ const existingUiClassNames = ((_a2 = field.uiSchema) == null ? void 0 : _a2["ui:classNames"]) || {};
1395
+ handleUiSchemaChange("ui:classNames", {
1396
+ ...existingUiClassNames,
1397
+ [element]: value
1398
+ });
1399
+ };
1400
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1401
+ "div",
1402
+ {
1403
+ style: {
1404
+ width: "320px",
1405
+ borderLeft: "1px solid #e5e7eb",
1406
+ backgroundColor: "white",
1407
+ display: "flex",
1408
+ flexDirection: "column",
1409
+ height: "100%",
1410
+ overflowY: "auto"
1411
+ },
1412
+ children: [
1413
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "1.5rem 1.5rem 0", borderBottom: "1px solid #e5e7eb" }, children: [
1414
+ /* @__PURE__ */ jsxRuntime.jsx(
1415
+ "h3",
1416
+ {
1417
+ style: { fontSize: "1.125rem", fontWeight: 600, color: "#111827", marginBottom: "1rem" },
1418
+ children: "Field Settings"
1419
+ }
1420
+ ),
1421
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", borderBottom: "1px solid #e5e7eb" }, children: [
1422
+ /* @__PURE__ */ jsxRuntime.jsxs(
1423
+ "button",
1424
+ {
1425
+ onClick: () => setActiveTab("general"),
1426
+ style: {
1427
+ flex: 1,
1428
+ padding: "0.75rem 0",
1429
+ fontSize: "0.875rem",
1430
+ fontWeight: 500,
1431
+ backgroundColor: "transparent",
1432
+ border: "none",
1433
+ borderBottom: `2px solid ${activeTab === "general" ? "#6366f1" : "transparent"}`,
1434
+ color: activeTab === "general" ? "#6366f1" : "#6b7280",
1435
+ cursor: "pointer",
1436
+ display: "flex",
1437
+ alignItems: "center",
1438
+ justifyContent: "center",
1439
+ gap: "0.25rem"
1440
+ },
1441
+ children: [
1442
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings, { size: 14 }),
1443
+ " General"
1444
+ ]
1445
+ }
1446
+ ),
1447
+ /* @__PURE__ */ jsxRuntime.jsxs(
1448
+ "button",
1449
+ {
1450
+ onClick: () => setActiveTab("validation"),
1451
+ style: {
1452
+ flex: 1,
1453
+ padding: "0.75rem 0",
1454
+ fontSize: "0.875rem",
1455
+ fontWeight: 500,
1456
+ backgroundColor: "transparent",
1457
+ border: "none",
1458
+ borderBottom: `2px solid ${activeTab === "validation" ? "#6366f1" : "transparent"}`,
1459
+ color: activeTab === "validation" ? "#6366f1" : "#6b7280",
1460
+ cursor: "pointer",
1461
+ display: "flex",
1462
+ alignItems: "center",
1463
+ justifyContent: "center",
1464
+ gap: "0.25rem"
1465
+ },
1466
+ children: [
1467
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { size: 14 }),
1468
+ " Validation"
1469
+ ]
1470
+ }
1471
+ ),
1472
+ /* @__PURE__ */ jsxRuntime.jsxs(
1473
+ "button",
1474
+ {
1475
+ onClick: () => setActiveTab("design"),
1476
+ style: {
1477
+ flex: 1,
1478
+ padding: "0.75rem 0",
1479
+ fontSize: "0.875rem",
1480
+ fontWeight: 500,
1481
+ backgroundColor: "transparent",
1482
+ border: "none",
1483
+ borderBottom: `2px solid ${activeTab === "design" ? "#6366f1" : "transparent"}`,
1484
+ color: activeTab === "design" ? "#6366f1" : "#6b7280",
1485
+ cursor: "pointer",
1486
+ display: "flex",
1487
+ alignItems: "center",
1488
+ justifyContent: "center",
1489
+ gap: "0.25rem"
1490
+ },
1491
+ children: [
1492
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Paintbrush, { size: 14 }),
1493
+ " Design"
1494
+ ]
1495
+ }
1496
+ )
1497
+ ] })
1498
+ ] }),
1499
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "1.5rem", display: "flex", flexDirection: "column", gap: "1.25rem" }, children: [
1500
+ activeTab === "general" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1501
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1502
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Property Key" }),
1503
+ /* @__PURE__ */ jsxRuntime.jsx(
1504
+ "input",
1505
+ {
1506
+ type: "text",
1507
+ value: field.key,
1508
+ onChange: (e) => onUpdate(field.id, { key: e.target.value.replace(/[^a-zA-Z0-9_]/g, "") }),
1509
+ style: {
1510
+ width: "100%",
1511
+ padding: "0.5rem",
1512
+ border: "1px solid #d1d5db",
1513
+ borderRadius: "0.375rem",
1514
+ fontSize: "0.875rem"
1515
+ },
1516
+ placeholder: "e.g. firstName"
1517
+ }
1518
+ ),
1519
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.75rem", color: "#9ca3af" }, children: "The key used in the final JSON output." })
1520
+ ] }),
1521
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1522
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Label / Title" }),
1523
+ /* @__PURE__ */ jsxRuntime.jsx(
1524
+ "input",
1525
+ {
1526
+ type: "text",
1527
+ value: field.schema.title || "",
1528
+ onChange: (e) => handleSchemaChange("title", e.target.value),
1529
+ style: {
1530
+ width: "100%",
1531
+ padding: "0.5rem",
1532
+ border: "1px solid #d1d5db",
1533
+ borderRadius: "0.375rem",
1534
+ fontSize: "0.875rem"
1535
+ }
1536
+ }
1537
+ )
1538
+ ] }),
1539
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1540
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Description" }),
1541
+ /* @__PURE__ */ jsxRuntime.jsx(
1542
+ "textarea",
1543
+ {
1544
+ value: field.schema.description || "",
1545
+ onChange: (e) => handleSchemaChange("description", e.target.value),
1546
+ style: {
1547
+ width: "100%",
1548
+ padding: "0.5rem",
1549
+ border: "1px solid #d1d5db",
1550
+ borderRadius: "0.375rem",
1551
+ fontSize: "0.875rem",
1552
+ minHeight: "80px"
1553
+ }
1554
+ }
1555
+ )
1556
+ ] }),
1557
+ (field.type === "select" || field.type === "radio" || field.type === "checkboxes") && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1558
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Options (Comma separated)" }),
1559
+ /* @__PURE__ */ jsxRuntime.jsx(
1560
+ "input",
1561
+ {
1562
+ type: "text",
1563
+ value: field.type === "checkboxes" ? field.schema.items && !Array.isArray(field.schema.items) ? (_a = field.schema.items.enum) == null ? void 0 : _a.join(", ") : "" : ((_b = field.schema.enum) == null ? void 0 : _b.join(", ")) || "",
1564
+ onChange: (e) => {
1565
+ const valArray = e.target.value.split(",").map((s) => s.trim()).filter(Boolean);
1566
+ if (field.type === "checkboxes") {
1567
+ handleSchemaChange("items", {
1568
+ ...field.schema.items || {},
1569
+ enum: valArray
1570
+ });
1571
+ } else {
1572
+ handleSchemaChange("enum", valArray);
1573
+ }
1574
+ },
1575
+ style: {
1576
+ width: "100%",
1577
+ padding: "0.5rem",
1578
+ border: "1px solid #d1d5db",
1579
+ borderRadius: "0.375rem",
1580
+ fontSize: "0.875rem"
1581
+ }
1582
+ }
1583
+ )
1584
+ ] })
1585
+ ] }),
1586
+ activeTab === "validation" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1587
+ /* @__PURE__ */ jsxRuntime.jsxs(
1588
+ "label",
1589
+ {
1590
+ style: {
1591
+ display: "flex",
1592
+ alignItems: "center",
1593
+ gap: "0.5rem",
1594
+ fontSize: "0.875rem",
1595
+ fontWeight: 500,
1596
+ color: "#374151",
1597
+ cursor: "pointer"
1598
+ },
1599
+ children: [
1600
+ /* @__PURE__ */ jsxRuntime.jsx(
1601
+ "input",
1602
+ {
1603
+ type: "checkbox",
1604
+ checked: field.isRequired || false,
1605
+ onChange: (e) => onUpdate(field.id, { isRequired: e.target.checked })
1606
+ }
1607
+ ),
1608
+ "Required Field"
1609
+ ]
1610
+ }
1611
+ ),
1612
+ (field.type === "text" || field.type === "email" || field.type === "password") && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1613
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1614
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Min Length" }),
1615
+ /* @__PURE__ */ jsxRuntime.jsx(
1616
+ "input",
1617
+ {
1618
+ type: "number",
1619
+ value: field.schema.minLength || "",
1620
+ onChange: (e) => handleSchemaChange(
1621
+ "minLength",
1622
+ e.target.value ? Number(e.target.value) : void 0
1623
+ ),
1624
+ style: {
1625
+ width: "100%",
1626
+ padding: "0.5rem",
1627
+ border: "1px solid #d1d5db",
1628
+ borderRadius: "0.375rem",
1629
+ fontSize: "0.875rem"
1630
+ }
1631
+ }
1632
+ )
1633
+ ] }),
1634
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1635
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Max Length" }),
1636
+ /* @__PURE__ */ jsxRuntime.jsx(
1637
+ "input",
1638
+ {
1639
+ type: "number",
1640
+ value: field.schema.maxLength || "",
1641
+ onChange: (e) => handleSchemaChange(
1642
+ "maxLength",
1643
+ e.target.value ? Number(e.target.value) : void 0
1644
+ ),
1645
+ style: {
1646
+ width: "100%",
1647
+ padding: "0.5rem",
1648
+ border: "1px solid #d1d5db",
1649
+ borderRadius: "0.375rem",
1650
+ fontSize: "0.875rem"
1651
+ }
1652
+ }
1653
+ )
1654
+ ] }),
1655
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1656
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Regex Pattern" }),
1657
+ /* @__PURE__ */ jsxRuntime.jsx(
1658
+ "input",
1659
+ {
1660
+ type: "text",
1661
+ value: field.schema.pattern || "",
1662
+ onChange: (e) => handleSchemaChange("pattern", e.target.value || void 0),
1663
+ style: {
1664
+ width: "100%",
1665
+ padding: "0.5rem",
1666
+ border: "1px solid #d1d5db",
1667
+ borderRadius: "0.375rem",
1668
+ fontSize: "0.875rem"
1669
+ }
1670
+ }
1671
+ )
1672
+ ] })
1673
+ ] }),
1674
+ field.type === "number" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1675
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1676
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Minimum Value" }),
1677
+ /* @__PURE__ */ jsxRuntime.jsx(
1678
+ "input",
1679
+ {
1680
+ type: "number",
1681
+ value: field.schema.minimum || "",
1682
+ onChange: (e) => handleSchemaChange(
1683
+ "minimum",
1684
+ e.target.value ? Number(e.target.value) : void 0
1685
+ ),
1686
+ style: {
1687
+ width: "100%",
1688
+ padding: "0.5rem",
1689
+ border: "1px solid #d1d5db",
1690
+ borderRadius: "0.375rem",
1691
+ fontSize: "0.875rem"
1692
+ }
1693
+ }
1694
+ )
1695
+ ] }),
1696
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1697
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Maximum Value" }),
1698
+ /* @__PURE__ */ jsxRuntime.jsx(
1699
+ "input",
1700
+ {
1701
+ type: "number",
1702
+ value: field.schema.maximum || "",
1703
+ onChange: (e) => handleSchemaChange(
1704
+ "maximum",
1705
+ e.target.value ? Number(e.target.value) : void 0
1706
+ ),
1707
+ style: {
1708
+ width: "100%",
1709
+ padding: "0.5rem",
1710
+ border: "1px solid #d1d5db",
1711
+ borderRadius: "0.375rem",
1712
+ fontSize: "0.875rem"
1713
+ }
1714
+ }
1715
+ )
1716
+ ] })
1717
+ ] })
1718
+ ] }),
1719
+ activeTab === "design" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1720
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1721
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Column Span" }),
1722
+ /* @__PURE__ */ jsxRuntime.jsxs(
1723
+ "select",
1724
+ {
1725
+ value: ((_c = field.uiSchema) == null ? void 0 : _c["ui:columnSpan"]) || 1,
1726
+ onChange: (e) => handleUiSchemaChange("ui:columnSpan", Number(e.target.value)),
1727
+ style: {
1728
+ width: "100%",
1729
+ padding: "0.5rem",
1730
+ border: "1px solid #d1d5db",
1731
+ borderRadius: "0.375rem",
1732
+ fontSize: "0.875rem"
1733
+ },
1734
+ children: [
1735
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: 1, children: "1 Column" }),
1736
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: 2, children: "2 Columns" }),
1737
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: 3, children: "3 Columns" }),
1738
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: 4, children: "4 Columns" })
1739
+ ]
1740
+ }
1741
+ )
1742
+ ] }),
1743
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem", borderTop: "1px solid #e5e7eb", paddingTop: "1rem" }, children: [
1744
+ /* @__PURE__ */ jsxRuntime.jsx(
1745
+ "h4",
1746
+ {
1747
+ style: {
1748
+ fontSize: "0.875rem",
1749
+ fontWeight: 600,
1750
+ color: "#111827",
1751
+ marginBottom: "0.5rem"
1752
+ },
1753
+ children: "Tailwind Classes (ui:classNames)"
1754
+ }
1755
+ ),
1756
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
1757
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
1758
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: "0.75rem", color: "#6b7280" }, children: "Input" }),
1759
+ /* @__PURE__ */ jsxRuntime.jsx(
1760
+ "input",
1761
+ {
1762
+ type: "text",
1763
+ value: ((_e = (_d = field.uiSchema) == null ? void 0 : _d["ui:classNames"]) == null ? void 0 : _e.input) || "",
1764
+ onChange: (e) => handleClassNamesChange("input", e.target.value),
1765
+ style: {
1766
+ width: "100%",
1767
+ padding: "0.4rem",
1768
+ border: "1px solid #d1d5db",
1769
+ borderRadius: "0.25rem",
1770
+ fontSize: "0.75rem",
1771
+ fontFamily: "monospace"
1772
+ },
1773
+ placeholder: "e.g. bg-gray-50 border-blue-500"
1774
+ }
1775
+ )
1776
+ ] }),
1777
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
1778
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: "0.75rem", color: "#6b7280" }, children: "Label" }),
1779
+ /* @__PURE__ */ jsxRuntime.jsx(
1780
+ "input",
1781
+ {
1782
+ type: "text",
1783
+ value: ((_g = (_f = field.uiSchema) == null ? void 0 : _f["ui:classNames"]) == null ? void 0 : _g.label) || "",
1784
+ onChange: (e) => handleClassNamesChange("label", e.target.value),
1785
+ style: {
1786
+ width: "100%",
1787
+ padding: "0.4rem",
1788
+ border: "1px solid #d1d5db",
1789
+ borderRadius: "0.25rem",
1790
+ fontSize: "0.75rem",
1791
+ fontFamily: "monospace"
1792
+ },
1793
+ placeholder: "e.g. text-blue-600 font-bold"
1794
+ }
1795
+ )
1796
+ ] })
1797
+ ] })
1798
+ ] })
1799
+ ] })
1800
+ ] })
1801
+ ]
1802
+ }
1803
+ );
1804
+ };
1805
+ var FormBuilder = ({
1806
+ initialSchema,
1807
+ initialUiSchema,
1808
+ initialColumns,
1809
+ initialTheme,
1810
+ onSave
1811
+ }) => {
1812
+ const {
1813
+ fields,
1814
+ selectedFieldId,
1815
+ setSelectedFieldId,
1816
+ selectedField,
1817
+ addField,
1818
+ removeField,
1819
+ updateField,
1820
+ reorderFields,
1821
+ compileSchemas,
1822
+ formSettings,
1823
+ updateFormSettings
1824
+ } = useFormBuilder(initialSchema, initialUiSchema, initialColumns, initialTheme);
1825
+ const [activeDragType, setActiveDragType] = react.useState(null);
1826
+ const [isPreviewMode, setIsPreviewMode] = react.useState(false);
1827
+ const sensors = core.useSensors(
1828
+ core.useSensor(core.PointerSensor),
1829
+ core.useSensor(core.KeyboardSensor, {
1830
+ coordinateGetter: sortable.sortableKeyboardCoordinates
1831
+ })
1832
+ );
1833
+ const handleDragStart = (event) => {
1834
+ var _a;
1835
+ const { active } = event;
1836
+ if (((_a = active.data.current) == null ? void 0 : _a.type) === "ToolboxItem") {
1837
+ setActiveDragType(active.data.current.fieldType);
1838
+ }
1839
+ };
1840
+ const handleDragEnd = (event) => {
1841
+ var _a, _b;
1842
+ const { active, over } = event;
1843
+ setActiveDragType(null);
1844
+ if (!over) return;
1845
+ if (((_a = active.data.current) == null ? void 0 : _a.type) === "ToolboxItem") {
1846
+ if (over.id === "canvas-droppable" || fields.find((f) => f.id === over.id)) {
1847
+ const overIndex = fields.findIndex((f) => f.id === over.id);
1848
+ addField(
1849
+ active.data.current.fieldType,
1850
+ overIndex >= 0 ? overIndex : void 0
1851
+ );
1852
+ }
1853
+ return;
1854
+ }
1855
+ if (((_b = active.data.current) == null ? void 0 : _b.type) === "SortableField" && active.id !== over.id) {
1856
+ reorderFields(active.id, over.id);
1857
+ }
1858
+ };
1859
+ const handleSave = () => {
1860
+ if (onSave) {
1861
+ const { schema, uiSchema } = compileSchemas();
1862
+ onSave(schema, uiSchema, formSettings);
1863
+ }
1864
+ };
1865
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1866
+ "div",
1867
+ {
1868
+ style: {
1869
+ display: "flex",
1870
+ flexDirection: "column",
1871
+ height: "100vh",
1872
+ width: "100vw",
1873
+ fontFamily: "system-ui, sans-serif"
1874
+ },
1875
+ children: [
1876
+ /* @__PURE__ */ jsxRuntime.jsxs(
1877
+ "div",
1878
+ {
1879
+ style: {
1880
+ height: "60px",
1881
+ borderBottom: "1px solid #e5e7eb",
1882
+ backgroundColor: "white",
1883
+ display: "flex",
1884
+ alignItems: "center",
1885
+ justifyContent: "space-between",
1886
+ padding: "0 1.5rem",
1887
+ zIndex: 20
1888
+ },
1889
+ children: [
1890
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1891
+ /* @__PURE__ */ jsxRuntime.jsx(
1892
+ "div",
1893
+ {
1894
+ style: {
1895
+ width: "32px",
1896
+ height: "32px",
1897
+ backgroundColor: "#6366f1",
1898
+ borderRadius: "0.5rem",
1899
+ display: "flex",
1900
+ alignItems: "center",
1901
+ justifyContent: "center",
1902
+ color: "white"
1903
+ },
1904
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code2, { size: 20 })
1905
+ }
1906
+ ),
1907
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { style: { fontSize: "1.25rem", fontWeight: 700, color: "#111827", margin: 0 }, children: "Visual Form Builder" })
1908
+ ] }),
1909
+ /* @__PURE__ */ jsxRuntime.jsxs(
1910
+ "div",
1911
+ {
1912
+ style: {
1913
+ display: "flex",
1914
+ backgroundColor: "#f3f4f6",
1915
+ padding: "0.25rem",
1916
+ borderRadius: "0.5rem"
1917
+ },
1918
+ children: [
1919
+ /* @__PURE__ */ jsxRuntime.jsxs(
1920
+ "button",
1921
+ {
1922
+ onClick: () => setIsPreviewMode(false),
1923
+ style: {
1924
+ display: "flex",
1925
+ alignItems: "center",
1926
+ gap: "0.375rem",
1927
+ padding: "0.375rem 0.75rem",
1928
+ fontSize: "0.875rem",
1929
+ fontWeight: 500,
1930
+ border: "none",
1931
+ borderRadius: "0.375rem",
1932
+ cursor: "pointer",
1933
+ transition: "all 0.2s",
1934
+ backgroundColor: !isPreviewMode ? "white" : "transparent",
1935
+ color: !isPreviewMode ? "#111827" : "#6b7280",
1936
+ boxShadow: !isPreviewMode ? "0 1px 3px rgba(0,0,0,0.1)" : "none"
1937
+ },
1938
+ children: [
1939
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LayoutTemplate, { size: 16 }),
1940
+ " Builder"
1941
+ ]
1942
+ }
1943
+ ),
1944
+ /* @__PURE__ */ jsxRuntime.jsxs(
1945
+ "button",
1946
+ {
1947
+ onClick: () => setIsPreviewMode(true),
1948
+ style: {
1949
+ display: "flex",
1950
+ alignItems: "center",
1951
+ gap: "0.375rem",
1952
+ padding: "0.375rem 0.75rem",
1953
+ fontSize: "0.875rem",
1954
+ fontWeight: 500,
1955
+ border: "none",
1956
+ borderRadius: "0.375rem",
1957
+ cursor: "pointer",
1958
+ transition: "all 0.2s",
1959
+ backgroundColor: isPreviewMode ? "white" : "transparent",
1960
+ color: isPreviewMode ? "#111827" : "#6b7280",
1961
+ boxShadow: isPreviewMode ? "0 1px 3px rgba(0,0,0,0.1)" : "none"
1962
+ },
1963
+ children: [
1964
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { size: 16 }),
1965
+ " Preview"
1966
+ ]
1967
+ }
1968
+ )
1969
+ ]
1970
+ }
1971
+ ),
1972
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(
1973
+ "button",
1974
+ {
1975
+ onClick: handleSave,
1976
+ style: {
1977
+ display: "flex",
1978
+ alignItems: "center",
1979
+ gap: "0.5rem",
1980
+ backgroundColor: "#6366f1",
1981
+ color: "white",
1982
+ border: "none",
1983
+ padding: "0.5rem 1rem",
1984
+ borderRadius: "0.375rem",
1985
+ fontWeight: 600,
1986
+ cursor: "pointer",
1987
+ transition: "background-color 0.2s"
1988
+ },
1989
+ onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "#4f46e5",
1990
+ onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "#6366f1",
1991
+ children: [
1992
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Save, { size: 16 }),
1993
+ " Save Form"
1994
+ ]
1995
+ }
1996
+ ) })
1997
+ ]
1998
+ }
1999
+ ),
2000
+ /* @__PURE__ */ jsxRuntime.jsx(
2001
+ "div",
2002
+ {
2003
+ style: {
2004
+ display: "flex",
2005
+ flex: 1,
2006
+ overflow: "hidden",
2007
+ backgroundColor: "#f3f4f6",
2008
+ minHeight: 0
2009
+ },
2010
+ children: isPreviewMode ? /* @__PURE__ */ jsxRuntime.jsx(
2011
+ "div",
2012
+ {
2013
+ style: {
2014
+ flex: 1,
2015
+ padding: "3rem",
2016
+ overflowY: "auto",
2017
+ display: "flex",
2018
+ justifyContent: "center"
2019
+ },
2020
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
2021
+ "div",
2022
+ {
2023
+ style: {
2024
+ width: "100%",
2025
+ maxWidth: "800px",
2026
+ backgroundColor: "white",
2027
+ padding: "2rem",
2028
+ borderRadius: "1rem",
2029
+ boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)"
2030
+ },
2031
+ children: [
2032
+ /* @__PURE__ */ jsxRuntime.jsx(
2033
+ "div",
2034
+ {
2035
+ style: {
2036
+ marginBottom: "2rem",
2037
+ paddingBottom: "1rem",
2038
+ borderBottom: "1px solid #e5e7eb",
2039
+ display: "flex",
2040
+ justifyContent: "space-between",
2041
+ alignItems: "center"
2042
+ },
2043
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2044
+ "span",
2045
+ {
2046
+ style: {
2047
+ fontSize: "0.875rem",
2048
+ fontWeight: 600,
2049
+ color: "#6366f1",
2050
+ textTransform: "uppercase",
2051
+ letterSpacing: "0.05em"
2052
+ },
2053
+ children: "Live Preview"
2054
+ }
2055
+ )
2056
+ }
2057
+ ),
2058
+ /* @__PURE__ */ jsxRuntime.jsx(
2059
+ SchemaForm,
2060
+ {
2061
+ schema: compileSchemas().schema,
2062
+ uiSchema: compileSchemas().uiSchema,
2063
+ columns: formSettings.columns,
2064
+ theme: formSettings.theme,
2065
+ onSubmit: (data) => alert("Preview Form Submitted!\n\n" + JSON.stringify(data, null, 2))
2066
+ }
2067
+ )
2068
+ ]
2069
+ }
2070
+ )
2071
+ }
2072
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(
2073
+ core.DndContext,
2074
+ {
2075
+ sensors,
2076
+ collisionDetection: core.closestCenter,
2077
+ onDragStart: handleDragStart,
2078
+ onDragEnd: handleDragEnd,
2079
+ children: [
2080
+ /* @__PURE__ */ jsxRuntime.jsx(Toolbox, {}),
2081
+ /* @__PURE__ */ jsxRuntime.jsx(
2082
+ Canvas,
2083
+ {
2084
+ fields,
2085
+ selectedFieldId,
2086
+ onSelectField: setSelectedFieldId,
2087
+ onRemoveField: removeField,
2088
+ onDuplicateField: (f) => {
2089
+ const idx = fields.findIndex((field) => field.id === f.id);
2090
+ addField(f.type, idx + 1);
2091
+ }
2092
+ }
2093
+ ),
2094
+ /* @__PURE__ */ jsxRuntime.jsx(
2095
+ PropertiesPanel,
2096
+ {
2097
+ field: selectedField || null,
2098
+ formSettings,
2099
+ onUpdate: updateField,
2100
+ onUpdateSettings: updateFormSettings
2101
+ }
2102
+ ),
2103
+ /* @__PURE__ */ jsxRuntime.jsx(core.DragOverlay, { children: activeDragType ? /* @__PURE__ */ jsxRuntime.jsxs(
2104
+ "div",
2105
+ {
2106
+ style: {
2107
+ padding: "0.75rem",
2108
+ backgroundColor: "#6366f1",
2109
+ color: "white",
2110
+ borderRadius: "0.5rem",
2111
+ opacity: 0.8,
2112
+ fontWeight: 500
2113
+ },
2114
+ children: [
2115
+ "Dropping ",
2116
+ activeDragType,
2117
+ "..."
2118
+ ]
2119
+ }
2120
+ ) : null })
2121
+ ]
2122
+ }
2123
+ )
2124
+ }
2125
+ )
2126
+ ]
2127
+ }
2128
+ );
2129
+ };
2130
+
699
2131
  exports.FieldRenderer = FieldRenderer;
2132
+ exports.FormBuilder = FormBuilder;
700
2133
  exports.SchemaForm = SchemaForm;
701
2134
  //# sourceMappingURL=index.js.map
702
2135
  //# sourceMappingURL=index.js.map