@wavemaker-ai/react-runtime 1.0.0-rc.647712 → 12.0.0-rc.647733

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 (106) hide show
  1. package/components/basic/richtexteditor/index.d.ts +1 -0
  2. package/components/basic/search/index.js +5 -4
  3. package/components/basic/search/utils.d.ts +1 -0
  4. package/components/basic/search/utils.js +9 -0
  5. package/components/common/index.d.ts +2 -0
  6. package/components/common/index.js +2 -0
  7. package/components/common/partial-content-wrapper.d.ts +15 -0
  8. package/components/common/partial-content-wrapper.js +11 -0
  9. package/components/container/index.js +5 -2
  10. package/components/container/tabs/index.js +5 -3
  11. package/components/container/wizard/index.js +36 -3
  12. package/components/container/wizard/props.d.ts +2 -2
  13. package/components/data/form/dynamic-fields/WmxDynamicFormField.js +9 -23
  14. package/components/data/form/form-controller/props.d.ts +2 -0
  15. package/components/data/form/form-controller/utils.js +3 -2
  16. package/components/data/form/form-controller/validation-contrustor.js +112 -1
  17. package/components/data/form/form-controller/withFormController.js +1 -1
  18. package/components/data/form/form-field/index.js +6 -3
  19. package/components/data/form/form-field/props.d.ts +1 -0
  20. package/components/data/list/components/ListItemWithTemplate.js +1 -1
  21. package/components/data/list/index.js +1 -1
  22. package/components/data/table/components/EditableCell.js +47 -24
  23. package/components/data/table/components/FieldValidationError.js +1 -1
  24. package/components/data/table/components/TableHeader.js +9 -3
  25. package/components/data/table/hooks/useFormWidget.js +11 -0
  26. package/components/data/table/hooks/useRowSelection.js +58 -1
  27. package/components/data/table/hooks/useTableEdit.d.ts +1 -1
  28. package/components/data/table/hooks/useTableEdit.js +115 -75
  29. package/components/data/table/hooks/useTableEditForms.d.ts +25 -0
  30. package/components/data/table/hooks/useTableEditForms.js +30 -0
  31. package/components/data/table/index.js +68 -32
  32. package/components/data/table/props.d.ts +42 -23
  33. package/components/data/table/utils/buildSelectionColumns.js +3 -3
  34. package/components/data/table/utils/columnProxy.d.ts +7 -1
  35. package/components/data/table/utils/columnProxy.js +21 -1
  36. package/components/data/table/utils/columnValidation.d.ts +19 -0
  37. package/components/data/table/utils/columnValidation.js +76 -0
  38. package/components/data/table/utils/constants.d.ts +2 -0
  39. package/components/data/table/utils/constants.js +2 -0
  40. package/components/data/table/utils/index.d.ts +4 -12
  41. package/components/data/table/utils/index.js +13 -77
  42. package/components/data/table/utils/selectionUtils.js +13 -5
  43. package/components/input/chips/index.d.ts +1 -0
  44. package/components/input/color-picker/index.d.ts +1 -0
  45. package/components/input/currency/index.d.ts +1 -0
  46. package/components/input/default/checkbox/index.d.ts +1 -0
  47. package/components/input/default/checkboxset/index.d.ts +1 -0
  48. package/components/input/default/radioset/index.d.ts +1 -0
  49. package/components/input/default/switch/index.d.ts +1 -0
  50. package/components/input/epoch/datetime/index.js +10 -2
  51. package/components/input/number/index.d.ts +1 -0
  52. package/components/input/rating/index.d.ts +1 -0
  53. package/components/input/select/index.d.ts +1 -0
  54. package/components/input/slider/index.d.ts +1 -0
  55. package/components/input/text/index.d.ts +1 -0
  56. package/components/input/textarea/index.d.ts +1 -0
  57. package/components/input/upload/index.d.ts +1 -0
  58. package/components/layout/footer/index.js +4 -2
  59. package/components/layout/footer/props.d.ts +1 -0
  60. package/components/layout/header/index.js +29 -3
  61. package/components/layout/header/props.d.ts +1 -0
  62. package/components/layout/leftnav/index.js +22 -6
  63. package/components/layout/leftnav/props.d.ts +1 -0
  64. package/components/layout/leftnav/utils/page-class-util.d.ts +1 -0
  65. package/components/layout/leftnav/utils/page-class-util.js +4 -3
  66. package/components/layout/rightnav/index.js +4 -2
  67. package/components/layout/rightnav/props.d.ts +1 -0
  68. package/components/layout/topnav/index.js +4 -2
  69. package/components/layout/topnav/props.d.ts +1 -0
  70. package/components/navbar/index.js +32 -7
  71. package/components/navigation/menu/index.js +6 -2
  72. package/components/page/index.js +60 -19
  73. package/components/page/page-context.d.ts +4 -0
  74. package/core/proxy-service.js +86 -19
  75. package/higherOrder/BaseApp.js +1 -1
  76. package/higherOrder/BasePage.js +2 -1
  77. package/higherOrder/withBaseWrapper.js +10 -2
  78. package/hooks/useHttp.d.ts +14 -4
  79. package/hooks/useHttp.js +47 -9
  80. package/package-lock.json +316 -310
  81. package/package.json +3 -3
  82. package/runtime-dynamic/App.js +21 -2
  83. package/runtime-dynamic/app-initializer.js +8 -1
  84. package/runtime-dynamic/factories/dynamic-component.js +4 -3
  85. package/runtime-dynamic/main.d.ts +1 -0
  86. package/runtime-dynamic/main.js +9 -1
  87. package/runtime-dynamic/services/compile-render.js +7 -0
  88. package/runtime-dynamic/services/css-scoping.d.ts +1 -1
  89. package/runtime-dynamic/services/css-scoping.js +2 -2
  90. package/runtime-dynamic/services/variable-factory.js +2 -1
  91. package/runtime-dynamic/services/variable-transpiler.js +4 -1
  92. package/runtime-dynamic/wmx-shared.d.ts +40 -0
  93. package/runtime-dynamic/wmx-shared.js +33 -0
  94. package/utils/style-utils.js +1 -1
  95. package/utils/wmx.utils.d.ts +0 -1
  96. package/utils/wmx.utils.js +0 -25
  97. package/variables/crud-variable.d.ts +10 -0
  98. package/variables/crud-variable.js +53 -2
  99. package/variables/live-variable.d.ts +1 -0
  100. package/variables/live-variable.js +2 -1
  101. package/variables/operation-params.d.ts +29 -0
  102. package/variables/operation-params.js +69 -0
  103. package/variables/service-variable.d.ts +9 -0
  104. package/variables/service-variable.js +21 -2
  105. package/components/data/table/utils/validation.d.ts +0 -13
  106. package/components/data/table/utils/validation.js +0 -82
