@enerjisaformlibrary/formbuilder-react 1.0.8 → 1.0.22

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/index.cjs CHANGED
@@ -8124,6 +8124,25 @@ const AlignLeft = createLucideIcon("AlignLeft", [
8124
8124
  */
8125
8125
 
8126
8126
 
8127
+ const BookOpen = createLucideIcon("BookOpen", [
8128
+ ["path", { d: "M12 7v14", key: "1akyts" }],
8129
+ [
8130
+ "path",
8131
+ {
8132
+ d: "M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z",
8133
+ key: "ruj8y"
8134
+ }
8135
+ ]
8136
+ ]);
8137
+
8138
+ /**
8139
+ * @license lucide-react v0.453.0 - ISC
8140
+ *
8141
+ * This source code is licensed under the ISC license.
8142
+ * See the LICENSE file in the root directory of this source tree.
8143
+ */
8144
+
8145
+
8127
8146
  const Box = createLucideIcon("Box", [
8128
8147
  [
8129
8148
  "path",
@@ -9434,16 +9453,26 @@ const createEmptyForm = () => ({
9434
9453
  createdAt: new Date().toISOString(),
9435
9454
  updatedAt: new Date().toISOString(),
9436
9455
  });
9456
+ const MAX_HISTORY = 50;
9457
+ const pushToHistory = (state) => {
9458
+ const newHistory = state.history.slice(0, state.historyIndex + 1);
9459
+ newHistory.push(JSON.parse(JSON.stringify(state.form)));
9460
+ if (newHistory.length > MAX_HISTORY) {
9461
+ newHistory.shift();
9462
+ }
9463
+ return { history: newHistory, historyIndex: newHistory.length - 1 };
9464
+ };
9465
+ const initialForm = createDemoForm();
9437
9466
  const useFormStore = create((set, get) => ({
9438
- form: createDemoForm(),
9467
+ form: initialForm,
9439
9468
  selection: { type: null },
9440
9469
  isPreviewMode: false,
9441
9470
  currentStepIndex: 0,
9442
9471
  currentLanguage: 'en',
9443
9472
  formValues: {},
9444
9473
  canvasWidth: 'full',
9445
- history: [],
9446
- historyIndex: -1,
9474
+ history: [JSON.parse(JSON.stringify(initialForm))],
9475
+ historyIndex: 0,
9447
9476
  setCanvasWidth: (width) => set({ canvasWidth: width }),
9448
9477
  undo: () => {
9449
9478
  const state = get();
@@ -9480,75 +9509,87 @@ const useFormStore = create((set, get) => ({
9480
9509
  selection: { type: null },
9481
9510
  formValues: {},
9482
9511
  })),
9483
- clearForm: () => set({
9484
- form: createEmptyForm(),
9485
- selection: { type: null },
9486
- currentStepIndex: 0,
9487
- formValues: {},
9488
- }),
9512
+ clearForm: () => {
9513
+ const newForm = createEmptyForm();
9514
+ return set({
9515
+ form: newForm,
9516
+ selection: { type: null },
9517
+ currentStepIndex: 0,
9518
+ formValues: {},
9519
+ history: [JSON.parse(JSON.stringify(newForm))],
9520
+ historyIndex: 0,
9521
+ });
9522
+ },
9489
9523
  loadForm: (form) => set({
9490
9524
  form,
9491
9525
  selection: { type: null },
9492
9526
  currentStepIndex: 0,
9493
9527
  formValues: {},
9528
+ history: [JSON.parse(JSON.stringify(form))],
9529
+ historyIndex: 0,
9494
9530
  }),
9495
9531
  addRow: (columns = 1, stepId) => set((state) => {
9496
9532
  const newRow = createEmptyRow(columns);
9533
+ let newForm;
9497
9534
  if (state.form.isMultiStep && state.form.steps?.length) {
9498
9535
  const targetStepId = stepId || state.form.steps[state.currentStepIndex]?.id;
9499
- return {
9500
- form: {
9501
- ...state.form,
9502
- steps: state.form.steps.map(s => s.id === targetStepId ? { ...s, rows: [...s.rows, newRow] } : s),
9503
- updatedAt: new Date().toISOString(),
9504
- },
9536
+ newForm = {
9537
+ ...state.form,
9538
+ steps: state.form.steps.map(s => s.id === targetStepId ? { ...s, rows: [...s.rows, newRow] } : s),
9539
+ updatedAt: new Date().toISOString(),
9505
9540
  };
9506
9541
  }
9507
- return {
9508
- form: {
9542
+ else {
9543
+ newForm = {
9509
9544
  ...state.form,
9510
9545
  rows: [...state.form.rows, newRow],
9511
9546
  updatedAt: new Date().toISOString(),
9512
- },
9513
- };
9547
+ };
9548
+ }
9549
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
9550
+ return { form: newForm, ...historyUpdate };
9514
9551
  }),
9515
9552
  updateRow: (rowId, updates) => set((state) => {
9516
9553
  const updateRows = (rows) => rows.map((row) => (row.id === rowId ? { ...row, ...updates } : row));
9554
+ let newForm;
9517
9555
  if (state.form.isMultiStep && state.form.steps?.length) {
9518
- return {
9519
- form: {
9520
- ...state.form,
9521
- steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9522
- updatedAt: new Date().toISOString(),
9523
- },
9556
+ newForm = {
9557
+ ...state.form,
9558
+ steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9559
+ updatedAt: new Date().toISOString(),
9524
9560
  };
9525
9561
  }
9526
- return {
9527
- form: {
9562
+ else {
9563
+ newForm = {
9528
9564
  ...state.form,
9529
9565
  rows: updateRows(state.form.rows),
9530
9566
  updatedAt: new Date().toISOString(),
9531
- },
9532
- };
9567
+ };
9568
+ }
9569
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
9570
+ return { form: newForm, ...historyUpdate };
9533
9571
  }),
9534
9572
  deleteRow: (rowId) => set((state) => {
9535
9573
  const filterRows = (rows) => rows.filter((row) => row.id !== rowId);
9574
+ let newForm;
9536
9575
  if (state.form.isMultiStep && state.form.steps?.length) {
9537
- return {
9538
- form: {
9539
- ...state.form,
9540
- steps: state.form.steps.map(s => ({ ...s, rows: filterRows(s.rows) })),
9541
- updatedAt: new Date().toISOString(),
9542
- },
9543
- selection: state.selection.rowId === rowId ? { type: null } : state.selection,
9576
+ newForm = {
9577
+ ...state.form,
9578
+ steps: state.form.steps.map(s => ({ ...s, rows: filterRows(s.rows) })),
9579
+ updatedAt: new Date().toISOString(),
9544
9580
  };
9545
9581
  }
9546
- return {
9547
- form: {
9582
+ else {
9583
+ newForm = {
9548
9584
  ...state.form,
9549
9585
  rows: filterRows(state.form.rows),
9550
9586
  updatedAt: new Date().toISOString(),
9551
- },
9587
+ };
9588
+ }
9589
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
9590
+ return {
9591
+ form: newForm,
9592
+ ...historyUpdate,
9552
9593
  selection: state.selection.rowId === rowId ? { type: null } : state.selection,
9553
9594
  };
9554
9595
  }),
@@ -9559,18 +9600,19 @@ const useFormStore = create((set, get) => ({
9559
9600
  newRows.splice(toIndex, 0, removed);
9560
9601
  return newRows;
9561
9602
  };
9603
+ let newForm;
9562
9604
  if (state.form.isMultiStep && stepId) {
9563
- return {
9564
- form: {
9565
- ...state.form,
9566
- steps: state.form.steps?.map(s => s.id === stepId ? { ...s, rows: moveInRows(s.rows) } : s),
9567
- updatedAt: new Date().toISOString(),
9568
- },
9605
+ newForm = {
9606
+ ...state.form,
9607
+ steps: state.form.steps?.map(s => s.id === stepId ? { ...s, rows: moveInRows(s.rows) } : s),
9608
+ updatedAt: new Date().toISOString(),
9569
9609
  };
9570
9610
  }
9571
- return {
9572
- form: { ...state.form, rows: moveInRows(state.form.rows) },
9573
- };
9611
+ else {
9612
+ newForm = { ...state.form, rows: moveInRows(state.form.rows), updatedAt: new Date().toISOString() };
9613
+ }
9614
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
9615
+ return { form: newForm, ...historyUpdate };
9574
9616
  }),
9575
9617
  addColumn: (rowId) => set((state) => {
9576
9618
  const updateRows = (rows) => rows.map((row) => {
@@ -9586,22 +9628,23 @@ const useFormStore = create((set, get) => ({
9586
9628
  ],
9587
9629
  };
9588
9630
  });
9631
+ let newForm;
9589
9632
  if (state.form.isMultiStep && state.form.steps?.length) {
9590
- return {
9591
- form: {
9592
- ...state.form,
9593
- steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9594
- updatedAt: new Date().toISOString(),
9595
- },
9633
+ newForm = {
9634
+ ...state.form,
9635
+ steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9636
+ updatedAt: new Date().toISOString(),
9596
9637
  };
9597
9638
  }
9598
- return {
9599
- form: {
9639
+ else {
9640
+ newForm = {
9600
9641
  ...state.form,
9601
9642
  rows: updateRows(state.form.rows),
9602
9643
  updatedAt: new Date().toISOString(),
9603
- },
9604
- };
9644
+ };
9645
+ }
9646
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
9647
+ return { form: newForm, ...historyUpdate };
9605
9648
  }),
9606
9649
  updateColumn: (rowId, columnId, updates) => set((state) => {
9607
9650
  const updateRows = (rows) => rows.map((row) => row.id === rowId
@@ -9610,22 +9653,23 @@ const useFormStore = create((set, get) => ({
9610
9653
  columns: row.columns.map((col) => col.id === columnId ? { ...col, ...updates } : col),
9611
9654
  }
9612
9655
  : row);
9656
+ let newForm;
9613
9657
  if (state.form.isMultiStep && state.form.steps?.length) {
9614
- return {
9615
- form: {
9616
- ...state.form,
9617
- steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9618
- updatedAt: new Date().toISOString(),
9619
- },
9658
+ newForm = {
9659
+ ...state.form,
9660
+ steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9661
+ updatedAt: new Date().toISOString(),
9620
9662
  };
9621
9663
  }
9622
- return {
9623
- form: {
9664
+ else {
9665
+ newForm = {
9624
9666
  ...state.form,
9625
9667
  rows: updateRows(state.form.rows),
9626
9668
  updatedAt: new Date().toISOString(),
9627
- },
9628
- };
9669
+ };
9670
+ }
9671
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
9672
+ return { form: newForm, ...historyUpdate };
9629
9673
  }),
9630
9674
  deleteColumn: (rowId, columnId) => set((state) => {
9631
9675
  const updateRows = (rows) => rows.map((row) => {
@@ -9640,22 +9684,25 @@ const useFormStore = create((set, get) => ({
9640
9684
  columns: newColumns.map((col) => ({ ...col, width })),
9641
9685
  };
9642
9686
  });
9687
+ let newForm;
9643
9688
  if (state.form.isMultiStep && state.form.steps?.length) {
9644
- return {
9645
- form: {
9646
- ...state.form,
9647
- steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9648
- updatedAt: new Date().toISOString(),
9649
- },
9650
- selection: state.selection.columnId === columnId ? { type: null } : state.selection,
9689
+ newForm = {
9690
+ ...state.form,
9691
+ steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9692
+ updatedAt: new Date().toISOString(),
9651
9693
  };
9652
9694
  }
9653
- return {
9654
- form: {
9695
+ else {
9696
+ newForm = {
9655
9697
  ...state.form,
9656
9698
  rows: updateRows(state.form.rows),
9657
9699
  updatedAt: new Date().toISOString(),
9658
- },
9700
+ };
9701
+ }
9702
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
9703
+ return {
9704
+ form: newForm,
9705
+ ...historyUpdate,
9659
9706
  selection: state.selection.columnId === columnId ? { type: null } : state.selection,
9660
9707
  };
9661
9708
  }),
@@ -9684,22 +9731,23 @@ const useFormStore = create((set, get) => ({
9684
9731
  columns: newColumns.map((col) => ({ ...col, width })),
9685
9732
  };
9686
9733
  });
9734
+ let newForm;
9687
9735
  if (state.form.isMultiStep && state.form.steps?.length) {
9688
- return {
9689
- form: {
9690
- ...state.form,
9691
- steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9692
- updatedAt: new Date().toISOString(),
9693
- },
9736
+ newForm = {
9737
+ ...state.form,
9738
+ steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9739
+ updatedAt: new Date().toISOString(),
9694
9740
  };
9695
9741
  }
9696
- return {
9697
- form: {
9742
+ else {
9743
+ newForm = {
9698
9744
  ...state.form,
9699
9745
  rows: updateRows(state.form.rows),
9700
9746
  updatedAt: new Date().toISOString(),
9701
- },
9702
- };
9747
+ };
9748
+ }
9749
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
9750
+ return { form: newForm, ...historyUpdate };
9703
9751
  }),
9704
9752
  addField: (rowId, columnId, field) => set((state) => {
9705
9753
  const updateRows = (rows) => rows.map((row) => row.id === rowId
@@ -9713,22 +9761,23 @@ const useFormStore = create((set, get) => ({
9713
9761
  : col),
9714
9762
  }
9715
9763
  : row);
9764
+ let newForm;
9716
9765
  if (state.form.isMultiStep && state.form.steps?.length) {
9717
- return {
9718
- form: {
9719
- ...state.form,
9720
- steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9721
- updatedAt: new Date().toISOString(),
9722
- },
9766
+ newForm = {
9767
+ ...state.form,
9768
+ steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9769
+ updatedAt: new Date().toISOString(),
9723
9770
  };
9724
9771
  }
9725
- return {
9726
- form: {
9772
+ else {
9773
+ newForm = {
9727
9774
  ...state.form,
9728
9775
  rows: updateRows(state.form.rows),
9729
9776
  updatedAt: new Date().toISOString(),
9730
- },
9731
- };
9777
+ };
9778
+ }
9779
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
9780
+ return { form: newForm, ...historyUpdate };
9732
9781
  }),
9733
9782
  addRowWithField: (field) => set((state) => {
9734
9783
  const newRow = {
@@ -9739,25 +9788,26 @@ const useFormStore = create((set, get) => ({
9739
9788
  fields: [{ ...field, id: nanoid() }],
9740
9789
  }],
9741
9790
  };
9791
+ let newForm;
9742
9792
  if (state.form.isMultiStep && state.form.steps?.length) {
9743
9793
  const currentStep = state.form.steps[state.currentStepIndex];
9744
- return {
9745
- form: {
9746
- ...state.form,
9747
- steps: state.form.steps.map(s => s.id === currentStep.id
9748
- ? { ...s, rows: [...s.rows, newRow] }
9749
- : s),
9750
- updatedAt: new Date().toISOString(),
9751
- },
9794
+ newForm = {
9795
+ ...state.form,
9796
+ steps: state.form.steps.map(s => s.id === currentStep.id
9797
+ ? { ...s, rows: [...s.rows, newRow] }
9798
+ : s),
9799
+ updatedAt: new Date().toISOString(),
9752
9800
  };
9753
9801
  }
9754
- return {
9755
- form: {
9802
+ else {
9803
+ newForm = {
9756
9804
  ...state.form,
9757
9805
  rows: [...state.form.rows, newRow],
9758
9806
  updatedAt: new Date().toISOString(),
9759
- },
9760
- };
9807
+ };
9808
+ }
9809
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
9810
+ return { form: newForm, ...historyUpdate };
9761
9811
  }),
9762
9812
  addFieldToContainerDirect: (rowId, columnId, containerFieldId, field) => set((state) => {
9763
9813
  const newField = { ...field, id: nanoid() };
@@ -9783,22 +9833,23 @@ const useFormStore = create((set, get) => ({
9783
9833
  : col),
9784
9834
  }
9785
9835
  : row);
9836
+ let newForm;
9786
9837
  if (state.form.isMultiStep && state.form.steps?.length) {
9787
- return {
9788
- form: {
9789
- ...state.form,
9790
- steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9791
- updatedAt: new Date().toISOString(),
9792
- },
9838
+ newForm = {
9839
+ ...state.form,
9840
+ steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9841
+ updatedAt: new Date().toISOString(),
9793
9842
  };
9794
9843
  }
9795
- return {
9796
- form: {
9844
+ else {
9845
+ newForm = {
9797
9846
  ...state.form,
9798
9847
  rows: updateRows(state.form.rows),
9799
9848
  updatedAt: new Date().toISOString(),
9800
- },
9801
- };
9849
+ };
9850
+ }
9851
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
9852
+ return { form: newForm, ...historyUpdate };
9802
9853
  }),
9803
9854
  addFieldToContainer: (rowId, columnId, containerFieldId, containerRowId, containerColumnId, field) => set((state) => {
9804
9855
  const newField = { ...field, id: nanoid() };
@@ -9834,22 +9885,23 @@ const useFormStore = create((set, get) => ({
9834
9885
  : col),
9835
9886
  }
9836
9887
  : row);
9888
+ let newForm;
9837
9889
  if (state.form.isMultiStep && state.form.steps?.length) {
9838
- return {
9839
- form: {
9840
- ...state.form,
9841
- steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9842
- updatedAt: new Date().toISOString(),
9843
- },
9890
+ newForm = {
9891
+ ...state.form,
9892
+ steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9893
+ updatedAt: new Date().toISOString(),
9844
9894
  };
9845
9895
  }
9846
- return {
9847
- form: {
9896
+ else {
9897
+ newForm = {
9848
9898
  ...state.form,
9849
9899
  rows: updateRows(state.form.rows),
9850
9900
  updatedAt: new Date().toISOString(),
9851
- },
9852
- };
9901
+ };
9902
+ }
9903
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
9904
+ return { form: newForm, ...historyUpdate };
9853
9905
  }),
9854
9906
  updateField: (rowId, columnId, fieldId, updates) => set((state) => {
9855
9907
  const updateFieldInContainer = (field) => {
@@ -9914,22 +9966,23 @@ const useFormStore = create((set, get) => ({
9914
9966
  : col),
9915
9967
  }
9916
9968
  : row);
9969
+ let newForm;
9917
9970
  if (state.form.isMultiStep && state.form.steps?.length) {
9918
- return {
9919
- form: {
9920
- ...state.form,
9921
- steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9922
- updatedAt: new Date().toISOString(),
9923
- },
9971
+ newForm = {
9972
+ ...state.form,
9973
+ steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9974
+ updatedAt: new Date().toISOString(),
9924
9975
  };
9925
9976
  }
9926
- return {
9927
- form: {
9977
+ else {
9978
+ newForm = {
9928
9979
  ...state.form,
9929
9980
  rows: updateRows(state.form.rows),
9930
9981
  updatedAt: new Date().toISOString(),
9931
- },
9932
- };
9982
+ };
9983
+ }
9984
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
9985
+ return { form: newForm, ...historyUpdate };
9933
9986
  }),
9934
9987
  deleteField: (rowId, columnId, fieldId) => set((state) => {
9935
9988
  const updateRows = (rows) => rows.map((row) => row.id === rowId
@@ -9960,22 +10013,25 @@ const useFormStore = create((set, get) => ({
9960
10013
  : col),
9961
10014
  }
9962
10015
  : row);
10016
+ let newForm;
9963
10017
  if (state.form.isMultiStep && state.form.steps?.length) {
9964
- return {
9965
- form: {
9966
- ...state.form,
9967
- steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
9968
- updatedAt: new Date().toISOString(),
9969
- },
9970
- selection: state.selection.fieldId === fieldId ? { type: null } : state.selection,
10018
+ newForm = {
10019
+ ...state.form,
10020
+ steps: state.form.steps.map(s => ({ ...s, rows: updateRows(s.rows) })),
10021
+ updatedAt: new Date().toISOString(),
9971
10022
  };
9972
10023
  }
9973
- return {
9974
- form: {
10024
+ else {
10025
+ newForm = {
9975
10026
  ...state.form,
9976
10027
  rows: updateRows(state.form.rows),
9977
10028
  updatedAt: new Date().toISOString(),
9978
- },
10029
+ };
10030
+ }
10031
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
10032
+ return {
10033
+ form: newForm,
10034
+ ...historyUpdate,
9979
10035
  selection: state.selection.fieldId === fieldId ? { type: null } : state.selection,
9980
10036
  };
9981
10037
  }),
@@ -10013,22 +10069,23 @@ const useFormStore = create((set, get) => ({
10013
10069
  }
10014
10070
  return row;
10015
10071
  });
10072
+ let newForm;
10016
10073
  if (state.form.isMultiStep && state.form.steps?.length) {
10017
10074
  let newSteps = state.form.steps.map(s => ({ ...s, rows: extractField(s.rows) }));
10018
10075
  if (!movedField)
10019
10076
  return state;
10020
10077
  newSteps = newSteps.map(s => ({ ...s, rows: insertField(s.rows) }));
10021
- return {
10022
- form: { ...state.form, steps: newSteps, updatedAt: new Date().toISOString() },
10023
- };
10078
+ newForm = { ...state.form, steps: newSteps, updatedAt: new Date().toISOString() };
10024
10079
  }
10025
- const rows = extractField(state.form.rows);
10026
- if (!movedField)
10027
- return state;
10028
- const finalRows = insertField(rows);
10029
- return {
10030
- form: { ...state.form, rows: finalRows, updatedAt: new Date().toISOString() },
10031
- };
10080
+ else {
10081
+ const rows = extractField(state.form.rows);
10082
+ if (!movedField)
10083
+ return state;
10084
+ const finalRows = insertField(rows);
10085
+ newForm = { ...state.form, rows: finalRows, updatedAt: new Date().toISOString() };
10086
+ }
10087
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
10088
+ return { form: newForm, ...historyUpdate };
10032
10089
  }),
10033
10090
  addStep: () => set((state) => {
10034
10091
  const newStep = createEmptyStep(state.form.steps?.length || 0);
@@ -10041,22 +10098,27 @@ const useFormStore = create((set, get) => ({
10041
10098
  },
10042
10099
  };
10043
10100
  }),
10044
- updateStep: (stepId, updates) => set((state) => ({
10045
- form: {
10101
+ updateStep: (stepId, updates) => set((state) => {
10102
+ const newForm = {
10046
10103
  ...state.form,
10047
10104
  steps: state.form.steps?.map(s => s.id === stepId ? { ...s, ...updates } : s),
10048
10105
  updatedAt: new Date().toISOString(),
10049
- },
10050
- })),
10106
+ };
10107
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
10108
+ return { form: newForm, ...historyUpdate };
10109
+ }),
10051
10110
  deleteStep: (stepId) => set((state) => {
10052
10111
  const newSteps = state.form.steps?.filter(s => s.id !== stepId) || [];
10112
+ const newForm = {
10113
+ ...state.form,
10114
+ steps: newSteps,
10115
+ isMultiStep: newSteps.length > 0,
10116
+ updatedAt: new Date().toISOString(),
10117
+ };
10118
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
10053
10119
  return {
10054
- form: {
10055
- ...state.form,
10056
- steps: newSteps,
10057
- isMultiStep: newSteps.length > 0,
10058
- updatedAt: new Date().toISOString(),
10059
- },
10120
+ form: newForm,
10121
+ ...historyUpdate,
10060
10122
  currentStepIndex: Math.min(state.currentStepIndex, Math.max(0, newSteps.length - 1)),
10061
10123
  selection: state.selection.stepId === stepId ? { type: null } : state.selection,
10062
10124
  };
@@ -10065,9 +10127,9 @@ const useFormStore = create((set, get) => ({
10065
10127
  const steps = [...(state.form.steps || [])];
10066
10128
  const [removed] = steps.splice(fromIndex, 1);
10067
10129
  steps.splice(toIndex, 0, removed);
10068
- return {
10069
- form: { ...state.form, steps, updatedAt: new Date().toISOString() },
10070
- };
10130
+ const newForm = { ...state.form, steps, updatedAt: new Date().toISOString() };
10131
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
10132
+ return { form: newForm, ...historyUpdate };
10071
10133
  }),
10072
10134
  setCurrentStep: (index) => set((state) => ({
10073
10135
  currentStepIndex: Math.max(0, Math.min(index, (state.form.steps?.length || 1) - 1)),
@@ -10079,33 +10141,30 @@ const useFormStore = create((set, get) => ({
10079
10141
  currentStepIndex: Math.max(0, state.currentStepIndex - 1),
10080
10142
  })),
10081
10143
  toggleMultiStep: () => set((state) => {
10144
+ let newForm;
10082
10145
  if (state.form.isMultiStep) {
10083
10146
  const allRows = state.form.steps?.flatMap(s => s.rows) || [];
10084
- return {
10085
- form: {
10086
- ...state.form,
10087
- isMultiStep: false,
10088
- rows: [...state.form.rows, ...allRows],
10089
- steps: [],
10090
- updatedAt: new Date().toISOString(),
10091
- },
10092
- currentStepIndex: 0,
10147
+ newForm = {
10148
+ ...state.form,
10149
+ isMultiStep: false,
10150
+ rows: [...state.form.rows, ...allRows],
10151
+ steps: [],
10152
+ updatedAt: new Date().toISOString(),
10093
10153
  };
10094
10154
  }
10095
10155
  else {
10096
10156
  const step = createEmptyStep(0);
10097
10157
  step.rows = [...state.form.rows];
10098
- return {
10099
- form: {
10100
- ...state.form,
10101
- isMultiStep: true,
10102
- rows: [],
10103
- steps: [step],
10104
- updatedAt: new Date().toISOString(),
10105
- },
10106
- currentStepIndex: 0,
10158
+ newForm = {
10159
+ ...state.form,
10160
+ isMultiStep: true,
10161
+ rows: [],
10162
+ steps: [step],
10163
+ updatedAt: new Date().toISOString(),
10107
10164
  };
10108
10165
  }
10166
+ const historyUpdate = pushToHistory({ form: newForm, history: state.history, historyIndex: state.historyIndex });
10167
+ return { form: newForm, ...historyUpdate, currentStepIndex: 0 };
10109
10168
  }),
10110
10169
  updateSubmissionConfig: (config) => set((state) => ({
10111
10170
  form: {
@@ -18604,7 +18663,7 @@ function MultiSelectField({ value, onChange, options, disabled, maxItems, classN
18604
18663
  }
18605
18664
  function CanvasField({ field, rowId, columnId, isPreviewMode: externalPreviewMode, getFieldValue: externalGetFieldValue, setFieldValue: externalSetFieldValue, isInsideContainer = false, fieldSize = 'normal' }) {
18606
18665
  const store = useFormStore();
18607
- const { selection, setSelection, deleteField, evaluateCondition, clearFormValues } = store;
18666
+ const { selection, setSelection, deleteField, evaluateCondition, clearFormValues, formValues } = store;
18608
18667
  const isPreviewMode = externalPreviewMode ?? store.isPreviewMode;
18609
18668
  const getFieldValue = externalGetFieldValue ?? store.getFieldValue;
18610
18669
  const setFieldValue = externalSetFieldValue ?? store.setFieldValue;
@@ -18628,6 +18687,15 @@ function CanvasField({ field, rowId, columnId, isPreviewMode: externalPreviewMod
18628
18687
  // Reset rating, slider values
18629
18688
  setRatingValue(field.props.defaultValue ? parseInt(field.props.defaultValue) || 0 : 0);
18630
18689
  setSliderValue([field.props.defaultValue ? parseInt(field.props.defaultValue) || 50 : 50]);
18690
+ // Auto focus when entering preview mode
18691
+ if (field.props.autoFocus) {
18692
+ setTimeout(() => {
18693
+ const input = document.querySelector(`[data-testid^="field-"][data-testid$="-${field.id}"]`);
18694
+ if (input && input.focus) {
18695
+ input.focus();
18696
+ }
18697
+ }, 100);
18698
+ }
18631
18699
  }
18632
18700
  }, [isPreviewMode]);
18633
18701
  const isSelected = selection.type === 'field' &&
@@ -18660,8 +18728,59 @@ function CanvasField({ field, rowId, columnId, isPreviewMode: externalPreviewMod
18660
18728
  break;
18661
18729
  }
18662
18730
  return { visible, enabled, required };
18663
- }, [field.conditionalLogic, field.validation?.required, evaluateCondition]);
18664
- if (isPreviewMode && !conditionalState.visible) {
18731
+ }, [field.conditionalLogic, field.validation?.required, evaluateCondition, formValues]);
18732
+ const handleChange = React.useCallback((newValue) => {
18733
+ setLocalValue(newValue);
18734
+ setFieldValue(field.props.key, newValue);
18735
+ if (touched) {
18736
+ setError(validateField(newValue, field.validation, field.type));
18737
+ }
18738
+ }, [touched, field.validation, field.type, field.props.key, setFieldValue]);
18739
+ const handleBlur = React.useCallback(() => {
18740
+ setTouched(true);
18741
+ setError(validateField(localValue, field.validation, field.type));
18742
+ }, [localValue, field.validation, field.type]);
18743
+ // Execute field actions (onClick, onChange, onFocus, onBlur events)
18744
+ const executeActions = React.useCallback((eventType) => {
18745
+ if (!isPreviewMode || !field.events)
18746
+ return;
18747
+ const actions = field.events[eventType];
18748
+ if (!actions || actions.length === 0)
18749
+ return;
18750
+ actions.forEach((action) => {
18751
+ if (action.type === 'common') {
18752
+ switch (action.name) {
18753
+ case 'focusField':
18754
+ if (action.args?.targetFieldKey) {
18755
+ setTimeout(() => {
18756
+ const allInputs = document.querySelectorAll('[data-field-key]');
18757
+ allInputs.forEach((el) => {
18758
+ if (el.getAttribute('data-field-key') === action.args?.targetFieldKey) {
18759
+ el.focus();
18760
+ }
18761
+ });
18762
+ }, 50);
18763
+ }
18764
+ break;
18765
+ case 'clearField':
18766
+ setLocalValue('');
18767
+ setFieldValue(field.props.key, '');
18768
+ break;
18769
+ case 'showMessage':
18770
+ if (action.args?.message) {
18771
+ alert(action.args.message);
18772
+ }
18773
+ break;
18774
+ case 'reset':
18775
+ clearFormValues();
18776
+ break;
18777
+ }
18778
+ }
18779
+ });
18780
+ }, [isPreviewMode, field.events, field.props.key, setFieldValue, clearFormValues]);
18781
+ // Early return for hidden fields - MUST be after all hooks
18782
+ // Check both conditional visibility AND explicit hidden property
18783
+ if (isPreviewMode && (!conditionalState.visible || field.props.hidden)) {
18665
18784
  return null;
18666
18785
  }
18667
18786
  const isFieldDisabled = field.props.disabled || !isPreviewMode || !conditionalState.enabled;
@@ -18676,18 +18795,10 @@ function CanvasField({ field, rowId, columnId, isPreviewMode: externalPreviewMod
18676
18795
  fieldId: field.id,
18677
18796
  });
18678
18797
  }
18679
- };
18680
- const handleChange = React.useCallback((newValue) => {
18681
- setLocalValue(newValue);
18682
- setFieldValue(field.props.key, newValue);
18683
- if (touched) {
18684
- setError(validateField(newValue, field.validation, field.type));
18798
+ else {
18799
+ executeActions('onClick');
18685
18800
  }
18686
- }, [touched, field.validation, field.type, field.props.key, setFieldValue]);
18687
- const handleBlur = React.useCallback(() => {
18688
- setTouched(true);
18689
- setError(validateField(localValue, field.validation, field.type));
18690
- }, [localValue, field.validation, field.type]);
18801
+ };
18691
18802
  const sizeClasses = {
18692
18803
  small: 'h-8 text-sm',
18693
18804
  medium: 'h-9',
@@ -18710,51 +18821,51 @@ function CanvasField({ field, rowId, columnId, isPreviewMode: externalPreviewMod
18710
18821
  const errorClass = hasError ? 'border-destructive focus-visible:ring-destructive' : '';
18711
18822
  switch (field.type) {
18712
18823
  case 'input':
18713
- return (jsxRuntime.jsx(Input, { placeholder: field.props.placeholder, disabled: isFieldDisabled, readOnly: field.props.readOnly, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18824
+ return (jsxRuntime.jsx(Input, { placeholder: field.props.placeholder, disabled: isFieldDisabled, readOnly: field.props.readOnly, autoFocus: isPreviewMode && field.props.autoFocus, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18714
18825
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18715
18826
  ...(field.customStyle?.backgroundColor ? { backgroundColor: field.customStyle.backgroundColor } : {}),
18716
- }, "data-testid": `field-input-${field.id}` }));
18827
+ }, "data-testid": `field-input-${field.id}`, "data-field-key": field.props.key }));
18717
18828
  case 'password':
18718
- return (jsxRuntime.jsx(Input, { type: "password", placeholder: field.props.placeholder, disabled: isFieldDisabled, value: isPreviewMode ? localValue : '', onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18829
+ return (jsxRuntime.jsx(Input, { type: "password", placeholder: field.props.placeholder, disabled: isFieldDisabled, autoFocus: isPreviewMode && field.props.autoFocus, value: isPreviewMode ? localValue : '', onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18719
18830
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18720
18831
  ...(field.customStyle?.backgroundColor ? { backgroundColor: field.customStyle.backgroundColor } : {}),
18721
- }, "data-testid": `field-password-${field.id}` }));
18832
+ }, "data-testid": `field-password-${field.id}`, "data-field-key": field.props.key }));
18722
18833
  case 'phone':
18723
- return (jsxRuntime.jsx(Input, { type: "tel", placeholder: field.props.placeholder || '+1 (555) 000-0000', disabled: isFieldDisabled, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18834
+ return (jsxRuntime.jsx(Input, { type: "tel", placeholder: field.props.placeholder || '+1 (555) 000-0000', disabled: isFieldDisabled, autoFocus: isPreviewMode && field.props.autoFocus, "data-field-key": field.props.key, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18724
18835
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18725
18836
  ...(field.customStyle?.backgroundColor ? { backgroundColor: field.customStyle.backgroundColor } : {}),
18726
18837
  }, "data-testid": `field-phone-${field.id}` }));
18727
18838
  case 'url':
18728
- return (jsxRuntime.jsx(Input, { type: "url", placeholder: field.props.placeholder || 'https://example.com', disabled: isFieldDisabled, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18839
+ return (jsxRuntime.jsx(Input, { type: "url", placeholder: field.props.placeholder || 'https://example.com', disabled: isFieldDisabled, autoFocus: isPreviewMode && field.props.autoFocus, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18729
18840
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18730
18841
  ...(field.customStyle?.backgroundColor ? { backgroundColor: field.customStyle.backgroundColor } : {}),
18731
- }, "data-testid": `field-url-${field.id}` }));
18842
+ }, "data-testid": `field-url-${field.id}`, "data-field-key": field.props.key }));
18732
18843
  case 'textarea':
18733
- return (jsxRuntime.jsx(Textarea, { placeholder: field.props.placeholder, disabled: isFieldDisabled, readOnly: field.props.readOnly, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `min-h-[80px] ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18844
+ return (jsxRuntime.jsx(Textarea, { placeholder: field.props.placeholder, disabled: isFieldDisabled, readOnly: field.props.readOnly, autoFocus: isPreviewMode && field.props.autoFocus, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `min-h-[80px] ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18734
18845
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18735
18846
  ...(field.customStyle?.backgroundColor ? { backgroundColor: field.customStyle.backgroundColor } : {}),
18736
- }, "data-testid": `field-textarea-${field.id}` }));
18847
+ }, "data-testid": `field-textarea-${field.id}`, "data-field-key": field.props.key }));
18737
18848
  case 'dropdown':
18738
18849
  const dropdownOptions = typeof field.props.optionsString === 'string'
18739
18850
  ? field.props.optionsString.split('\n').filter((o) => o.trim())
18740
18851
  : (field.props.optionsString || []);
18741
- return (jsxRuntime.jsxs(Select, { disabled: isFieldDisabled, value: isPreviewMode ? localValue : undefined, onValueChange: (v) => isPreviewMode && handleChange(v), children: [jsxRuntime.jsx(SelectTrigger, { className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18852
+ return (jsxRuntime.jsxs(Select, { disabled: isFieldDisabled, value: isPreviewMode ? localValue : undefined, onValueChange: (v) => isPreviewMode && handleChange(v), children: [jsxRuntime.jsx(SelectTrigger, { className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, tabIndex: tabIndexValue, style: {
18742
18853
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18743
18854
  ...(field.customStyle?.backgroundColor ? { backgroundColor: field.customStyle.backgroundColor } : {}),
18744
18855
  }, "data-testid": `field-dropdown-${field.id}`, children: jsxRuntime.jsx(SelectValue, { placeholder: field.props.placeholder || 'Select...' }) }), jsxRuntime.jsx(SelectContent, { children: dropdownOptions.map((option, i) => (jsxRuntime.jsx(SelectItem, { value: option, children: option }, i))) })] }));
18745
18856
  case 'checkbox':
18746
- return (jsxRuntime.jsxs("div", { className: `flex items-center gap-2 ${field.customStyle?.inputClassName || ''}`, children: [jsxRuntime.jsx(Checkbox, { disabled: isFieldDisabled, "data-testid": `field-checkbox-${field.id}` }), jsxRuntime.jsx("span", { className: "text-sm text-foreground", style: {
18857
+ return (jsxRuntime.jsxs("div", { className: `flex items-center gap-2 ${field.customStyle?.inputClassName || ''}`, children: [jsxRuntime.jsx(Checkbox, { disabled: isFieldDisabled, tabIndex: tabIndexValue, "data-testid": `field-checkbox-${field.id}` }), jsxRuntime.jsx("span", { className: "text-sm text-foreground", style: {
18747
18858
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18748
18859
  }, children: field.props.label })] }));
18749
18860
  case 'radio':
18750
18861
  const radioOptions = typeof field.props.optionsString === 'string'
18751
18862
  ? field.props.optionsString.split('\n').filter((o) => o.trim())
18752
18863
  : (field.props.optionsString || []);
18753
- return (jsxRuntime.jsx(RadioGroup$1, { disabled: isFieldDisabled, className: field.customStyle?.inputClassName || '', children: radioOptions.map((option, i) => (jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(RadioGroupItem, { value: option, id: `${field.id}-${i}`, "data-testid": `field-radio-${field.id}-${i}` }), jsxRuntime.jsx(Label$2, { htmlFor: `${field.id}-${i}`, className: "text-sm", style: {
18864
+ return (jsxRuntime.jsx(RadioGroup$1, { disabled: isFieldDisabled, className: field.customStyle?.inputClassName || '', children: radioOptions.map((option, i) => (jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(RadioGroupItem, { value: option, id: `${field.id}-${i}`, tabIndex: tabIndexValue, "data-testid": `field-radio-${field.id}-${i}` }), jsxRuntime.jsx(Label$2, { htmlFor: `${field.id}-${i}`, className: "text-sm", style: {
18754
18865
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18755
18866
  }, children: option })] }, i))) }));
18756
18867
  case 'toggle':
18757
- return (jsxRuntime.jsxs("div", { className: `flex items-center gap-2 ${field.customStyle?.inputClassName || ''}`, children: [jsxRuntime.jsx(Switch, { disabled: isFieldDisabled, "data-testid": `field-toggle-${field.id}` }), jsxRuntime.jsx("span", { className: "text-sm text-foreground", style: {
18868
+ return (jsxRuntime.jsxs("div", { className: `flex items-center gap-2 ${field.customStyle?.inputClassName || ''}`, children: [jsxRuntime.jsx(Switch, { disabled: isFieldDisabled, tabIndex: tabIndexValue, "data-testid": `field-toggle-${field.id}` }), jsxRuntime.jsx("span", { className: "text-sm text-foreground", style: {
18758
18869
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18759
18870
  }, children: field.props.label })] }));
18760
18871
  case 'multiselect':
@@ -18763,30 +18874,30 @@ function CanvasField({ field, rowId, columnId, isPreviewMode: externalPreviewMod
18763
18874
  setFieldValue(field.props.key, v);
18764
18875
  }, options: field.props.optionsString || [], disabled: isFieldDisabled, maxItems: field.props.multiSelectConfig?.maxItems, className: field.customStyle?.inputClassName }));
18765
18876
  case 'date':
18766
- return (jsxRuntime.jsx(Input, { type: "date", disabled: isFieldDisabled, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18877
+ return (jsxRuntime.jsx(Input, { type: "date", disabled: isFieldDisabled, autoFocus: isPreviewMode && field.props.autoFocus, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18767
18878
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18768
18879
  ...(field.customStyle?.backgroundColor ? { backgroundColor: field.customStyle.backgroundColor } : {}),
18769
- }, "data-testid": `field-date-${field.id}` }));
18880
+ }, "data-testid": `field-date-${field.id}`, "data-field-key": field.props.key }));
18770
18881
  case 'time':
18771
- return (jsxRuntime.jsx(Input, { type: "time", disabled: isFieldDisabled, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18882
+ return (jsxRuntime.jsx(Input, { type: "time", disabled: isFieldDisabled, autoFocus: isPreviewMode && field.props.autoFocus, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18772
18883
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18773
18884
  ...(field.customStyle?.backgroundColor ? { backgroundColor: field.customStyle.backgroundColor } : {}),
18774
- }, "data-testid": `field-time-${field.id}` }));
18885
+ }, "data-testid": `field-time-${field.id}`, "data-field-key": field.props.key }));
18775
18886
  case 'daterange':
18776
- return (jsxRuntime.jsxs("div", { className: `flex gap-2 items-center ${field.customStyle?.inputClassName || ''}`, children: [jsxRuntime.jsx(Input, { type: "date", disabled: isFieldDisabled, className: inputSize, style: {
18887
+ return (jsxRuntime.jsxs("div", { className: `flex gap-2 items-center ${field.customStyle?.inputClassName || ''}`, children: [jsxRuntime.jsx(Input, { type: "date", disabled: isFieldDisabled, tabIndex: tabIndexValue, className: inputSize, style: {
18777
18888
  ...(field.customStyle?.backgroundColor ? { backgroundColor: field.customStyle.backgroundColor } : {}),
18778
18889
  }, "data-testid": `field-daterange-start-${field.id}` }), jsxRuntime.jsx("span", { className: "text-muted-foreground", style: {
18779
18890
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18780
- }, children: "to" }), jsxRuntime.jsx(Input, { type: "date", disabled: isFieldDisabled, className: inputSize, style: {
18891
+ }, children: "to" }), jsxRuntime.jsx(Input, { type: "date", disabled: isFieldDisabled, tabIndex: tabIndexValue !== undefined ? tabIndexValue + 1 : undefined, className: inputSize, style: {
18781
18892
  ...(field.customStyle?.backgroundColor ? { backgroundColor: field.customStyle.backgroundColor } : {}),
18782
18893
  }, "data-testid": `field-daterange-end-${field.id}` })] }));
18783
18894
  case 'number':
18784
- return (jsxRuntime.jsx(Input, { type: "number", placeholder: field.props.placeholder, disabled: isFieldDisabled, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18895
+ return (jsxRuntime.jsx(Input, { type: "number", placeholder: field.props.placeholder, disabled: isFieldDisabled, autoFocus: isPreviewMode && field.props.autoFocus, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18785
18896
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18786
18897
  ...(field.customStyle?.backgroundColor ? { backgroundColor: field.customStyle.backgroundColor } : {}),
18787
- }, "data-testid": `field-number-${field.id}` }));
18898
+ }, "data-testid": `field-number-${field.id}`, "data-field-key": field.props.key }));
18788
18899
  case 'email':
18789
- return (jsxRuntime.jsx(Input, { type: "email", placeholder: field.props.placeholder, disabled: isFieldDisabled, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, style: {
18900
+ return (jsxRuntime.jsx(Input, { type: "email", placeholder: field.props.placeholder, disabled: isFieldDisabled, autoFocus: isPreviewMode && field.props.autoFocus, value: isPreviewMode ? localValue : (field.props.defaultValue || ''), onChange: (e) => isPreviewMode && handleChange(e.target.value), onBlur: handleBlur, tabIndex: tabIndexValue, className: `${inputSize} ${errorClass} ${field.customStyle?.inputClassName || ''}`, "data-field-key": field.props.key, style: {
18790
18901
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18791
18902
  ...(field.customStyle?.backgroundColor ? { backgroundColor: field.customStyle.backgroundColor } : {}),
18792
18903
  }, "data-testid": `field-email-${field.id}` }));
@@ -18812,7 +18923,7 @@ function CanvasField({ field, rowId, columnId, isPreviewMode: externalPreviewMod
18812
18923
  ...(field.customStyle?.backgroundColor ? { backgroundColor: field.customStyle.backgroundColor } : {}),
18813
18924
  }, "data-testid": `field-richtext-${field.id}` }));
18814
18925
  case 'autocomplete':
18815
- return (jsxRuntime.jsx("div", { className: `relative ${field.customStyle?.inputClassName || ''}`, children: jsxRuntime.jsx(Input, { placeholder: field.props.placeholder || 'Start typing...', disabled: isFieldDisabled, value: isPreviewMode ? localValue : '', onChange: (e) => isPreviewMode && handleChange(e.target.value), className: `${inputSize} ${errorClass}`, style: {
18926
+ return (jsxRuntime.jsx("div", { className: `relative ${field.customStyle?.inputClassName || ''}`, children: jsxRuntime.jsx(Input, { placeholder: field.props.placeholder || 'Start typing...', disabled: isFieldDisabled, value: isPreviewMode ? localValue : '', onChange: (e) => isPreviewMode && handleChange(e.target.value), tabIndex: tabIndexValue, className: `${inputSize} ${errorClass}`, style: {
18816
18927
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18817
18928
  ...(field.customStyle?.backgroundColor ? { backgroundColor: field.customStyle.backgroundColor } : {}),
18818
18929
  }, "data-testid": `field-autocomplete-${field.id}` }) }));
@@ -18820,7 +18931,7 @@ function CanvasField({ field, rowId, columnId, isPreviewMode: externalPreviewMod
18820
18931
  return (jsxRuntime.jsxs("div", { className: `space-y-2 ${field.customStyle?.inputClassName || ''}`, children: [jsxRuntime.jsx(Slider, { value: sliderValue, onValueChange: (v) => {
18821
18932
  setSliderValue(v);
18822
18933
  setFieldValue(field.props.key, v[0]);
18823
- }, min: field.validation?.min || 0, max: field.validation?.max || 100, step: 1, disabled: isFieldDisabled, "data-testid": `field-slider-${field.id}` }), jsxRuntime.jsxs("div", { className: "flex justify-between text-xs text-muted-foreground", children: [jsxRuntime.jsx("span", { children: field.validation?.min || 0 }), jsxRuntime.jsx("span", { className: "font-medium text-foreground", style: {
18934
+ }, min: field.validation?.min || 0, max: field.validation?.max || 100, step: 1, disabled: isFieldDisabled, tabIndex: tabIndexValue, "data-testid": `field-slider-${field.id}` }), jsxRuntime.jsxs("div", { className: "flex justify-between text-xs text-muted-foreground", children: [jsxRuntime.jsx("span", { children: field.validation?.min || 0 }), jsxRuntime.jsx("span", { className: "font-medium text-foreground", style: {
18824
18935
  ...(field.customStyle?.color ? { color: field.customStyle.color } : {}),
18825
18936
  }, children: sliderValue[0] }), jsxRuntime.jsx("span", { children: field.validation?.max || 100 })] })] }));
18826
18937
  case 'header':
@@ -19815,15 +19926,30 @@ function FieldProperties() {
19815
19926
  });
19816
19927
  }, className: "w-full gap-2", children: [jsxRuntime.jsx(Plus, { className: "h-4 w-4" }), "Add Attribute"] })] })] }), jsxRuntime.jsx(Separator$1, {}), hasOptions && (jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Options" }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [getOptionsArray().map((option, i) => (jsxRuntime.jsxs("div", { className: "flex gap-2", children: [jsxRuntime.jsx(Input, { value: option, onChange: (e) => handleUpdateOption(i, e.target.value), className: "flex-1", "data-testid": `input-option-${i}` }), jsxRuntime.jsx(Button, { variant: "outline", size: "icon", onClick: () => handleRemoveOption(i), "data-testid": `button-remove-option-${i}`, children: jsxRuntime.jsx(Trash2, { className: "h-4 w-4" }) })] }, i))), jsxRuntime.jsxs(Button, { variant: "outline", size: "sm", onClick: handleAddOption, className: "w-full gap-2", "data-testid": "button-add-option", children: [jsxRuntime.jsx(Plus, { className: "h-4 w-4" }), "Add Option"] })] })] })), field.type === 'button' && (jsxRuntime.jsxs("div", { className: "space-y-4", children: [jsxRuntime.jsx(Separator$1, {}), jsxRuntime.jsx("h4", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Button Settings" }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Action" }), jsxRuntime.jsxs(Select, { value: field.props.buttonConfig?.action || 'submit', onValueChange: (value) => handleUpdateProp('buttonConfig', { ...field.props.buttonConfig, action: value }), children: [jsxRuntime.jsx(SelectTrigger, { children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "submit", children: "Submit Form" }), jsxRuntime.jsx(SelectItem, { value: "reset", children: "Reset Form" }), jsxRuntime.jsx(SelectItem, { value: "custom", children: "Custom Action" })] })] })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Variant" }), jsxRuntime.jsxs(Select, { value: field.props.buttonConfig?.variant || 'default', onValueChange: (value) => handleUpdateProp('buttonConfig', { ...field.props.buttonConfig, variant: value }), children: [jsxRuntime.jsx(SelectTrigger, { children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "default", children: "Default" }), jsxRuntime.jsx(SelectItem, { value: "outline", children: "Outline" }), jsxRuntime.jsx(SelectItem, { value: "secondary", children: "Secondary" }), jsxRuntime.jsx(SelectItem, { value: "destructive", children: "Destructive" }), jsxRuntime.jsx(SelectItem, { value: "ghost", children: "Ghost" })] })] })] })] })), field.type === 'pattern' && (jsxRuntime.jsxs("div", { className: "space-y-4", children: [jsxRuntime.jsx(Separator$1, {}), jsxRuntime.jsx("h4", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Pattern Format" }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Format Pattern" }), jsxRuntime.jsx(Input, { value: field.props.patternConfig?.format || '(###) ###-####', onChange: (e) => handleUpdateProp('patternConfig', { ...field.props.patternConfig, format: e.target.value }), placeholder: "(###) ###-####" }), jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Use # for digit placeholders" })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Mask Character" }), jsxRuntime.jsx(Input, { value: field.props.patternConfig?.mask || '_', onChange: (e) => handleUpdateProp('patternConfig', { ...field.props.patternConfig, mask: e.target.value }), maxLength: 1 })] })] })), field.type === 'qrcode' && (jsxRuntime.jsxs("div", { className: "space-y-4", children: [jsxRuntime.jsx(Separator$1, {}), jsxRuntime.jsx("h4", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "QR Code Settings" }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "QR Value" }), jsxRuntime.jsx(Input, { value: field.props.qrCodeConfig?.value || 'https://example.com', onChange: (e) => handleUpdateProp('qrCodeConfig', { ...field.props.qrCodeConfig, value: e.target.value }), placeholder: "https://example.com" })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Size (px)" }), jsxRuntime.jsx(Input, { type: "number", value: field.props.qrCodeConfig?.size || 128, onChange: (e) => handleUpdateProp('qrCodeConfig', { ...field.props.qrCodeConfig, size: parseInt(e.target.value) }), min: 64, max: 512 })] })] })), field.type === 'container' && (jsxRuntime.jsxs("div", { className: "space-y-4", children: [jsxRuntime.jsx(Separator$1, {}), jsxRuntime.jsx("h4", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Container Settings" }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Direction" }), jsxRuntime.jsxs(Select, { value: field.props.containerConfig?.direction || 'row', onValueChange: (value) => handleUpdateProp('containerConfig', { ...field.props.containerConfig, direction: value }), children: [jsxRuntime.jsx(SelectTrigger, { "data-testid": "select-container-direction", children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "row", children: "Row (Horizontal)" }), jsxRuntime.jsx(SelectItem, { value: "column", children: "Column (Vertical)" })] })] })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Inner Field Size (Density)" }), jsxRuntime.jsxs(Select, { value: field.props.containerConfig?.fieldSize || 'normal', onValueChange: (value) => handleUpdateProp('containerConfig', { ...field.props.containerConfig, fieldSize: value }), children: [jsxRuntime.jsx(SelectTrigger, { "data-testid": "container-field-size", children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "compact", "data-testid": "field-size-compact", children: "Compact (Minimal)" }), jsxRuntime.jsx(SelectItem, { value: "normal", "data-testid": "field-size-normal", children: "Normal" }), jsxRuntime.jsx(SelectItem, { value: "comfortable", "data-testid": "field-size-comfortable", children: "Comfortable (Spacious)" })] })] }), jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Controls padding and font sizes for fields inside this container" })] }), jsxRuntime.jsx(Separator$1, {}), jsxRuntime.jsx("h5", { className: "text-xs font-medium text-muted-foreground", children: "Spacing & Layout" }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Gap (between items)" }), jsxRuntime.jsx(Input, { type: "number", value: field.props.containerConfig?.gap ?? 4, onChange: (e) => handleUpdateProp('containerConfig', { ...field.props.containerConfig, gap: parseInt(e.target.value) }), min: 0, max: 16 }), jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Space between child elements (0-16)" })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Padding (inner space)" }), jsxRuntime.jsx(Input, { type: "number", value: field.props.containerConfig?.padding ?? 4, onChange: (e) => handleUpdateProp('containerConfig', { ...field.props.containerConfig, padding: parseInt(e.target.value) }), min: 0, max: 16 }), jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Inner spacing around content (0-16)" })] }), jsxRuntime.jsx(Separator$1, {}), jsxRuntime.jsx("h5", { className: "text-xs font-medium text-muted-foreground", children: "Flex Properties" }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Justify Content" }), jsxRuntime.jsxs(Select, { value: field.props.containerConfig?.justifyContent || 'flex-start', onValueChange: (value) => handleUpdateProp('containerConfig', { ...field.props.containerConfig, justifyContent: value }), children: [jsxRuntime.jsx(SelectTrigger, { "data-testid": "select-justify-content", children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "flex-start", children: "Start" }), jsxRuntime.jsx(SelectItem, { value: "flex-end", children: "End" }), jsxRuntime.jsx(SelectItem, { value: "center", children: "Center" }), jsxRuntime.jsx(SelectItem, { value: "space-between", children: "Space Between" }), jsxRuntime.jsx(SelectItem, { value: "space-around", children: "Space Around" }), jsxRuntime.jsx(SelectItem, { value: "space-evenly", children: "Space Evenly" })] })] })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Align Items" }), jsxRuntime.jsxs(Select, { value: field.props.containerConfig?.alignItems || 'stretch', onValueChange: (value) => handleUpdateProp('containerConfig', { ...field.props.containerConfig, alignItems: value }), children: [jsxRuntime.jsx(SelectTrigger, { "data-testid": "select-align-items", children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "flex-start", children: "Start" }), jsxRuntime.jsx(SelectItem, { value: "flex-end", children: "End" }), jsxRuntime.jsx(SelectItem, { value: "center", children: "Center" }), jsxRuntime.jsx(SelectItem, { value: "stretch", children: "Stretch" }), jsxRuntime.jsx(SelectItem, { value: "baseline", children: "Baseline" })] })] })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Flex Wrap" }), jsxRuntime.jsxs(Select, { value: field.props.containerConfig?.flexWrap || 'wrap', onValueChange: (value) => handleUpdateProp('containerConfig', { ...field.props.containerConfig, flexWrap: value }), children: [jsxRuntime.jsx(SelectTrigger, { "data-testid": "select-flex-wrap", children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "wrap", children: "Wrap" }), jsxRuntime.jsx(SelectItem, { value: "nowrap", children: "No Wrap" })] })] })] }), jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Show Border" }), jsxRuntime.jsx(Switch, { checked: field.props.containerConfig?.border || false, onCheckedChange: (checked) => handleUpdateProp('containerConfig', { ...field.props.containerConfig, border: checked }) })] }), jsxRuntime.jsx(Separator$1, {}), jsxRuntime.jsxs("div", { className: "space-y-3", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsx("h5", { className: "text-sm font-medium", children: "Container Fields" }), jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [(field.props.containerConfig?.fields || []).length, " field(s)"] })] }), jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Drag fields onto the container. Set each field's width in its properties." })] })] })), field.type === 'table' && (jsxRuntime.jsxs("div", { className: "space-y-4 p-3 bg-muted/30 rounded-md", children: [jsxRuntime.jsx("h4", { className: "text-sm font-medium", children: "Table Configuration" }), jsxRuntime.jsxs("div", { className: "space-y-3", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Show Row Numbers" }), jsxRuntime.jsx(Switch, { checked: field.props.tableConfig?.showRowNumbers ?? true, onCheckedChange: (checked) => handleUpdateProp('tableConfig', { ...field.props.tableConfig, showRowNumbers: checked }) })] }), jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Allow Add Rows" }), jsxRuntime.jsx(Switch, { checked: field.props.tableConfig?.allowAddRows ?? true, onCheckedChange: (checked) => handleUpdateProp('tableConfig', { ...field.props.tableConfig, allowAddRows: checked }) })] }), jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Allow Delete Rows" }), jsxRuntime.jsx(Switch, { checked: field.props.tableConfig?.allowDeleteRows ?? false, onCheckedChange: (checked) => handleUpdateProp('tableConfig', { ...field.props.tableConfig, allowDeleteRows: checked }) })] }), jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Striped Rows" }), jsxRuntime.jsx(Switch, { checked: field.props.tableConfig?.striped ?? false, onCheckedChange: (checked) => handleUpdateProp('tableConfig', { ...field.props.tableConfig, striped: checked }) })] }), jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Bordered" }), jsxRuntime.jsx(Switch, { checked: field.props.tableConfig?.bordered ?? true, onCheckedChange: (checked) => handleUpdateProp('tableConfig', { ...field.props.tableConfig, bordered: checked }) })] }), jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Compact" }), jsxRuntime.jsx(Switch, { checked: field.props.tableConfig?.compact ?? false, onCheckedChange: (checked) => handleUpdateProp('tableConfig', { ...field.props.tableConfig, compact: checked }) })] })] }), jsxRuntime.jsx(Separator$1, {}), jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3", children: [jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Min Rows" }), jsxRuntime.jsx(Input, { type: "number", value: field.props.tableConfig?.minRows ?? 1, onChange: (e) => handleUpdateProp('tableConfig', { ...field.props.tableConfig, minRows: parseInt(e.target.value) || 1 }), min: 1, max: 100 })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Max Rows" }), jsxRuntime.jsx(Input, { type: "number", value: field.props.tableConfig?.maxRows ?? 100, onChange: (e) => handleUpdateProp('tableConfig', { ...field.props.tableConfig, maxRows: parseInt(e.target.value) || 100 }), min: 1, max: 1000 })] })] }), jsxRuntime.jsx(Separator$1, {}), jsxRuntime.jsxs("div", { className: "space-y-3", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsx("h5", { className: "text-sm font-medium", children: "Columns" }), jsxRuntime.jsxs(Button, { variant: "outline", size: "sm", onClick: () => {
19817
19928
  const currentColumns = field.props.tableConfig?.columns || [];
19929
+ const totalColumns = currentColumns.length + 1;
19930
+ const widthPerColumn = Math.floor(100 / totalColumns);
19931
+ const extraWidth = 100 % totalColumns;
19932
+ const updatedColumns = currentColumns.map((c, idx) => ({
19933
+ ...c,
19934
+ width: `${widthPerColumn + (idx < extraWidth ? 1 : 0)}%`
19935
+ }));
19818
19936
  const newColumn = {
19819
19937
  key: `col_${Date.now()}`,
19820
- label: `Column ${currentColumns.length + 1}`,
19938
+ label: `Column ${totalColumns}`,
19821
19939
  type: 'text',
19940
+ width: `${widthPerColumn}%`,
19822
19941
  };
19823
- handleUpdateProp('tableConfig', { ...field.props.tableConfig, columns: [...currentColumns, newColumn] });
19942
+ handleUpdateProp('tableConfig', { ...field.props.tableConfig, columns: [...updatedColumns, newColumn] });
19824
19943
  }, children: [jsxRuntime.jsx(Plus, { className: "h-4 w-4 mr-1" }), "Add Column"] })] }), (field.props.tableConfig?.columns || []).map((col, colIndex) => (jsxRuntime.jsxs("div", { className: "p-3 bg-background rounded-md border border-border space-y-3", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsxs("span", { className: "text-xs font-medium text-muted-foreground", children: ["Column ", colIndex + 1] }), jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", onClick: () => {
19825
19944
  const currentColumns = [...(field.props.tableConfig?.columns || [])];
19826
19945
  currentColumns.splice(colIndex, 1);
19946
+ if (currentColumns.length > 0) {
19947
+ const widthPerColumn = Math.floor(100 / currentColumns.length);
19948
+ const extraWidth = 100 % currentColumns.length;
19949
+ currentColumns.forEach((c, idx) => {
19950
+ currentColumns[idx] = { ...c, width: `${widthPerColumn + (idx < extraWidth ? 1 : 0)}%` };
19951
+ });
19952
+ }
19827
19953
  handleUpdateProp('tableConfig', { ...field.props.tableConfig, columns: currentColumns });
19828
19954
  }, children: jsxRuntime.jsx(Trash2, { className: "h-3 w-3 text-destructive" }) })] }), jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-2", children: [jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "Key" }), jsxRuntime.jsx(Input, { value: col.key, onChange: (e) => {
19829
19955
  const currentColumns = [...(field.props.tableConfig?.columns || [])];
@@ -19837,11 +19963,12 @@ function FieldProperties() {
19837
19963
  const currentColumns = [...(field.props.tableConfig?.columns || [])];
19838
19964
  currentColumns[colIndex] = { ...col, type: value };
19839
19965
  handleUpdateProp('tableConfig', { ...field.props.tableConfig, columns: currentColumns });
19840
- }, children: [jsxRuntime.jsx(SelectTrigger, { className: "h-8 text-xs", children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "text", children: "Text" }), jsxRuntime.jsx(SelectItem, { value: "number", children: "Number" }), jsxRuntime.jsx(SelectItem, { value: "email", children: "Email" }), jsxRuntime.jsx(SelectItem, { value: "date", children: "Date" }), jsxRuntime.jsx(SelectItem, { value: "select", children: "Select" }), jsxRuntime.jsx(SelectItem, { value: "checkbox", children: "Checkbox" })] })] })] }), jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "Width" }), jsxRuntime.jsx(Input, { value: col.width || '', onChange: (e) => {
19966
+ }, children: [jsxRuntime.jsx(SelectTrigger, { className: "h-8 text-xs", children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "text", children: "Text" }), jsxRuntime.jsx(SelectItem, { value: "number", children: "Number" }), jsxRuntime.jsx(SelectItem, { value: "email", children: "Email" }), jsxRuntime.jsx(SelectItem, { value: "date", children: "Date" }), jsxRuntime.jsx(SelectItem, { value: "select", children: "Select" }), jsxRuntime.jsx(SelectItem, { value: "checkbox", children: "Checkbox" })] })] })] }), jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "%Width" }), jsxRuntime.jsx(Input, { type: "number", value: col.width ? parseInt(col.width) || '' : '', onChange: (e) => {
19841
19967
  const currentColumns = [...(field.props.tableConfig?.columns || [])];
19842
- currentColumns[colIndex] = { ...col, width: e.target.value };
19968
+ const newWidth = parseInt(e.target.value) || 0;
19969
+ currentColumns[colIndex] = { ...col, width: newWidth > 0 ? `${newWidth}%` : '' };
19843
19970
  handleUpdateProp('tableConfig', { ...field.props.tableConfig, columns: currentColumns });
19844
- }, placeholder: "auto", className: "text-xs h-8" })] }), jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "Required" }), jsxRuntime.jsx("div", { className: "flex items-center h-8", children: jsxRuntime.jsx(Switch, { checked: col.required || false, onCheckedChange: (checked) => {
19971
+ }, placeholder: "25", min: 1, max: 100, className: "text-xs h-8" })] }), jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "Required" }), jsxRuntime.jsx("div", { className: "flex items-center h-8", children: jsxRuntime.jsx(Switch, { checked: col.required || false, onCheckedChange: (checked) => {
19845
19972
  const currentColumns = [...(field.props.tableConfig?.columns || [])];
19846
19973
  currentColumns[colIndex] = { ...col, required: checked };
19847
19974
  handleUpdateProp('tableConfig', { ...field.props.tableConfig, columns: currentColumns });
@@ -19869,7 +19996,12 @@ function FieldProperties() {
19869
19996
  currentOptions.splice(optIndex, 1);
19870
19997
  currentColumns[colIndex] = { ...col, options: currentOptions };
19871
19998
  handleUpdateProp('tableConfig', { ...field.props.tableConfig, columns: currentColumns });
19872
- }, children: jsxRuntime.jsx(Trash2, { className: "h-3 w-3 text-destructive" }) })] }, optIndex))), (!col.options || col.options.length === 0) && (jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground italic", children: "Hen\u00FCz se\u00E7enek eklenmedi" }))] }))] }, col.key)))] })] })), (() => {
19999
+ }, children: jsxRuntime.jsx(Trash2, { className: "h-3 w-3 text-destructive" }) })] }, optIndex))), (!col.options || col.options.length === 0) && (jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground italic", children: "Hen\u00FCz se\u00E7enek eklenmedi" }))] }))] }, `col-${colIndex}`))), (field.props.tableConfig?.columns || []).length > 0 && (() => {
20000
+ const columns = field.props.tableConfig?.columns || [];
20001
+ const totalWidth = columns.reduce((sum, c) => sum + (parseInt(c.width || '0') || 0), 0);
20002
+ const isValid = totalWidth === 100;
20003
+ return (jsxRuntime.jsxs("div", { className: `flex items-center justify-between p-2 rounded-md text-xs ${isValid ? 'bg-green-500/10 text-green-600 dark:text-green-400' : 'bg-destructive/10 text-destructive'}`, children: [jsxRuntime.jsxs("span", { className: "font-medium", children: ["Total Width: ", totalWidth, "%"] }), !isValid && (jsxRuntime.jsx("span", { children: "Must equal 100%" })), isValid && (jsxRuntime.jsx("span", { children: "\u2713" }))] }));
20004
+ })()] })] })), (() => {
19873
20005
  const staticDisplayTypes = ['spacer', 'divider', 'header', 'subheader', 'label', 'paragraph', 'alert', 'image', 'qrcode', 'button'];
19874
20006
  if (staticDisplayTypes.includes(field.type))
19875
20007
  return null;
@@ -19880,7 +20012,7 @@ function FieldProperties() {
19880
20012
  return (jsxRuntime.jsx("div", { className: "text-center py-8 text-muted-foreground", children: jsxRuntime.jsx("p", { className: "text-sm", children: "Bu bile\u015Fen i\u00E7in do\u011Frulama kurallar\u0131 gerekli de\u011Fil." }) }));
19881
20013
  }
19882
20014
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-4", children: [jsxRuntime.jsx(Settings2, { className: "h-4 w-4 text-muted-foreground" }), jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Validation Rules" })] }), jsxRuntime.jsxs("div", { className: "space-y-3 pb-4", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Auto Validate" }), jsxRuntime.jsx(Switch, { checked: field.validation?.autoValidate || false, onCheckedChange: (checked) => handleUpdateValidation('autoValidate', checked) })] }), jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Validate while typing" }), jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Validate on Blur" }), jsxRuntime.jsx(Switch, { checked: field.validation?.validateOnBlur ?? true, onCheckedChange: (checked) => handleUpdateValidation('validateOnBlur', checked) })] }), jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Validate on Change" }), jsxRuntime.jsx(Switch, { checked: field.validation?.validateOnChange || false, onCheckedChange: (checked) => handleUpdateValidation('validateOnChange', checked) })] })] }), jsxRuntime.jsx(Separator$1, {}), jsxRuntime.jsxs("div", { className: "space-y-2 pt-4", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Validation Type" }), jsxRuntime.jsxs(Select, { value: field.validation?.validationType || '', onValueChange: (value) => handleUpdateValidation('validationType', value || undefined), children: [jsxRuntime.jsx(SelectTrigger, { children: jsxRuntime.jsx(SelectValue, { placeholder: "None" }) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "email", children: "Email" }), jsxRuntime.jsx(SelectItem, { value: "url", children: "URL" }), jsxRuntime.jsx(SelectItem, { value: "phone", children: "Phone" }), jsxRuntime.jsx(SelectItem, { value: "custom", children: "Custom" })] })] })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Min Length" }), jsxRuntime.jsx(Input, { type: "number", min: 0, value: field.validation?.minLength || '', onChange: (e) => handleUpdateValidation('minLength', e.target.value ? parseInt(e.target.value) : undefined), "data-testid": "input-min-length" })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Max Length" }), jsxRuntime.jsx(Input, { type: "number", min: 0, value: field.validation?.maxLength || '', onChange: (e) => handleUpdateValidation('maxLength', e.target.value ? parseInt(e.target.value) : undefined), "data-testid": "input-max-length" })] }), ['number', 'slider'].includes(field.type) && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Min Value" }), jsxRuntime.jsx(Input, { type: "number", value: field.validation?.min ?? '', onChange: (e) => handleUpdateValidation('min', e.target.value ? parseFloat(e.target.value) : undefined), "data-testid": "input-min-value" })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Max Value" }), jsxRuntime.jsx(Input, { type: "number", value: field.validation?.max ?? '', onChange: (e) => handleUpdateValidation('max', e.target.value ? parseFloat(e.target.value) : undefined), "data-testid": "input-max-value" })] })] })), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Pattern (Regex)" }), jsxRuntime.jsx(Input, { value: field.validation?.pattern || '', onChange: (e) => handleUpdateValidation('pattern', e.target.value || undefined), placeholder: "^[a-zA-Z]+$", className: "font-mono text-sm", "data-testid": "input-pattern" })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Custom Error Message" }), jsxRuntime.jsx(Input, { value: field.validation?.errorMessage || '', onChange: (e) => handleUpdateValidation('errorMessage', e.target.value || undefined), placeholder: "Please enter a valid value", "data-testid": "input-error-message" })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Custom Validation (JS)" }), jsxRuntime.jsx(Textarea, { value: field.validation?.customValidation || '', onChange: (e) => handleUpdateValidation('customValidation', e.target.value || undefined), placeholder: "return value.length > 5;", className: "font-mono text-sm min-h-[80px]" }), jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Write JavaScript that returns true for valid values" })] }), jsxRuntime.jsx(Separator$1, {}), jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(Zap, { className: "h-4 w-4 text-muted-foreground" }), jsxRuntime.jsx(Label$2, { className: "text-sm font-medium", children: "Conditional Logic" })] }), jsxRuntime.jsx(Switch, { checked: field.conditionalLogic?.enabled || false, onCheckedChange: (checked) => handleUpdateConditionalLogic({ enabled: checked }) })] }), field.conditionalLogic?.enabled && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "Action" }), jsxRuntime.jsxs(Select, { value: field.conditionalLogic?.action || 'show', onValueChange: (value) => handleUpdateConditionalLogic({ action: value }), children: [jsxRuntime.jsx(SelectTrigger, { children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "show", children: "Show this field" }), jsxRuntime.jsx(SelectItem, { value: "hide", children: "Hide this field" }), jsxRuntime.jsx(SelectItem, { value: "enable", children: "Enable this field" }), jsxRuntime.jsx(SelectItem, { value: "disable", children: "Disable this field" }), jsxRuntime.jsx(SelectItem, { value: "require", children: "Make required" })] })] })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-sm", children: "When" }), jsxRuntime.jsxs(Select, { value: field.conditionalLogic?.logicType || 'all', onValueChange: (value) => handleUpdateConditionalLogic({ logicType: value }), children: [jsxRuntime.jsx(SelectTrigger, { children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "all", children: "All conditions are met" }), jsxRuntime.jsx(SelectItem, { value: "any", children: "Any condition is met" })] })] })] }), jsxRuntime.jsx(Separator$1, {}), jsxRuntime.jsxs("div", { className: "space-y-3", children: [jsxRuntime.jsx(Label$2, { className: "text-sm font-medium", children: "Conditions" }), (field.conditionalLogic?.conditions || []).map((condition, index) => (jsxRuntime.jsxs("div", { className: "p-3 border border-border rounded-md space-y-3", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsxs(Badge, { variant: "secondary", children: ["Condition ", index + 1] }), jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", onClick: () => removeCondition(index), children: jsxRuntime.jsx(Trash2, { className: "h-4 w-4" }) })] }), jsxRuntime.jsxs(Select, { value: condition.fieldKey, onValueChange: (value) => updateCondition(index, { fieldKey: value }), children: [jsxRuntime.jsx(SelectTrigger, { children: jsxRuntime.jsx(SelectValue, { placeholder: "Select field..." }) }), jsxRuntime.jsx(SelectContent, { children: allFields.map((f) => (jsxRuntime.jsxs(SelectItem, { value: f.props.key, children: [f.props.label, " (", f.props.key, ")"] }, f.id))) })] }), jsxRuntime.jsxs(Select, { value: condition.operator, onValueChange: (value) => updateCondition(index, { operator: value }), children: [jsxRuntime.jsx(SelectTrigger, { children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "equals", children: "Equals" }), jsxRuntime.jsx(SelectItem, { value: "notEquals", children: "Not equals" }), jsxRuntime.jsx(SelectItem, { value: "contains", children: "Contains" }), jsxRuntime.jsx(SelectItem, { value: "notContains", children: "Does not contain" }), jsxRuntime.jsx(SelectItem, { value: "greaterThan", children: "Greater than" }), jsxRuntime.jsx(SelectItem, { value: "lessThan", children: "Less than" }), jsxRuntime.jsx(SelectItem, { value: "isEmpty", children: "Is empty" }), jsxRuntime.jsx(SelectItem, { value: "isNotEmpty", children: "Is not empty" }), jsxRuntime.jsx(SelectItem, { value: "startsWith", children: "Starts with" }), jsxRuntime.jsx(SelectItem, { value: "endsWith", children: "Ends with" })] })] }), !['isEmpty', 'isNotEmpty'].includes(condition.operator) && (jsxRuntime.jsx(Input, { value: condition.value || '', onChange: (e) => updateCondition(index, { value: e.target.value }), placeholder: "Value..." }))] }, index))), jsxRuntime.jsxs(Button, { variant: "outline", size: "sm", onClick: addCondition, className: "w-full gap-2", children: [jsxRuntime.jsx(Plus, { className: "h-4 w-4" }), "Add Condition"] })] })] }))] }));
19883
- })() }), jsxRuntime.jsxs(TabsContent, { value: "actions", className: "space-y-4 mt-0", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-4", children: [jsxRuntime.jsx(MousePointerClick, { className: "h-4 w-4 text-muted-foreground" }), jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Event Handlers" })] }), jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mb-4", children: "Add actions that trigger on specific events like click, change, focus, or blur." }), ['onClick', 'onChange', 'onFocus', 'onBlur'].map((eventType) => (jsxRuntime.jsxs(Collapsible, { className: "border border-border rounded-md", children: [jsxRuntime.jsxs(CollapsibleTrigger, { className: "flex items-center justify-between w-full p-3 hover:bg-muted/50", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(Play, { className: "h-3 w-3 text-muted-foreground" }), jsxRuntime.jsx("span", { className: "text-sm font-medium", children: eventType }), (field.events?.[eventType]?.length || 0) > 0 && (jsxRuntime.jsx(Badge, { variant: "secondary", className: "text-xs", children: field.events?.[eventType]?.length }))] }), jsxRuntime.jsx(ChevronDown, { className: "h-4 w-4 text-muted-foreground" })] }), jsxRuntime.jsxs(CollapsibleContent, { className: "p-3 pt-0 space-y-3", children: [(field.events?.[eventType] || []).map((action, index) => (jsxRuntime.jsxs("div", { className: "p-3 border border-border rounded-md space-y-3 bg-muted/30", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsxs(Badge, { variant: "outline", children: ["Action ", index + 1] }), jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", onClick: () => removeEventAction(eventType, index), children: jsxRuntime.jsx(Trash2, { className: "h-4 w-4" }) })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "Type" }), jsxRuntime.jsxs(Select, { value: action.type, onValueChange: (value) => updateEventAction(eventType, index, { type: value }), children: [jsxRuntime.jsx(SelectTrigger, { children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "common", children: "Common Action" }), jsxRuntime.jsx(SelectItem, { value: "code", children: "Code Action" }), jsxRuntime.jsx(SelectItem, { value: "custom", children: "Custom Action" })] })] })] }), action.type === 'common' && (jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "Action" }), jsxRuntime.jsxs(Select, { value: action.name, onValueChange: (value) => updateEventAction(eventType, index, { name: value }), children: [jsxRuntime.jsx(SelectTrigger, { children: jsxRuntime.jsx(SelectValue, { placeholder: "Select action..." }) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "validate", children: "Validate Form" }), jsxRuntime.jsx(SelectItem, { value: "reset", children: "Reset Form" }), jsxRuntime.jsx(SelectItem, { value: "submit", children: "Submit Form" }), jsxRuntime.jsx(SelectItem, { value: "clearField", children: "Clear This Field" }), jsxRuntime.jsx(SelectItem, { value: "focusField", children: "Focus Field" }), jsxRuntime.jsx(SelectItem, { value: "showMessage", children: "Show Message" })] })] })] })), action.type === 'code' && (jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "JavaScript Code" }), jsxRuntime.jsx(Textarea, { value: action.code || '', onChange: (e) => updateEventAction(eventType, index, { code: e.target.value }), placeholder: "console.log('Action triggered');", className: "font-mono text-xs min-h-[60px]" })] })), action.type === 'custom' && (jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "Custom Action Name" }), jsxRuntime.jsx(Input, { value: action.name, onChange: (e) => updateEventAction(eventType, index, { name: e.target.value }), placeholder: "myCustomAction", className: "font-mono text-sm" }), jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "This will call the custom action passed to FormViewer" })] }))] }, index))), jsxRuntime.jsxs(Button, { variant: "outline", size: "sm", onClick: () => addEventAction(eventType), className: "w-full gap-2", children: [jsxRuntime.jsx(Plus, { className: "h-4 w-4" }), "Add Action"] })] })] }, eventType)))] }), jsxRuntime.jsxs(TabsContent, { value: "style", className: "space-y-4 mt-0", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-4", children: [jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "For device" }), jsxRuntime.jsxs(Select, { value: field.customStyle?.deviceTarget || 'any', onValueChange: (value) => handleUpdateCustomStyle('deviceTarget', value), children: [jsxRuntime.jsx(SelectTrigger, { className: "w-32", children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "any", children: "Any" }), jsxRuntime.jsx(SelectItem, { value: "mobile", children: "Mobile" }), jsxRuntime.jsx(SelectItem, { value: "tablet", children: "Tablet" }), jsxRuntime.jsx(SelectItem, { value: "desktop", children: "Desktop" })] })] })] }), jsxRuntime.jsxs("div", { className: "space-y-4", children: [jsxRuntime.jsx("h4", { className: "text-sm font-semibold", children: "Component" }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(Paintbrush, { className: "h-4 w-4 text-muted-foreground" }), jsxRuntime.jsx(Label$2, { className: "text-sm w-24", children: "Class Name" }), jsxRuntime.jsx(Input, { value: field.customStyle?.inputClassName || '', onChange: (e) => handleUpdateCustomStyle('inputClassName', e.target.value), placeholder: "", className: "font-mono text-sm flex-1" }), field.customStyle?.inputClassName && (jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", onClick: () => handleUpdateCustomStyle('inputClassName', ''), children: jsxRuntime.jsx(Trash2, { className: "h-4 w-4" }) }))] })] }), jsxRuntime.jsx(Separator$1, {}), jsxRuntime.jsxs("div", { className: "space-y-4", children: [jsxRuntime.jsx("h4", { className: "text-sm font-semibold", children: "Wrapper" }), jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3", children: [jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "Width" }), jsxRuntime.jsxs("div", { className: "flex gap-1", children: [jsxRuntime.jsx(Input, { type: "number", value: field.customStyle?.width?.value ?? 100, onChange: (e) => handleUpdateCustomStyle('width', {
20015
+ })() }), jsxRuntime.jsxs(TabsContent, { value: "actions", className: "space-y-4 mt-0", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-4", children: [jsxRuntime.jsx(MousePointerClick, { className: "h-4 w-4 text-muted-foreground" }), jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Event Handlers" })] }), jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mb-4", children: "Add actions that trigger on specific events like click, change, focus, or blur." }), ['onClick', 'onChange', 'onFocus', 'onBlur'].map((eventType) => (jsxRuntime.jsxs(Collapsible, { className: "border border-border rounded-md", children: [jsxRuntime.jsxs(CollapsibleTrigger, { className: "flex items-center justify-between w-full p-3 hover:bg-muted/50", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(Play, { className: "h-3 w-3 text-muted-foreground" }), jsxRuntime.jsx("span", { className: "text-sm font-medium", children: eventType }), (field.events?.[eventType]?.length || 0) > 0 && (jsxRuntime.jsx(Badge, { variant: "secondary", className: "text-xs", children: field.events?.[eventType]?.length }))] }), jsxRuntime.jsx(ChevronDown, { className: "h-4 w-4 text-muted-foreground" })] }), jsxRuntime.jsxs(CollapsibleContent, { className: "p-3 pt-0 space-y-3", children: [(field.events?.[eventType] || []).map((action, index) => (jsxRuntime.jsxs("div", { className: "p-3 border border-border rounded-md space-y-3 bg-muted/30", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsxs(Badge, { variant: "outline", children: ["Action ", index + 1] }), jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", onClick: () => removeEventAction(eventType, index), children: jsxRuntime.jsx(Trash2, { className: "h-4 w-4" }) })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "Type" }), jsxRuntime.jsxs(Select, { value: action.type, onValueChange: (value) => updateEventAction(eventType, index, { type: value }), children: [jsxRuntime.jsx(SelectTrigger, { children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "common", children: "Common Action" }), jsxRuntime.jsx(SelectItem, { value: "code", children: "Code Action" }), jsxRuntime.jsx(SelectItem, { value: "custom", children: "Custom Action" })] })] })] }), action.type === 'common' && (jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "Action" }), jsxRuntime.jsxs(Select, { value: action.name, onValueChange: (value) => updateEventAction(eventType, index, { name: value }), children: [jsxRuntime.jsx(SelectTrigger, { children: jsxRuntime.jsx(SelectValue, { placeholder: "Select action..." }) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "validate", children: "Validate Form" }), jsxRuntime.jsx(SelectItem, { value: "reset", children: "Reset Form" }), jsxRuntime.jsx(SelectItem, { value: "submit", children: "Submit Form" }), jsxRuntime.jsx(SelectItem, { value: "clearField", children: "Clear This Field" }), jsxRuntime.jsx(SelectItem, { value: "focusField", children: "Focus Field" }), jsxRuntime.jsx(SelectItem, { value: "showMessage", children: "Show Message" })] })] }), action.name === 'focusField' && (jsxRuntime.jsxs("div", { className: "space-y-2 mt-2", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "Target Field" }), jsxRuntime.jsxs(Select, { value: action.args?.targetFieldKey || '', onValueChange: (value) => updateEventAction(eventType, index, { args: { ...action.args, targetFieldKey: value } }), children: [jsxRuntime.jsx(SelectTrigger, { children: jsxRuntime.jsx(SelectValue, { placeholder: "Select field to focus..." }) }), jsxRuntime.jsx(SelectContent, { children: allFields.map((f) => (jsxRuntime.jsx(SelectItem, { value: f.props.key, children: f.props.label || f.props.key }, f.id))) })] })] })), action.name === 'showMessage' && (jsxRuntime.jsxs("div", { className: "space-y-2 mt-2", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "Message" }), jsxRuntime.jsx(Input, { value: action.args?.message || '', onChange: (e) => updateEventAction(eventType, index, { args: { ...action.args, message: e.target.value } }), placeholder: "Enter message to show..." })] }))] })), action.type === 'code' && (jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "JavaScript Code" }), jsxRuntime.jsx(Textarea, { value: action.code || '', onChange: (e) => updateEventAction(eventType, index, { code: e.target.value }), placeholder: "console.log('Action triggered');", className: "font-mono text-xs min-h-[60px]" })] })), action.type === 'custom' && (jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "Custom Action Name" }), jsxRuntime.jsx(Input, { value: action.name, onChange: (e) => updateEventAction(eventType, index, { name: e.target.value }), placeholder: "myCustomAction", className: "font-mono text-sm" }), jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "This will call the custom action passed to FormViewer" })] }))] }, index))), jsxRuntime.jsxs(Button, { variant: "outline", size: "sm", onClick: () => addEventAction(eventType), className: "w-full gap-2", children: [jsxRuntime.jsx(Plus, { className: "h-4 w-4" }), "Add Action"] })] })] }, eventType)))] }), jsxRuntime.jsxs(TabsContent, { value: "style", className: "space-y-4 mt-0", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-4", children: [jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "For device" }), jsxRuntime.jsxs(Select, { value: field.customStyle?.deviceTarget || 'any', onValueChange: (value) => handleUpdateCustomStyle('deviceTarget', value), children: [jsxRuntime.jsx(SelectTrigger, { className: "w-32", children: jsxRuntime.jsx(SelectValue, {}) }), jsxRuntime.jsxs(SelectContent, { children: [jsxRuntime.jsx(SelectItem, { value: "any", children: "Any" }), jsxRuntime.jsx(SelectItem, { value: "mobile", children: "Mobile" }), jsxRuntime.jsx(SelectItem, { value: "tablet", children: "Tablet" }), jsxRuntime.jsx(SelectItem, { value: "desktop", children: "Desktop" })] })] })] }), jsxRuntime.jsxs("div", { className: "space-y-4", children: [jsxRuntime.jsx("h4", { className: "text-sm font-semibold", children: "Component" }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(Paintbrush, { className: "h-4 w-4 text-muted-foreground" }), jsxRuntime.jsx(Label$2, { className: "text-sm w-24", children: "Class Name" }), jsxRuntime.jsx(Input, { value: field.customStyle?.inputClassName || '', onChange: (e) => handleUpdateCustomStyle('inputClassName', e.target.value), placeholder: "", className: "font-mono text-sm flex-1" }), field.customStyle?.inputClassName && (jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", onClick: () => handleUpdateCustomStyle('inputClassName', ''), children: jsxRuntime.jsx(Trash2, { className: "h-4 w-4" }) }))] })] }), jsxRuntime.jsx(Separator$1, {}), jsxRuntime.jsxs("div", { className: "space-y-4", children: [jsxRuntime.jsx("h4", { className: "text-sm font-semibold", children: "Wrapper" }), jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3", children: [jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsx(Label$2, { className: "text-xs", children: "Width" }), jsxRuntime.jsxs("div", { className: "flex gap-1", children: [jsxRuntime.jsx(Input, { type: "number", value: field.customStyle?.width?.value ?? 100, onChange: (e) => handleUpdateCustomStyle('width', {
19884
20016
  ...field.customStyle?.width,
19885
20017
  value: parseInt(e.target.value) || 100
19886
20018
  }), className: "w-16" }), jsxRuntime.jsxs(Select, { value: field.customStyle?.width?.unit || '%', onValueChange: (value) => handleUpdateCustomStyle('width', {
@@ -25054,12 +25186,12 @@ function DraggableComponent({ type, label, icon, isCollapsed }) {
25054
25186
  }
25055
25187
  const fieldCategories = {
25056
25188
  basic: { label: 'Basic Fields', types: FIELD_TYPES.filter(f => f.category === 'basic') },
25057
- selection: { label: 'Selection Fields', types: FIELD_TYPES.filter(f => f.category === 'selection') },
25058
25189
  advanced: { label: 'Advanced Fields', types: FIELD_TYPES.filter(f => f.category === 'advanced') },
25190
+ selection: { label: 'Selection Fields', types: FIELD_TYPES.filter(f => f.category === 'selection') },
25059
25191
  };
25060
25192
  function ComponentLibrary({ isCollapsed = false, onToggleCollapse }) {
25061
25193
  if (isCollapsed) {
25062
- return (jsxRuntime.jsxs("aside", { className: "w-[60px] border-r border-border bg-card shrink-0 flex flex-col", children: [jsxRuntime.jsx("div", { className: "p-2 border-b border-border", children: jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", onClick: onToggleCollapse, "data-testid": "button-expand-sidebar", children: jsxRuntime.jsx(PanelLeft, { className: "h-4 w-4" }) }) }), jsxRuntime.jsx(ScrollArea, { className: "flex-1", children: jsxRuntime.jsxs("div", { className: "p-2 space-y-4", children: [jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("p", { className: "text-[10px] font-semibold uppercase text-muted-foreground text-center cursor-default", children: "LY" }) }), jsxRuntime.jsx(TooltipContent, { side: "right", children: "Layout" })] }), jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-1", children: STRUCTURE_TYPES.map((item) => (jsxRuntime.jsx(DraggableComponent, { type: item.type, label: item.label, icon: item.icon, isCollapsed: true }, item.type))) })] }), jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("p", { className: "text-[10px] font-semibold uppercase text-muted-foreground text-center cursor-default", children: "BF" }) }), jsxRuntime.jsx(TooltipContent, { side: "right", children: "Basic Fields" })] }), jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-1", children: fieldCategories.basic.types.map((item) => (jsxRuntime.jsx(DraggableComponent, { type: item.type, label: item.label, icon: item.icon, isCollapsed: true }, item.type))) })] }), jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("p", { className: "text-[10px] font-semibold uppercase text-muted-foreground text-center cursor-default", children: "SF" }) }), jsxRuntime.jsx(TooltipContent, { side: "right", children: "Selection Fields" })] }), jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-1", children: fieldCategories.selection.types.map((item) => (jsxRuntime.jsx(DraggableComponent, { type: item.type, label: item.label, icon: item.icon, isCollapsed: true }, item.type))) })] }), jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("p", { className: "text-[10px] font-semibold uppercase text-muted-foreground text-center cursor-default", children: "AD" }) }), jsxRuntime.jsx(TooltipContent, { side: "right", children: "Advanced Fields" })] }), jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-1", children: fieldCategories.advanced.types.map((item) => (jsxRuntime.jsx(DraggableComponent, { type: item.type, label: item.label, icon: item.icon, isCollapsed: true }, item.type))) })] }), jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("p", { className: "text-[10px] font-semibold uppercase text-muted-foreground text-center cursor-default", children: "EL" }) }), jsxRuntime.jsx(TooltipContent, { side: "right", children: "Static Elements" })] }), jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-1", children: STATIC_TYPES.map((item) => (jsxRuntime.jsx(DraggableComponent, { type: item.type, label: item.label, icon: item.icon, isCollapsed: true }, item.type))) })] })] }) })] }));
25194
+ return (jsxRuntime.jsxs("aside", { className: "w-[60px] border-r border-border bg-card shrink-0 flex flex-col", children: [jsxRuntime.jsx("div", { className: "p-2 border-b border-border", children: jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", onClick: onToggleCollapse, "data-testid": "button-expand-sidebar", children: jsxRuntime.jsx(PanelLeft, { className: "h-4 w-4" }) }) }), jsxRuntime.jsx(ScrollArea, { className: "flex-1", children: jsxRuntime.jsxs("div", { className: "p-2 space-y-4", children: [jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("p", { className: "text-[10px] font-semibold uppercase text-muted-foreground text-center cursor-default", children: "LY" }) }), jsxRuntime.jsx(TooltipContent, { side: "right", children: "Layout" })] }), jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-1", children: STRUCTURE_TYPES.map((item) => (jsxRuntime.jsx(DraggableComponent, { type: item.type, label: item.label, icon: item.icon, isCollapsed: true }, item.type))) })] }), jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("p", { className: "text-[10px] font-semibold uppercase text-muted-foreground text-center cursor-default", children: "BF" }) }), jsxRuntime.jsx(TooltipContent, { side: "right", children: "Basic Fields" })] }), jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-1", children: fieldCategories.basic.types.map((item) => (jsxRuntime.jsx(DraggableComponent, { type: item.type, label: item.label, icon: item.icon, isCollapsed: true }, item.type))) })] }), jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("p", { className: "text-[10px] font-semibold uppercase text-muted-foreground text-center cursor-default", children: "AD" }) }), jsxRuntime.jsx(TooltipContent, { side: "right", children: "Advanced Fields" })] }), jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-1", children: fieldCategories.advanced.types.map((item) => (jsxRuntime.jsx(DraggableComponent, { type: item.type, label: item.label, icon: item.icon, isCollapsed: true }, item.type))) })] }), jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("p", { className: "text-[10px] font-semibold uppercase text-muted-foreground text-center cursor-default", children: "SF" }) }), jsxRuntime.jsx(TooltipContent, { side: "right", children: "Selection Fields" })] }), jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-1", children: fieldCategories.selection.types.map((item) => (jsxRuntime.jsx(DraggableComponent, { type: item.type, label: item.label, icon: item.icon, isCollapsed: true }, item.type))) })] }), jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx("p", { className: "text-[10px] font-semibold uppercase text-muted-foreground text-center cursor-default", children: "EL" }) }), jsxRuntime.jsx(TooltipContent, { side: "right", children: "Static Elements" })] }), jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-1", children: STATIC_TYPES.map((item) => (jsxRuntime.jsx(DraggableComponent, { type: item.type, label: item.label, icon: item.icon, isCollapsed: true }, item.type))) })] })] }) })] }));
25063
25195
  }
