@wavemaker-ai/react-runtime 1.0.0-rc.647684 → 12.0.0-rc.335

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.
Files changed (215) hide show
  1. package/components/advanced/carousel/index.d.ts +1 -0
  2. package/components/advanced/carousel/template.d.ts +1 -0
  3. package/components/advanced/login/index.d.ts +1 -0
  4. package/components/advanced/marquee/index.d.ts +1 -0
  5. package/components/basic/anchor/index.d.ts +1 -0
  6. package/components/basic/anchor/index.js +3 -5
  7. package/components/basic/audio/index.d.ts +1 -0
  8. package/components/basic/html/index.d.ts +1 -0
  9. package/components/basic/icon/index.d.ts +1 -0
  10. package/components/basic/iframe/index.d.ts +1 -0
  11. package/components/basic/label/index.d.ts +1 -0
  12. package/components/basic/picture/index.d.ts +1 -0
  13. package/components/basic/progress-bar/index.d.ts +1 -0
  14. package/components/basic/progress-circle/index.d.ts +1 -0
  15. package/components/basic/richtexteditor/index.d.ts +3 -0
  16. package/components/basic/search/index.js +5 -4
  17. package/components/basic/search/utils.d.ts +1 -0
  18. package/components/basic/search/utils.js +9 -0
  19. package/components/basic/spinner/index.d.ts +1 -0
  20. package/components/basic/tile/index.d.ts +1 -0
  21. package/components/basic/tree/index.d.ts +1 -0
  22. package/components/basic/video/index.d.ts +1 -0
  23. package/components/chart/index.d.ts +1 -0
  24. package/components/common/index.d.ts +2 -0
  25. package/components/common/index.js +2 -0
  26. package/components/common/partial-content-wrapper.d.ts +15 -0
  27. package/components/common/partial-content-wrapper.js +11 -0
  28. package/components/container/accordion/accordion-pane/index.d.ts +1 -0
  29. package/components/container/accordion/index.d.ts +1 -0
  30. package/components/container/index.d.ts +4 -0
  31. package/components/container/index.js +38 -11
  32. package/components/container/layout-grid/grid-column/index.d.ts +1 -0
  33. package/components/container/layout-grid/grid-row/index.d.ts +1 -0
  34. package/components/container/layout-grid/index.d.ts +1 -0
  35. package/components/container/layout-grid/index.js +1 -1
  36. package/components/container/linear-layout/index.d.ts +1 -0
  37. package/components/container/linear-layout/linear-layout-item/index.d.ts +1 -0
  38. package/components/container/panel/index.d.ts +1 -0
  39. package/components/container/props.d.ts +1 -0
  40. package/components/container/repeat-template/index.d.ts +1 -0
  41. package/components/container/repeat-template/index.js +1 -1
  42. package/components/container/tabs/index.d.ts +1 -0
  43. package/components/container/tabs/index.js +12 -8
  44. package/components/container/tabs/tab-pane/index.d.ts +1 -0
  45. package/components/container/tabs/tab-pane/index.js +2 -2
  46. package/components/container/wizard/index.d.ts +2 -0
  47. package/components/container/wizard/index.js +92 -43
  48. package/components/container/wizard/props.d.ts +2 -2
  49. package/components/container/wizard/wizard-step/index.d.ts +1 -0
  50. package/components/data/card/card-actions/index.d.ts +1 -0
  51. package/components/data/card/card-content/index.d.ts +1 -0
  52. package/components/data/card/card-footer/index.d.ts +1 -0
  53. package/components/data/card/index.d.ts +1 -0
  54. package/components/data/form/base-form/hooks/useFormOperations.d.ts +1 -1
  55. package/components/data/form/base-form/hooks/useFormOperations.js +5 -2
  56. package/components/data/form/base-form/index.js +10 -14
  57. package/components/data/form/base-form/props.d.ts +1 -0
  58. package/components/data/form/dynamic-fields/WmxDynamicFormField.js +9 -23
  59. package/components/data/form/form-action/index.d.ts +2 -0
  60. package/components/data/form/form-controller/props.d.ts +2 -0
  61. package/components/data/form/form-controller/utils.js +3 -2
  62. package/components/data/form/form-controller/validation-contrustor.js +112 -1
  63. package/components/data/form/form-controller/withFormController.js +16 -3
  64. package/components/data/form/form-field/index.js +38 -11
  65. package/components/data/form/form-field/props.d.ts +8 -2
  66. package/components/data/list/components/ListItemWithTemplate.js +1 -1
  67. package/components/data/list/index.d.ts +2 -0
  68. package/components/data/list/index.js +5 -10
  69. package/components/data/pagination/hooks/usePagination.js +6 -6
  70. package/components/data/table/components/EditableCell.js +47 -24
  71. package/components/data/table/components/FieldValidationError.js +1 -1
  72. package/components/data/table/components/RowExpansionButton.js +5 -1
  73. package/components/data/table/components/TableBody.js +2 -0
  74. package/components/data/table/components/TableHeader.js +12 -4
  75. package/components/data/table/hooks/useFormWidget.js +13 -2
  76. package/components/data/table/hooks/usePanelStructure.js +6 -1
  77. package/components/data/table/hooks/useResponsiveColumns.d.ts +1 -0
  78. package/components/data/table/hooks/useRowHandlers.js +1 -1
  79. package/components/data/table/hooks/useRowSelection.js +65 -4
  80. package/components/data/table/hooks/useTableData.js +10 -2
  81. package/components/data/table/hooks/useTableEdit.d.ts +1 -1
  82. package/components/data/table/hooks/useTableEdit.js +115 -75
  83. package/components/data/table/hooks/useTableEditForms.d.ts +25 -0
  84. package/components/data/table/hooks/useTableEditForms.js +30 -0
  85. package/components/data/table/index.d.ts +2 -0
  86. package/components/data/table/index.js +82 -45
  87. package/components/data/table/live-table/index.d.ts +1 -0
  88. package/components/data/table/props.d.ts +43 -23
  89. package/components/data/table/table-action/index.d.ts +1 -0
  90. package/components/data/table/table-column/index.d.ts +1 -0
  91. package/components/data/table/table-row/index.d.ts +1 -0
  92. package/components/data/table/table-row-action/index.d.ts +1 -0
  93. package/components/data/table/utils/buildSelectionColumns.js +19 -24
  94. package/components/data/table/utils/columnProxy.d.ts +7 -1
  95. package/components/data/table/utils/columnProxy.js +21 -1
  96. package/components/data/table/utils/columnValidation.d.ts +19 -0
  97. package/components/data/table/utils/columnValidation.js +76 -0
  98. package/components/data/table/utils/constants.d.ts +2 -0
  99. package/components/data/table/utils/constants.js +2 -0
  100. package/components/data/table/utils/crud-handlers.js +3 -1
  101. package/components/data/table/utils/expansionColumn.js +1 -1
  102. package/components/data/table/utils/index.d.ts +14 -15
  103. package/components/data/table/utils/index.js +18 -85
  104. package/components/data/table/utils/selectionUtils.d.ts +12 -0
  105. package/components/data/table/utils/selectionUtils.js +23 -5
  106. package/components/dialogs/alert-dialog/index.d.ts +2 -0
  107. package/components/dialogs/confirm-dialog/index.d.ts +2 -0
  108. package/components/dialogs/dialog/index.d.ts +2 -0
  109. package/components/dialogs/dialog-actions/index.d.ts +1 -0
  110. package/components/dialogs/dialog-body/index.d.ts +1 -0
  111. package/components/dialogs/dialog-content/index.d.ts +1 -0
  112. package/components/dialogs/dialog-header/index.d.ts +1 -0
  113. package/components/dialogs/iframe-dialog/index.d.ts +2 -0
  114. package/components/dialogs/login-dialog/index.d.ts +2 -0
  115. package/components/dialogs/page-dialog/index.d.ts +2 -0
  116. package/components/dialogs/withDialogWrapper.js +12 -2
  117. package/components/form/button/index.d.ts +1 -0
  118. package/components/form/button-group/index.d.ts +1 -0
  119. package/components/input/calendar/index.d.ts +2 -0
  120. package/components/input/chips/index.d.ts +3 -0
  121. package/components/input/color-picker/index.d.ts +3 -0
  122. package/components/input/composite/index.d.ts +1 -0
  123. package/components/input/composite/index.js +32 -6
  124. package/components/input/currency/index.d.ts +1 -0
  125. package/components/input/default/checkbox/index.d.ts +3 -0
  126. package/components/input/default/checkboxset/index.d.ts +3 -0
  127. package/components/input/default/radioset/index.d.ts +3 -0
  128. package/components/input/default/switch/index.d.ts +3 -0
  129. package/components/input/epoch/date/index.d.ts +1 -0
  130. package/components/input/epoch/datetime/index.d.ts +1 -0
  131. package/components/input/epoch/datetime/index.js +13 -3
  132. package/components/input/epoch/time/index.d.ts +1 -0
  133. package/components/input/fileupload/index.d.ts +1 -0
  134. package/components/input/fileupload/index.js +2 -1
  135. package/components/input/number/index.d.ts +3 -0
  136. package/components/input/rating/index.d.ts +3 -0
  137. package/components/input/select/index.d.ts +1 -0
  138. package/components/input/slider/index.d.ts +3 -0
  139. package/components/input/text/index.d.ts +3 -0
  140. package/components/input/text/index.js +9 -2
  141. package/components/input/textarea/index.d.ts +3 -0
  142. package/components/input/upload/index.d.ts +3 -0
  143. package/components/layout/footer/index.js +4 -2
  144. package/components/layout/footer/props.d.ts +1 -0
  145. package/components/layout/header/index.js +29 -3
  146. package/components/layout/header/props.d.ts +1 -0
  147. package/components/layout/leftnav/index.js +22 -6
  148. package/components/layout/leftnav/props.d.ts +1 -0
  149. package/components/layout/leftnav/utils/page-class-util.d.ts +1 -0
  150. package/components/layout/leftnav/utils/page-class-util.js +4 -3
  151. package/components/layout/rightnav/index.js +4 -2
  152. package/components/layout/rightnav/props.d.ts +1 -0
  153. package/components/layout/topnav/index.js +4 -2
  154. package/components/layout/topnav/props.d.ts +1 -0
  155. package/components/navbar/index.d.ts +1 -0
  156. package/components/navbar/index.js +32 -7
  157. package/components/navbar/nav-item/index.d.ts +1 -0
  158. package/components/navigation/breadcrumb/index.d.ts +1 -0
  159. package/components/navigation/menu/index.d.ts +1 -0
  160. package/components/navigation/menu/index.js +19 -11
  161. package/components/navigation/menu/props.d.ts +1 -0
  162. package/components/navigation/popover/index.d.ts +1 -0
  163. package/components/navigation/popover/index.js +15 -3
  164. package/components/page/index.js +60 -19
  165. package/components/page/page-context.d.ts +4 -0
  166. package/components/page/partial/index.d.ts +1 -0
  167. package/context/PopoverContext.d.ts +5 -0
  168. package/context/PopoverContext.js +5 -0
  169. package/context/WidgetProvider.js +9 -2
  170. package/core/proxy-service.d.ts +2 -0
  171. package/core/proxy-service.js +132 -22
  172. package/higherOrder/BaseApp.js +3 -2
  173. package/higherOrder/BasePage.js +4 -10
  174. package/higherOrder/props.d.ts +1 -0
  175. package/higherOrder/useActivePageReactivity.js +1 -4
  176. package/higherOrder/withBaseWrapper.js +12 -3
  177. package/hooks/useHttp.d.ts +14 -4
  178. package/hooks/useHttp.js +47 -9
  179. package/package-lock.json +332 -325
  180. package/package.json +3 -3
  181. package/runtime-dynamic/App.js +21 -2
  182. package/runtime-dynamic/app-initializer.js +8 -1
  183. package/runtime-dynamic/components/PageWrapper.js +1 -1
  184. package/runtime-dynamic/components/PrefabPreview.js +1 -1
  185. package/runtime-dynamic/components/partial-content.js +17 -1
  186. package/runtime-dynamic/factories/build-base-page-like-component.js +11 -7
  187. package/runtime-dynamic/factories/dynamic-component.js +5 -10
  188. package/runtime-dynamic/main.d.ts +1 -0
  189. package/runtime-dynamic/main.js +9 -1
  190. package/runtime-dynamic/routes.js +17 -8
  191. package/runtime-dynamic/services/compile-render.js +7 -0
  192. package/runtime-dynamic/services/css-scoping.d.ts +1 -1
  193. package/runtime-dynamic/services/css-scoping.js +2 -2
  194. package/runtime-dynamic/services/variable-factory.js +2 -1
  195. package/runtime-dynamic/services/variable-transpiler.js +4 -1
  196. package/runtime-dynamic/wmx-shared.d.ts +40 -0
  197. package/runtime-dynamic/wmx-shared.js +33 -0
  198. package/utils/page-params-util.js +22 -1
  199. package/utils/partial-host-util.d.ts +40 -0
  200. package/utils/partial-host-util.js +41 -0
  201. package/utils/style-utils.js +1 -1
  202. package/utils/wmx.utils.d.ts +0 -1
  203. package/utils/wmx.utils.js +0 -25
  204. package/variables/crud-variable.d.ts +10 -0
  205. package/variables/crud-variable.js +53 -2
  206. package/variables/live-variable.d.ts +1 -0
  207. package/variables/live-variable.js +2 -1
  208. package/variables/model-variable.d.ts +2 -0
  209. package/variables/model-variable.js +14 -0
  210. package/variables/operation-params.d.ts +29 -0
  211. package/variables/operation-params.js +69 -0
  212. package/variables/service-variable.d.ts +9 -0
  213. package/variables/service-variable.js +21 -2
  214. package/components/data/table/utils/validation.d.ts +0 -13
  215. package/components/data/table/utils/validation.js +0 -82
