@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
@@ -121,6 +121,8 @@ export interface WithFormControllerProps {
121
121
  standalone?: boolean;
122
122
  formRef?: any;
123
123
  formKey?: string;
124
+ /** Suppress the inline help-block; set by hosts that show validation errors their own way. */
125
+ hideValidationMessage?: boolean;
124
126
  name: string;
125
127
  datavalue?: any;
126
128
  defaultvalue?: any;
@@ -30,6 +30,7 @@ function resolveValue(value) {
30
30
  }
31
31
  return value === null ? void 0 : value;
32
32
  }
33
+ const toPatternSource = (regexp) => regexp instanceof RegExp ? regexp.source : regexp;
33
34
  function extractDynamicValidationProps(validators, rules) {
34
35
  const result = {
35
36
  required: rules.required,
@@ -55,8 +56,8 @@ function extractDynamicValidationProps(validators, rules) {
55
56
  result.maxchars = resolveValue(validator.validator);
56
57
  break;
57
58
  case "regexp":
58
- result.regexp = resolveValue(
59
- validator.validator
59
+ result.regexp = toPatternSource(
60
+ resolveValue(validator.validator)
60
61
  );
61
62
  break;
62
63
  case "minvalue":
@@ -58,6 +58,82 @@ const parseTime = (time) => {
58
58
  }
59
59
  return null;
60
60
  };
61
+ const resolveValidatorValue = (validator) => {
62
+ if (!isFunction(validator)) return validator;
63
+ try {
64
+ return validator();
65
+ } catch (error) {
66
+ console.warn("Error resolving validator value:", error);
67
+ return void 0;
68
+ }
69
+ };
70
+ const parseDateValue = (value) => {
71
+ if (value === null || value === void 0 || value === "") return null;
72
+ if (isDate(value)) {
73
+ const parsed = moment(value);
74
+ return parsed.isValid() ? parsed : null;
75
+ }
76
+ if (isNumber(value)) {
77
+ const parsed = moment(value);
78
+ return parsed.isValid() ? parsed : null;
79
+ }
80
+ if (!isString(value)) return null;
81
+ const trimmed = value.trim();
82
+ if (trimmed === "") return null;
83
+ if (/^-?\d+$/.test(trimmed)) {
84
+ const parsed = moment(Number(trimmed));
85
+ return parsed.isValid() ? parsed : null;
86
+ }
87
+ const iso = moment(trimmed, moment.ISO_8601, true);
88
+ if (iso.isValid()) return iso;
89
+ const loose = moment(new Date(trimmed));
90
+ return loose.isValid() ? loose : null;
91
+ };
92
+ const toMinutesOfDay = (value) => {
93
+ if (value === null || value === void 0 || value === "") return null;
94
+ if (isString(value)) {
95
+ const fromTime = parseTime(value);
96
+ if (fromTime !== null) return fromTime;
97
+ }
98
+ const parsed = parseDateValue(value);
99
+ return parsed ? parsed.hours() * 60 + parsed.minutes() : null;
100
+ };
101
+ const toNumberList = (validator) => {
102
+ const raw = isArray(validator) ? validator : isString(validator) ? validator.split(",") : [];
103
+ return raw.map((entry) => Number(String(entry).trim())).filter((n) => !isNaN(n));
104
+ };
105
+ const toDateList = (validator) => {
106
+ const raw = isArray(validator) ? validator : isString(validator) ? validator.split(",") : [];
107
+ return raw.map((entry) => parseDateValue(isString(entry) ? entry.trim() : entry)).filter((entry) => entry !== null);
108
+ };
109
+ const dateTimeRule = (key, check) => {
110
+ return (config, rules, form, fieldName) => {
111
+ rules.validate = __spreadProps(__spreadValues({}, rules.validate), {
112
+ [key]: async (value) => {
113
+ if (value === null || value === void 0 || value === "") return true;
114
+ const bound = resolveValidatorValue(config.validator);
115
+ if (bound === null || bound === void 0 || bound === "") return true;
116
+ const result = check(value, bound);
117
+ if (result === null) {
118
+ console.warn(`Could not evaluate "${key}" validator for field "${fieldName}":`, {
119
+ value,
120
+ validator: bound
121
+ });
122
+ return true;
123
+ }
124
+ if (result) return true;
125
+ return await resolveErrorMessage(config.errorMessage, value, fieldName, form);
126
+ }
127
+ });
128
+ return rules;
129
+ };
130
+ };
131
+ const compareDay = (value, bound, ok) => {
132
+ const parsedValue = parseDateValue(value);
133
+ const parsedBound = parseDateValue(bound);
134
+ if (!parsedValue || !parsedBound) return null;
135
+ return ok(parsedValue.startOf("day").valueOf(), parsedBound.startOf("day").valueOf());
136
+ };
61
137
  const validationHandlers = {
62
138
  required: (config, rules, form, fieldName) => {
63
139
  if (config.validator) {
@@ -170,7 +246,42 @@ const validationHandlers = {
170
246
  };
171
247
  }
172
248
  return rules;
173
- }
249
+ },
250
+ mindate: dateTimeRule(
251
+ "minDate",
252
+ (value, bound) => compareDay(value, bound, (v, b) => v >= b)
253
+ ),
254
+ maxdate: dateTimeRule(
255
+ "maxDate",
256
+ (value, bound) => compareDay(value, bound, (v, b) => v <= b)
257
+ ),
258
+ mintime: dateTimeRule("minTime", (value, bound) => {
259
+ const current = toMinutesOfDay(value);
260
+ const min = toMinutesOfDay(bound);
261
+ if (current === null || min === null) return null;
262
+ return current >= min;
263
+ }),
264
+ maxtime: dateTimeRule("maxTime", (value, bound) => {
265
+ const current = toMinutesOfDay(value);
266
+ const max = toMinutesOfDay(bound);
267
+ if (current === null || max === null) return null;
268
+ return current <= max;
269
+ }),
270
+ excludedays: dateTimeRule("excludeDays", (value, bound) => {
271
+ const parsed = parseDateValue(value);
272
+ if (!parsed) return null;
273
+ const days = toNumberList(bound);
274
+ if (days.length === 0) return true;
275
+ return !days.includes(parsed.day());
276
+ }),
277
+ excludedates: dateTimeRule("excludeDates", (value, bound) => {
278
+ const parsed = parseDateValue(value);
279
+ if (!parsed) return null;
280
+ const excluded = toDateList(bound);
281
+ if (excluded.length === 0) return true;
282
+ const day = parsed.startOf("day").valueOf();
283
+ return !excluded.some((entry) => entry.startOf("day").valueOf() === day);
284
+ })
174
285
  };
175
286
  const isValidatorConfig = (config) => {
176
287
  return config && typeof config === "object" && !Array.isArray(config) && typeof config !== "function" && isString(config.type) && (isString(config.errorMessage) || isFunction(config.errorMessage)) && config.validator !== void 0;
@@ -48,6 +48,8 @@ import {
48
48
  useHTMLValidationProps,
49
49
  useExternalDataSync
50
50
  } from "./hooks";
51
+ const ALWAYS_MULTI_VALUE_WIDGETS = ["WmChips", "WmCheckboxset"];
52
+ const MULTI_SELECT_WIDGET = "WmSelect";
51
53
  const withFormController = (WrappedComponent) => {
52
54
  const WithFormControllerComponent = memo((props) => {
53
55
  const _a = props, {
@@ -121,6 +123,9 @@ const withFormController = (WrappedComponent) => {
121
123
  useDefaultValueSync(defaultvalue, datavalue, fieldRef);
122
124
  const widget = WrappedComponent == null ? void 0 : WrappedComponent.displayName;
123
125
  const ignoreRange = ["WmRadioset", "WmCheckboxset"].includes(widget != null ? widget : "");
126
+ const isMultipleSelect = widget === MULTI_SELECT_WIDGET && props.multiple == true;
127
+ const isMultiValueWidget = ALWAYS_MULTI_VALUE_WIDGETS.includes(widget != null ? widget : "") || isMultipleSelect;
128
+ const fallbackDefaultValue = isMultiValueWidget && defaultvalue === void 0 ? [] : defaultvalue;
124
129
  const validationRules = useValidationRules(
125
130
  validationType,
126
131
  validators,
@@ -172,6 +177,10 @@ const withFormController = (WrappedComponent) => {
172
177
  trigger(effectiveFormKey);
173
178
  }
174
179
  }, [customValidationMsg]);
180
+ const onChangeRef = useRef(props.onChange);
181
+ useEffect(() => {
182
+ onChangeRef.current = props.onChange;
183
+ }, [props.onChange]);
175
184
  const createOnChangeHandler = useCallback(
176
185
  (field) => {
177
186
  return (e, componentProps, newValue, oldValue, isValid) => {
@@ -199,7 +208,7 @@ const withFormController = (WrappedComponent) => {
199
208
  setTouched(true);
200
209
  trigger(effectiveFormKey);
201
210
  }
202
- (_a2 = props.onChange) == null ? void 0 : _a2.call(props, e, componentProps, newValue, oldValue);
211
+ (_a2 = onChangeRef.current) == null ? void 0 : _a2.call(onChangeRef, e, componentProps, newValue, oldValue);
203
212
  };
204
213
  },
205
214
  [type, props.datafield, updateon, effectiveFormKey]
@@ -231,12 +240,13 @@ const withFormController = (WrappedComponent) => {
231
240
  control: formRef.control,
232
241
  name: effectiveFormKey,
233
242
  rules: validationRules,
234
- defaultValue: effectiveDataValue !== void 0 ? effectiveDataValue : defaultvalue,
243
+ defaultValue: effectiveDataValue !== void 0 ? effectiveDataValue : fallbackDefaultValue,
235
244
  render: ({ field, fieldState }) => {
236
245
  var _a2, _b, _c;
237
246
  fieldRef.current = field;
238
247
  const processedValue = processFieldValue(field.value, type, props.datafield);
239
248
  const errorState = getErrorState(fieldState, validationType, touched);
249
+ const isExplicitFormField = !props.hideValidationMessage && (props.formfield === true || props.formfield === "true");
240
250
  let valueToUse;
241
251
  if (processedValue !== void 0) {
242
252
  valueToUse = processedValue;
@@ -321,11 +331,14 @@ const withFormController = (WrappedComponent) => {
321
331
  value = JSON.stringify(value);
322
332
  }
323
333
  }
334
+ if (value && typeof value === "object") {
335
+ value = JSON.stringify(value);
336
+ }
324
337
  return value;
325
338
  })()
326
339
  }
327
340
  ),
328
- shouldShowErrorMessage(validationType, fieldState, touched) && /* @__PURE__ */ jsx(
341
+ isExplicitFormField && shouldShowErrorMessage(validationType, fieldState, touched) && /* @__PURE__ */ jsx(
329
342
  "p",
330
343
  {
331
344
  className: "help-block text-danger",
@@ -48,7 +48,7 @@ const WmFormField = memo(
48
48
  const formProxy = useWidgetProxy(`${props.formName}`);
49
49
  const overriddenItemsRef = useRef({});
50
50
  const fieldKey = props.formKey || props.name;
51
- const defaultValueRegisteredRef = useRef(false);
51
+ const prevDefaultValueRef = useRef(props.defaultvalue);
52
52
  const showfield = (_b = (_a = overriddenItemsRef == null ? void 0 : overriddenItemsRef.current) == null ? void 0 : _a.show) != null ? _b : show;
53
53
  const formReady = (formProxy == null ? void 0 : formProxy.listener) !== void 0 || ((_c = props.formRef) == null ? void 0 : _c.name) === props.formName;
54
54
  const reset = useCallback(
@@ -81,7 +81,19 @@ const WmFormField = memo(
81
81
  formProxy.formWidgets = {};
82
82
  formProxy.formfields = {};
83
83
  }
84
- const mutableTarget = __spreadProps(__spreadValues({}, props), { reset, show, deferload });
84
+ const mutableTarget = __spreadProps(__spreadValues({}, props), {
85
+ reset,
86
+ show,
87
+ deferload,
88
+ fieldValidations: {
89
+ validate: () => {
90
+ var _a2;
91
+ if (fieldKey && typeof ((_a2 = props.formRef) == null ? void 0 : _a2.trigger) === "function") {
92
+ props.formRef.trigger(fieldKey);
93
+ }
94
+ }
95
+ }
96
+ });
85
97
  const fieldProxy = createFormFieldProxy(
86
98
  mutableTarget,
87
99
  setProxyProps,
@@ -93,16 +105,19 @@ const WmFormField = memo(
93
105
  }, [formReady]);
94
106
  useEffect(() => {
95
107
  if (!formReady || !fieldProxyRef.current) return;
96
- if (defaultValueRegisteredRef.current) return;
97
- defaultValueRegisteredRef.current = true;
108
+ if (prevDefaultValueRef.current === props.defaultvalue) return;
109
+ const valueUnset = fieldProxyRef.current.datavalue === void 0 || fieldProxyRef.current.datavalue === prevDefaultValueRef.current;
110
+ prevDefaultValueRef.current = props.defaultvalue;
111
+ if (!valueUnset) return;
98
112
  fieldProxyRef.current.datavalue = props.defaultvalue;
99
113
  fieldProxyRef.current.value = props.defaultvalue;
100
114
  fieldProxyRef.current.defaultvalue = props.defaultvalue;
101
- }, [props.defaultvalue]);
115
+ }, [props.defaultvalue, formReady]);
102
116
  useEffect(() => {
103
- var _a2;
104
117
  const fieldProxy = fieldProxyRef.current;
105
- if (!fieldProxy || !((_a2 = props.dataset) == null ? void 0 : _a2.length)) return;
118
+ if (!fieldProxy) return;
119
+ const hasDataset = typeof props.dataset === "function" || props.dataset && props.dataset.length > 0;
120
+ if (!hasDataset) return;
106
121
  DATASET_SYNC_KEYS.forEach((key) => {
107
122
  const value = props[key];
108
123
  if (value != null && fieldProxy[key] !== value) {
@@ -111,20 +126,25 @@ const WmFormField = memo(
111
126
  });
112
127
  }, [props.dataset, props.datafield, props.displayfield, props.displaylabel, props.searchkey]);
113
128
  function renderFormFields() {
114
- var _a2, _b2, _c2, _d2, _e, _f, _g, _h;
129
+ var _a2, _b2, _c2, _d2, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
115
130
  if (props.formRef) {
116
131
  const errors = (_a2 = props.formRef) == null ? void 0 : _a2.errors;
117
132
  const formKey = (_b2 = props.formKey) != null ? _b2 : props.name;
118
133
  const fieldError = formKey && errors ? get(errors, formKey) : void 0;
119
134
  const invalid = Boolean(fieldError);
120
135
  const invalidCls = invalid ? " text-danger " : "";
121
- return /* @__PURE__ */ jsx(Fragment, { children: (_h = props == null ? void 0 : props.renderFormFields) == null ? void 0 : _h.call(props, __spreadProps(__spreadValues(__spreadValues({}, proxyProps), overriddenItemsRef.current), {
136
+ return /* @__PURE__ */ jsx(Fragment, { children: (_n = props == null ? void 0 : props.renderFormFields) == null ? void 0 : _n.call(props, __spreadProps(__spreadValues(__spreadValues({}, proxyProps), overriddenItemsRef.current), {
137
+ // proxyProps snapshots onChange once at mount; nothing resyncs it, so a
138
+ // handler assigned after mount (e.g. from a page's onReady) is never seen
139
+ // unless we read the live prop here, same as onTrailingiconclick below.
140
+ onChange: props.onChange,
122
141
  show: showfield,
123
142
  disabled: (_d2 = (_c2 = overriddenItemsRef == null ? void 0 : overriddenItemsRef.current) == null ? void 0 : _c2.disabled) != null ? _d2 : props == null ? void 0 : props.disabled,
124
143
  readonly: (_f = (_e = overriddenItemsRef == null ? void 0 : overriddenItemsRef.current) == null ? void 0 : _e.readonly) != null ? _f : props == null ? void 0 : props.readonly,
125
144
  // BaseField derives this from live validators. A direct field-proxy write wins,
126
145
  // but never fall back to the initial proxyProps.required snapshot.
127
146
  required: (_g = overriddenItemsRef.current.required) != null ? _g : props.required,
147
+ displayname: (_h = overriddenItemsRef.current.displayname) != null ? _h : props.displayname,
128
148
  fieldError,
129
149
  validators: props.validators,
130
150
  asyncValidators: props.asyncValidators,
@@ -132,7 +152,14 @@ const WmFormField = memo(
132
152
  invalid,
133
153
  invalidCls,
134
154
  iswidget: "false",
135
- onChangeHandler
155
+ onChangeHandler,
156
+ onTrailingiconclick: (_i = overriddenItemsRef.current.onTrailingiconclick) != null ? _i : props.onTrailingiconclick,
157
+ trailingiconurl: (_j = overriddenItemsRef.current.trailingiconurl) != null ? _j : props.trailingiconurl,
158
+ onLeadingiconclick: (_k = overriddenItemsRef.current.onLeadingiconclick) != null ? _k : props.onLeadingiconclick,
159
+ leadingiconurl: (_l = overriddenItemsRef.current.leadingiconurl) != null ? _l : props.leadingiconurl,
160
+ styles: {},
161
+ style: {},
162
+ limitdisplaytext: (_m = overriddenItemsRef.current.limitdisplaytext) != null ? _m : props.limitdisplaytext
136
163
  })) });
137
164
  } else {
138
165
  return null;
@@ -145,7 +172,7 @@ const WmFormField = memo(
145
172
  }
146
173
  const isDeferLoad = deferload === true;
147
174
  const showValue = (showfield == null ? void 0 : showfield.toString()) !== "false";
148
- if ((!showValue || showfield) && isDeferLoad) {
175
+ if (!showValue && isDeferLoad) {
149
176
  return null;
150
177
  }
151
178
  const shouldHide = !showValue && !isDeferLoad;
@@ -146,9 +146,9 @@ export interface FormFieldProps {
146
146
  */
147
147
  displaylabel?: string;
148
148
  /**
149
- * The collection of data items for the field.
149
+ * The collection of data items for the field, or a thunk returning them.
150
150
  */
151
- dataset?: any[];
151
+ dataset?: any[] | (() => any[]);
152
152
  /**
153
153
  * Key to use for searching.
154
154
  */
@@ -206,6 +206,12 @@ export interface FormFieldProps {
206
206
  reset?: () => void;
207
207
  setValidationMessage?: (message: string) => void;
208
208
  disabled?: boolean;
209
+ trailingiconurl?: string;
210
+ onTrailingiconclick?: (...args: any[]) => void;
211
+ leadingiconurl?: string;
212
+ onLeadingiconclick?: (...args: any[]) => void;
213
+ onChange?: (...args: any[]) => void;
214
+ limitdisplaytext?: string;
209
215
  }
210
216
  /**
211
217
  * Combined props for the WmFormField component, including base WaveMaker props.
@@ -60,7 +60,7 @@ const ListItemWithTemplate = ({
60
60
  },
61
61
  [WidgetProxy, name]
62
62
  );
63
- if (isPlainObject(item)) {
63
+ if (isPlainObject(item) && item.selected !== isActive) {
64
64
  item.selected = isActive;
65
65
  }
66
66
  const templateContent = renderItem ? renderItem(item, globalIndex != null ? globalIndex : index, WidgetProxy[name], getCurrentItemWidgets) : itemTemplate || /* @__PURE__ */ jsx(MediaWmListtemplate, {});
@@ -84,6 +84,7 @@ declare const WmListStandalone: React.ComponentType<{
84
84
  datavalue?: any;
85
85
  width?: number | string;
86
86
  height?: number | string;
87
+ class?: string;
87
88
  animation?: string;
88
89
  show?: boolean | string;
89
90
  padding?: string;
@@ -139,6 +140,7 @@ declare const _default: React.ComponentType<{
139
140
  width?: number | string;
140
141
  height?: number | string;
141
142
  className?: string;
143
+ class?: string;
142
144
  conditionalstyle?: React.CSSProperties;
143
145
  conditionalclass?: string;
144
146
  showindevice?: ("xs" | "sm" | "md" | "lg" | "all")[];
@@ -182,7 +182,7 @@ const WmList = (props) => {
182
182
  }
183
183
  const safeDataset = useMemo(() => {
184
184
  return addUniqueRowIds(resolvedDataset, { type: "list" });
185
- }, [currentDataset]);
185
+ }, [currentDataset, dataset]);
186
186
  const [initialRender, setinitialRender] = useState(true);
187
187
  const userInitiatedSelectionRef = React.useRef(false);
188
188
  const listScrollContainerRef = useRef(null);
@@ -339,7 +339,7 @@ const WmList = (props) => {
339
339
  if (navigation === LIST_NAVIGATION_TYPES.NONE || !navigation) {
340
340
  paginationState.setCurrentPageSize(resolvedDataset.length);
341
341
  }
342
- }, [resolvedDataset.length, pagesize, paginationState]);
342
+ }, [resolvedDataset.length, pagesize, paginationState.setCurrentPageSize]);
343
343
  const effectiveStateHandler = navigation === LIST_NAVIGATION_TYPES.ON_DEMAND || navigation === LIST_NAVIGATION_TYPES.SCROLL ? "none" : statehandler;
344
344
  const stateManager = useListStateManager({
345
345
  name,
@@ -512,18 +512,13 @@ const WmList = (props) => {
512
512
  return /* @__PURE__ */ jsxs(
513
513
  Box,
514
514
  __spreadProps(__spreadValues(__spreadProps(__spreadValues({
515
- className: clsx(
516
- DEFAULT_CLS,
517
- "wm-position-relative",
518
- className,
519
- hidden && "wm-hidden",
520
- wrapper_autoLayout_Classes
521
- ),
515
+ className: clsx(DEFAULT_CLS, "wm-position-relative", className, wrapper_autoLayout_Classes),
522
516
  component: "div",
523
517
  "data-name": name
524
518
  }, { name }), {
525
519
  "data-navigation": navigation,
526
- ref: ListWrapperRef
520
+ ref: ListWrapperRef,
521
+ hidden
527
522
  }), direction ? { direction } : {}), {
528
523
  children: [
529
524
  /* @__PURE__ */ jsx(
@@ -381,7 +381,7 @@ const usePagination = ({
381
381
  const updatedMaxResults = newMaxResults || prev.currentMaxResults;
382
382
  const updatedDataSize = newDataSize !== void 0 ? newDataSize : prev.dataSize;
383
383
  const updatedCurrentPage = currentPage !== void 0 ? currentPage : prev.currentPage;
384
- const newPageCount = (paginationMeta == null ? void 0 : paginationMeta.totalPages) !== void 0 && (paginationMeta == null ? void 0 : paginationMeta.totalPages) > 1 ? paginationMeta.totalPages : updatedDataSize > updatedMaxResults ? Math.ceil(updatedDataSize / updatedMaxResults) : updatedDataSize < 0 ? 0 : 1;
384
+ const newPageCount = (paginationMeta == null ? void 0 : paginationMeta.totalPages) !== void 0 && (isServerSidePagination || paginationMeta.totalPages > 1) ? paginationMeta.totalPages : updatedDataSize > updatedMaxResults ? Math.ceil(updatedDataSize / updatedMaxResults) : updatedDataSize < 0 ? 0 : 1;
385
385
  return __spreadProps(__spreadValues({}, prev), {
386
386
  currentPage: updatedCurrentPage,
387
387
  dataSize: updatedDataSize,
@@ -390,7 +390,7 @@ const usePagination = ({
390
390
  }
391
391
  });
392
392
  },
393
- [paginationMeta]
393
+ [isServerSidePagination, paginationMeta]
394
394
  );
395
395
  const disableNavigation = useCallback(() => {
396
396
  setDisableStates({
@@ -551,7 +551,7 @@ const usePagination = ({
551
551
  totalElements: (paginationMeta == null ? void 0 : paginationMeta.totalElements) || dataState.fullData.length,
552
552
  totalPages: paginationState.pageCount
553
553
  };
554
- onSetRecord(event || createDummyEvent("setrecord"), widgetInstance, data, pageInfo);
554
+ onSetRecord(createDummyEvent("setrecord"), widgetInstance, data, pageInfo);
555
555
  }
556
556
  if (setIsLoadingMore) {
557
557
  setIsLoadingMore(false);
@@ -582,7 +582,7 @@ const usePagination = ({
582
582
  totalElements: (paginationMeta == null ? void 0 : paginationMeta.totalElements) || dataState.fullData.length,
583
583
  totalPages: paginationState.pageCount
584
584
  };
585
- onSetRecord(event || createDummyEvent("setrecord"), widgetInstance, data, pageInfo);
585
+ onSetRecord(createDummyEvent("setrecord"), widgetInstance, data, pageInfo);
586
586
  }
587
587
  if (setIsLoadingMore) {
588
588
  setIsLoadingMore(false);
@@ -679,7 +679,7 @@ const usePagination = ({
679
679
  totalElements: (paginationMeta == null ? void 0 : paginationMeta.totalElements) || fullData.length,
680
680
  totalPages: pageCount
681
681
  };
682
- onSetRecord(event, widgetInstance, data, pageInfo);
682
+ onSetRecord(createDummyEvent("setrecord"), widgetInstance, data, pageInfo);
683
683
  }
684
684
  goToPage();
685
685
  },
@@ -737,7 +737,7 @@ const usePagination = ({
737
737
  totalElements: (paginationMeta == null ? void 0 : paginationMeta.totalElements) || dataState.fullData.length,
738
738
  totalPages: newPageCount
739
739
  };
740
- onSetRecord(event || createDummyEvent("setrecord"), widgetInstance, data, pageInfo);
740
+ onSetRecord(createDummyEvent("setrecord"), widgetInstance, data, pageInfo);
741
741
  }
742
742
  if (setIsLoadingMore) {
743
743
  setIsLoadingMore(false);
@@ -1,7 +1,21 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { useEffect, useRef, useState } from "react";
2
+ import { useCallback, useEffect } from "react";
3
3
  import { Box } from "@mui/material";
4
+ import { useFormState } from "react-hook-form";
5
+ import { get, isString } from "lodash-es";
4
6
  import { FieldValidationError } from "./FieldValidationError";
7
+ import { isColumnValidatable } from "../utils/columnValidation";
8
+ const CELL_SX = {
9
+ position: "relative",
10
+ "& > .wi-error": {
11
+ position: "absolute",
12
+ // Centres the 16px glyph on the editor without depending on the editor's height.
13
+ top: "calc(50% - 10px)",
14
+ right: 0,
15
+ // Above the input, which would otherwise paint over the icon.
16
+ zIndex: 3
17
+ }
18
+ };
5
19
  const EditableCell = ({
6
20
  column,
7
21
  rowData,
@@ -9,8 +23,9 @@ const EditableCell = ({
9
23
  fieldName,
10
24
  widgetType,
11
25
  editValue,
12
- fieldValidationErrorsRef,
13
- cellUpdateCallbacksRef,
26
+ formRef,
27
+ cellErrorsRef,
28
+ columnValidatorsRef,
14
29
  fieldRefs,
15
30
  renderFormWidget,
16
31
  updateFieldValue,
@@ -19,31 +34,32 @@ const EditableCell = ({
19
34
  editMode = "inline"
20
35
  }) => {
21
36
  var _a;
22
- const cellRef = useRef(null);
23
- const [, setForceUpdate] = useState(0);
24
37
  const fieldKey = `${rowId}_${fieldName}`;
25
- const cellRefCallback = (element) => {
26
- cellRef.current = element;
27
- if (element && fieldRefs.current) {
28
- fieldRefs.current[fieldKey] = element;
29
- }
30
- };
38
+ const { errors } = useFormState({ control: formRef.control, name: fieldName, exact: true });
39
+ const error = get(errors, fieldName);
40
+ const showError = Boolean(error);
41
+ const cellRefCallback = useCallback(
42
+ (element) => {
43
+ if (!fieldRefs.current) return;
44
+ if (element) fieldRefs.current[fieldKey] = element;
45
+ else delete fieldRefs.current[fieldKey];
46
+ },
47
+ [fieldKey, fieldRefs]
48
+ );
31
49
  useEffect(() => {
32
- if (cellUpdateCallbacksRef.current) {
33
- cellUpdateCallbacksRef.current[fieldKey] = () => setForceUpdate((prev) => prev + 1);
34
- }
50
+ const cellErrors = cellErrorsRef == null ? void 0 : cellErrorsRef.current;
51
+ if (!cellErrors) return;
52
+ if (showError) cellErrors[fieldKey] = true;
53
+ else delete cellErrors[fieldKey];
35
54
  return () => {
36
- if (cellUpdateCallbacksRef.current) {
37
- delete cellUpdateCallbacksRef.current[fieldKey];
38
- }
55
+ delete cellErrors[fieldKey];
39
56
  };
40
- }, [fieldKey, cellUpdateCallbacksRef]);
41
- const showError = ((_a = fieldValidationErrorsRef.current) == null ? void 0 : _a[fieldKey]) === true;
57
+ }, [showError, fieldKey, cellErrorsRef]);
42
58
  const handleKeyDown = (e) => {
43
- if (onKeyDown) {
44
- onKeyDown(e, rowId);
45
- }
59
+ onKeyDown == null ? void 0 : onKeyDown(e, rowId);
46
60
  };
61
+ const ignoreInForm = !isColumnValidatable(column);
62
+ const columnValidators = (_a = columnValidatorsRef == null ? void 0 : columnValidatorsRef.current) == null ? void 0 : _a[fieldName];
47
63
  return /* @__PURE__ */ jsxs(
48
64
  Box,
49
65
  {
@@ -51,6 +67,7 @@ const EditableCell = ({
51
67
  onKeyDown: editMode === "quickedit" || editMode === "inline" ? handleKeyDown : void 0,
52
68
  "data-field-name": fieldName,
53
69
  "data-row-id": rowId,
70
+ sx: CELL_SX,
54
71
  children: [
55
72
  renderFormWidget(
56
73
  fieldName,
@@ -64,14 +81,20 @@ const EditableCell = ({
64
81
  defaultvalue: column.defaultvalue,
65
82
  sessionKey: `${sessionKey}_${rowId}_${fieldName}`,
66
83
  rowData,
67
- column
84
+ column,
85
+ formRef,
86
+ // formKey stays stable; widget name keeps session-unique value
87
+ formKey: fieldName,
88
+ validators: columnValidators == null ? void 0 : columnValidators.validators,
89
+ asyncValidators: columnValidators == null ? void 0 : columnValidators.asyncValidators,
90
+ ignoreInForm
68
91
  }
69
92
  ),
70
93
  showError && /* @__PURE__ */ jsx(
71
94
  FieldValidationError,
72
95
  {
73
96
  showError: true,
74
- title: column.validationmessage ? column.validationmessage : column.required ? "This field is required" : "Field validation failed"
97
+ title: isString(error == null ? void 0 : error.message) && error.message || column.validationmessage || (column.required ? "This field is required" : "Field validation failed")
75
98
  }
76
99
  )
77
100
  ]
@@ -9,7 +9,7 @@ const FieldValidationError = ({
9
9
  return /* @__PURE__ */ jsx(
10
10
  "span",
11
11
  {
12
- className: "text-danger wi wi-error",
12
+ className: "app-label text-danger wi wi-error",
13
13
  "data-placement": "top",
14
14
  "data-container": "body",
15
15
  title
@@ -49,7 +49,11 @@ const RowExpansionButton = ({
49
49
  "aria-label": ariaLabel,
50
50
  "aria-expanded": isExpanded,
51
51
  "aria-live": "polite",
52
- tabIndex: 0
52
+ tabIndex: 0,
53
+ styles: __spreadValues({
54
+ minWidth: 0,
55
+ padding: 0
56
+ }, config.styles)
53
57
  };
54
58
  if (config.listener) {
55
59
  commonProps.listener = config.listener;
@@ -69,6 +69,8 @@ const ExpansionCell = memo(({ rowId, rowData, isExpanded, onToggle, config }) =>
69
69
  textAlign: "center",
70
70
  position: "relative",
71
71
  width: config.columnwidth || DEFAULT_EXPANSION_WIDTH,
72
+ minWidth: config.columnwidth || DEFAULT_EXPANSION_WIDTH,
73
+ maxWidth: config.columnwidth || DEFAULT_EXPANSION_WIDTH,
72
74
  padding: "4px"
73
75
  },
74
76
  children: /* @__PURE__ */ jsx(Box, { component: "span", className: "row-expansion-column", "data-identifier": "rowExpansionButtons", children: /* @__PURE__ */ jsx(