25064
25196
  return (jsxRuntime.jsxs("aside", { className: "w-[200px] border-r border-border bg-card shrink-0 flex flex-col", children: [jsxRuntime.jsxs("div", { className: "p-2 border-b border-border flex items-center justify-between gap-2", children: [jsxRuntime.jsx("span", { className: "text-sm font-medium text-foreground pl-1", children: "Components" }), jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6 shrink-0", onClick: onToggleCollapse, "data-testid": "button-collapse-sidebar", children: jsxRuntime.jsx(PanelLeftClose, { className: "h-3.5 w-3.5" }) })] }), jsxRuntime.jsx(ScrollArea, { className: "flex-1", children: jsxRuntime.jsx("div", { className: "p-2", children: jsxRuntime.jsxs(Accordion, { type: "multiple", defaultValue: ['structure', 'basic', 'selection', 'advanced', 'static'], className: "w-full", children: [jsxRuntime.jsxs(AccordionItem, { value: "structure", className: "border-b-0 bg-muted/50 rounded-md mb-1 px-2", children: [jsxRuntime.jsxs(AccordionTrigger, { className: "py-1.5 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground hover:no-underline", children: ["Layout (", STRUCTURE_TYPES.length, ")"] }), jsxRuntime.jsx(AccordionContent, { children: jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-1 pb-2", children: STRUCTURE_TYPES.map((item) => (jsxRuntime.jsx(DraggableComponent, { type: item.type, label: item.label, icon: item.icon }, item.type))) }) })] }), Object.entries(fieldCategories).map(([key, category]) => (jsxRuntime.jsxs(AccordionItem, { value: key, className: "border-b-0 bg-background dark:bg-card rounded-md mb-1 px-2", children: [jsxRuntime.jsxs(AccordionTrigger, { className: "py-1.5 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground hover:no-underline", children: [category.label.split(' ')[0], " (", category.types.length, ")"] }), jsxRuntime.jsx(AccordionContent, { children: jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-1 pb-2", children: category.types.map((item) => (jsxRuntime.jsx(DraggableComponent, { type: item.type, label: item.label, icon: item.icon }, item.type))) }) })] }, key))), jsxRuntime.jsxs(AccordionItem, { value: "static", className: "border-b-0 bg-background dark:bg-card rounded-md mb-1 px-2", children: [jsxRuntime.jsxs(AccordionTrigger, { className: "py-1.5 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground hover:no-underline", children: ["Attributes (", STATIC_TYPES.length, ")"] }), jsxRuntime.jsx(AccordionContent, { children: jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-1 pb-2", children: STATIC_TYPES.map((item) => (jsxRuntime.jsx(DraggableComponent, { type: item.type, label: item.label, icon: item.icon }, item.type))) }) })] })] }) }) })] }));