@@ -0,0 +1,30 @@
1
+ import { useMemo } from "react";
2
+ import { useForm } from "react-hook-form";
3
+ const EDIT_FORM_OPTIONS = {
4
+ mode: "onChange",
5
+ // Validate on blur (widgets use updateon="blur")
6
+ shouldUnregister: true
7
+ // Drop field on unmount; prevents orphaned errors
8
+ };
9
+ const useTableEditForm = (tableName) => {
10
+ const { control, trigger, setValue, setError, reset, getFieldState } = useForm(EDIT_FORM_OPTIONS);
11
+ return useMemo(
12
+ () => ({
13
+ formRef: { control, trigger, name: tableName, validationtype: "default" },
14
+ validate: () => trigger(),
15
+ getInvalidFields: (fieldNames) => fieldNames.filter((fieldName) => getFieldState(fieldName).invalid),
16
+ setFieldValue: (fieldName, value) => setValue(fieldName, value, { shouldValidate: false, shouldDirty: true }),
17
+ setFieldError: (fieldName, message) => setError(fieldName, { type: "native", message }),
18
+ reset: () => reset()
19
+ }),
20
+ [control, trigger, setValue, setError, reset, getFieldState, tableName]
21
+ );
22
+ };
23
+ const useTableEditForms = (tableName) => {
24
+ const editForm = useTableEditForm(tableName);
25
+ const newRowForm = useTableEditForm(tableName);
26
+ return { editForm, newRowForm };
27
+ };
28
+ export {
29
+ useTableEditForms
30
+ };
@@ -102,6 +102,7 @@ declare const WmTableStandalone: React.ComponentType<{
102
102
  width?: number | string;
103
103
  height?: number | string;
104
104
  className?: string;
105
+ class?: string;
105
106
  conditionalstyle?: React.CSSProperties;
106
107
  conditionalclass?: string;
107
108
  showindevice?: ("xs" | "sm" | "md" | "lg" | "all")[];
@@ -245,6 +246,7 @@ declare const WmTable: React.ComponentType<{
245
246
  width?: number | string;
246
247
  height?: number | string;
247
248
  className?: string;
249
+ class?: string;
248
250
  conditionalstyle?: React.CSSProperties;
249
251
  conditionalclass?: string;
250
252
  showindevice?: ("xs" | "sm" | "md" | "lg" | "all")[];
@@ -446,7 +446,9 @@ const WmTableComponent = memo(
446
446
  handleMultiSelection,
447
447
  handleSelectAll,
448
448
  handleRowSelectionClick,
449
- isRowSelected
449
+ isRowSelected,
450
+ selectItem,
451
+ deselectItem
450
452
  } = useRowSelection({
451
453
  radioselect,
452
454
  multiselect: effectiveMultiselect,
@@ -532,6 +534,7 @@ const WmTableComponent = memo(
532
534
  }),
533
535
  [wmTableColumns, columnOverrides]
534
536
  );
537
+ const columnValidatorsRef = useRef({});
535
538
  const {
536
539
  editingRowId,
537
540
  isRowEditing,
@@ -577,7 +580,8 @@ const WmTableComponent = memo(
577
580
  onRowdelete,
578
581
  tableRef,
579
582
  isServerSidePagination: isServerSidePagination(),
580
- tableName: name
583
+ tableName: name,
584
+ columnValidatorsRef
581
585
  });
582
586
  const { handleRowClick } = useRowHandlers({
583
587
  editingRowId,
@@ -638,9 +642,10 @@ const WmTableComponent = memo(
638
642
  if (onSort && newSorting.length > 0) {
639
643
  const sortData = {
640
644
  field: newSorting[0].id,
641
- direction: newSorting[0].desc ? "desc" : "asc"
645
+ direction: newSorting[0].desc ? "desc" : "asc",
646
+ sortDirection: newSorting[0].desc ? "desc" : "asc"
642
647
  };
643
- onSort(null, (_a2 = listener == null ? void 0 : listener.Widgets) == null ? void 0 : _a2[name], sortData);
648
+ onSort(null, (_a2 = viewParent == null ? void 0 : viewParent.Widgets) == null ? void 0 : _a2[name], sortData);
644
649
  }
645
650
  },
646
651
  [sorting, name]
@@ -755,7 +760,13 @@ const WmTableComponent = memo(
755
760
  []
756
761
  );
757
762
  const columnsProxy = useMemo(
758
- () => createColumnsProxy(wmTableColumns, applyOverride, setColumnsVersion, setSummaryRowDef),
763
+ () => createColumnsProxy(
764
+ wmTableColumns,
765
+ applyOverride,
766
+ setColumnsVersion,
767
+ setSummaryRowDef,
768
+ columnValidatorsRef.current
769
+ ),
759
770
  [wmTableColumns, applyOverride, setColumnsVersion, setSummaryRowDef]
760
771
  );
761
772
  const {
@@ -779,7 +790,7 @@ const WmTableComponent = memo(
779
790
  listener.Widgets[name].nativeElement = tableContainerRef.current;
780
791
  }
781
792
  const data = internalDataset && internalDataset.length > 0 ? internalDataset : table.getRowModel().rows.map((row) => row.original) || [];
782
- onDatarender((_a2 = listener == null ? void 0 : listener.Widgets) == null ? void 0 : _a2[name], data);
793
+ onDatarender((_a2 = viewParent == null ? void 0 : viewParent.Widgets) == null ? void 0 : _a2[name], data);
783
794
  }, [onDatarender, name]);
784
795
  columnsStateRef.current = columns;
785
796
  const columnsForTable = useMemo(() => {
@@ -944,7 +955,7 @@ const WmTableComponent = memo(
944
955
  listener,
945
956
  name
946
957
  });
947
- const { showPanelHeading, showPagination } = usePanelStructure({
958
+ const { showPanelHeading, showPagination, showFooter } = usePanelStructure({
948
959
  title,
949
960
  subheading,
950
961
  iconclass,
@@ -968,6 +979,23 @@ const WmTableComponent = memo(
968
979
  },
969
980
  [name]
970
981
  );
982
+ const selectItemRef = useRef(selectItem);
983
+ const deselectItemRef = useRef(deselectItem);
984
+ selectItemRef.current = selectItem;
985
+ deselectItemRef.current = deselectItem;
986
+ const widgetSelectItem = useCallback((itemOrIndex) => {
987
+ selectItemRef.current(itemOrIndex);
988
+ }, []);
989
+ const widgetDeselectItem = useCallback((itemOrIndex) => {
990
+ deselectItemRef.current(itemOrIndex);
991
+ }, []);
992
+ useEffect(() => {
993
+ var _a2;
994
+ (_a2 = listener == null ? void 0 : listener.onChange) == null ? void 0 : _a2.call(listener, widgetRegistrationKey, {
995
+ selectItem: widgetSelectItem,
996
+ deselectItem: widgetDeselectItem
997
+ });
998
+ });
971
999
  const sortInfoForExport = useMemo(() => {
972
1000
  if (sorting.length > 0) {
973
1001
  return {
@@ -1026,7 +1054,8 @@ const WmTableComponent = memo(
1026
1054
  const firstSort = sorting[0];
1027
1055
  return {
1028
1056
  field: firstSort.id,
1029
- direction: firstSort.desc ? "desc" : "asc"
1057
+ direction: firstSort.desc ? "desc" : "asc",
1058
+ sortDirection: firstSort.desc ? "desc" : "asc"
1030
1059
  };
1031
1060
  }
1032
1061
  return void 0;
@@ -1118,8 +1147,8 @@ const WmTableComponent = memo(
1118
1147
  });
1119
1148
  if (onBeforedatarender) {
1120
1149
  onBeforedatarender(
1121
- (_a2 = listener == null ? void 0 : listener.Widgets) == null ? void 0 : _a2[name],
1122
- // widget reference
1150
+ (_a2 = viewParent == null ? void 0 : viewParent.Widgets) == null ? void 0 : _a2[name],
1151
+ // widget reference (reactive proxy, not raw listener)
1123
1152
  data,
1124
1153
  // data
1125
1154
  columnsProxy
@@ -1133,10 +1162,9 @@ const WmTableComponent = memo(
1133
1162
  } else {
1134
1163
  queueOnDatarenderAfterPaint();
1135
1164
  }
1136
- const nextRows = internalDataset.map(
1137
- (r) => typeof r === "object" && r !== null ? __spreadValues({}, r) : r
1165
+ setInternalDataset(
1166
+ (prev) => prev.map((r) => typeof r === "object" && r !== null ? __spreadValues({}, r) : r)
1138
1167
  );
1139
- setInternalDataset(nextRows);
1140
1168
  } else if (onDatarender) {
1141
1169
  queueOnDatarenderAfterPaint();
1142
1170
  }
@@ -1275,7 +1303,7 @@ const WmTableComponent = memo(
1275
1303
  const rowIndex = internalDataset.findIndex(
1276
1304
  (r) => r._wmTableRowId === row._wmTableRowId || r.id !== void 0 && r.id === row.id
1277
1305
  );
1278
- const result = await onBeforerowdelete(event, (_a2 = listener == null ? void 0 : listener.Widgets) == null ? void 0 : _a2[name], cleanedRow, {
1306
+ const result = await onBeforerowdelete(event, (_a2 = viewParent == null ? void 0 : viewParent.Widgets) == null ? void 0 : _a2[name], cleanedRow, {
1279
1307
  rowIndex,
1280
1308
  data: cleanedRow
1281
1309
  });
@@ -1339,7 +1367,7 @@ const WmTableComponent = memo(
1339
1367
  showToast("Failed to refresh table data", "Error");
1340
1368
  }
1341
1369
  if (onError) {
1342
- onError(null, (_b2 = listener == null ? void 0 : listener.Widgets) == null ? void 0 : _b2[name], error, "refresh");
1370
+ onError(null, (_b2 = viewParent == null ? void 0 : viewParent.Widgets) == null ? void 0 : _b2[name], error, "refresh");
1343
1371
  }
1344
1372
  }
1345
1373
  },
@@ -1354,7 +1382,10 @@ const WmTableComponent = memo(
1354
1382
  datasource,
1355
1383
  dataset,
1356
1384
  selectPageSize,
1357
- rowDefInstances
1385
+ rowDefInstances,
1386
+ // Angular parity: table.selectItem / table.deselectItem (accepts a row or an index).
1387
+ selectItem: widgetSelectItem,
1388
+ deselectItem: widgetDeselectItem
1358
1389
  };
1359
1390
  const getRowId = (row) => row._wmTableRowId || String(row.id);
1360
1391
  const pushSelectedItemsToWidget = (selectedIds) => {
@@ -1524,34 +1555,40 @@ const WmTableComponent = memo(
1524
1555
  } : {})
1525
1556
  }, { name }), {
1526
1557
  children: [
1527
- showheader && wmTableColumns.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
1528
- /* @__PURE__ */ jsx(
1529
- TableHeaderComponent,
1530
- {
1531
- table,
1532
- enablesort,
1533
- enablecolumnselection,
1534
- rowClass,
1535
- ColClassSignature,
1536
- sorting,
1537
- columnSizing,
1538
- rowSelection,
1539
- rowExpansionConfig: visibleRowExpansionConfig,
1540
- columnsVersion,
1541
- filterMode: filtermode,
1542
- columnFilters,
1543
- onColumnFilterChange: setColumnFilter,
1544
- renderFormWidget,
1545
- listener,
1546
- tableStructure,
1547
- onColumnSelect: handleColumnSelect,
1548
- onColumnDeselect: handleColumnDeselect,
1549
- onHeaderclick,
1550
- tableName: name
1551
- }
1552
- ),
1553
- /* @__PURE__ */ jsx("colgroup", { children: colGroupSpec.map((c) => /* @__PURE__ */ jsx("col", { style: c.style, width: c.width }, c.key)) })
1554
- ] }),
1558
+ colGroupSpec.length > 0 && /* @__PURE__ */ jsx("colgroup", { children: colGroupSpec.map((c) => /* @__PURE__ */ jsx(
1559
+ "col",
1560
+ __spreadValues({
1561
+ style: c.style,
1562
+ width: c.width
1563
+ }, c.domHidden ? { "data-wm-col-hidden": "" } : {}),
1564
+ c.key
1565
+ )) }),
1566
+ showheader && wmTableColumns.length > 0 && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
1567
+ TableHeaderComponent,
1568
+ {
1569
+ table,
1570
+ enablesort,
1571
+ enablecolumnselection,
1572
+ rowClass,
1573
+ ColClassSignature,
1574
+ sorting,
1575
+ columnSizing,
1576
+ rowSelection,
1577
+ rowExpansionConfig: visibleRowExpansionConfig,
1578
+ columnsVersion,
1579
+ filterMode: filtermode,
1580
+ columnFilters,
1581
+ onColumnFilterChange: setColumnFilter,
1582
+ renderFormWidget,
1583
+ listener,
1584
+ viewParent,
1585
+ tableStructure,
1586
+ onColumnSelect: handleColumnSelect,
1587
+ onColumnDeselect: handleColumnDeselect,
1588
+ onHeaderclick,
1589
+ tableName: name
1590
+ }
1591
+ ) }),
1555
1592
  (internalDataset.length > 0 || !isTableLoading) && /* @__PURE__ */ jsx(
1556
1593
  TableBodyComponent,
1557
1594
  {
@@ -1601,7 +1638,7 @@ const WmTableComponent = memo(
1601
1638
  }
1602
1639
  ) }) })
1603
1640
  ] }),
1604
- /* @__PURE__ */ jsxs(Box, { className: "panel-footer clearfix", children: [
1641
+ showFooter && /* @__PURE__ */ jsxs(Box, { className: "panel-footer clearfix", children: [
1605
1642
  showPagination && /* @__PURE__ */ jsx(Box, { className: "app-datagrid-paginator", children: /* @__PURE__ */ jsx(
1606
1643
  WmPagination,
1607
1644
  {
@@ -35,6 +35,7 @@ declare const _default: React.ComponentType<{
35
35
  width?: number | string;
36
36
  height?: number | string;
37
37
  className?: string;
38
+ class?: string;
38
39
  conditionalstyle?: React.CSSProperties;
39
40
  conditionalclass?: string;
40
41
  showindevice?: ("xs" | "sm" | "md" | "lg" | "all")[];
@@ -6,6 +6,9 @@ import { IAlignment, INavigation } from "../list/props";
6
6
  import { EditWidgetType } from "./utils";
7
7
  import { StorageType } from "../../../utils/state-persistance";
8
8
  import { LiveVariableConfig } from "@wavemaker-ai/react-runtime/variables/live-variable";
9
+ import { ValidatorConfig } from "@wavemaker-ai/react-runtime/components/data/form/form-controller/props";
10
+ import { ColumnValidatorRegistry } from "./utils/columnValidation";
11
+ import { TableEditFormRef } from "./hooks/useTableEditForms";
9
12
  export type TableEditMode = "inline" | "dialog" | "form" | "quickedit" | "none";
10
13
  export type TableActionPosition = "header" | "footer";
11
14
  export type TableFormPosition = "top" | "bottom";
@@ -820,6 +823,7 @@ export interface TableHeaderProps {
820
823
  columnsVersion?: number;
821
824
  filterMode?: TableFilterMode;
822
825
  listener: any;
826
+ viewParent?: any;
823
827
  columnFilters?: Record<string, any>;
824
828
  onColumnFilterChange?: (columnId: string, value: string, matchMode?: string) => void;
825
829
  renderFormWidget: (fieldName: string, widgetType: string, value: any, onChange: (value: any) => void, additionalProps?: any) => React.ReactNode;
@@ -854,7 +858,7 @@ export interface AddNewRowProps {
854
858
  sessionKey: number;
855
859
  editingRowData: Record<string, any>;
856
860
  renderEditableCell: (column: WmTableColumnProps, fieldName: string, widgetType: string, editValue: any, rowId: string) => ReactElement;
857
- onKeyDown?: (e: KeyboardEvent, sourceRowId?: string) => void;
861
+ onKeyDown?: (e: React.KeyboardEvent, sourceRowId?: string) => void;
858
862
  handleSave: () => void;
859
863
  handleCancel: () => void;
860
864
  listener?: any;
@@ -868,13 +872,17 @@ export interface EditableCellProps {
868
872
  fieldName: string;
869
873
  widgetType: string;
870
874
  editValue: any;
871
- fieldValidationErrorsRef: RefObject<Record<string, boolean>>;
872
- cellUpdateCallbacksRef: RefObject<Record<string, () => void>>;
875
+ /** The react-hook-form instance for this edit session, handed to the cell's widget. */
876
+ formRef: TableEditFormRef;
877
+ /** Shared `${rowId}_${fieldName}` -> true map of cells currently in error. */
878
+ cellErrorsRef?: RefObject<Record<string, boolean>>;
879
+ /** Cell containers, keyed `${rowId}_${fieldName}`. */
873
880
  fieldRefs: RefObject<Record<string, HTMLElement | null>>;
874
- renderFormWidget: (name: string, type: string, value: any, onChange: (newValue: any) => void, props: any) => ReactElement;
881
+ columnValidatorsRef?: RefObject<ColumnValidatorRegistry>;
882
+ renderFormWidget: (name: string, type: string, value: any, onChange: (newValue: any) => void, props: TableEditWidgetProps) => ReactElement;
875
883
  updateFieldValue: (fieldName: string, newValue: any, rowId?: string) => void;
876
884
  sessionKey?: number;
877
- onKeyDown?: (e: KeyboardEvent, sourceRowId?: string) => void;
885
+ onKeyDown?: (e: React.KeyboardEvent, sourceRowId?: string) => void;
878
886
  editMode?: TableEditMode;
879
887
  validationmessage?: string;
880
888
  }
@@ -980,14 +988,32 @@ export interface UseTableDataReturn {
980
988
  export interface UseFormWidgetProps {
981
989
  listener?: any;
982
990
  }
991
+ /** Everything an editable cell hands to its edit widget beyond the value itself. */
992
+ export interface TableEditWidgetProps {
993
+ required?: boolean;
994
+ disabled?: boolean;
995
+ placeholder?: string;
996
+ defaultvalue?: string | number | boolean;
997
+ sessionKey?: string | number;
998
+ rowData?: any;
999
+ column?: any;
1000
+ /**
1001
+ * The edit session's react-hook-form instance. `withFormController` validates the widget
1002
+ * against it and, from the same validators, derives the date/time bounds the picker enforces
1003
+ * on its own input.
1004
+ */
1005
+ formRef?: TableEditFormRef;
1006
+ /** Form field name for the cell — the column field, independent of the row. */
1007
+ formKey?: string;
1008
+ /** Validators set by a page script via `columns.<name>.setValidators([...])`. */
1009
+ validators?: ValidatorConfig[];
1010
+ /** Validators set via `columns.<name>.setAsyncValidators([...])`. */
1011
+ asyncValidators?: ValidatorConfig[];
1012
+ /** Keep the widget out of the form entirely (hidden columns). */
1013
+ ignoreInForm?: boolean;
1014
+ }
983
1015
  export interface UseFormWidgetReturn {
984
- renderFormWidget: (fieldName: string, widgetType: string, value: any, onFieldChange?: (newValue: any) => void, widgetProps?: {
985
- required?: boolean;
986
- disabled?: boolean;
987
- placeholder?: string;
988
- defaultvalue?: string | number | boolean;
989
- sessionKey?: string | number;
990
- }) => ReactElement;
1016
+ renderFormWidget: (fieldName: string, widgetType: string, value: any, onFieldChange?: (newValue: any) => void, widgetProps?: TableEditWidgetProps) => ReactElement;
991
1017
  }
992
1018
  export interface UseTableEditProps {
993
1019
  editMode?: TableEditMode;
@@ -1020,6 +1046,8 @@ export interface UseTableEditProps {
1020
1046
  onRowupdate?: (event: any, widget: any, data: any) => void;
1021
1047
  tableRef?: React.RefObject<any>;
1022
1048
  isServerSidePagination?: boolean;
1049
+ /** Validators set by a page script via `columns.<name>.setValidators([...])`. */
1050
+ columnValidatorsRef?: RefObject<Record<string, any>>;
1023
1051
  }
1024
1052
  export interface UseTableEditReturn {
1025
1053
  editingRowId: string | null;
@@ -1095,6 +1123,7 @@ export interface UsePanelStructureProps {
1095
1123
  export interface UsePanelStructureReturn {
1096
1124
  showPanelHeading: boolean;
1097
1125
  showPagination: boolean;
1126
+ showFooter: boolean;
1098
1127
  }
1099
1128
  export interface UseRowSelectionProps {
1100
1129
  radioselect?: boolean;
@@ -1127,6 +1156,8 @@ export interface UseRowSelectionReturn {
1127
1156
  handleRowSelectionClick: (event: MouseEvent, rowId: string, rowData: any) => boolean;
1128
1157
  isRowSelected: (rowId: string) => boolean;
1129
1158
  isInteractiveElement: (event: MouseEvent) => boolean;
1159
+ selectItem: (itemOrIndex: any) => void;
1160
+ deselectItem: (itemOrIndex: any) => void;
1130
1161
  }
1131
1162
  export interface UseTableStateProps {
1132
1163
  editMode?: TableEditMode;
@@ -1301,17 +1332,6 @@ export interface UseRowExpansionReturn {
1301
1332
  registerRowDefInstance: (rowId: string, instance: any, rowData?: any) => void;
1302
1333
  rowDefInstances: Record<string, any>;
1303
1334
  }
1304
- export interface FieldValidationState {
1305
- fieldRefs: RefObject<Record<string, HTMLElement | null>>;
1306
- fieldValidationErrors: RefObject<Record<string, boolean>>;
1307
- cellUpdateCallbacks: RefObject<Record<string, () => void>>;
1308
- }
1309
- export interface ValidationResult {
1310
- isValid: boolean;
1311
- invalidElements: HTMLElement[];
1312
- invalidFieldKeys?: string[];
1313
- firstInvalidElement?: HTMLElement;
1314
- }
1315
1335
  /**
1316
1336
  * Interface for summary row value with optional styling
1317
1337
  */
@@ -21,6 +21,7 @@ declare const _default: React.ComponentType<{
21
21
  width?: number | string;
22
22
  height?: number | string;
23
23
  className?: string;
24
+ class?: string;
24
25
  conditionalstyle?: React.CSSProperties;
25
26
  conditionalclass?: string;
26
27
  showindevice?: ("xs" | "sm" | "md" | "lg" | "all")[];
@@ -21,6 +21,7 @@ declare const _default: React.ComponentType<{
21
21
  width?: number | string;
22
22
  height?: number | string;
23
23
  className?: string;
24
+ class?: string;
24
25
  conditionalstyle?: React.CSSProperties;
25
26
  conditionalclass?: string;
26
27
  showindevice?: ("xs" | "sm" | "md" | "lg" | "all")[];
@@ -21,6 +21,7 @@ declare const _default: React.ComponentType<{
21
21
  width?: number | string;
22
22
  height?: number | string;
23
23
  className?: string;
24
+ class?: string;
24
25
  conditionalstyle?: React.CSSProperties;
25
26
  conditionalclass?: string;
26
27
  showindevice?: ("xs" | "sm" | "md" | "lg" | "all")[];
@@ -29,6 +29,7 @@ export declare const WmTableRowAction: React.FC<{
29
29
  margin?: string;
30
30
  width?: number | string;
31
31
  height?: number | string;
32
+ class?: string;
32
33
  conditionalstyle?: React.CSSProperties;
33
34
  conditionalclass?: string;
34
35
  showindevice?: ("xs" | "sm" | "md" | "lg" | "all")[];
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { Box, Radio, FormControlLabel, Tooltip } from "@mui/material";
2
+ import { Box, Tooltip } from "@mui/material";
3
3
  import { TABLE_MESSAGES } from "./constants";
4
4
  const getSelectionMeta = (ctx) => {
5
5
  var _a, _b, _c, _d;
@@ -10,27 +10,22 @@ function RadioSelectCell(ctx) {
10
10
  const rowId = row.id;
11
11
  const isSelected = row.getIsSelected();
12
12
  const { handleRadioSelection, radioselecttitle, radioselectarialabel, tableName } = getSelectionMeta(ctx);
13
- return /* @__PURE__ */ jsx(Box, { sx: { display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsx(Tooltip, { title: radioselecttitle != null ? radioselecttitle : "", placement: "top", children: /* @__PURE__ */ jsx(Box, { className: "radio app-radio", children: /* @__PURE__ */ jsx(
14
- FormControlLabel,
15
- {
16
- control: /* @__PURE__ */ jsx(
17
- Radio,
18
- {
19
- checked: isSelected,
20
- onChange: (e) => handleRadioSelection == null ? void 0 : handleRadioSelection(rowId, row.original, e),
21
- value: rowId,
22
- name: `wmRadioselect-${tableName != null ? tableName : "table"}`,
23
- inputProps: {
24
- "aria-label": radioselectarialabel
25
- },
26
- rowselectinput: "",
27
- size: "small"
28
- }
29
- ),
30
- label: "",
31
- className: "caption"
32
- }
33
- ) }) }) });
13
+ return /* @__PURE__ */ jsx(Box, { sx: { display: "flex", justifyContent: "center" }, "data-role": "select-row", children: /* @__PURE__ */ jsx(Tooltip, { title: radioselecttitle != null ? radioselecttitle : "", placement: "top", children: /* @__PURE__ */ jsx(Box, { className: "radio app-radio", children: /* @__PURE__ */ jsxs(Box, { component: "label", children: [
14
+ /* @__PURE__ */ jsx(
15
+ Box,
16
+ {
17
+ component: "input",
18
+ type: "radio",
19
+ checked: isSelected,
20
+ onChange: (e) => handleRadioSelection == null ? void 0 : handleRadioSelection(rowId, row.original, e),
21
+ value: rowId,
22
+ name: `wmRadioselect-${tableName != null ? tableName : "table"}`,
23
+ "aria-label": radioselectarialabel,
24
+ rowselectinput: ""
25
+ }
26
+ ),
27
+ /* @__PURE__ */ jsx(Box, { component: "span", className: "caption" })
28
+ ] }) }) }) });
34
29
  }
35
30
  RadioSelectCell.displayName = "RadioSelectCell";
36
31
  function MultiSelectCell(ctx) {
@@ -38,7 +33,7 @@ function MultiSelectCell(ctx) {
38
33
  const rowId = row.id;
39
34
  const isSelected = row.getIsSelected();
40
35
  const { handleMultiSelection, multiselecttitle, multiselectarialabel } = getSelectionMeta(ctx);
41
- return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex" }, children: [
36
+ return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex" }, "data-role": "select-row", children: [
42
37
  /* @__PURE__ */ jsx(Tooltip, { title: multiselecttitle != null ? multiselecttitle : "", placement: "top", children: /* @__PURE__ */ jsx(Box, { className: "app-checkbox checkbox", children: /* @__PURE__ */ jsxs(Box, { component: "label", className: isSelected ? "" : "unchecked", children: [
43
38
  /* @__PURE__ */ jsx(Box, { component: "span", className: "sr-only", "aria-live": "assertive", children: "Select row" }),
44
39
  /* @__PURE__ */ jsx(
@@ -64,7 +59,7 @@ function MultiSelectHeader({ table, column }) {
64
59
  var _a, _b;
65
60
  const isAllSelected = table.getIsAllRowsSelected();
66
61
  const { handleSelectAll } = (_b = (_a = column.columnDef.meta) == null ? void 0 : _a.selection) != null ? _b : {};
67
- return /* @__PURE__ */ jsx(Box, { sx: { display: "flex", width: "100%" }, children: /* @__PURE__ */ jsx(Box, { className: "app-checkbox checkbox", children: /* @__PURE__ */ jsxs(Box, { component: "label", className: isAllSelected ? "" : "unchecked", children: [
62
+ return /* @__PURE__ */ jsx(Box, { sx: { display: "flex", width: "100%" }, "data-role": "select-all", children: /* @__PURE__ */ jsx(Box, { className: "app-checkbox checkbox", children: /* @__PURE__ */ jsxs(Box, { component: "label", className: isAllSelected ? "" : "unchecked", children: [
68
63
  /* @__PURE__ */ jsx(
69
64
  Box,
70
65
  {
@@ -1,3 +1,5 @@
1
+ import { ValidatorConfig } from "@wavemaker-ai/react-runtime/components/data/form/form-controller/props";
2
+ import { ColumnValidatorRegistry } from "./columnValidation";
1
3
  export declare const keyMap: {
2
4
  [key: string]: string;
3
5
  };
@@ -17,5 +19,9 @@ export interface ColumnAggregate {
17
19
  export interface EnhancedColumnProxy {
18
20
  aggregate: ColumnAggregate;
19
21
  setSummaryRowData: (data: SummaryRowData | SummaryRowData[]) => void;
22
+ setValidators: (validators: ValidatorConfig[]) => void;
23
+ setAsyncValidators: (asyncValidators: ValidatorConfig[]) => void;
20
24
  }
21
- export declare function createColumnsProxy(wmTableColumns: any[], applyOverride: (field: string, key: string, value: any) => void, setColumnsVersion?: (updater: (v: number) => number) => void, setSummaryRowDef?: (columnKey: string, data: any, rowIndex: number, refresh: boolean, show?: boolean) => void): Record<string, any>;
25
+ export declare function createColumnsProxy(wmTableColumns: any[], applyOverride: (field: string, key: string, value: any) => void, setColumnsVersion?: (updater: (v: number) => number) => void, setSummaryRowDef?: (columnKey: string, data: any, rowIndex: number, refresh: boolean, show?: boolean) => void,
26
+ /** Live validator store, held in a ref so script calls survive column-def rebuilds. */
27
+ validatorRegistry?: ColumnValidatorRegistry): Record<string, any>;
@@ -17,6 +17,9 @@ var __spreadValues = (a, b) => {
17
17
  return a;
18
18
  };
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ import {
21
+ storeColumnValidators
22
+ } from "./columnValidation";
20
23
  const keyMap = {
21
24
  caption: "header",
22
25
  name: "accessorKey",
@@ -29,7 +32,7 @@ const keyMap = {
29
32
  "col-class": "meta.className",
30
33
  style: "meta"
31
34
  };
32
- function createColumnsProxy(wmTableColumns, applyOverride, setColumnsVersion, setSummaryRowDef) {
35
+ function createColumnsProxy(wmTableColumns, applyOverride, setColumnsVersion, setSummaryRowDef, validatorRegistry) {
33
36
  const proxy = {};
34
37
  wmTableColumns.forEach((col, idx) => {
35
38
  const key = col.field;
@@ -39,11 +42,28 @@ function createColumnsProxy(wmTableColumns, applyOverride, setColumnsVersion, se
39
42
  const newData = Array.isArray(data) ? data : [data];
40
43
  invokeSummaryRowData(key, newData, setSummaryRowDef, columnShow);
41
44
  };
45
+ const storeValidators = (kind, method) => (validators) => {
46
+ if (!validatorRegistry) {
47
+ console.warn(
48
+ `${method} called on column "${key}" before the table wired up validation.`
49
+ );
50
+ return;
51
+ }
52
+ storeColumnValidators(validatorRegistry, key, kind, validators);
53
+ };
54
+ const setValidators = storeValidators("validators", "setValidators");
55
+ const setAsyncValidators = storeValidators("asyncValidators", "setAsyncValidators");
42
56
  proxy[key] = new Proxy(col, {
43
57
  get(target, prop) {
44
58
  if (prop === "setSummaryRowData") {
45
59
  return setSummaryRowData;
46
60
  }
61
+ if (prop === "setValidators") {
62
+ return setValidators;
63
+ }
64
+ if (prop === "setAsyncValidators") {
65
+ return setAsyncValidators;
66
+ }
47
67
  return target[prop];
48
68
  },
49
69
  set(target, prop, value) {
@@ -0,0 +1,19 @@
1
+ import { ValidatorConfig } from "@wavemaker-ai/react-runtime/components/data/form/form-controller/props";
2
+ import { WmTableColumnProps } from "../props";
3
+ export interface ColumnValidators {
4
+ /** From `columns.<field>.setValidators([...])`. */
5
+ validators: ValidatorConfig[];
6
+ /** From `columns.<field>.setAsyncValidators([...])`. */
7
+ asyncValidators: ValidatorConfig[];
8
+ }
9
+ export type ColumnValidatorRegistry = Record<string, ColumnValidators>;
10
+ export declare const isColumnValidatable: (column: WmTableColumnProps | undefined) => boolean;
11
+ export declare const cloneValidators: (validators: ValidatorConfig[]) => ValidatorConfig[];
12
+ export declare const storeColumnValidators: (registry: ColumnValidatorRegistry, field: string, kind: keyof ColumnValidators, validators: ValidatorConfig[]) => void;
13
+ export interface NativeValidityError {
14
+ /** The column field, i.e. the react-hook-form field name for the cell. */
15
+ fieldName: string;
16
+ message: string;
17
+ }
18
+ export declare const collectNativeValidityErrors: (cellElements: Record<string, HTMLElement | null>, rowId: string) => NativeValidityError[];
19
+ export declare const focusFirstInvalidCell: (cellElements: Record<string, HTMLElement | null>, rowId: string, invalidFieldNames: string[]) => void;