form-builder-pro 0.0.2 → 0.0.4

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.mjs CHANGED
@@ -4053,6 +4053,7 @@ var NEVER = INVALID;
4053
4053
  var FormSchemaValidation = external_exports.object({
4054
4054
  id: external_exports.string(),
4055
4055
  title: external_exports.string(),
4056
+ formName: external_exports.string(),
4056
4057
  sections: external_exports.array(external_exports.object({
4057
4058
  id: external_exports.string(),
4058
4059
  title: external_exports.string(),
@@ -4127,6 +4128,7 @@ var DEFAULT_FIELD_CONFIG = {
4127
4128
  var INITIAL_SCHEMA = {
4128
4129
  id: "form_1",
4129
4130
  title: "My New Form",
4131
+ formName: "myNewForm",
4130
4132
  sections: [
4131
4133
  {
4132
4134
  id: generateId(),
@@ -4469,7 +4471,7 @@ var FormRenderer = class {
4469
4471
  this.schema.sections.forEach((section) => {
4470
4472
  const sectionEl = createElement("div", { className: "space-y-4" });
4471
4473
  sectionEl.appendChild(createElement("h2", { className: "text-xl font-semibold text-gray-800 dark:text-gray-200 border-b pb-2", text: section.title }));
4472
- const grid = createElement("div", { className: "grid grid-cols-4 gap-4" });
4474
+ const grid = createElement("div", { className: "form-builder-grid" });
4473
4475
  section.fields.forEach((field) => {
4474
4476
  const fieldWrapper = createElement("div");
4475
4477
  const span = field.width === "100%" ? "col-span-4" : field.width === "50%" ? "col-span-2" : "col-span-1";
@@ -25148,10 +25150,12 @@ var createIcons = ({
25148
25150
 
25149
25151
  // src/builder/FormBuilder.ts
25150
25152
  var FormBuilder = class {
25151
- constructor(container) {
25153
+ constructor(container, options) {
25152
25154
  __publicField(this, "container");
25153
25155
  __publicField(this, "unsubscribe");
25156
+ __publicField(this, "onSave");
25154
25157
  this.container = container;
25158
+ this.onSave = options?.onSave;
25155
25159
  this.render();
25156
25160
  this.setupSubscriptions();
25157
25161
  }
@@ -25166,6 +25170,18 @@ var FormBuilder = class {
25166
25170
  }
25167
25171
  render() {
25168
25172
  const state = formStore.getState();
25173
+ const activeElement = document.activeElement;
25174
+ let focusState = null;
25175
+ if (activeElement && (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA")) {
25176
+ const focusId = activeElement.getAttribute("data-focus-id");
25177
+ if (focusId) {
25178
+ focusState = {
25179
+ id: focusId,
25180
+ selectionStart: activeElement.selectionStart,
25181
+ selectionEnd: activeElement.selectionEnd
25182
+ };
25183
+ }
25184
+ }
25169
25185
  this.container.innerHTML = "";
25170
25186
  const wrapper = createElement("div", { className: "flex flex-col h-screen bg-gray-100 dark:bg-gray-950" });
25171
25187
  wrapper.appendChild(this.renderToolbar(state));
@@ -25183,6 +25199,17 @@ var FormBuilder = class {
25183
25199
  }
25184
25200
  wrapper.appendChild(main);
25185
25201
  this.container.appendChild(wrapper);
25202
+ if (focusState) {
25203
+ setTimeout(() => {
25204
+ const elementToFocus = document.querySelector(`[data-focus-id="${focusState.id}"]`);
25205
+ if (elementToFocus) {
25206
+ elementToFocus.focus();
25207
+ if (focusState.selectionStart !== null && focusState.selectionEnd !== null) {
25208
+ elementToFocus.setSelectionRange(focusState.selectionStart, focusState.selectionEnd);
25209
+ }
25210
+ }
25211
+ }, 0);
25212
+ }
25186
25213
  createIcons({ icons: iconsAndAliases_exports });
25187
25214
  if (!state.isPreviewMode) {
25188
25215
  this.initSortable();
@@ -25212,7 +25239,7 @@ var FormBuilder = class {
25212
25239
  className: "flex items-center px-3 py-2 text-sm font-medium text-red-600 hover:bg-red-50 rounded-md transition-colors",
25213
25240
  onclick: () => {
25214
25241
  if (confirm("Are you sure?")) {
25215
- formStore.getState().setSchema({ id: "new", title: "New Form", sections: [] });
25242
+ formStore.getState().setSchema({ id: "new", title: "New Form", formName: "newForm", sections: [] });
25216
25243
  }
25217
25244
  }
25218
25245
  }, [getIcon("Trash2", 16), createElement("span", { className: "ml-2", text: "Clear" })]);
@@ -25223,8 +25250,11 @@ var FormBuilder = class {
25223
25250
  const saveBtn = createElement("button", {
25224
25251
  className: "flex items-center px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-md shadow-sm transition-colors",
25225
25252
  onclick: () => {
25226
- console.log(formStore.getState().schema);
25227
- alert("Schema saved to console");
25253
+ const schema = formStore.getState().schema;
25254
+ console.log("Schema saved:", schema);
25255
+ if (this.onSave) {
25256
+ this.onSave(schema);
25257
+ }
25228
25258
  }
25229
25259
  }, [getIcon("Save", 16), createElement("span", { className: "ml-2", text: "Save" })]);
25230
25260
  right.appendChild(clearBtn);
@@ -25259,13 +25289,14 @@ var FormBuilder = class {
25259
25289
  }
25260
25290
  });
25261
25291
  const inner = createElement("div", { className: "max-w-3xl mx-auto" });
25262
- const titleInput = createElement("input", {
25263
- className: "text-3xl font-bold text-center bg-transparent border-none focus:outline-none focus:ring-0 w-full text-gray-900 dark:text-white mb-8",
25264
- value: state.schema.title,
25265
- placeholder: "Form Title",
25266
- oninput: (e) => formStore.getState().setSchema({ ...state.schema, title: e.target.value })
25292
+ const formNameInput = createElement("input", {
25293
+ className: "text-lg text-center bg-transparent border-none focus:outline-none focus:ring-0 w-full text-gray-600 dark:text-gray-400 mb-8",
25294
+ value: state.schema.formName,
25295
+ placeholder: "formName (e.g., contactForm)",
25296
+ "data-focus-id": "form-name",
25297
+ oninput: (e) => formStore.getState().setSchema({ ...state.schema, formName: e.target.value })
25267
25298
  });
25268
- inner.appendChild(titleInput);
25299
+ inner.appendChild(formNameInput);
25269
25300
  const sectionsContainer = createElement("div", { className: "space-y-6 min-h-[200px]", id: "sections-list" });
25270
25301
  state.schema.sections.forEach((section) => {
25271
25302
  const sectionEl = createElement("div", {
@@ -25278,6 +25309,7 @@ var FormBuilder = class {
25278
25309
  headerLeft.appendChild(createElement("input", {
25279
25310
  className: "bg-transparent font-semibold text-gray-700 dark:text-gray-200 focus:outline-none focus:border-b border-blue-500",
25280
25311
  value: section.title,
25312
+ "data-focus-id": `section-title-${section.id}`,
25281
25313
  oninput: (e) => formStore.getState().updateSection(section.id, { title: e.target.value })
25282
25314
  }));
25283
25315
  header.appendChild(headerLeft);
@@ -25287,14 +25319,14 @@ var FormBuilder = class {
25287
25319
  }, [getIcon("Trash2", 18)]));
25288
25320
  sectionEl.appendChild(header);
25289
25321
  const fieldsGrid = createElement("div", {
25290
- className: "p-4 min-h-[100px] grid grid-cols-4 gap-4 fields-list",
25322
+ className: "form-builder-grid p-4 min-h-[100px] fields-list",
25291
25323
  "data-section-id": section.id
25292
25324
  });
25293
25325
  section.fields.forEach((field) => {
25294
25326
  const isSelected = state.selectedFieldId === field.id;
25295
25327
  const span = field.width === "100%" ? "col-span-4" : field.width === "50%" ? "col-span-2" : "col-span-1";
25296
25328
  const fieldWrapper = createElement("div", {
25297
- className: `relative group rounded-lg border-2 transition-all bg-white dark:bg-gray-800 ${isSelected ? "border-blue-500 ring-2 ring-blue-200" : "border-transparent hover:border-gray-300 dark:hover:border-gray-600"} ${span}`,
25329
+ className: `form-builder-field-wrapper ${isSelected ? "selected" : ""} ${span}`,
25298
25330
  "data-id": field.id,
25299
25331
  onclick: (e) => {
25300
25332
  e.stopPropagation();
@@ -25348,6 +25380,7 @@ var FormBuilder = class {
25348
25380
  labelGroup.appendChild(createElement("input", {
25349
25381
  className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-md bg-transparent",
25350
25382
  value: selectedField.label,
25383
+ "data-focus-id": `field-label-${selectedField.id}`,
25351
25384
  oninput: (e) => formStore.getState().updateField(selectedField.id, { label: e.target.value })
25352
25385
  }));
25353
25386
  body.appendChild(labelGroup);
@@ -25356,6 +25389,7 @@ var FormBuilder = class {
25356
25389
  placeholderGroup.appendChild(createElement("input", {
25357
25390
  className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-md bg-transparent",
25358
25391
  value: selectedField.placeholder || "",
25392
+ "data-focus-id": `field-placeholder-${selectedField.id}`,
25359
25393
  oninput: (e) => formStore.getState().updateField(selectedField.id, { placeholder: e.target.value })
25360
25394
  }));
25361
25395
  body.appendChild(placeholderGroup);