25065
25197
  }
@@ -28343,7 +28475,9 @@ const DropdownMenuSeparator = React__namespace.forwardRef(({ className, ...props
28343
28475
  DropdownMenuSeparator.displayName = Separator2.displayName;
28344
28476
 
28345
28477
  function Toolbar({ onOpenJsonViewer }) {
28346
- const { form, setFormName, isPreviewMode, togglePreviewMode, clearForm, toggleMultiStep, saveVersion, restoreVersion, updateSubmissionConfig, undo, redo, canUndo, canRedo, canvasWidth, setCanvasWidth, } = useFormStore();
28478
+ const { form, setFormName, isPreviewMode, togglePreviewMode, clearForm, toggleMultiStep, saveVersion, restoreVersion, updateSubmissionConfig, undo, redo, canvasWidth, setCanvasWidth, historyIndex, history, } = useFormStore();
28479
+ const canUndo = historyIndex > 0;
28480
+ const canRedo = historyIndex < history.length - 1;
28347
28481
  const widthOptions = [
28348
28482
  { value: 'compact', label: 'Compact', description: '672px' },
28349
28483
  { value: 'medium', label: 'Medium', description: '896px' },
@@ -28356,6 +28490,7 @@ function Toolbar({ onOpenJsonViewer }) {
28356
28490
  const [versionDialogOpen, setVersionDialogOpen] = React.useState(false);
28357
28491
  const [changelog, setChangelog] = React.useState('');
28358
28492
  const [settingsDialogOpen, setSettingsDialogOpen] = React.useState(false);
28493
+ const [docsDialogOpen, setDocsDialogOpen] = React.useState(false);
28359
28494
  const [isDarkMode, setIsDarkMode] = React.useState(false);
28360
28495
  const { toast } = useToast();
28361
28496
  const toggleTheme = () => {
@@ -28452,7 +28587,101 @@ function Toolbar({ onOpenJsonViewer }) {
28452
28587
  return (jsxRuntime.jsxs("header", { className: "h-14 border-b border-border bg-card px-6 flex items-center justify-between gap-4 shrink-0", children: [jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: isEditing ? (jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(Input, { value: tempName, onChange: (e) => setTempName(e.target.value), onKeyDown: handleKeyDown, onBlur: handleSaveName, className: "h-8 w-64 text-sm font-medium", autoFocus: true, "data-testid": "input-form-name" }), jsxRuntime.jsx(Button, { size: "icon", variant: "ghost", onClick: handleSaveName, "data-testid": "button-save-name", children: jsxRuntime.jsx(Check, { className: "h-4 w-4" }) })] })) : (jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("h1", { className: "text-lg font-semibold text-foreground", children: form.name }), jsxRuntime.jsx(Button, { size: "icon", variant: "ghost", onClick: () => {
28453
28588
  setTempName(form.name);
28454
28589
  setIsEditing(true);
28455
- }, "data-testid": "button-edit-name", children: jsxRuntime.jsx(PenLine, { className: "h-4 w-4" }) }), form.isMultiStep && (jsxRuntime.jsx(Badge, { variant: "secondary", className: "text-xs", children: "Multi-Step" })), form.currentVersion && (jsxRuntime.jsxs(Badge, { variant: "outline", className: "text-xs", children: ["v", form.currentVersion] }))] })) }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", onClick: undo, disabled: !canUndo(), "data-testid": "button-undo", children: jsxRuntime.jsx(Undo2, { className: "h-4 w-4" }) }) }), jsxRuntime.jsx(TooltipContent, { children: "Undo" })] }), jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", onClick: redo, disabled: !canRedo(), "data-testid": "button-redo", children: jsxRuntime.jsx(Redo2, { className: "h-4 w-4" }) }) }), jsxRuntime.jsx(TooltipContent, { children: "Redo" })] }), jsxRuntime.jsxs(DropdownMenu, { children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", "data-testid": "button-canvas-width", children: jsxRuntime.jsx(Maximize2, { className: "h-4 w-4" }) }) }) }), jsxRuntime.jsx(TooltipContent, { children: "Canvas Width" })] }), jsxRuntime.jsxs(DropdownMenuContent, { align: "end", children: [jsxRuntime.jsx(DropdownMenuLabel, { children: "Canvas Width" }), jsxRuntime.jsx(DropdownMenuSeparator, {}), widthOptions.map((option) => (jsxRuntime.jsxs(DropdownMenuItem, { onClick: () => setCanvasWidth(option.value), className: "flex justify-between gap-4", "data-testid": `menu-width-${option.value}`, children: [jsxRuntime.jsx("span", { children: option.label }), jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs", children: option.description }), canvasWidth === option.value && jsxRuntime.jsx(Check, { className: "h-4 w-4 ml-2" })] }, option.value)))] })] }), jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1" }), jsxRuntime.jsxs(Button, { variant: "default", size: "sm", onClick: handleSaveForm, disabled: isSaving, className: "gap-2", "data-testid": "button-save-form", children: [isSaving ? (jsxRuntime.jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" })) : (jsxRuntime.jsx(Save, { className: "h-4 w-4" })), jsxRuntime.jsx("span", { children: "Save" })] }), jsxRuntime.jsx(Button, { variant: isPreviewMode ? 'default' : 'outline', size: "sm", onClick: togglePreviewMode, className: "gap-2", "data-testid": "button-toggle-preview", children: isPreviewMode ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(EyeOff, { className: "h-4 w-4" }), jsxRuntime.jsx("span", { children: "Edit" })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Eye, { className: "h-4 w-4" }), jsxRuntime.jsx("span", { children: "Preview" })] })) }), jsxRuntime.jsx(Button, { variant: form.isMultiStep ? 'default' : 'outline', size: "sm", onClick: toggleMultiStep, className: "gap-2", title: form.isMultiStep ? 'Switch to single page' : 'Switch to multi-step wizard', "data-testid": "button-toggle-multistep", children: jsxRuntime.jsx(Layers, { className: "h-4 w-4" }) }), jsxRuntime.jsxs(Dialog, { open: versionDialogOpen, onOpenChange: setVersionDialogOpen, children: [jsxRuntime.jsx(DialogTrigger, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "outline", size: "sm", className: "gap-2", "data-testid": "button-version", children: jsxRuntime.jsx(History, { className: "h-4 w-4" }) }) }), jsxRuntime.jsxs(DialogContent, { className: "max-w-md", children: [jsxRuntime.jsxs(DialogHeader, { children: [jsxRuntime.jsx(DialogTitle, { children: "Version History" }), jsxRuntime.jsx(DialogDescription, { children: "Save snapshots and restore previous versions of your form." })] }), jsxRuntime.jsxs("div", { className: "space-y-4", children: [jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { children: "Save New Version" }), jsxRuntime.jsx(Textarea, { value: changelog, onChange: (e) => setChangelog(e.target.value), placeholder: "What changed in this version?", className: "min-h-[60px]" }), jsxRuntime.jsxs(Button, { onClick: handleSaveVersion, className: "w-full gap-2", size: "sm", children: [jsxRuntime.jsx(Save, { className: "h-4 w-4" }), "Save Version ", (form.currentVersion || 0) + 1] })] }), form.versions && form.versions.length > 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs("div", { className: "border-t pt-4", children: [jsxRuntime.jsx(Label$2, { className: "mb-2 block", children: "Previous Versions" }), jsxRuntime.jsx(ScrollArea, { className: "h-[200px]", children: jsxRuntime.jsx("div", { className: "space-y-2", children: [...form.versions].reverse().map((version) => (jsxRuntime.jsxs("div", { className: "p-3 border rounded-md space-y-2", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsxs("span", { className: "font-medium", children: ["Version ", version.version] }), jsxRuntime.jsx(Button, { variant: "outline", size: "sm", onClick: () => handleRestoreVersion(version.id, version.version), children: "Restore" })] }), version.changelog && (jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: version.changelog })), jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: new Date(version.createdAt).toLocaleString() })] }, version.id))) }) })] }) }))] })] })] }), jsxRuntime.jsxs(Dialog, { open: settingsDialogOpen, onOpenChange: setSettingsDialogOpen, children: [jsxRuntime.jsx(DialogTrigger, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "outline", size: "sm", className: "gap-2", "data-testid": "button-settings", children: jsxRuntime.jsx(Settings, { className: "h-4 w-4" }) }) }), jsxRuntime.jsxs(DialogContent, { className: "max-w-lg", children: [jsxRuntime.jsxs(DialogHeader, { children: [jsxRuntime.jsx(DialogTitle, { children: "Form Settings" }), jsxRuntime.jsx(DialogDescription, { children: "Configure submission, webhooks, and other form settings." })] }), jsxRuntime.jsx("div", { className: "space-y-6", children: jsxRuntime.jsxs("div", { className: "space-y-4", children: [jsxRuntime.jsx("h4", { className: "font-medium", children: "Submission Settings" }), jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsx(Label$2, { children: "Enable Submission Handler" }), jsxRuntime.jsx(Switch, { checked: form.submissionConfig?.enabled || false, onCheckedChange: (checked) => updateSubmissionConfig({ enabled: checked }) })] }), form.submissionConfig?.enabled && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { children: "Webhook URL" }), jsxRuntime.jsx(Input, { value: form.submissionConfig?.webhookUrl || '', onChange: (e) => updateSubmissionConfig({ webhookUrl: e.target.value }), placeholder: "https://your-api.com/webhook" })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { children: "Success Message" }), jsxRuntime.jsx(Input, { value: form.submissionConfig?.successMessage || '', onChange: (e) => updateSubmissionConfig({ successMessage: e.target.value }), placeholder: "Thank you for your submission!" })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { children: "Redirect URL (optional)" }), jsxRuntime.jsx(Input, { value: form.submissionConfig?.redirectUrl || '', onChange: (e) => updateSubmissionConfig({ redirectUrl: e.target.value }), placeholder: "https://your-site.com/thank-you" })] })] }))] }) }), jsxRuntime.jsx(DialogFooter, { children: jsxRuntime.jsx(Button, { onClick: () => setSettingsDialogOpen(false), children: "Done" }) })] })] }), jsxRuntime.jsxs(DropdownMenu, { children: [jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "outline", size: "sm", className: "gap-2", "data-testid": "button-more", children: jsxRuntime.jsx(FileJson, { className: "h-4 w-4" }) }) }), jsxRuntime.jsxs(DropdownMenuContent, { align: "end", children: [jsxRuntime.jsx(DropdownMenuLabel, { children: "Export / Import" }), jsxRuntime.jsx(DropdownMenuSeparator, {}), jsxRuntime.jsxs(DropdownMenuItem, { onClick: onOpenJsonViewer, children: [jsxRuntime.jsx(FileJson, { className: "h-4 w-4 mr-2" }), "View JSON Schema"] }), jsxRuntime.jsxs(DropdownMenuItem, { onClick: handleExportJson, children: [jsxRuntime.jsx(Download, { className: "h-4 w-4 mr-2" }), "Download JSON"] }), jsxRuntime.jsx(DropdownMenuItem, { asChild: true, children: jsxRuntime.jsxs("label", { className: "cursor-pointer flex items-center", children: [jsxRuntime.jsx(Upload, { className: "h-4 w-4 mr-2" }), "Import JSON", jsxRuntime.jsx("input", { type: "file", accept: ".json", onChange: handleImportJson, className: "hidden" })] }) })] })] }), jsxRuntime.jsx(Button, { variant: "outline", size: "sm", onClick: clearForm, className: "gap-2 text-destructive hover:text-destructive", "data-testid": "button-clear-form", children: jsxRuntime.jsx(Trash2, { className: "h-4 w-4" }) }), jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1" }), jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", onClick: toggleTheme, "data-testid": "button-toggle-theme", children: isDarkMode ? jsxRuntime.jsx(Sun, { className: "h-4 w-4" }) : jsxRuntime.jsx(Moon, { className: "h-4 w-4" }) }) }), jsxRuntime.jsx(TooltipContent, { children: isDarkMode ? 'Light Mode' : 'Dark Mode' })] })] })] }));
28590
+ }, "data-testid": "button-edit-name", children: jsxRuntime.jsx(PenLine, { className: "h-4 w-4" }) }), form.isMultiStep && (jsxRuntime.jsx(Badge, { variant: "secondary", className: "text-xs", children: "Multi-Step" })), form.currentVersion && (jsxRuntime.jsxs(Badge, { variant: "outline", className: "text-xs", children: ["v", form.currentVersion] }))] })) }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", onClick: undo, disabled: !canUndo, "data-testid": "button-undo", children: jsxRuntime.jsx(Undo2, { className: "h-4 w-4" }) }) }), jsxRuntime.jsx(TooltipContent, { children: "Undo" })] }), jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", onClick: redo, disabled: !canRedo, "data-testid": "button-redo", children: jsxRuntime.jsx(Redo2, { className: "h-4 w-4" }) }) }), jsxRuntime.jsx(TooltipContent, { children: "Redo" })] }), jsxRuntime.jsxs(DropdownMenu, { children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", "data-testid": "button-canvas-width", children: jsxRuntime.jsx(Maximize2, { className: "h-4 w-4" }) }) }) }), jsxRuntime.jsx(TooltipContent, { children: "Canvas Width" })] }), jsxRuntime.jsxs(DropdownMenuContent, { align: "end", children: [jsxRuntime.jsx(DropdownMenuLabel, { children: "Canvas Width" }), jsxRuntime.jsx(DropdownMenuSeparator, {}), widthOptions.map((option) => (jsxRuntime.jsxs(DropdownMenuItem, { onClick: () => setCanvasWidth(option.value), className: "flex justify-between gap-4", "data-testid": `menu-width-${option.value}`, children: [jsxRuntime.jsx("span", { children: option.label }), jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs", children: option.description }), canvasWidth === option.value && jsxRuntime.jsx(Check, { className: "h-4 w-4 ml-2" })] }, option.value)))] })] }), jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1" }), jsxRuntime.jsxs(Button, { variant: "default", size: "sm", onClick: handleSaveForm, disabled: isSaving, className: "gap-2", "data-testid": "button-save-form", children: [isSaving ? (jsxRuntime.jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" })) : (jsxRuntime.jsx(Save, { className: "h-4 w-4" })), jsxRuntime.jsx("span", { children: "Save" })] }), jsxRuntime.jsx(Button, { variant: isPreviewMode ? 'default' : 'outline', size: "sm", onClick: togglePreviewMode, className: "gap-2", "data-testid": "button-toggle-preview", children: isPreviewMode ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(EyeOff, { className: "h-4 w-4" }), jsxRuntime.jsx("span", { children: "Edit" })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Eye, { className: "h-4 w-4" }), jsxRuntime.jsx("span", { children: "Preview" })] })) }), jsxRuntime.jsx(Button, { variant: form.isMultiStep ? 'default' : 'outline', size: "sm", onClick: toggleMultiStep, className: "gap-2", title: form.isMultiStep ? 'Switch to single page' : 'Switch to multi-step wizard', "data-testid": "button-toggle-multistep", children: jsxRuntime.jsx(Layers, { className: "h-4 w-4" }) }), jsxRuntime.jsxs(Dialog, { open: versionDialogOpen, onOpenChange: setVersionDialogOpen, children: [jsxRuntime.jsx(DialogTrigger, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "outline", size: "sm", className: "gap-2", "data-testid": "button-version", children: jsxRuntime.jsx(History, { className: "h-4 w-4" }) }) }), jsxRuntime.jsxs(DialogContent, { className: "max-w-md", children: [jsxRuntime.jsxs(DialogHeader, { children: [jsxRuntime.jsx(DialogTitle, { children: "Version History" }), jsxRuntime.jsx(DialogDescription, { children: "Save snapshots and restore previous versions of your form." })] }), jsxRuntime.jsxs("div", { className: "space-y-4", children: [jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { children: "Save New Version" }), jsxRuntime.jsx(Textarea, { value: changelog, onChange: (e) => setChangelog(e.target.value), placeholder: "What changed in this version?", className: "min-h-[60px]" }), jsxRuntime.jsxs(Button, { onClick: handleSaveVersion, className: "w-full gap-2", size: "sm", children: [jsxRuntime.jsx(Save, { className: "h-4 w-4" }), "Save Version ", (form.currentVersion || 0) + 1] })] }), form.versions && form.versions.length > 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs("div", { className: "border-t pt-4", children: [jsxRuntime.jsx(Label$2, { className: "mb-2 block", children: "Previous Versions" }), jsxRuntime.jsx(ScrollArea, { className: "h-[200px]", children: jsxRuntime.jsx("div", { className: "space-y-2", children: [...form.versions].reverse().map((version) => (jsxRuntime.jsxs("div", { className: "p-3 border rounded-md space-y-2", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsxs("span", { className: "font-medium", children: ["Version ", version.version] }), jsxRuntime.jsx(Button, { variant: "outline", size: "sm", onClick: () => handleRestoreVersion(version.id, version.version), children: "Restore" })] }), version.changelog && (jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: version.changelog })), jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: new Date(version.createdAt).toLocaleString() })] }, version.id))) }) })] }) }))] })] })] }), jsxRuntime.jsxs(Dialog, { open: docsDialogOpen, onOpenChange: setDocsDialogOpen, children: [jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx(DialogTrigger, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "outline", size: "sm", className: "gap-2", "data-testid": "button-docs", children: jsxRuntime.jsx(BookOpen, { className: "h-4 w-4" }) }) }) }), jsxRuntime.jsx(TooltipContent, { children: "Documentation" })] }), jsxRuntime.jsxs(DialogContent, { className: "max-w-4xl max-h-[85vh]", children: [jsxRuntime.jsxs(DialogHeader, { children: [jsxRuntime.jsx(DialogTitle, { children: "FormBuilder Documentation" }), jsxRuntime.jsx(DialogDescription, { children: "Complete guide for the drag-and-drop form builder component" })] }), jsxRuntime.jsx(ScrollArea, { className: "h-[60vh] pr-4", children: jsxRuntime.jsxs("div", { className: "prose prose-sm dark:prose-invert max-w-none space-y-6", children: [jsxRuntime.jsxs("section", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-semibold border-b pb-2", children: "Quick Start" }), jsxRuntime.jsx("pre", { className: "bg-muted p-3 rounded text-xs overflow-x-auto text-foreground", children: `import { FormBuilder } from '@enerjisaformlibrary/formbuilder-react';
28591
+ import '@enerjisaformlibrary/formbuilder-react/styles.css';
28592
+
28593
+ function App() {
28594
+ return (
28595
+ <FormBuilder
28596
+ onSave={(form) => saveToDatabase(JSON.stringify(form))}
28597
+ onChange={(form) => console.log('Updated:', form)}
28598
+ theme="light"
28599
+ />
28600
+ );
28601
+ }` })] }), jsxRuntime.jsxs("section", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-semibold border-b pb-2", children: "Field Types (20+)" }), jsxRuntime.jsxs("div", { className: "grid grid-cols-3 gap-2 text-sm", children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: "Basic:" }), " input, textarea, number, email, password, phone, url"] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: "Selection:" }), " dropdown, checkbox, radio, toggle, multiselect"] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: "Date/Time:" }), " date, time, daterange"] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: "Advanced:" }), " file, signature, rating, richtext, slider, color, autocomplete"] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: "Static:" }), " header, label, paragraph, divider, spacer, alert, image"] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: "Structure:" }), " button, qrcode, pattern, container"] })] })] }), jsxRuntime.jsxs("section", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-semibold border-b pb-2", children: "Form Schema Structure" }), jsxRuntime.jsx("pre", { className: "bg-muted p-3 rounded text-xs overflow-x-auto text-foreground", children: `FormSchema {
28602
+ id: string;
28603
+ name: string;
28604
+ rows: FormRow[]; // Single-page mode
28605
+ steps?: FormStep[]; // Multi-step wizard mode
28606
+ isMultiStep?: boolean;
28607
+ submissionConfig?: { webhookUrl, successMessage, redirectUrl };
28608
+ }
28609
+
28610
+ FormRow → columns[] → FormColumn (width: 1-12) → fields[] → FormField` })] }), jsxRuntime.jsxs("section", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-semibold border-b pb-2", children: "FormField Properties" }), jsxRuntime.jsx("pre", { className: "bg-muted p-3 rounded text-xs overflow-x-auto text-foreground", children: `FormField {
28611
+ id: string;
28612
+ type: 'input' | 'dropdown' | 'checkbox' | ...;
28613
+ props: {
28614
+ key: string; // Unique identifier for form values
28615
+ label?: string;
28616
+ placeholder?: string;
28617
+ defaultValue?: string;
28618
+ tooltip?: string; // Help text on hover
28619
+ autoFocus?: boolean; // Focus on preview mode
28620
+ hidden?: boolean;
28621
+ disabled?: boolean;
28622
+ readOnly?: boolean;
28623
+ size?: 'small' | 'medium' | 'large';
28624
+ };
28625
+ validation?: { required, minLength, maxLength, pattern, min, max };
28626
+ conditionalLogic?: { enabled, action, conditions[] };
28627
+ customStyle?: { containerClassName, labelClassName, inputClassName };
28628
+ events?: { onClick, onChange, onFocus, onBlur };
28629
+ }` })] }), jsxRuntime.jsxs("section", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-semibold border-b pb-2", children: "Conditional Logic" }), jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mb-2", children: "Show/hide/enable/disable fields based on other field values" }), jsxRuntime.jsx("pre", { className: "bg-muted p-3 rounded text-xs overflow-x-auto text-foreground", children: `conditionalLogic: {
28630
+ enabled: true,
28631
+ action: 'show' | 'hide' | 'enable' | 'disable' | 'require',
28632
+ conditions: [{
28633
+ field: 'country', // Target field's props.key
28634
+ operator: 'equals' | 'notEquals' | 'contains' | 'isEmpty' | ...,
28635
+ value: 'USA'
28636
+ }],
28637
+ conditionLogic: 'and' | 'or' // How to combine multiple conditions
28638
+ }` })] }), jsxRuntime.jsxs("section", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-semibold border-b pb-2", children: "Events & Actions" }), jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mb-2", children: "Execute actions on field interactions (preview mode only)" }), jsxRuntime.jsxs("div", { className: "text-sm mb-2", children: [jsxRuntime.jsx("strong", { children: "Available Actions:" }), jsxRuntime.jsxs("ul", { className: "list-disc list-inside mt-1", children: [jsxRuntime.jsxs("li", { children: [jsxRuntime.jsx("code", { children: "focusField" }), " - Focus another field (args: targetFieldKey)"] }), jsxRuntime.jsxs("li", { children: [jsxRuntime.jsx("code", { children: "clearField" }), " - Clear current field value"] }), jsxRuntime.jsxs("li", { children: [jsxRuntime.jsx("code", { children: "showMessage" }), " - Display alert (args: message)"] }), jsxRuntime.jsxs("li", { children: [jsxRuntime.jsx("code", { children: "reset" }), " - Reset all form values"] })] })] }), jsxRuntime.jsx("pre", { className: "bg-muted p-3 rounded text-xs overflow-x-auto text-foreground", children: `events: {
28639
+ onChange: [{
28640
+ type: 'common',
28641
+ name: 'focusField',
28642
+ args: { targetFieldKey: 'nextField' }
28643
+ }]
28644
+ }` })] }), jsxRuntime.jsxs("section", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-semibold border-b pb-2", children: "Zustand Store API" }), jsxRuntime.jsx("pre", { className: "bg-muted p-3 rounded text-xs overflow-x-auto text-foreground", children: `import { useFormStore } from '@enerjisaformlibrary/formbuilder-react';
28645
+
28646
+ const {
28647
+ form, // Current FormSchema
28648
+ formValues, // Values in preview mode
28649
+ previewMode, // boolean
28650
+ loadForm, // Load existing form
28651
+ addRow, deleteRow, // Row operations
28652
+ addField, updateField, // Field operations
28653
+ setFieldValue, // Set value in preview
28654
+ getFormValues, // Get all form values
28655
+ } = useFormStore();` })] }), jsxRuntime.jsxs("section", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-semibold border-b pb-2", children: "Container Fields" }), jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mb-2", children: "Group fields with nested row/column structure" }), jsxRuntime.jsx("pre", { className: "bg-muted p-3 rounded text-xs overflow-x-auto text-foreground", children: `{
28656
+ type: 'container',
28657
+ props: {
28658
+ key: 'addressGroup',
28659
+ label: 'Address',
28660
+ containerConfig: {
28661
+ rows: [{
28662
+ id: 'row1',
28663
+ columns: [
28664
+ { id: 'col1', width: 6, fields: [...] },
28665
+ { id: 'col2', width: 6, fields: [...] }
28666
+ ]
28667
+ }]
28668
+ }
28669
+ }
28670
+ }` })] }), jsxRuntime.jsxs("section", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-semibold border-b pb-2", children: "Multi-Step Forms" }), jsxRuntime.jsx("pre", { className: "bg-muted p-3 rounded text-xs overflow-x-auto text-foreground", children: `{
28671
+ isMultiStep: true,
28672
+ steps: [{
28673
+ id: 'step1',
28674
+ title: 'Personal Info',
28675
+ order: 0,
28676
+ rows: [...],
28677
+ validation: { validateOnNext: true }
28678
+ }, {
28679
+ id: 'step2',
28680
+ title: 'Contact',
28681
+ order: 1,
28682
+ rows: [...]
28683
+ }]
28684
+ }` })] })] }) }), jsxRuntime.jsx(DialogFooter, { children: jsxRuntime.jsx(Button, { onClick: () => setDocsDialogOpen(false), children: "Close" }) })] })] }), jsxRuntime.jsxs(Dialog, { open: settingsDialogOpen, onOpenChange: setSettingsDialogOpen, children: [jsxRuntime.jsx(DialogTrigger, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "outline", size: "sm", className: "gap-2", "data-testid": "button-settings", children: jsxRuntime.jsx(Settings, { className: "h-4 w-4" }) }) }), jsxRuntime.jsxs(DialogContent, { className: "max-w-lg", children: [jsxRuntime.jsxs(DialogHeader, { children: [jsxRuntime.jsx(DialogTitle, { children: "Form Settings" }), jsxRuntime.jsx(DialogDescription, { children: "Configure submission, webhooks, and other form settings." })] }), jsxRuntime.jsx("div", { className: "space-y-6", children: jsxRuntime.jsxs("div", { className: "space-y-4", children: [jsxRuntime.jsx("h4", { className: "font-medium", children: "Submission Settings" }), jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [jsxRuntime.jsx(Label$2, { children: "Enable Submission Handler" }), jsxRuntime.jsx(Switch, { checked: form.submissionConfig?.enabled || false, onCheckedChange: (checked) => updateSubmissionConfig({ enabled: checked }) })] }), form.submissionConfig?.enabled && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { children: "Webhook URL" }), jsxRuntime.jsx(Input, { value: form.submissionConfig?.webhookUrl || '', onChange: (e) => updateSubmissionConfig({ webhookUrl: e.target.value }), placeholder: "https://your-api.com/webhook" })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { children: "Success Message" }), jsxRuntime.jsx(Input, { value: form.submissionConfig?.successMessage || '', onChange: (e) => updateSubmissionConfig({ successMessage: e.target.value }), placeholder: "Thank you for your submission!" })] }), jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsx(Label$2, { children: "Redirect URL (optional)" }), jsxRuntime.jsx(Input, { value: form.submissionConfig?.redirectUrl || '', onChange: (e) => updateSubmissionConfig({ redirectUrl: e.target.value }), placeholder: "https://your-site.com/thank-you" })] })] }))] }) }), jsxRuntime.jsx(DialogFooter, { children: jsxRuntime.jsx(Button, { onClick: () => setSettingsDialogOpen(false), children: "Done" }) })] })] }), jsxRuntime.jsxs(DropdownMenu, { children: [jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "outline", size: "sm", className: "gap-2", "data-testid": "button-more", children: jsxRuntime.jsx(FileJson, { className: "h-4 w-4" }) }) }), jsxRuntime.jsxs(DropdownMenuContent, { align: "end", children: [jsxRuntime.jsx(DropdownMenuLabel, { children: "Export / Import" }), jsxRuntime.jsx(DropdownMenuSeparator, {}), jsxRuntime.jsxs(DropdownMenuItem, { onClick: onOpenJsonViewer, children: [jsxRuntime.jsx(FileJson, { className: "h-4 w-4 mr-2" }), "View JSON Schema"] }), jsxRuntime.jsxs(DropdownMenuItem, { onClick: handleExportJson, children: [jsxRuntime.jsx(Download, { className: "h-4 w-4 mr-2" }), "Download JSON"] }), jsxRuntime.jsx(DropdownMenuItem, { asChild: true, children: jsxRuntime.jsxs("label", { className: "cursor-pointer flex items-center", children: [jsxRuntime.jsx(Upload, { className: "h-4 w-4 mr-2" }), "Import JSON", jsxRuntime.jsx("input", { type: "file", accept: ".json", onChange: handleImportJson, className: "hidden" })] }) })] })] }), jsxRuntime.jsx(Button, { variant: "outline", size: "sm", onClick: clearForm, className: "gap-2 text-destructive hover:text-destructive", "data-testid": "button-clear-form", children: jsxRuntime.jsx(Trash2, { className: "h-4 w-4" }) }), jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1" }), jsxRuntime.jsxs(Tooltip, { children: [jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "ghost", size: "icon", onClick: toggleTheme, "data-testid": "button-toggle-theme", children: isDarkMode ? jsxRuntime.jsx(Sun, { className: "h-4 w-4" }) : jsxRuntime.jsx(Moon, { className: "h-4 w-4" }) }) }), jsxRuntime.jsx(TooltipContent, { children: isDarkMode ? 'Light Mode' : 'Dark Mode' })] })] })] }));
28456
28685
  }
28457
28686
 
28458
28687
  const iconMap = {