form-builder-pro 1.0.0 → 1.0.2
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.css +155 -20
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +63 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +63 -24
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -4353,6 +4353,29 @@ var formStore = createStore((set, get) => ({
|
|
|
4353
4353
|
historyIndex: historyIndex + 1
|
|
4354
4354
|
});
|
|
4355
4355
|
},
|
|
4356
|
+
addTemplateFields: (targetSectionId, template, index2) => {
|
|
4357
|
+
set((state) => {
|
|
4358
|
+
const sectionIndex = state.schema.sections.findIndex((s) => s.id === targetSectionId);
|
|
4359
|
+
if (sectionIndex === -1)
|
|
4360
|
+
return state;
|
|
4361
|
+
const section = state.schema.sections[sectionIndex];
|
|
4362
|
+
const newFields = template.fields.map(cloneField);
|
|
4363
|
+
const currentFields = [...section.fields];
|
|
4364
|
+
if (typeof index2 === "number" && index2 >= 0) {
|
|
4365
|
+
currentFields.splice(index2, 0, ...newFields);
|
|
4366
|
+
} else {
|
|
4367
|
+
currentFields.push(...newFields);
|
|
4368
|
+
}
|
|
4369
|
+
const newSection = { ...section, fields: currentFields };
|
|
4370
|
+
const newSections = [...state.schema.sections];
|
|
4371
|
+
newSections[sectionIndex] = newSection;
|
|
4372
|
+
return {
|
|
4373
|
+
schema: { ...state.schema, sections: newSections },
|
|
4374
|
+
history: [...state.history.slice(0, state.historyIndex + 1), { ...state.schema, sections: newSections }],
|
|
4375
|
+
historyIndex: state.historyIndex + 1
|
|
4376
|
+
};
|
|
4377
|
+
});
|
|
4378
|
+
},
|
|
4356
4379
|
undo: () => {
|
|
4357
4380
|
const { history, historyIndex } = get();
|
|
4358
4381
|
if (historyIndex > 0) {
|
|
@@ -4476,7 +4499,7 @@ var FieldRenderer = class {
|
|
|
4476
4499
|
const wrapper = createElement("div", { className: "w-full" });
|
|
4477
4500
|
if (field.type !== "checkbox") {
|
|
4478
4501
|
const label = createElement("label", {
|
|
4479
|
-
className: "text-sm font-medium leading-none mb-2 block text-gray-900 dark:text-gray-100",
|
|
4502
|
+
className: "text-xs sm:text-sm font-medium leading-none mb-2 block text-gray-900 dark:text-gray-100",
|
|
4480
4503
|
text: field.label
|
|
4481
4504
|
});
|
|
4482
4505
|
if (field.required) {
|
|
@@ -4485,7 +4508,7 @@ var FieldRenderer = class {
|
|
|
4485
4508
|
wrapper.appendChild(label);
|
|
4486
4509
|
} else {
|
|
4487
4510
|
const label = createElement("label", {
|
|
4488
|
-
className: "text-sm font-medium leading-none mb-2 block text-gray-900 dark:text-gray-100",
|
|
4511
|
+
className: "text-xs sm:text-sm font-medium leading-none mb-2 block text-gray-900 dark:text-gray-100",
|
|
4489
4512
|
text: field.label
|
|
4490
4513
|
});
|
|
4491
4514
|
if (field.required) {
|
|
@@ -4497,7 +4520,7 @@ var FieldRenderer = class {
|
|
|
4497
4520
|
switch (field.type) {
|
|
4498
4521
|
case "textarea":
|
|
4499
4522
|
input = createElement("textarea", {
|
|
4500
|
-
className: "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
4523
|
+
className: "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm sm:text-base ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
4501
4524
|
placeholder: field.placeholder,
|
|
4502
4525
|
value: value || "",
|
|
4503
4526
|
disabled: readOnly,
|
|
@@ -4506,7 +4529,7 @@ var FieldRenderer = class {
|
|
|
4506
4529
|
break;
|
|
4507
4530
|
case "select":
|
|
4508
4531
|
input = createElement("select", {
|
|
4509
|
-
className: "flex h-
|
|
4532
|
+
className: "flex min-h-touch w-full rounded-md border border-input bg-background px-3 py-2 text-sm sm:text-base ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
4510
4533
|
value: value || "",
|
|
4511
4534
|
disabled: readOnly,
|
|
4512
4535
|
onchange: (e) => onChange?.(e.target.value)
|
|
@@ -4517,10 +4540,10 @@ var FieldRenderer = class {
|
|
|
4517
4540
|
});
|
|
4518
4541
|
break;
|
|
4519
4542
|
case "checkbox":
|
|
4520
|
-
input = createElement("div", { className: "flex items-center h-
|
|
4543
|
+
input = createElement("div", { className: "flex items-center min-h-touch" });
|
|
4521
4544
|
const checkbox = createElement("input", {
|
|
4522
4545
|
type: "checkbox",
|
|
4523
|
-
className: "h-5 w-5 rounded border-gray-300 text-primary focus:ring-primary cursor-pointer",
|
|
4546
|
+
className: "h-5 w-5 sm:h-6 sm:w-6 rounded border-gray-300 text-primary focus:ring-primary cursor-pointer",
|
|
4524
4547
|
checked: !!value,
|
|
4525
4548
|
disabled: readOnly,
|
|
4526
4549
|
onchange: (e) => onChange?.(e.target.checked)
|
|
@@ -4530,18 +4553,18 @@ var FieldRenderer = class {
|
|
|
4530
4553
|
case "radio":
|
|
4531
4554
|
input = createElement("div", { className: "space-y-2" });
|
|
4532
4555
|
field.options?.forEach((opt) => {
|
|
4533
|
-
const radioWrapper = createElement("div", { className: "flex items-center space-x-2" });
|
|
4556
|
+
const radioWrapper = createElement("div", { className: "flex items-center space-x-2 min-h-touch" });
|
|
4534
4557
|
const radio = createElement("input", {
|
|
4535
4558
|
type: "radio",
|
|
4536
4559
|
name: field.id,
|
|
4537
4560
|
value: opt.value,
|
|
4538
4561
|
checked: value === opt.value,
|
|
4539
4562
|
disabled: readOnly,
|
|
4540
|
-
className: "aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
4563
|
+
className: "aspect-square h-4 w-4 sm:h-5 sm:w-5 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
4541
4564
|
onchange: (e) => onChange?.(e.target.value)
|
|
4542
4565
|
});
|
|
4543
4566
|
const radioLabel = createElement("label", {
|
|
4544
|
-
className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
4567
|
+
className: "text-xs sm:text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
4545
4568
|
text: opt.label
|
|
4546
4569
|
});
|
|
4547
4570
|
radioWrapper.appendChild(radio);
|
|
@@ -4552,7 +4575,7 @@ var FieldRenderer = class {
|
|
|
4552
4575
|
default:
|
|
4553
4576
|
input = createElement("input", {
|
|
4554
4577
|
type: field.type === "phone" ? "tel" : field.type,
|
|
4555
|
-
className: "flex h-
|
|
4578
|
+
className: "flex min-h-touch w-full rounded-md border border-input bg-background px-3 py-2 text-sm sm:text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
4556
4579
|
placeholder: field.placeholder,
|
|
4557
4580
|
value: value || "",
|
|
4558
4581
|
disabled: readOnly,
|
|
@@ -4561,7 +4584,7 @@ var FieldRenderer = class {
|
|
|
4561
4584
|
}
|
|
4562
4585
|
wrapper.appendChild(input);
|
|
4563
4586
|
if (field.description) {
|
|
4564
|
-
wrapper.appendChild(createElement("p", { className: "text-sm text-muted-foreground mt-1", text: field.description }));
|
|
4587
|
+
wrapper.appendChild(createElement("p", { className: "text-xs sm:text-sm text-muted-foreground mt-1", text: field.description }));
|
|
4565
4588
|
}
|
|
4566
4589
|
return wrapper;
|
|
4567
4590
|
}
|
|
@@ -4585,11 +4608,11 @@ var FormRenderer = class {
|
|
|
4585
4608
|
}
|
|
4586
4609
|
render() {
|
|
4587
4610
|
this.container.innerHTML = "";
|
|
4588
|
-
const form = createElement("form", { className: "space-y-8" });
|
|
4589
|
-
form.appendChild(createElement("h1", { className: "text-2xl font-bold text-gray-900 dark:text-white", text: this.schema.title }));
|
|
4611
|
+
const form = createElement("form", { className: "space-y-6 md:space-y-8" });
|
|
4612
|
+
form.appendChild(createElement("h1", { className: "text-xl md:text-2xl font-bold text-gray-900 dark:text-white", text: this.schema.title }));
|
|
4590
4613
|
this.schema.sections.forEach((section) => {
|
|
4591
|
-
const sectionEl = createElement("div", { className: "space-y-4" });
|
|
4592
|
-
sectionEl.appendChild(createElement("h2", { className: "text-xl font-semibold text-gray-800 dark:text-gray-200 border-b pb-2", text: section.title }));
|
|
4614
|
+
const sectionEl = createElement("div", { className: "space-y-3 md:space-y-4" });
|
|
4615
|
+
sectionEl.appendChild(createElement("h2", { className: "text-lg md:text-xl font-semibold text-gray-800 dark:text-gray-200 border-b pb-2", text: section.title }));
|
|
4593
4616
|
const grid = createElement("div", { className: "form-builder-grid" });
|
|
4594
4617
|
section.fields.forEach((field) => {
|
|
4595
4618
|
const fieldWrapper = createElement("div");
|
|
@@ -4616,14 +4639,14 @@ var FormRenderer = class {
|
|
|
4616
4639
|
});
|
|
4617
4640
|
const submitBtn = createElement("button", {
|
|
4618
4641
|
type: "submit",
|
|
4619
|
-
className: "px-6 py-
|
|
4642
|
+
className: "w-full sm:w-auto px-6 py-3 min-h-touch bg-blue-600 text-white font-medium rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-colors",
|
|
4620
4643
|
text: "Submit"
|
|
4621
4644
|
});
|
|
4622
4645
|
form.onsubmit = (e) => {
|
|
4623
4646
|
e.preventDefault();
|
|
4624
4647
|
this.onSubmit?.(this.data);
|
|
4625
4648
|
};
|
|
4626
|
-
const btnWrapper = createElement("div", { className: "pt-4" });
|
|
4649
|
+
const btnWrapper = createElement("div", { className: "pt-4 flex justify-center sm:justify-start" });
|
|
4627
4650
|
btnWrapper.appendChild(submitBtn);
|
|
4628
4651
|
form.appendChild(btnWrapper);
|
|
4629
4652
|
this.container.appendChild(form);
|
|
@@ -6982,7 +7005,7 @@ var FormBuilder = class {
|
|
|
6982
7005
|
this.container.innerHTML = "";
|
|
6983
7006
|
const wrapper = createElement("div", { className: "flex flex-col h-screen " });
|
|
6984
7007
|
wrapper.appendChild(this.renderToolbar(state));
|
|
6985
|
-
const main = createElement("div", { className: "flex flex-1 overflow-hidden" });
|
|
7008
|
+
const main = createElement("div", { className: "flex flex-col md:flex-row flex-1 overflow-hidden" });
|
|
6986
7009
|
if (state.isPreviewMode) {
|
|
6987
7010
|
const previewContainer = createElement("div", { className: "flex-1 p-8 overflow-y-auto bg-white dark:bg-gray-900 flex justify-center" });
|
|
6988
7011
|
const inner = createElement("div", { className: "w-full max-w-3xl" });
|
|
@@ -6990,9 +7013,15 @@ var FormBuilder = class {
|
|
|
6990
7013
|
previewContainer.appendChild(inner);
|
|
6991
7014
|
main.appendChild(previewContainer);
|
|
6992
7015
|
} else {
|
|
6993
|
-
|
|
6994
|
-
|
|
6995
|
-
main.appendChild(
|
|
7016
|
+
const toolboxWrapper = createElement("div", { className: "form-builder-toolbox-wrapper w-full md:w-80 bg-white dark:bg-gray-900 border-r md:border-r border-b md:border-b-0 border-gray-200 dark:border-gray-800" });
|
|
7017
|
+
toolboxWrapper.appendChild(this.renderToolbox());
|
|
7018
|
+
main.appendChild(toolboxWrapper);
|
|
7019
|
+
const canvasWrapper = createElement("div", { className: "form-builder-canvas flex-1 overflow-y-auto" });
|
|
7020
|
+
canvasWrapper.appendChild(this.renderCanvas(state));
|
|
7021
|
+
main.appendChild(canvasWrapper);
|
|
7022
|
+
const configWrapper = createElement("div", { className: "form-builder-config-wrapper w-full md:w-80 bg-white dark:bg-gray-900 border-l md:border-l border-t md:border-t-0 border-gray-200 dark:border-gray-800" });
|
|
7023
|
+
configWrapper.appendChild(this.renderConfigPanel(state));
|
|
7024
|
+
main.appendChild(configWrapper);
|
|
6996
7025
|
}
|
|
6997
7026
|
wrapper.appendChild(main);
|
|
6998
7027
|
this.container.appendChild(wrapper);
|
|
@@ -7090,7 +7119,7 @@ var FormBuilder = class {
|
|
|
7090
7119
|
return toolbar;
|
|
7091
7120
|
}
|
|
7092
7121
|
renderToolbox() {
|
|
7093
|
-
const toolbox = createElement("div", { className: "
|
|
7122
|
+
const toolbox = createElement("div", { className: "bg-white dark:bg-gray-900 flex flex-col h-full" });
|
|
7094
7123
|
const tabs = createElement("div", { className: "flex border-b border-gray-200 dark:border-gray-800" });
|
|
7095
7124
|
const createTab = (id, label) => {
|
|
7096
7125
|
const isActive = this.activeTab === id;
|
|
@@ -7189,7 +7218,7 @@ var FormBuilder = class {
|
|
|
7189
7218
|
}
|
|
7190
7219
|
renderCanvas(state) {
|
|
7191
7220
|
const canvas = createElement("div", {
|
|
7192
|
-
className: "flex-1 bg-white dark:bg-gray-950 p-8 overflow-y-auto
|
|
7221
|
+
className: "flex-1 bg-white dark:bg-gray-950 p-4 md:p-8 overflow-y-auto",
|
|
7193
7222
|
onclick: (e) => {
|
|
7194
7223
|
if (e.target === canvas || e.target === canvas.firstElementChild) {
|
|
7195
7224
|
formStore.getState().selectField(null);
|
|
@@ -7306,7 +7335,7 @@ var FormBuilder = class {
|
|
|
7306
7335
|
return canvas;
|
|
7307
7336
|
}
|
|
7308
7337
|
renderConfigPanel(state) {
|
|
7309
|
-
const panel = createElement("div", { className: "
|
|
7338
|
+
const panel = createElement("div", { className: "bg-white dark:bg-gray-900 flex flex-col h-full" });
|
|
7310
7339
|
const selectedField = state.schema.sections.flatMap((s) => s.fields).find((f) => f.id === state.selectedFieldId);
|
|
7311
7340
|
if (!selectedField) {
|
|
7312
7341
|
panel.appendChild(createElement("div", { className: "p-6 text-center text-gray-500", text: "Select a field to configure" }));
|
|
@@ -7552,6 +7581,16 @@ var FormBuilder = class {
|
|
|
7552
7581
|
const type = item.getAttribute("data-type");
|
|
7553
7582
|
const sectionId = list.getAttribute("data-section-id");
|
|
7554
7583
|
if (type && sectionId) {
|
|
7584
|
+
if (type === "template-section") {
|
|
7585
|
+
const templateId = item.getAttribute("data-template-id");
|
|
7586
|
+
const templates = formStore.getState().templates;
|
|
7587
|
+
const template = templates.find((t) => t.id === templateId);
|
|
7588
|
+
item.remove();
|
|
7589
|
+
if (template) {
|
|
7590
|
+
formStore.getState().addTemplateFields(sectionId, template, evt.newIndex);
|
|
7591
|
+
}
|
|
7592
|
+
return;
|
|
7593
|
+
}
|
|
7555
7594
|
item.remove();
|
|
7556
7595
|
formStore.getState().addField(sectionId, type, evt.newIndex);
|
|
7557
7596
|
} else if (sectionId) {
|