@@ -78,6 +78,7 @@ declare const _default: React.ComponentType<{
78
78
  standalone?: boolean;
79
79
  formRef?: any;
80
80
  formKey?: string;
81
+ hideValidationMessage?: boolean;
81
82
  name: string;
82
83
  datavalue?: any;
83
84
  defaultvalue?: any;
@@ -55,6 +55,7 @@ import {
55
55
  CustomTemplateCaption,
56
56
  useCustomTemplate
57
57
  } from "../../common/customTemplate";
58
+ import { toPlainText } from "./utils";
58
59
  const DEFAULT_CLASS = "app-search input-group";
59
60
  const Search = React.forwardRef((props, ref) => {
60
61
  const _a = props, {
@@ -303,7 +304,7 @@ const Search = React.forwardRef((props, ref) => {
303
304
  const value2 = Array.isArray(datavalue) ? datavalue[0] : datavalue;
304
305
  if (value2) {
305
306
  const key = searchkey.split(",")[0] || searchkey;
306
- const item = (getDisplayExpression == null ? void 0 : getDisplayExpression(value2)) || value2[key];
307
+ const item = toPlainText(getDisplayExpression == null ? void 0 : getDisplayExpression(value2)) || value2[key];
307
308
  if (item) {
308
309
  setQuery(item);
309
310
  handleQueryChange(item);
@@ -313,7 +314,7 @@ const Search = React.forwardRef((props, ref) => {
313
314
  } else if (datafield !== "All Fields" && datafield) {
314
315
  let findItem = normalizedData == null ? void 0 : normalizedData.find((item) => item.value === datavalue);
315
316
  if (findItem) {
316
- let displayValue2 = (getDisplayExpression == null ? void 0 : getDisplayExpression(getSelectedItem(findItem))) || findItem.label;
317
+ let displayValue2 = toPlainText(getDisplayExpression == null ? void 0 : getDisplayExpression(getSelectedItem(findItem))) || findItem.label;
317
318
  setQuery(displayValue2);
318
319
  handleQueryChange(displayValue2);
319
320
  handleUpdateDatavalue(findItem);
@@ -342,7 +343,7 @@ const Search = React.forwardRef((props, ref) => {
342
343
  if (!key) return;
343
344
  const findItem = response.find((item) => item[key] == value2);
344
345
  if (findItem && Object.keys(findItem).length > 0) {
345
- let displayValue2 = (getDisplayExpression == null ? void 0 : getDisplayExpression(getSelectedItem(findItem))) || findItem[key];
346
+ let displayValue2 = toPlainText(getDisplayExpression == null ? void 0 : getDisplayExpression(getSelectedItem(findItem))) || findItem[key];
346
347
  setQuery(displayValue2);
347
348
  handleQueryChange(displayValue2);
348
349
  }
@@ -816,7 +817,7 @@ const Search = React.forwardRef((props, ref) => {
816
817
  try {
817
818
  const item = JSON.parse(itemData);
818
819
  const selectedItem2 = getSelectedItem(item);
819
- const displayVal = (getDisplayExpression == null ? void 0 : getDisplayExpression(selectedItem2)) || item.displayValue || item.label;
820
+ const displayVal = toPlainText(getDisplayExpression == null ? void 0 : getDisplayExpression(selectedItem2)) || item.displayValue || item.label;
820
821
  if (props.isSearchInChips) {
821
822
  setQuery("");
822
823
  handleQueryChange("");
@@ -0,0 +1 @@
1
+ export declare function toPlainText(value: any): any;
@@ -0,0 +1,9 @@
1
+ import DOMPurify from "dompurify";
2
+ function toPlainText(value) {
3
+ if (value == null) return value;
4
+ const str = String(value);
5
+ return /<[^>]+>/.test(str) ? DOMPurify.sanitize(str, { ALLOWED_TAGS: [] }) : str;
6
+ }
7
+ export {
8
+ toPlainText
9
+ };
@@ -3,3 +3,5 @@ export { WmSkeleton, SKELETON_REGISTRY, shouldShowSkeleton, useShouldShowSkeleto
3
3
  export type { WmSkeletonProps, SkeletonConfig } from "./wm-skeleton";
4
4
  export { WmAppIcon } from "./WmAppIcon";
5
5
  export type { WmAppIconProps } from "./WmAppIcon/props";
6
+ export { PartialContentWrapper } from "./partial-content-wrapper";
7
+ export type { PartialContentWrapperProps } from "./partial-content-wrapper";
@@ -6,8 +6,10 @@ import {
6
6
  useShouldShowSkeleton
7
7
  } from "./wm-skeleton";
8
8
  import { WmAppIcon } from "./WmAppIcon";
9
+ import { PartialContentWrapper } from "./partial-content-wrapper";
9
10
  export {
10
11
  AppSpinner,
12
+ PartialContentWrapper,
11
13
  SKELETON_REGISTRY,
12
14
  WmAppIcon,
13
15
  WmSkeleton,
@@ -0,0 +1,15 @@
1
+ import { ReactNode } from "react";
2
+ export interface PartialContentWrapperProps {
3
+ content?: string;
4
+ children?: ReactNode;
5
+ }
6
+ /**
7
+ * Wraps a layout region's rendered partial in an `app-partial-{content}` div,
8
+ * matching the DOM produced by WmPartialContainer in preview so CSS scoped to
9
+ * that class (e.g. `.app-partial-header`) also applies in codegen builds.
10
+ * Used by the header/leftnav/rightnav/topnav/footer layout regions only.
11
+ */
12
+ export declare const PartialContentWrapper: {
13
+ ({ content, children }: PartialContentWrapperProps): import("react/jsx-runtime").JSX.Element;
14
+ displayName: string;
15
+ };
@@ -0,0 +1,11 @@
1
+ import { Fragment, jsx } from "react/jsx-runtime";
2
+ const PartialContentWrapper = ({ content, children }) => {
3
+ if (!content) {
4
+ return /* @__PURE__ */ jsx(Fragment, { children });
5
+ }
6
+ return /* @__PURE__ */ jsx("div", { className: `app-partial-${content.toLowerCase()}`, children });
7
+ };
8
+ PartialContentWrapper.displayName = "PartialContentWrapper";
9
+ export {
10
+ PartialContentWrapper
11
+ };
@@ -42,7 +42,10 @@ import { clsx } from "clsx";
42
42
  import { withBaseWrapper } from "../../higherOrder/withBaseWrapper";
43
43
  import { useLayoutSize } from "../../hooks/useLayoutSize";
44
44
  import { removeInvalidAttributes } from "../../utils/attr";
45
- import { normalizeBackgroundImage } from "../../utils/style-utils";
45
+ import {
46
+ normalizeBackgroundImage,
47
+ sanitizeStyleObject
48
+ } from "../../utils/style-utils";
46
49
  import { publishPartialNamespaces, toHostWidgetProps } from "../../utils/partial-host-util";
47
50
  const DEFAULT_CLASS = "app-container";
48
51
  const WmContainerContext = createContext(void 0);
@@ -261,7 +264,7 @@ const WmContainer = (props) => {
261
264
  id,
262
265
  hidden: props.hidden || hostShouldHide
263
266
  }, removeInvalidAttributes(rest)), domEvents), { name }), {
264
- style: __spreadValues(__spreadValues({}, containerStyles), conditionalstyle),
267
+ style: __spreadValues(__spreadValues({}, sanitizeStyleObject(containerStyles)), sanitizeStyleObject(conditionalstyle)),
265
268
  ref: containerRef
266
269
  }), direction ? { direction } : {}), {
267
270
  children: renderPartial ? renderPartial(restPartialProps, handleOnLoad) : children
@@ -26,6 +26,7 @@ import React, {
26
26
  useCallback,
27
27
  useContext,
28
28
  useEffect,
29
+ useLayoutEffect,
29
30
  useMemo,
30
31
  useRef,
31
32
  useState
@@ -169,6 +170,7 @@ const WmTabs = memo(
169
170
  const changeTab = (newIndex) => {
170
171
  if (newIndex >= 0 && newIndex < panesCount.current && newIndex !== currentSelectedIndex.current) {
171
172
  prevSelectedIndex.current = currentSelectedIndex.current;
173
+ currentSelectedIndex.current = newIndex;
172
174
  setSelectedIndex(newIndex);
173
175
  saveStateToStorage(newIndex);
174
176
  return true;
@@ -257,7 +259,7 @@ const WmTabs = memo(
257
259
  activeTab: getActiveTab(activeIndex)
258
260
  });
259
261
  };
260
- useEffect(() => {
262
+ useLayoutEffect(() => {
261
263
  updateListener();
262
264
  }, [prev, next, goToTab]);
263
265
  const getStateFromStorage = () => {
@@ -395,7 +397,7 @@ const WmTabs = memo(
395
397
  });
396
398
  panesCount.current = tabIndex;
397
399
  return headers;
398
- }, [dataset, paneHeaderOverrides]);
400
+ }, [dataset, paneHeaderOverrides, renderTabHeader]);
399
401
  const renderStaticTabs = React.useCallback(() => {
400
402
  const visibleChildren = filterVisibleChildren(children, hiddenTabNames);
401
403
  panesCount.current = visibleChildren.length;
@@ -555,7 +557,7 @@ const WmTabs = memo(
555
557
  "styles"
556
558
  ];
557
559
  return keys.every((key) => {
558
- if (key === "children") {
560
+ if (key === "children" || key === "dataset") {
559
561
  return prev[key] === next[key];
560
562
  }
561
563
  return isEqual(prev[key], next[key]);
@@ -51,6 +51,7 @@ import { getFormData } from "../../../utils/form-utils";
51
51
  import { useParentFormData } from "../../data/form/form-context";
52
52
  import isEqual from "lodash-es/isEqual";
53
53
  import withStandalone from "../../../higherOrder/withStandalone";
54
+ import { publishPartialNamespaces, toHostWidgetProps } from "../../../utils/partial-host-util";
54
55
  import {
55
56
  WmSkeleton,
56
57
  SKELETON_REGISTRY,
@@ -89,7 +90,9 @@ const WmWizardComponent = memo(
89
90
  width,
90
91
  height,
91
92
  render,
92
- standalone = false
93
+ standalone = false,
94
+ viewParent,
95
+ prefab
93
96
  } = props;
94
97
  const [steps, setSteps] = useState([]);
95
98
  const [wizardMessage, setWizardMessage] = useState(message || { caption: "", type: "" });
@@ -99,6 +102,34 @@ const WmWizardComponent = memo(
99
102
  const navIndexRef = useRef(-1);
100
103
  const loadedStepNameRef = useRef(null);
101
104
  const [formReady, setFormReady] = useState(false);
105
+ const loadedStepPartialKeysRef = useRef(/* @__PURE__ */ new Set());
106
+ const currentStepRef = useRef(null);
107
+ const currentStepIndexRef = useRef(-1);
108
+ const handleStepPartialOnLoad = useCallback(
109
+ (widget, partialName) => {
110
+ var _a, _b, _c, _d;
111
+ if (!viewParent || !viewParent.Widgets) return;
112
+ const hostKey = ((_a = currentStepRef.current) == null ? void 0 : _a.name) || partialName;
113
+ if (!hostKey || loadedStepPartialKeysRef.current.has(hostKey)) return;
114
+ loadedStepPartialKeysRef.current.add(hostKey);
115
+ if (!widget || prefab) {
116
+ viewParent.Widgets[hostKey] = widget || props;
117
+ } else {
118
+ if (!viewParent.Widgets[hostKey]) {
119
+ viewParent.Widgets[hostKey] = toHostWidgetProps(props);
120
+ }
121
+ publishPartialNamespaces(viewParent.Widgets[hostKey], widget);
122
+ }
123
+ if (((_b = currentStepRef.current) == null ? void 0 : _b.name) === hostKey) {
124
+ (_d = (_c = currentStepRef.current) == null ? void 0 : _c.onLoad) == null ? void 0 : _d.call(
125
+ _c,
126
+ viewParent.Widgets[hostKey],
127
+ currentStepIndexRef.current
128
+ );
129
+ }
130
+ },
131
+ [viewParent, prefab]
132
+ );
102
133
  const parentFormContext = useParentFormData();
103
134
  const isInsideOuterForm = !!parentFormContext && Object.keys(parentFormContext).length > 0;
104
135
  const createDynamicSteps = useCallback(
@@ -146,6 +177,7 @@ const WmWizardComponent = memo(
146
177
  [defaultstepindex]
147
178
  );
148
179
  const currentStep = useMemo(() => steps.find((step) => step.active) || null, [steps]);
180
+ currentStepRef.current = currentStep;
149
181
  const visibleSteps = useMemo(() => steps.filter((step) => step.show), [steps]);
150
182
  const visibleStepsRef = useRef(visibleSteps);
151
183
  visibleStepsRef.current = visibleSteps;
@@ -157,6 +189,7 @@ const WmWizardComponent = memo(
157
189
  }, [currentStep, visibleSteps]);
158
190
  useEffect(() => {
159
191
  navIndexRef.current = currentStepIndex;
192
+ currentStepIndexRef.current = currentStepIndex;
160
193
  }, [currentStepIndex]);
161
194
  const hasNextStep = useMemo(
162
195
  () => currentStepIndex < visibleSteps.length - 1,
@@ -780,7 +813,7 @@ const WmWizardComponent = memo(
780
813
  className: clsx("app-wizard-step-content", {
781
814
  active: step.active
782
815
  }),
783
- children: (currentStep == null ? void 0 : currentStep.name) && step.active && currentStep.render ? currentStep.render(step, index) : step.children
816
+ children: (currentStep == null ? void 0 : currentStep.name) && step.active && currentStep.render ? currentStep.render(step, handleStepPartialOnLoad) : step.children
784
817
  }
785
818
  )
786
819
  ) : (
@@ -796,7 +829,7 @@ const WmWizardComponent = memo(
796
829
  }),
797
830
  listener,
798
831
  isInsideWizard: true,
799
- children: (currentStep == null ? void 0 : currentStep.name) && step.active && currentStep.render ? currentStep.render(step, index) : step.children
832
+ children: (currentStep == null ? void 0 : currentStep.name) && step.active && currentStep.render ? currentStep.render(step, handleStepPartialOnLoad) : step.children
800
833
  }
801
834
  )
802
835
  )
@@ -49,7 +49,7 @@ export interface WizardStepData extends Record<string, unknown> {
49
49
  isValid: boolean;
50
50
  isInitialized: boolean;
51
51
  content?: ReactNode;
52
- render?: (step: WizardStepData, stepIndex?: number, dataset?: Record<string, unknown>[]) => ReactNode;
52
+ render?: (step: WizardStepData, onLoad?: (widget?: Record<string, unknown>, partialName?: string) => void) => ReactNode;
53
53
  dynamicStepIndex?: number;
54
54
  isdynamic?: boolean;
55
55
  onLoad?: (step: WizardStepData, stepIndex: number) => void;
@@ -256,7 +256,7 @@ export interface WmWizardStepProps {
256
256
  ref?: React.Ref<unknown>;
257
257
  className?: string;
258
258
  props?: Record<string, unknown>;
259
- render?: (item: Record<string, unknown>, index?: number, dataset?: Record<string, unknown>[]) => ReactNode;
259
+ render?: (props: Record<string, unknown>, onLoad?: (widget?: Record<string, unknown>, partialName?: string) => void) => ReactNode;
260
260
  listener?: Record<string, unknown>;
261
261
  }
262
262
  /**
@@ -30,38 +30,24 @@ var __objRest = (source, exclude) => {
30
30
  return target;
31
31
  };
32
32
  import { jsx } from "react/jsx-runtime";
33
- import { useEffect, useMemo, useState } from "react";
33
+ import { useMemo } from "react";
34
34
  import WmText from "../../../input/text";
35
35
  import withFormController from "../form-controller/withFormController";
36
- import { loadWmxComponent, getWmxComponentName } from "../../../../utils/wmx.utils";
36
+ import { getWmxComponentName, getWmxModule } from "../../../../utils/wmx.utils";
37
37
  const WmxDynamicFormField = ({ field, fieldProps }) => {
38
- var _b;
38
+ var _b, _c, _d;
39
39
  const componentName = getWmxComponentName(String((field == null ? void 0 : field.widget) || ""));
40
40
  const _a = fieldProps, { class: className } = _a, restProps = __objRest(_a, ["class"]);
41
41
  const resolvedClassName = className || fieldProps.className;
42
- const [RawComponent, setRawComponent] = useState(null);
43
- useEffect(() => {
44
- if (!componentName) return;
45
- let isActive = true;
46
- loadWmxComponent(componentName).then((component) => {
47
- if (isActive) {
48
- setRawComponent(component);
49
- }
50
- }).catch((e) => {
51
- console.error(e);
52
- });
53
- return () => {
54
- isActive = false;
55
- };
56
- }, [componentName]);
57
- const EnhancedWmxComponent = useMemo(() => {
58
- if (!RawComponent) return null;
59
- return withFormController(RawComponent);
60
- }, [RawComponent]);
42
+ const RawComponent = componentName ? (_c = (_b = getWmxModule()) == null ? void 0 : _b[`Wmx${componentName}`]) != null ? _c : null : null;
43
+ const EnhancedWmxComponent = useMemo(
44
+ () => RawComponent ? withFormController(RawComponent) : null,
45
+ [RawComponent]
46
+ );
61
47
  if (!EnhancedWmxComponent) {
62
48
  return /* @__PURE__ */ jsx(WmText, __spreadProps(__spreadValues({ name: field == null ? void 0 : field.name }, restProps), { className: resolvedClassName }));
63
49
  }
64
- const dataset = (_b = field == null ? void 0 : field.dataset) != null ? _b : fieldProps == null ? void 0 : fieldProps.dataset;
50
+ const dataset = (_d = field == null ? void 0 : field.dataset) != null ? _d : fieldProps == null ? void 0 : fieldProps.dataset;
65
51
  return /* @__PURE__ */ jsx(
66
52
  EnhancedWmxComponent,
67
53
  __spreadProps(__spreadValues({
@@ -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;
@@ -246,7 +246,7 @@ const withFormController = (WrappedComponent) => {
246
246
  fieldRef.current = field;
247
247
  const processedValue = processFieldValue(field.value, type, props.datafield);
248
248
  const errorState = getErrorState(fieldState, validationType, touched);
249
- const isExplicitFormField = props.formfield === true || props.formfield === "true";
249
+ const isExplicitFormField = !props.hideValidationMessage && (props.formfield === true || props.formfield === "true");
250
250
  let valueToUse;
251
251
  if (processedValue !== void 0) {
252
252
  valueToUse = processedValue;
@@ -126,14 +126,14 @@ const WmFormField = memo(
126
126
  });
127
127
  }, [props.dataset, props.datafield, props.displayfield, props.displaylabel, props.searchkey]);
128
128
  function renderFormFields() {
129
- var _a2, _b2, _c2, _d2, _e, _f, _g, _h, _i, _j, _k, _l, _m;
129
+ var _a2, _b2, _c2, _d2, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
130
130
  if (props.formRef) {
131
131
  const errors = (_a2 = props.formRef) == null ? void 0 : _a2.errors;
132
132
  const formKey = (_b2 = props.formKey) != null ? _b2 : props.name;
133
133
  const fieldError = formKey && errors ? get(errors, formKey) : void 0;
134
134
  const invalid = Boolean(fieldError);
135
135
  const invalidCls = invalid ? " text-danger " : "";
136
- return /* @__PURE__ */ jsx(Fragment, { children: (_m = props == null ? void 0 : props.renderFormFields) == null ? void 0 : _m.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
137
  // proxyProps snapshots onChange once at mount; nothing resyncs it, so a
138
138
  // handler assigned after mount (e.g. from a page's onReady) is never seen
139
139
  // unless we read the live prop here, same as onTrailingiconclick below.
@@ -156,7 +156,10 @@ const WmFormField = memo(
156
156
  onTrailingiconclick: (_i = overriddenItemsRef.current.onTrailingiconclick) != null ? _i : props.onTrailingiconclick,
157
157
  trailingiconurl: (_j = overriddenItemsRef.current.trailingiconurl) != null ? _j : props.trailingiconurl,
158
158
  onLeadingiconclick: (_k = overriddenItemsRef.current.onLeadingiconclick) != null ? _k : props.onLeadingiconclick,
159
- leadingiconurl: (_l = overriddenItemsRef.current.leadingiconurl) != null ? _l : props.leadingiconurl
159
+ leadingiconurl: (_l = overriddenItemsRef.current.leadingiconurl) != null ? _l : props.leadingiconurl,
160
+ styles: {},
161
+ style: {},
162
+ limitdisplaytext: (_m = overriddenItemsRef.current.limitdisplaytext) != null ? _m : props.limitdisplaytext
160
163
  })) });
161
164
  } else {
162
165
  return null;
@@ -211,6 +211,7 @@ export interface FormFieldProps {
211
211
  leadingiconurl?: string;
212
212
  onLeadingiconclick?: (...args: any[]) => void;
213
213
  onChange?: (...args: any[]) => void;
214
+ limitdisplaytext?: string;
214
215
  }
215
216
  /**
216
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, {});
@@ -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,