@syncfusion/ej2-form-renderer 34.2.8 → 35.1.42

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/dist/ej2-form-renderer.umd.min.js +2 -2
  2. package/dist/ej2-form-renderer.umd.min.js.map +1 -1
  3. package/dist/es6/ej2-form-renderer.es2015.js +3271 -1523
  4. package/dist/es6/ej2-form-renderer.es2015.js.map +1 -1
  5. package/dist/es6/ej2-form-renderer.es5.js +3326 -1540
  6. package/dist/es6/ej2-form-renderer.es5.js.map +1 -1
  7. package/dist/global/ej2-form-renderer.min.js +2 -2
  8. package/dist/global/ej2-form-renderer.min.js.map +1 -1
  9. package/dist/global/index.d.ts +1 -1
  10. package/package.json +11 -11
  11. package/src/{common → form-renderer/common}/checkbox-group.js +1 -1
  12. package/src/{common → form-renderer/common}/conditional-rule-engine.d.ts +1 -6
  13. package/src/{common → form-renderer/common}/custom-validation-engine.d.ts +1 -1
  14. package/src/{common → form-renderer/common}/expressions/expression-engine.d.ts +1 -4
  15. package/src/{common → form-renderer/common}/expressions/expression-parser.d.ts +1 -9
  16. package/src/{common → form-renderer/common}/index.d.ts +2 -0
  17. package/src/{common → form-renderer/common}/index.js +2 -0
  18. package/src/{common → form-renderer/common}/json-converter.d.ts +6 -1
  19. package/src/{common → form-renderer/common}/json-converter.js +49 -8
  20. package/src/form-renderer/common/props-forwarder.d.ts +38 -0
  21. package/src/form-renderer/common/props-forwarder.js +123 -0
  22. package/src/{common → form-renderer/common}/utils.d.ts +6 -0
  23. package/src/form-renderer/form-renderer/custom-widget-resolver.d.ts +17 -0
  24. package/src/form-renderer/form-renderer/custom-widget-resolver.js +39 -0
  25. package/src/form-renderer/form-renderer/form-renderer-model.d.ts +125 -0
  26. package/src/form-renderer/form-renderer/form-renderer.d.ts +373 -0
  27. package/src/form-renderer/{form-renderer.js → form-renderer/form-renderer.js} +429 -298
  28. package/src/form-renderer/form-renderer/index.d.ts +7 -0
  29. package/src/form-renderer/form-renderer/index.js +6 -0
  30. package/src/form-renderer/{render-form-field.js → form-renderer/render-form-field.js} +154 -25
  31. package/src/form-renderer/index.d.ts +3 -4
  32. package/src/form-renderer/index.js +3 -3
  33. package/src/index.d.ts +1 -4
  34. package/src/index.js +1 -4
  35. package/common.d.ts +0 -4
  36. package/common.js +0 -4
  37. package/src/form-renderer/form-renderer-model.d.ts +0 -65
  38. package/src/form-renderer/form-renderer.d.ts +0 -425
  39. package/styles/bds-lite.css +0 -599
  40. package/styles/bds-lite.scss +0 -2
  41. package/styles/bds.css +0 -599
  42. package/styles/bds.scss +0 -2
  43. package/styles/bootstrap-dark-lite.css +0 -608
  44. package/styles/bootstrap-dark-lite.scss +0 -2
  45. package/styles/bootstrap-dark.css +0 -608
  46. package/styles/bootstrap-dark.scss +0 -2
  47. package/styles/bootstrap-lite.css +0 -595
  48. package/styles/bootstrap-lite.scss +0 -2
  49. package/styles/bootstrap.css +0 -595
  50. package/styles/bootstrap.scss +0 -2
  51. package/styles/bootstrap4-lite.css +0 -595
  52. package/styles/bootstrap4-lite.scss +0 -2
  53. package/styles/bootstrap4.css +0 -595
  54. package/styles/bootstrap4.scss +0 -2
  55. package/styles/bootstrap5-dark-lite.css +0 -595
  56. package/styles/bootstrap5-dark-lite.scss +0 -2
  57. package/styles/bootstrap5-dark.css +0 -595
  58. package/styles/bootstrap5-dark.scss +0 -2
  59. package/styles/bootstrap5-lite.css +0 -595
  60. package/styles/bootstrap5-lite.scss +0 -2
  61. package/styles/bootstrap5.3-lite.css +0 -679
  62. package/styles/bootstrap5.3-lite.scss +0 -2
  63. package/styles/bootstrap5.3.css +0 -679
  64. package/styles/bootstrap5.3.scss +0 -2
  65. package/styles/bootstrap5.css +0 -595
  66. package/styles/bootstrap5.scss +0 -2
  67. package/styles/fabric-dark-lite.css +0 -608
  68. package/styles/fabric-dark-lite.scss +0 -2
  69. package/styles/fabric-dark.css +0 -608
  70. package/styles/fabric-dark.scss +0 -2
  71. package/styles/fabric-lite.css +0 -595
  72. package/styles/fabric-lite.scss +0 -2
  73. package/styles/fabric.css +0 -595
  74. package/styles/fabric.scss +0 -2
  75. package/styles/fluent-dark-lite.css +0 -595
  76. package/styles/fluent-dark-lite.scss +0 -2
  77. package/styles/fluent-dark.css +0 -595
  78. package/styles/fluent-dark.scss +0 -2
  79. package/styles/fluent-lite.css +0 -595
  80. package/styles/fluent-lite.scss +0 -2
  81. package/styles/fluent.css +0 -595
  82. package/styles/fluent.scss +0 -2
  83. package/styles/fluent2-lite.css +0 -681
  84. package/styles/fluent2-lite.scss +0 -2
  85. package/styles/fluent2.css +0 -681
  86. package/styles/fluent2.scss +0 -2
  87. package/styles/form-renderer/_all.scss +0 -2
  88. package/styles/form-renderer/_bds-definition.scss +0 -8
  89. package/styles/form-renderer/_bootstrap-dark-definition.scss +0 -8
  90. package/styles/form-renderer/_bootstrap-definition.scss +0 -8
  91. package/styles/form-renderer/_bootstrap4-definition.scss +0 -8
  92. package/styles/form-renderer/_bootstrap5-dark-definition.scss +0 -8
  93. package/styles/form-renderer/_bootstrap5-definition.scss +0 -8
  94. package/styles/form-renderer/_bootstrap5.3-definition.scss +0 -8
  95. package/styles/form-renderer/_fabric-dark-definition.scss +0 -8
  96. package/styles/form-renderer/_fabric-definition.scss +0 -8
  97. package/styles/form-renderer/_fluent-dark-definition.scss +0 -8
  98. package/styles/form-renderer/_fluent-definition.scss +0 -8
  99. package/styles/form-renderer/_fluent2-definition.scss +0 -8
  100. package/styles/form-renderer/_highcontrast-definition.scss +0 -8
  101. package/styles/form-renderer/_highcontrast-light-definition.scss +0 -8
  102. package/styles/form-renderer/_layout.scss +0 -480
  103. package/styles/form-renderer/_material-dark-definition.scss +0 -8
  104. package/styles/form-renderer/_material-definition.scss +0 -8
  105. package/styles/form-renderer/_material3-dark-definition.scss +0 -8
  106. package/styles/form-renderer/_material3-definition.scss +0 -8
  107. package/styles/form-renderer/_mixin.scss +0 -26
  108. package/styles/form-renderer/_tailwind-dark-definition.scss +0 -8
  109. package/styles/form-renderer/_tailwind-definition.scss +0 -8
  110. package/styles/form-renderer/_tailwind3-definition.scss +0 -8
  111. package/styles/form-renderer/_theme.scss +0 -69
  112. package/styles/form-renderer/_variables.scss +0 -2
  113. package/styles/form-renderer/bds.css +0 -599
  114. package/styles/form-renderer/bds.scss +0 -2
  115. package/styles/form-renderer/bootstrap-dark.css +0 -608
  116. package/styles/form-renderer/bootstrap-dark.scss +0 -2
  117. package/styles/form-renderer/bootstrap.css +0 -595
  118. package/styles/form-renderer/bootstrap.scss +0 -2
  119. package/styles/form-renderer/bootstrap4.css +0 -595
  120. package/styles/form-renderer/bootstrap4.scss +0 -2
  121. package/styles/form-renderer/bootstrap5-dark.css +0 -595
  122. package/styles/form-renderer/bootstrap5-dark.scss +0 -2
  123. package/styles/form-renderer/bootstrap5.3.css +0 -679
  124. package/styles/form-renderer/bootstrap5.3.scss +0 -2
  125. package/styles/form-renderer/bootstrap5.css +0 -595
  126. package/styles/form-renderer/bootstrap5.scss +0 -2
  127. package/styles/form-renderer/fabric-dark.css +0 -608
  128. package/styles/form-renderer/fabric-dark.scss +0 -2
  129. package/styles/form-renderer/fabric.css +0 -595
  130. package/styles/form-renderer/fabric.scss +0 -2
  131. package/styles/form-renderer/fluent-dark.css +0 -595
  132. package/styles/form-renderer/fluent-dark.scss +0 -2
  133. package/styles/form-renderer/fluent.css +0 -595
  134. package/styles/form-renderer/fluent.scss +0 -2
  135. package/styles/form-renderer/fluent2.css +0 -681
  136. package/styles/form-renderer/fluent2.scss +0 -2
  137. package/styles/form-renderer/highcontrast-light.css +0 -595
  138. package/styles/form-renderer/highcontrast-light.scss +0 -2
  139. package/styles/form-renderer/highcontrast.css +0 -608
  140. package/styles/form-renderer/highcontrast.scss +0 -2
  141. package/styles/form-renderer/material-dark.css +0 -608
  142. package/styles/form-renderer/material-dark.scss +0 -2
  143. package/styles/form-renderer/material.css +0 -595
  144. package/styles/form-renderer/material.scss +0 -2
  145. package/styles/form-renderer/material3-dark.css +0 -677
  146. package/styles/form-renderer/material3-dark.scss +0 -2
  147. package/styles/form-renderer/material3.css +0 -679
  148. package/styles/form-renderer/material3.scss +0 -2
  149. package/styles/form-renderer/tailwind-dark.css +0 -595
  150. package/styles/form-renderer/tailwind-dark.scss +0 -2
  151. package/styles/form-renderer/tailwind.css +0 -595
  152. package/styles/form-renderer/tailwind.scss +0 -2
  153. package/styles/form-renderer/tailwind3.css +0 -669
  154. package/styles/form-renderer/tailwind3.scss +0 -2
  155. package/styles/highcontrast-light-lite.css +0 -595
  156. package/styles/highcontrast-light-lite.scss +0 -2
  157. package/styles/highcontrast-light.css +0 -595
  158. package/styles/highcontrast-light.scss +0 -2
  159. package/styles/highcontrast-lite.css +0 -608
  160. package/styles/highcontrast-lite.scss +0 -2
  161. package/styles/highcontrast.css +0 -608
  162. package/styles/highcontrast.scss +0 -2
  163. package/styles/material-dark-lite.css +0 -608
  164. package/styles/material-dark-lite.scss +0 -2
  165. package/styles/material-dark.css +0 -608
  166. package/styles/material-dark.scss +0 -2
  167. package/styles/material-lite.css +0 -595
  168. package/styles/material-lite.scss +0 -2
  169. package/styles/material.css +0 -595
  170. package/styles/material.scss +0 -2
  171. package/styles/material3-dark-lite.css +0 -677
  172. package/styles/material3-dark-lite.scss +0 -2
  173. package/styles/material3-dark.css +0 -677
  174. package/styles/material3-dark.scss +0 -2
  175. package/styles/material3-lite.css +0 -679
  176. package/styles/material3-lite.scss +0 -2
  177. package/styles/material3.css +0 -679
  178. package/styles/material3.scss +0 -2
  179. package/styles/tailwind-dark-lite.css +0 -595
  180. package/styles/tailwind-dark-lite.scss +0 -2
  181. package/styles/tailwind-dark.css +0 -595
  182. package/styles/tailwind-dark.scss +0 -2
  183. package/styles/tailwind-lite.css +0 -595
  184. package/styles/tailwind-lite.scss +0 -2
  185. package/styles/tailwind.css +0 -595
  186. package/styles/tailwind.scss +0 -2
  187. package/styles/tailwind3-lite.css +0 -669
  188. package/styles/tailwind3-lite.scss +0 -2
  189. package/styles/tailwind3.css +0 -669
  190. package/styles/tailwind3.scss +0 -2
  191. /package/src/{common → form-renderer/common}/checkbox-group.d.ts +0 -0
  192. /package/src/{common → form-renderer/common}/conditional-rule-engine.js +0 -0
  193. /package/src/{common → form-renderer/common}/custom-validation-engine.js +0 -0
  194. /package/src/{common → form-renderer/common}/datagrid-component.d.ts +0 -0
  195. /package/src/{common → form-renderer/common}/datagrid-component.js +0 -0
  196. /package/src/{common → form-renderer/common}/expressions/dependency-tracker.d.ts +0 -0
  197. /package/src/{common → form-renderer/common}/expressions/dependency-tracker.js +0 -0
  198. /package/src/{common → form-renderer/common}/expressions/expression-engine.js +0 -0
  199. /package/src/{common → form-renderer/common}/expressions/expression-parser.js +0 -0
  200. /package/src/{common → form-renderer/common}/expressions/grid-expressions.d.ts +0 -0
  201. /package/src/{common → form-renderer/common}/expressions/grid-expressions.js +0 -0
  202. /package/src/{common → form-renderer/common}/expressions/index.d.ts +0 -0
  203. /package/src/{common → form-renderer/common}/expressions/index.js +0 -0
  204. /package/src/{common → form-renderer/common}/minmax-rule-engine.d.ts +0 -0
  205. /package/src/{common → form-renderer/common}/minmax-rule-engine.js +0 -0
  206. /package/src/{common → form-renderer/common}/option-fetcher.d.ts +0 -0
  207. /package/src/{common → form-renderer/common}/option-fetcher.js +0 -0
  208. /package/src/{common → form-renderer/common}/parser.d.ts +0 -0
  209. /package/src/{common → form-renderer/common}/parser.js +0 -0
  210. /package/src/{common → form-renderer/common}/static-html-renderer.d.ts +0 -0
  211. /package/src/{common → form-renderer/common}/static-html-renderer.js +0 -0
  212. /package/src/{common → form-renderer/common}/utils.js +0 -0
  213. /package/src/form-renderer/{render-form-field.d.ts → form-renderer/render-form-field.d.ts} +0 -0
  214. /package/src/form-renderer/{types → form-renderer/types}/form-schema.d.ts +0 -0
  215. /package/src/form-renderer/{types → form-renderer/types}/form-schema.js +0 -0
@@ -28,23 +28,22 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
28
28
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
29
29
  return c > 3 && r && Object.defineProperty(target, key, r), r;
30
30
  };
31
- import { Component, Property, Event, NotifyPropertyChanges, enableRipple, createElement, isNullOrUndefined, L10n, getComponent, addClass } from '@syncfusion/ej2-base';
31
+ import { Component, Collection, Property, Event, NotifyPropertyChanges, enableRipple, createElement, ChildProperty, isNullOrUndefined, L10n, getComponent, addClass, compile, SanitizeHtmlHelper } from '@syncfusion/ej2-base';
32
32
  import { Tab } from '@syncfusion/ej2-navigations';
33
33
  import { Tooltip } from '@syncfusion/ej2-popups';
34
34
  import { FormValidator } from '@syncfusion/ej2-inputs';
35
35
  import { renderFormField } from './render-form-field';
36
- import { mergeSchema } from '../common/json-converter';
36
+ import { resolveCustomWidget } from './custom-widget-resolver';
37
+ import { mergeSchema, inferTypeFromWidget } from '../common/json-converter';
37
38
  import { UniversalJsonParser } from '../common/parser';
38
39
  import { VALIDATION_REGEX, formatDateValues, splitWidths } from '../common/utils';
39
40
  import StaticHtmlRenderer from '../common/static-html-renderer';
40
- import { ConditionalRuleEngine } from '../common/conditional-rule-engine';
41
+ import { ConditionalRuleEngine } from '../common/index';
41
42
  import { ExpressionEngine } from '../common/expressions/expression-engine';
42
43
  import { MinMaxRuleEngine } from '../common/minmax-rule-engine';
43
44
  import { CustomValidationEngine } from '../common/custom-validation-engine';
44
45
  /**
45
46
  * @private
46
- *
47
- * Internal input target types array to define a target.
48
47
  */
49
48
  var inputTargetTypes = [
50
49
  'textbox',
@@ -68,6 +67,29 @@ var inputTargetTypes = [
68
67
  export var defaultLocale = {
69
68
  "unsupportedComponent": "Unsupported Component type"
70
69
  };
70
+ /**
71
+ * Specifies the custom widget settings for rendering custom templates for existing FormComponentTypes.
72
+ */
73
+ var CustomWidgetSetting = /** @class */ (function (_super) {
74
+ __extends(CustomWidgetSetting, _super);
75
+ function CustomWidgetSetting() {
76
+ return _super !== null && _super.apply(this, arguments) || this;
77
+ }
78
+ __decorate([
79
+ Property(null)
80
+ ], CustomWidgetSetting.prototype, "template", void 0);
81
+ __decorate([
82
+ Property('')
83
+ ], CustomWidgetSetting.prototype, "type", void 0);
84
+ __decorate([
85
+ Property('')
86
+ ], CustomWidgetSetting.prototype, "templateId", void 0);
87
+ __decorate([
88
+ Property('')
89
+ ], CustomWidgetSetting.prototype, "fieldName", void 0);
90
+ return CustomWidgetSetting;
91
+ }(ChildProperty));
92
+ export { CustomWidgetSetting };
71
93
  /**
72
94
  * The FormRenderer component consumes a JSON form schema and renders a fully functional, Syncfusion-based form. It handles field mapping, conditional visibility/disabling, expression evaluation, custom validation, and data submission.
73
95
  *
@@ -82,131 +104,57 @@ export var defaultLocale = {
82
104
  var FormRenderer = /** @class */ (function (_super) {
83
105
  __extends(FormRenderer, _super);
84
106
  /**
85
- * Constructor for creating the widget
86
- *
87
- * @param {FormRendererModel} options - Specifies the form renderer model
88
- * @param {string|HTMLDivElement} element - Specifies the target element
107
+ * @private
89
108
  */
90
109
  function FormRenderer(options, element) {
91
110
  var _this = _super.call(this, options, element) || this;
92
111
  _this.processedSchemaCache = { version: '1.0.0', components: [] };
93
- /** Localization instance */
94
112
  _this.l10n = new L10n('form-renderer', defaultLocale, _this.locale);
95
113
  /**
96
114
  * @private
97
- *
98
- * Minimal form-state container owned by the orchestrator. The previous
99
- * vanilla-TS port delegated this to `FormStateBridge`; that bridge's
100
- * `registeredFields` gate silently short-circuited every field to "no
101
- * error" because the orchestrator never called `registerField`. The
102
- * EJ2 native `FormValidator` (bound to `this.element`) now handles all
103
- * rule evaluation, error-element placement, change/blur/submit wiring,
104
- * and ARIA — exactly what `FormValidator` was designed for. This object
105
- * is the orchestrator's authoritative values store; `errors` are
106
- * mirrored from the FormValidator's `errorRules` for `renderField`'s
107
- * initial-paint logic and for submit-time `isValid` checks.
108
115
  */
109
116
  _this.formState = { values: Object.create(null), errors: Object.create(null) };
110
- /** EJ2 native FormValidator bound to `this.element` (replaces FormStateBridge). */
111
117
  _this.validator = null;
112
- /** Map of input component instances keyed by `name` (or `${name}_${idx}`). */
113
118
  _this.inputRefs = {};
114
- /** Conditional value applied tracker (per-field). */
115
119
  _this.conditionalValueApplied = {};
116
- /** Expression engine + dependency graph + computed-field set. */
117
120
  _this.expressionEngine = null;
118
121
  _this.expressionDependencyGraph = {};
119
122
  _this.expressionEvaluationInProgress = false;
120
123
  _this.previousFormValues = {};
121
124
  _this.computedFieldNames = new Set();
122
- /** Custom validation engine instance. */
123
125
  _this.customValidationEngine = new CustomValidationEngine();
124
- /** Latest form values snapshot for custom validation (named-key context). */
125
126
  _this.currentFormValues = {};
126
- /** Whether initial values have been seeded once. */
127
127
  _this.isInitialized = false;
128
- /** Cached layout detection result. */
129
128
  _this.hasLayoutComponentsCache = false;
130
- /** Cached id→label map. */
131
129
  _this.idToLabelCache = {};
132
- /** Cached initial values (recomputed on schema change). */
133
130
  _this.initialValuesCache = {};
134
- /** Rendered child EJ2 instances (for destroy cleanup). */
135
131
  _this.renderedInstances = [];
136
- /** Tooltip instances keyed by field id so stale tooltips can be replaced promptly. */
137
132
  _this.tooltipRefs = {};
138
- /** `created` fired-once guard. */
139
133
  _this.createdFired = false;
140
- /**
141
- * Coalescing guard for `scheduleRerender`. Prevents redundant full-form
142
- * re-renders within a single microtask — mirrors React's batched-state
143
- * semantics so that a user keystroke + expression cascade fire one render.
144
- */
145
134
  _this.rerenderScheduled = false;
146
- /**
147
- * Set of `component.id`s that are referenced as the trigger field of any
148
- * other component's `conditions` (`visibleWhen` / `hideWhen` /
149
- * `disabledWhen` / `requiredWhen` / `readOnlyWhen` / `setValueWhen` /
150
- * `choiceBasedField.primaryFieldId`). Only changes to these fields can
151
- * affect visibility / disabled / required / valueWhen of any other
152
- * field, so only they need to trigger a full-form re-render. Changes to
153
- * fields *not* in this set are guaranteed to have no conditional side
154
- * effects and safely skip the (expensive) full DOM teardown + rebuild.
155
- * Built once per schema in `buildConditionalDependencyMap`.
156
- */
157
135
  _this.conditionalTriggerFieldIds = new Set();
158
- /**
159
- * Maps `component.id` → the previously-rendered DOM subtree (form-group)
160
- * for "expensive" components (dataGrid, dropdown, multiselect,
161
- * checkboxGroup) that support remote data. During a full-form re-render
162
- * triggered by an *unrelated* conditional change, these subtrees are
163
- * detached (not destroyed) and re-attached in place, avoiding a re-fetch
164
- * of their remote data sources and preventing the visible blink/reload.
165
- * A subtree is *invalidated* (dropped from this map, forcing a fresh
166
- * render) when a field it depends on (via its own `conditions` or
167
- * `conditionalData`) is the one that changed.
168
- */
169
136
  _this.preservedFields = new Map();
170
- /**
171
- * Per-consumer dependency map: `component.id` → set of trigger field ids
172
- * that the consumer's own `conditions` / `conditionalData` /
173
- * `choiceBasedField` reference. Used during `rerenderForm` to decide
174
- * whether a preserved subtree must be invalidated (rebuilt) because the
175
- * changed field is one of its own dependencies, or can be safely reused.
176
- */
177
137
  _this.consumerDependencyMap = new Map();
178
138
  /**
179
139
  * @private
180
- *
181
- * Coalesced full-form re-render. Multiple triggers within the same
182
- * microtask drain into a single `rerenderForm()` call. The set of
183
- * changed field ids is accumulated across the tick so `rerenderForm`
184
- * can decide which preserved subtrees must be invalidated (because one
185
- * of the changed fields is in their own dependency set).
186
140
  */
187
141
  _this.pendingChangedFieldIds = new Set();
188
142
  return _this;
189
143
  }
190
144
  FormRenderer_1 = FormRenderer;
191
145
  /**
192
- * Returns the EJ2 component module name.
193
146
  * @private
194
147
  */
195
148
  FormRenderer.prototype.getModuleName = function () {
196
149
  return 'form-renderer';
197
150
  };
198
151
  /**
199
- * Return the persisted-state payload. The base class declares this
200
- * abstract; FormRenderer does not implement state persistence, so an
201
- * empty object is returned (mirrors the EJ2 convention for
202
- * non-persistent components).
203
152
  * @private
204
153
  */
205
154
  FormRenderer.prototype.getPersistData = function () {
206
155
  return this.addOnPersist(['formState', JSON.stringify(this.formState)]);
207
156
  };
208
157
  /**
209
- * Pre-render wiring: enable ripple, init the expression engine + bridge.
210
158
  * @private
211
159
  */
212
160
  FormRenderer.prototype.preRender = function () {
@@ -215,7 +163,6 @@ var FormRenderer = /** @class */ (function (_super) {
215
163
  this.expressionEngine = new ExpressionEngine();
216
164
  };
217
165
  /**
218
- * Main render: normalize schema, build rules + initial values, render tree.
219
166
  * @private
220
167
  */
221
168
  FormRenderer.prototype.render = function () {
@@ -237,10 +184,12 @@ var FormRenderer = /** @class */ (function (_super) {
237
184
  this.idToLabelCache = this.computeIdToLabel();
238
185
  this.initialValuesCache = this.buildInitialValues();
239
186
  this.buildValidationRulesAndBridge();
240
- // Seed initial values into the form-state values map once.
241
187
  if (!this.isInitialized) {
242
188
  this.isInitialized = true;
243
189
  }
190
+ if (this.isReact && this.portals) {
191
+ this.renderReactTemplates();
192
+ }
244
193
  if (this.formState && this.initialValuesCache) {
245
194
  var initKeys = Object.keys(this.initialValuesCache);
246
195
  for (var _i = 0, initKeys_1 = initKeys; _i < initKeys_1.length; _i++) {
@@ -264,21 +213,7 @@ var FormRenderer = /** @class */ (function (_super) {
264
213
  var rendered = _this.renderComponent(component);
265
214
  if (rendered) {
266
215
  root.appendChild(rendered);
267
- }
268
- if (component.type === 'richTextEditor') {
269
- var rteElement = rendered.querySelector('.e-richtexteditor');
270
- var rteInstance = getComponent(rteElement, 'richtexteditor');
271
- rteInstance.refreshUI();
272
- }
273
- if (component.type === 'dataGrid') {
274
- var toolbarElement = rendered.querySelector('.e-control.e-toolbar');
275
- var rteInstance = getComponent(toolbarElement, 'toolbar');
276
- rteInstance.refresh();
277
- }
278
- if (component.type === 'tabs') {
279
- var tabElement = rendered.querySelector('.e-control.e-tab');
280
- var tabInstance = getComponent(tabElement, 'tab');
281
- tabInstance.refreshOverflow();
216
+ _this.refreshRenderedComponent(component, rendered);
282
217
  }
283
218
  });
284
219
  if (this.created && !this.createdFired) {
@@ -290,6 +225,58 @@ var FormRenderer = /** @class */ (function (_super) {
290
225
  }, 0);
291
226
  }
292
227
  };
228
+ FormRenderer.prototype.refreshRenderedComponent = function (component, rendered) {
229
+ var _this = this;
230
+ var componentRoot = rendered;
231
+ if (component.type === 'tabs') {
232
+ componentRoot = rendered.querySelector("#" + component.id + ".e-control.e-tab") || rendered;
233
+ }
234
+ else {
235
+ componentRoot = rendered.querySelector("[data-field-id=\"" + component.id + "\"]") || rendered;
236
+ }
237
+ if (component.type === 'richTextEditor') {
238
+ var rteElement = componentRoot.querySelector('.e-richtexteditor');
239
+ var rteInstance = rteElement ? getComponent(rteElement, 'richtexteditor') : null;
240
+ if (rteInstance) {
241
+ rteInstance.refreshUI();
242
+ }
243
+ }
244
+ else if (component.type === 'dataGrid') {
245
+ var toolbarElement = componentRoot.querySelector('.e-control.e-toolbar');
246
+ var toolbarInstance = toolbarElement ? getComponent(toolbarElement, 'toolbar') : null;
247
+ if (toolbarInstance) {
248
+ toolbarInstance.refresh();
249
+ }
250
+ }
251
+ else if (component.type === 'imageEditor') {
252
+ var editorElement = componentRoot.querySelector('.e-control.e-image-editor');
253
+ var editorInstance = editorElement ? getComponent(editorElement, 'image-editor') : null;
254
+ if (editorInstance) {
255
+ editorInstance.refresh();
256
+ }
257
+ }
258
+ else if (component.type === 'tabs') {
259
+ var tabInstance = getComponent(componentRoot, 'tab');
260
+ if (tabInstance) {
261
+ tabInstance.refreshOverflow();
262
+ }
263
+ }
264
+ if (component.children) {
265
+ component.children.forEach(function (child) { return _this.refreshRenderedComponent(child, rendered); });
266
+ }
267
+ if (component.tableCells) {
268
+ component.tableCells.forEach(function (row) {
269
+ row.forEach(function (cell) { return cell.forEach(function (child) { return _this.refreshRenderedComponent(child, rendered); }); });
270
+ });
271
+ }
272
+ if (component.tabItems) {
273
+ component.tabItems.forEach(function (tab) {
274
+ if (tab.content) {
275
+ tab.content.forEach(function (child) { return _this.refreshRenderedComponent(child, rendered); });
276
+ }
277
+ });
278
+ }
279
+ };
293
280
  /**
294
281
  * @private
295
282
  */
@@ -318,7 +305,7 @@ var FormRenderer = /** @class */ (function (_super) {
318
305
  var isUnifiedSchema = parsedInput && typeof parsedInput === 'object' &&
319
306
  parsedInput.properties && Array.isArray(parsedInput.layout);
320
307
  if (isUnifiedSchema) {
321
- this.processedSchemaCache = mergeSchema(parsedInput);
308
+ this.processedSchemaCache = mergeSchema(parsedInput, this.dataModel || undefined);
322
309
  }
323
310
  else {
324
311
  var parser = new UniversalJsonParser();
@@ -345,12 +332,7 @@ var FormRenderer = /** @class */ (function (_super) {
345
332
  this.processedSchemaCache = { version: '1.0.0', components: [] };
346
333
  }
347
334
  };
348
- // ----------------------------------------------------------------------
349
- // G3 — layout detection + suppression map
350
- // ----------------------------------------------------------------------
351
335
  /**
352
- * Recursively scan the schema for any `table`/`tabs`/`panel`/`card`
353
- * (including inside table cells and tab content). Mirrors `hasLayoutComponents`.
354
336
  * @private
355
337
  */
356
338
  FormRenderer.prototype.computeHasLayoutComponents = function () {
@@ -392,7 +374,6 @@ var FormRenderer = /** @class */ (function (_super) {
392
374
  };
393
375
  Object.defineProperty(FormRenderer.prototype, "layoutClass", {
394
376
  /**
395
- * The layout CSS class (suppressed when layout components are present).
396
377
  * @private
397
378
  */
398
379
  get: function () {
@@ -414,11 +395,7 @@ var FormRenderer = /** @class */ (function (_super) {
414
395
  enumerable: true,
415
396
  configurable: true
416
397
  });
417
- // ----------------------------------------------------------------------
418
- // G4 — collectAllComponents + idToLabel
419
- // ----------------------------------------------------------------------
420
398
  /**
421
- * Recursively collect all components including nested ones.
422
399
  * @private
423
400
  */
424
401
  FormRenderer.prototype.collectAllComponents = function (components) {
@@ -446,6 +423,22 @@ var FormRenderer = /** @class */ (function (_super) {
446
423
  traverse(components);
447
424
  return all;
448
425
  };
426
+ FormRenderer.prototype.getDataModelByName = function () {
427
+ var _this = this;
428
+ var dataModel = {};
429
+ var components = this.collectAllComponents(this.processedSchemaCache.components);
430
+ var componentsById = {};
431
+ components.forEach(function (component) {
432
+ componentsById[component.id] = component;
433
+ });
434
+ Object.keys(this.formState.values).forEach(function (id) {
435
+ var component = componentsById[id];
436
+ if (component && component.name) {
437
+ dataModel[component.name] = _this.formState.values[id];
438
+ }
439
+ });
440
+ return dataModel;
441
+ };
449
442
  /**
450
443
  * @private
451
444
  */
@@ -477,10 +470,6 @@ var FormRenderer = /** @class */ (function (_super) {
477
470
  traverse(this.processedSchemaCache.components);
478
471
  return map;
479
472
  };
480
- // ----------------------------------------------------------------------
481
- // G5 — buildValidationRules via FormStateBridge + ConditionalRuleEngine +
482
- // EMAIL/URL auto-regex + customValidator closure
483
- // ----------------------------------------------------------------------
484
473
  /**
485
474
  * @private
486
475
  */
@@ -597,13 +586,11 @@ var FormRenderer = /** @class */ (function (_super) {
597
586
  });
598
587
  };
599
588
  collectRules(this.processedSchemaCache.components);
600
- // Preserve previously-entered values across a re-render.
601
589
  var previousValues = this.formState ? __assign({}, this.formState.values) : __assign({}, this.initialValuesCache);
602
590
  this.formState = {
603
591
  values: Object.assign(Object.create(null), this.initialValuesCache, previousValues),
604
592
  errors: this.enablePersistence ? this.formState.errors : Object.create(null)
605
593
  };
606
- // Restore any previously-entered values that the merge above pruned.
607
594
  if (previousValues) {
608
595
  Object.keys(previousValues).forEach(function (id) {
609
596
  if (!(id in _this.formState.values)) {
@@ -611,7 +598,6 @@ var FormRenderer = /** @class */ (function (_super) {
611
598
  }
612
599
  });
613
600
  }
614
- // (Re)create the EJ2 native FormValidator bound to the host element.
615
601
  if (this.validator) {
616
602
  try {
617
603
  this.validator.refresh();
@@ -630,14 +616,6 @@ var FormRenderer = /** @class */ (function (_super) {
630
616
  errorElement: 'div',
631
617
  errorContainer: 'div',
632
618
  customPlacement: function (inputElement, errorElement) {
633
- // Locate the per-field error-message slot rendered in
634
- // `renderField` by its id (`error-<component.id>`). The
635
- // input's `name` attribute matches `component.id`
636
- // (set in renderField), so `getElementById('error-' + name)`
637
- // resolves the slot and the validator's error element is
638
- // appended into it (FormValidator sets
639
- // `errorElement.style.display = 'block'` before invoking
640
- // customPlacement, which makes the slot visible).
641
619
  var name = inputElement.getAttribute('name');
642
620
  if (!name) {
643
621
  if (inputElement.parentElement) {
@@ -658,15 +636,7 @@ var FormRenderer = /** @class */ (function (_super) {
658
636
  }
659
637
  },
660
638
  validationComplete: function (args) {
661
- // Mirror the validator's error state into formState.errors so
662
- // submit-time isValid and renderField's initial-paint logic
663
- // (which read formState.errors[id]) continue to work.
664
639
  self.syncFormStateErrors();
665
- // Keep the per-field error slot's visibility in sync with
666
- // the validator's outcome. On `success`, the FormValidator's
667
- // `hideMessage` sets its own error element's `display: none`,
668
- // but our slot (`error-<id>`) would otherwise keep the stale
669
- // error element appended. Clear + hide the slot on success.
670
640
  if (args && args.inputName) {
671
641
  var slot = document.getElementById("error-" + args.inputName);
672
642
  if (slot) {
@@ -701,10 +671,6 @@ var FormRenderer = /** @class */ (function (_super) {
701
671
  reset: function () {
702
672
  }
703
673
  });
704
- // Apply cached previous values to the FormValidator's input elements.
705
- // The validator reads live values from inputs at validate() time, but
706
- // initial values seeded here ensure any pre-populated values are
707
- // respected even if a field is never focused before submit.
708
674
  if (previousValues) {
709
675
  Object.keys(previousValues).forEach(function (id) {
710
676
  var inputEl = _this.validator.getInputElement(id);
@@ -719,10 +685,6 @@ var FormRenderer = /** @class */ (function (_super) {
719
685
  };
720
686
  /**
721
687
  * @private
722
- *
723
- * Mirror the FormValidator's `errorRules` array into `this.formState.errors`
724
- * keyed by field `name` (= `component.id`). Called after every
725
- * `validationComplete` callback and from submit-time `isValid` reads.
726
688
  */
727
689
  FormRenderer.prototype.syncFormStateErrors = function () {
728
690
  var errors = {};
@@ -779,11 +741,7 @@ var FormRenderer = /** @class */ (function (_super) {
779
741
  }
780
742
  return values;
781
743
  };
782
- // ----------------------------------------------------------------------
783
- // Expression engine init (used by G9)
784
- // ----------------------------------------------------------------------
785
744
  /**
786
- * Initialize the expression engine dependency graph + computed-field set.
787
745
  * @private
788
746
  */
789
747
  FormRenderer.prototype.initExpressionEngine = function () {
@@ -836,7 +794,7 @@ var FormRenderer = /** @class */ (function (_super) {
836
794
  var _this = this;
837
795
  var formState = this.formState;
838
796
  var formValues = formState ? formState.values : {};
839
- if (['panel', 'table', 'tabs', 'card', 'message', 'button', 'splitButton', 'staticHtml'].indexOf(component.type) !== -1) {
797
+ if (['panel', 'table', 'tabs', 'card', 'message', 'staticHtml'].indexOf(component.type) !== -1) {
840
798
  return null;
841
799
  }
842
800
  var conditionalReadOnly = ConditionalRuleEngine.isFieldReadOnly(component.conditions, formValues);
@@ -866,7 +824,6 @@ var FormRenderer = /** @class */ (function (_super) {
866
824
  var shouldShowError = !!(formState && formState.errors[component.id]);
867
825
  var isRequiredError = shouldShowError && !!(formState && formState.errors[component.id].indexOf('required') !== -1);
868
826
  var hasError = shouldShowError && !(isRequiredError && !computedRequired);
869
- // setValueWhen false→true transition tracking.
870
827
  var conditionIsActive = conditionalValue !== undefined;
871
828
  var wasConditionActive = this.conditionalValueApplied[component.id] || false;
872
829
  if (formState) {
@@ -969,7 +926,7 @@ var FormRenderer = /** @class */ (function (_super) {
969
926
  _this.formState.values[component.id] = value;
970
927
  formState.values[component.id] = value;
971
928
  }
972
- _this.trigger('change', { fieldName: component.name, label: component.label || component.id, value: value });
929
+ _this.trigger('change', { fieldName: component.name, label: component.label || component.id, value: value, dataModel: _this.getDataModelByName() });
973
930
  _this.afterValueChange(component.id);
974
931
  }
975
932
  };
@@ -991,60 +948,145 @@ var FormRenderer = /** @class */ (function (_super) {
991
948
  target.setAttribute('name', component.id);
992
949
  }
993
950
  fieldInput.appendChild(target);
994
- var instance = renderFormField({
995
- component: mergedComponent,
996
- value: formState ? formState.values[component.id] : undefined,
997
- onChange: onChangeHandler,
998
- formState: formState,
999
- settings: this.processedSchemaCache.settings,
1000
- onBlur: function () {
1001
- if (formState && component.type !== 'staticHtml') {
1002
- if (_this.validator) {
1003
- try {
1004
- _this.beforeValidate(component.id);
1005
- _this.validator.validate(component.id);
951
+ var skipDefault = false;
952
+ var resolvedWidget = resolveCustomWidget(component, this.customWidgetSettings);
953
+ if (resolvedWidget) {
954
+ var compiled = null;
955
+ try {
956
+ compiled = this.getTemplateFunction(resolvedWidget.entry.template);
957
+ }
958
+ catch (e) {
959
+ if (this.failure) {
960
+ this.trigger('failure', { error: e });
961
+ }
962
+ compiled = null;
963
+ }
964
+ if (compiled) {
965
+ try {
966
+ if (target.parentNode) {
967
+ target.parentNode.removeChild(target);
968
+ }
969
+ var swappedComponent = Object.assign({}, component, {
970
+ id: component.name,
971
+ name: component.id,
972
+ type: inferTypeFromWidget(component.type),
973
+ widget: component.type
974
+ });
975
+ var renderedOut = compiled({
976
+ fieldData: swappedComponent,
977
+ value: formState ? formState.values[component.id] : undefined,
978
+ }, this, 'customWidgetTemplate' + component.id, (this.element.id || 'form-renderer') + 'customWidgetTemplate', this.isStringTemplate, undefined, fieldInput, this.root);
979
+ var outList = void 0;
980
+ if (renderedOut == null) {
981
+ outList = [];
982
+ }
983
+ else if (Array.isArray(renderedOut)) {
984
+ outList = renderedOut;
985
+ }
986
+ else if (typeof renderedOut === 'string') {
987
+ outList = [renderedOut];
988
+ }
989
+ else if (typeof renderedOut === 'object'
990
+ && !renderedOut.nodeType
991
+ && typeof renderedOut.length === 'number'
992
+ && typeof renderedOut.item === 'function') {
993
+ var snapshot = [];
994
+ var list = renderedOut;
995
+ for (var i = 0; i < list.length; i++) {
996
+ snapshot.push(list[i]);
1006
997
  }
1007
- catch (e) { /* swallow */ }
1008
- _this.syncFormStateErrors();
998
+ outList = snapshot;
1009
999
  }
1010
- }
1011
- },
1012
- ref: setInputRef,
1013
- hasError: hasError,
1014
- locale: this.locale,
1015
- components: this.collectAllComponents(this.processedSchemaCache.components),
1016
- enableRtl: this.enableRtl,
1017
- target: target,
1018
- l10n: this.l10n
1019
- });
1020
- if (Array.isArray(instance)) {
1021
- instance.forEach(function (entry) {
1022
- if (entry && typeof entry.destroy === 'function') {
1023
- _this.renderedInstances.push(entry);
1024
- }
1025
- else if (entry instanceof HTMLElement) {
1026
- for (var _i = 0, _a = Object.keys(_this.inputRefs); _i < _a.length; _i++) {
1027
- var key = _a[_i];
1028
- var inst = _this.inputRefs[key];
1029
- var hostEl = inst && (inst.element || inst.target || (inst.hostElement && inst.hostElement()));
1030
- if (hostEl && (hostEl === entry || entry.contains(hostEl))) {
1031
- _this.renderedInstances.push(inst);
1000
+ else {
1001
+ outList = [renderedOut];
1002
+ }
1003
+ for (var _i = 0, outList_1 = outList; _i < outList_1.length; _i++) {
1004
+ var node = outList_1[_i];
1005
+ if (node && typeof node === 'object' && node.nodeType) {
1006
+ fieldInput.appendChild(node);
1007
+ }
1008
+ else if (typeof node === 'string') {
1009
+ var markup = this.sanitizeTemplateValue(node);
1010
+ var span = createElement('span');
1011
+ span.innerHTML = markup;
1012
+ while (span.firstChild) {
1013
+ fieldInput.appendChild(span.firstChild);
1014
+ }
1015
+ }
1016
+ else if (node && typeof node === 'object') {
1017
+ throw new Error('Custom widget template for "' + component.name + '" returned a ' +
1018
+ 'framework object that the vanilla renderer cannot insert. Use the ' +
1019
+ 'React/Angular/Vue wrapper (registered templates / portals) for ' +
1020
+ 'JSX or platform templates.');
1032
1021
  }
1033
1022
  }
1023
+ setInputRef(fieldInput);
1024
+ skipDefault = true;
1034
1025
  }
1026
+ catch (renderErr) {
1027
+ if (this.failure) {
1028
+ this.trigger('failure', { error: renderErr });
1029
+ }
1030
+ skipDefault = false;
1031
+ }
1032
+ }
1033
+ }
1034
+ if (!skipDefault) {
1035
+ var instance = renderFormField({
1036
+ component: mergedComponent,
1037
+ value: formState ? formState.values[component.id] : undefined,
1038
+ onChange: onChangeHandler,
1039
+ formState: formState,
1040
+ settings: this.processedSchemaCache.settings,
1041
+ onBlur: function () {
1042
+ if (formState && component.type !== 'staticHtml') {
1043
+ if (_this.validator) {
1044
+ try {
1045
+ _this.beforeValidate(component.id);
1046
+ _this.validator.validate(component.id);
1047
+ }
1048
+ catch (e) { /* swallow */ }
1049
+ _this.syncFormStateErrors();
1050
+ }
1051
+ }
1052
+ },
1053
+ ref: setInputRef,
1054
+ hasError: hasError,
1055
+ locale: this.locale,
1056
+ components: this.collectAllComponents(this.processedSchemaCache.components),
1057
+ enableRtl: this.enableRtl,
1058
+ target: target,
1059
+ l10n: this.l10n
1035
1060
  });
1036
- }
1037
- else if (instance) {
1038
- if (typeof instance.destroy === 'function') {
1039
- this.renderedInstances.push(instance);
1040
- }
1041
- else if (instance instanceof HTMLElement) {
1042
- for (var _i = 0, _a = Object.keys(this.inputRefs); _i < _a.length; _i++) {
1043
- var key = _a[_i];
1044
- var inst = this.inputRefs[key];
1045
- var hostEl = inst && (inst.element || inst.target || (inst.hostElement && inst.hostElement()));
1046
- if (hostEl && (hostEl === instance || instance.contains(hostEl))) {
1047
- this.renderedInstances.push(inst);
1061
+ if (Array.isArray(instance)) {
1062
+ instance.forEach(function (entry) {
1063
+ if (entry && typeof entry.destroy === 'function') {
1064
+ _this.renderedInstances.push(entry);
1065
+ }
1066
+ else if (entry instanceof HTMLElement) {
1067
+ for (var _i = 0, _a = Object.keys(_this.inputRefs); _i < _a.length; _i++) {
1068
+ var key = _a[_i];
1069
+ var inst = _this.inputRefs[key];
1070
+ var hostEl = inst && (inst.element || inst.target || (inst.hostElement && inst.hostElement()));
1071
+ if (hostEl && (hostEl === entry || entry.contains(hostEl))) {
1072
+ _this.renderedInstances.push(inst);
1073
+ }
1074
+ }
1075
+ }
1076
+ });
1077
+ }
1078
+ else if (instance) {
1079
+ if (typeof instance.destroy === 'function') {
1080
+ this.renderedInstances.push(instance);
1081
+ }
1082
+ else if (instance instanceof HTMLElement) {
1083
+ for (var _a = 0, _b = Object.keys(this.inputRefs); _a < _b.length; _a++) {
1084
+ var key = _b[_a];
1085
+ var inst = this.inputRefs[key];
1086
+ var hostEl = inst && (inst.element || inst.target || (inst.hostElement && inst.hostElement()));
1087
+ if (hostEl && (hostEl === instance || instance.contains(hostEl))) {
1088
+ this.renderedInstances.push(inst);
1089
+ }
1048
1090
  }
1049
1091
  }
1050
1092
  }
@@ -1090,11 +1132,6 @@ var FormRenderer = /** @class */ (function (_super) {
1090
1132
  }
1091
1133
  return null;
1092
1134
  }
1093
- // Re-attach preserved subtree for expensive / remote-data components
1094
- // (dataGrid / dropdown / multiselect / checkboxGroup / lookup). The
1095
- // subtree was detached in `rerenderForm` before the rest of the tree
1096
- // was destroyed; re-attaching it here avoids a re-fetch of remote
1097
- // data sources and prevents the visible blink of a fresh render.
1098
1135
  if (FormRenderer_1.PRESERVABLE_TYPES.has(component.type) && this.preservedFields.has(component.id)) {
1099
1136
  var preservedNode = this.preservedFields.get(component.id);
1100
1137
  if (preservedNode) {
@@ -1191,14 +1228,6 @@ var FormRenderer = /** @class */ (function (_super) {
1191
1228
  tabHost.appendChild(tabHeader_1);
1192
1229
  tabHost.appendChild(tabContent_1);
1193
1230
  tabsDiv.appendChild(tabHost);
1194
- // Build the tab's host DOM up front so each `.e-content > .e-item`
1195
- // wrapper exists during initialization. Using the JSON `items`
1196
- // path causes EJ2 to lazily materialize only the active content
1197
- // panel, which leaves the remaining rendered tab bodies missing
1198
- // from the live DOM. By seeding the HTML markup structure and
1199
- // inserting the already-rendered live child nodes into every
1200
- // content item, the bound EJ2 instances stay attached and all
1201
- // tabs render correctly.
1202
1231
  (component.tabItems || []).forEach(function (tab) {
1203
1232
  var headerItem = createElement('div');
1204
1233
  headerItem.textContent = tab.header;
@@ -1308,6 +1337,9 @@ var FormRenderer = /** @class */ (function (_super) {
1308
1337
  return wrapper;
1309
1338
  }
1310
1339
  case 'button': {
1340
+ if (resolveCustomWidget(component, this.customWidgetSettings)) {
1341
+ return this.renderField(component);
1342
+ }
1311
1343
  var buttonlDisabled = ConditionalRuleEngine.isFieldDisabled(component.conditions, formValues);
1312
1344
  var buttonComputed = !!component.disabled || buttonlDisabled;
1313
1345
  var wrapper = createElement('div', { className: 'form-group' });
@@ -1332,6 +1364,12 @@ var FormRenderer = /** @class */ (function (_super) {
1332
1364
  form.querySelectorAll('.e-control.e-multiselect.e-lib').forEach(function (cb) {
1333
1365
  (cb.ej2_instances[0]).value = [];
1334
1366
  });
1367
+ form.querySelectorAll('.e-control.e-slider.e-lib').forEach(function (slider) {
1368
+ (slider.ej2_instances[0]).value = 0;
1369
+ });
1370
+ form.querySelectorAll('.e-control.e-uploader.e-lib').forEach(function (upload) {
1371
+ (upload.ej2_instances[0]).clearAll();
1372
+ });
1335
1373
  }
1336
1374
  _this.formState.values = {};
1337
1375
  form.reset();
@@ -1369,6 +1407,9 @@ var FormRenderer = /** @class */ (function (_super) {
1369
1407
  return wrapper;
1370
1408
  }
1371
1409
  case 'splitButton': {
1410
+ if (resolveCustomWidget(component, this.customWidgetSettings)) {
1411
+ return this.renderField(component);
1412
+ }
1372
1413
  var splitButtonDisabled = ConditionalRuleEngine.isFieldDisabled(component.conditions, formValues);
1373
1414
  var computedDisabled = !!component.disabled || splitButtonDisabled;
1374
1415
  var wrapper = createElement('div', { className: 'form-group' });
@@ -1422,11 +1463,6 @@ var FormRenderer = /** @class */ (function (_super) {
1422
1463
  this.beforeValidate(changedFieldId);
1423
1464
  this.validator.validate(changedFieldId);
1424
1465
  this.syncFormStateErrors();
1425
- // Only schedule a full-form re-render when the changed field is a
1426
- // conditional trigger (i.e. some other field's visibility/disabled/
1427
- // required/readOnly/valueWhen references its id). Changes to fields
1428
- // that nothing depends on skip the expensive DOM teardown + rebuild,
1429
- // keeping keystroke latency low for non-conditional inputs.
1430
1466
  if (changedFieldId && this.isConditionalTrigger(changedFieldId)) {
1431
1467
  this.scheduleRerender(changedFieldId);
1432
1468
  }
@@ -1440,8 +1476,12 @@ var FormRenderer = /** @class */ (function (_super) {
1440
1476
  infoElement.classList.remove('e-error');
1441
1477
  }
1442
1478
  var inputElement = this.getInputElementByName(fieldId);
1479
+ if (!inputElement) {
1480
+ return;
1481
+ }
1443
1482
  var inputParent = inputElement.parentElement;
1444
1483
  var grandParent = inputParent.parentElement;
1484
+ var greatGrandParent = grandParent ? grandParent.parentElement : null;
1445
1485
  if (inputParent.classList.contains('e-control-wrapper') || inputParent.classList.contains('e-wrapper') ||
1446
1486
  (inputElement.classList.contains('e-input') && inputParent.classList.contains('e-input-group'))) {
1447
1487
  inputParent.classList.remove('e-error');
@@ -1449,6 +1489,9 @@ var FormRenderer = /** @class */ (function (_super) {
1449
1489
  else if ((grandParent != null) && (grandParent.classList.contains('e-control-wrapper') || grandParent.classList.contains('e-wrapper'))) {
1450
1490
  grandParent.classList.remove('e-error');
1451
1491
  }
1492
+ else if ((greatGrandParent != null) && (greatGrandParent.classList.contains('e-control-wrapper') || greatGrandParent.classList.contains('e-wrapper'))) {
1493
+ greatGrandParent.classList.remove('e-error');
1494
+ }
1452
1495
  else {
1453
1496
  inputElement.classList.remove('e-error');
1454
1497
  }
@@ -1474,23 +1517,15 @@ var FormRenderer = /** @class */ (function (_super) {
1474
1517
  };
1475
1518
  /**
1476
1519
  * @private
1477
- *
1478
- * Recursively walk a `ConditionType` (a `ConditionalRule { field }` leaf
1479
- * or a `CompositeConditionalRule { rules: [...] }` tree) and collect the
1480
- * `field` ids of every leaf rule into the supplied `acc` set. These are
1481
- * the trigger ids whose value changes can affect the visibility/disabled/
1482
- * required/readOnly/valueWhen of the component that owns this `conditions`.
1483
1520
  */
1484
1521
  FormRenderer.prototype.collectConditionFieldIds = function (condition, acc) {
1485
1522
  if (!condition) {
1486
1523
  return;
1487
1524
  }
1488
1525
  if (typeof condition.field === 'string') {
1489
- // Leaf rule.
1490
1526
  acc.add(condition.field);
1491
1527
  }
1492
1528
  else if (Array.isArray(condition.rules)) {
1493
- // Composite (and/or) — recurse.
1494
1529
  for (var _i = 0, _a = condition.rules; _i < _a.length; _i++) {
1495
1530
  var sub = _a[_i];
1496
1531
  this.collectConditionFieldIds(sub, acc);
@@ -1519,18 +1554,9 @@ var FormRenderer = /** @class */ (function (_super) {
1519
1554
  };
1520
1555
  /**
1521
1556
  * @private
1522
- *
1523
- * Build `this.conditionalTriggerFieldIds` — the set of every
1524
- * `component.id` that is referenced by *any* other component's
1525
- * `conditions` (visibleWhen / hideWhen / disabledWhen / requiredWhen /
1526
- * readOnlyWhen / setValueWhen / choiceBasedField.primaryFieldId).
1527
- * Only changes to ids in this set can affect another field's
1528
- * visibility/enabled/required/value, so only they need to trigger a
1529
- * full-form re-render. Called once per schema during `render()`.
1530
1557
  */
1531
1558
  FormRenderer.prototype.buildConditionalDependencyMap = function () {
1532
1559
  var triggers = new Set();
1533
- // Per-consumer dependency set (rebuilt each pass).
1534
1560
  var consumerDeps = new Map();
1535
1561
  var allComps = this.collectAllComponents(this.processedSchemaCache.components);
1536
1562
  var _loop_3 = function (comp) {
@@ -1561,7 +1587,6 @@ var FormRenderer = /** @class */ (function (_super) {
1561
1587
  this_1.collectConditionFieldIds(item.condition, triggers);
1562
1588
  this_1.collectConditionFieldIds(item.condition, myDeps);
1563
1589
  }
1564
- // DataGrid conditional columns
1565
1590
  if (item && Array.isArray(item.conditions)) {
1566
1591
  for (var _c = 0, _d = item.conditions; _c < _d.length; _c++) {
1567
1592
  var subCond = _d[_c];
@@ -1609,13 +1634,6 @@ var FormRenderer = /** @class */ (function (_super) {
1609
1634
  collectMinMaxReferenceIds(range);
1610
1635
  }
1611
1636
  }
1612
- // ==========================================================
1613
- // DataGrid remote datasource dependencies
1614
- // Example:
1615
- // search.key = "{combobox}"
1616
- // filter.value = "{department}"
1617
- // Resolve component by NAME and add its ID as dependency.
1618
- // ==========================================================
1619
1637
  var ds = comp.dataSource;
1620
1638
  if ((comp.type === 'dataGrid') &&
1621
1639
  ds &&
@@ -1645,26 +1663,29 @@ var FormRenderer = /** @class */ (function (_super) {
1645
1663
  };
1646
1664
  /**
1647
1665
  * @private
1648
- *
1649
- * Returns `true` if a value change to `fieldId` can affect any other
1650
- * field's conditional state (visibility/disabled/required/readOnly/
1651
- * valueWhen/choiceBasedField) — i.e. `fieldId` is in the
1652
- * `conditionalTriggerFieldIds` set built by
1653
- * `buildConditionalDependencyMap`. Used by `afterValueChange` to skip
1654
- * the expensive full-form re-render when the changed field is not a
1655
- * conditional trigger.
1656
1666
  */
1657
1667
  FormRenderer.prototype.isConditionalTrigger = function (fieldId) {
1658
1668
  return this.conditionalTriggerFieldIds.has(fieldId);
1659
1669
  };
1670
+ FormRenderer.prototype.getScrollParent = function () {
1671
+ var parent = this.element.parentElement;
1672
+ while (parent) {
1673
+ var style = window.getComputedStyle(parent);
1674
+ var overflowY = style.overflowY;
1675
+ var overflowX = style.overflowX;
1676
+ var canScrollY = (overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'overlay') &&
1677
+ parent.scrollHeight > parent.clientHeight;
1678
+ var canScrollX = (overflowX === 'auto' || overflowX === 'scroll' || overflowX === 'overlay') &&
1679
+ parent.scrollWidth > parent.clientWidth;
1680
+ if (canScrollY || canScrollX) {
1681
+ return parent;
1682
+ }
1683
+ parent = parent.parentElement;
1684
+ }
1685
+ return null;
1686
+ };
1660
1687
  /**
1661
1688
  * @private
1662
- *
1663
- * Tear down the rendered tree and re-render it, preserving user-entered
1664
- * `formState.values` (carried through `buildValidationRulesAndBridge`'s
1665
- * `previousValues` merge) and restoring keyboard focus to the field that
1666
- * had it before re-render (so a user typing in a textbox is not
1667
- * interrupted by a dependent field appearing/disappearing on the page).
1668
1689
  */
1669
1690
  FormRenderer.prototype.rerenderForm = function (changedFieldIds) {
1670
1691
  var _this = this;
@@ -1680,12 +1701,15 @@ var FormRenderer = /** @class */ (function (_super) {
1680
1701
  selectionStart = activeEl.selectionStart;
1681
1702
  selectionEnd = activeEl.selectionEnd;
1682
1703
  }
1683
- catch (e) { /* not a text input — ignore */ }
1704
+ catch (e) { /* ignore */ }
1684
1705
  }
1685
1706
  var savedElementScrollTop = this.element.scrollTop;
1686
1707
  var savedElementScrollLeft = this.element.scrollLeft;
1687
1708
  var savedWindowScrollX = window.scrollX;
1688
1709
  var savedWindowScrollY = window.scrollY;
1710
+ var scrollParent = this.getScrollParent();
1711
+ var savedScrollParentTop = scrollParent ? scrollParent.scrollTop : 0;
1712
+ var savedScrollParentLeft = scrollParent ? scrollParent.scrollLeft : 0;
1689
1713
  this.preservedFields.clear();
1690
1714
  var allComps = this.collectAllComponents(this.processedSchemaCache.components);
1691
1715
  var _loop_4 = function (comp) {
@@ -1716,6 +1740,9 @@ var FormRenderer = /** @class */ (function (_super) {
1716
1740
  _loop_4(comp);
1717
1741
  }
1718
1742
  this.refreshing = true;
1743
+ if (this.isReact || this.isAngular) {
1744
+ this.clearTemplate();
1745
+ }
1719
1746
  this.destroyRenderedExcludingPreserved();
1720
1747
  this.removePreviousRoot();
1721
1748
  if (this.validator) {
@@ -1726,6 +1753,10 @@ var FormRenderer = /** @class */ (function (_super) {
1726
1753
  try {
1727
1754
  this.element.scrollTop = savedElementScrollTop;
1728
1755
  this.element.scrollLeft = savedElementScrollLeft;
1756
+ if (scrollParent) {
1757
+ scrollParent.scrollTop = savedScrollParentTop;
1758
+ scrollParent.scrollLeft = savedScrollParentLeft;
1759
+ }
1729
1760
  window.scrollTo(savedWindowScrollX, savedWindowScrollY);
1730
1761
  }
1731
1762
  catch (e) { /* swallow */ }
@@ -1745,15 +1776,9 @@ var FormRenderer = /** @class */ (function (_super) {
1745
1776
  catch (e) { /* swallow */ }
1746
1777
  }
1747
1778
  }
1748
- // Drop preserved subtrees that were not re-attached (e.g. their
1749
- // field became hidden during this re-render). Their EJ2 instances
1750
- // are still in `renderedInstances`; destroy them now to avoid leaks.
1751
1779
  if (this.preservedFields.size > 0) {
1752
1780
  var stillKept_1 = [];
1753
1781
  this.preservedFields.forEach(function (node, id) {
1754
- // If the node is no longer in the live document tree, the
1755
- // field was not re-attached (hidden / removed). Destroy it
1756
- // and remove the detached DOM node so it cannot be re-used.
1757
1782
  if (!_this.element.contains(node) && !document.body.contains(node)) {
1758
1783
  _this.destroyPreservedSubtree(node);
1759
1784
  try {
@@ -1762,7 +1787,7 @@ var FormRenderer = /** @class */ (function (_super) {
1762
1787
  }
1763
1788
  }
1764
1789
  catch (e) {
1765
- // swallow
1790
+ // ignore
1766
1791
  }
1767
1792
  _this.preservedFields.delete(id);
1768
1793
  }
@@ -1816,11 +1841,6 @@ var FormRenderer = /** @class */ (function (_super) {
1816
1841
  };
1817
1842
  /**
1818
1843
  * @private
1819
- *
1820
- * Destroy all rendered EJ2 instances except those whose host element
1821
- * lives inside a preserved subtree (those are kept alive for re-use in
1822
- * the upcoming `render()` pass). Mirrors `destroyRendered` but skips
1823
- * instances rooted in `preservedFields` nodes.
1824
1844
  */
1825
1845
  FormRenderer.prototype.destroyRenderedExcludingPreserved = function () {
1826
1846
  var survived = [];
@@ -1841,8 +1861,6 @@ var FormRenderer = /** @class */ (function (_super) {
1841
1861
  _loop_5(inst);
1842
1862
  }
1843
1863
  this.renderedInstances = survived;
1844
- // Prune inputRefs whose host element lives in a destroyed subtree
1845
- // (preserved ones stay).
1846
1864
  var inputRefKeys = Object.keys(this.inputRefs);
1847
1865
  var _loop_6 = function (key) {
1848
1866
  var inst = this_4.inputRefs[key];
@@ -1865,10 +1883,6 @@ var FormRenderer = /** @class */ (function (_super) {
1865
1883
  };
1866
1884
  /**
1867
1885
  * @private
1868
- *
1869
- * Destroy EJ2 instances whose host element lives inside a preserved
1870
- * subtree that was NOT re-attached (field became hidden). Used during
1871
- * the post-render cleanup pass in `rerenderForm`.
1872
1886
  */
1873
1887
  FormRenderer.prototype.destroyPreservedSubtree = function (rootNode) {
1874
1888
  var survived = [];
@@ -1898,7 +1912,6 @@ var FormRenderer = /** @class */ (function (_super) {
1898
1912
  return inputEl;
1899
1913
  };
1900
1914
  /**
1901
- * Evaluate expressions in topological order with type coercion.
1902
1915
  * @private
1903
1916
  */
1904
1917
  FormRenderer.prototype.evaluateExpressions = function () {
@@ -1999,22 +2012,10 @@ var FormRenderer = /** @class */ (function (_super) {
1999
2012
  }
2000
2013
  if (result !== null && result !== undefined && result !== formValues[component.id] && this_5.formState) {
2001
2014
  this_5.formState.values[component.id] = result;
2002
- // Sync the underlying input element so the
2003
- // FormValidator reads the new value on its
2004
- // next validate() pass.
2005
2015
  if (this_5.validator) {
2006
2016
  var inputEl = this_5.getInputElementByName(component.id);
2007
2017
  if (inputEl) {
2008
- try {
2009
- if (inputEl.ej2_instances[0]) {
2010
- inputEl.ej2_instances[0].value = result;
2011
- // (inputEl as any).ej2_instances[0].refresh();
2012
- }
2013
- else {
2014
- (inputEl).value = String(result);
2015
- }
2016
- }
2017
- catch (e) { /* swallow */ }
2018
+ this_5.syncValueToInput(inputEl, component.id, result);
2018
2019
  }
2019
2020
  }
2020
2021
  }
@@ -2041,7 +2042,6 @@ var FormRenderer = /** @class */ (function (_super) {
2041
2042
  }
2042
2043
  };
2043
2044
  /**
2044
- * Re-trigger custom validation for changed + dependent fields.
2045
2045
  * @private
2046
2046
  */
2047
2047
  FormRenderer.prototype.retriggerCustomValidation = function () {
@@ -2146,13 +2146,106 @@ var FormRenderer = /** @class */ (function (_super) {
2146
2146
  }
2147
2147
  };
2148
2148
  /**
2149
- * Retrieves the underlying Syncfusion form-input component instance by its field name. Use this to call Syncfusion component methods and properties.
2149
+ * Retrieves the underlying Syncfusion form-input component instance by its field name.
2150
+ * Use this to call Syncfusion component methods and properties.
2151
+ *
2152
+ * @param {string} name - Specifies the name for the built-in Syncfusion component.
2153
+ * @returns {object | null} - Specifies the instance of the Syncfusion component in the form.
2150
2154
  */
2151
2155
  FormRenderer.prototype.getComponent = function (name) {
2152
2156
  return this.inputRefs[name] || null;
2153
2157
  };
2154
2158
  /**
2155
- * Re-normalize + re-render on `schema`/`locale`/`enableRtl` change.
2159
+ * Programmatically sets a form field's value for user edits.
2160
+ *
2161
+ * @param {string} fieldName - The field's `name` (the schema property's `name`).
2162
+ * @param {any} value - The new value to set.
2163
+ * @returns void
2164
+ */
2165
+ FormRenderer.prototype.setFieldValue = function (fieldName, value) {
2166
+ var allComponents = this.collectAllComponents(this.processedSchemaCache.components || []);
2167
+ var component = allComponents.find(function (c) { return c.name === fieldName; });
2168
+ if (!component) {
2169
+ return;
2170
+ }
2171
+ if (this.formState) {
2172
+ this.formState.values[component.id] = value;
2173
+ }
2174
+ var inputEl = this.getInputElementByName(component.id);
2175
+ if (inputEl) {
2176
+ this.syncValueToInput(inputEl, component.id, value);
2177
+ }
2178
+ this.afterValueChange(component.id);
2179
+ };
2180
+ /**
2181
+ * @private
2182
+ */
2183
+ FormRenderer.prototype.syncValueToInput = function (inputEl, fieldId, value) {
2184
+ if (!inputEl) {
2185
+ return;
2186
+ }
2187
+ try {
2188
+ var nativeInput = (inputEl instanceof HTMLInputElement) ? inputEl : null;
2189
+ var isCheckable = !!nativeInput &&
2190
+ (nativeInput.type === 'checkbox' || nativeInput.type === 'radio');
2191
+ var ej2Inst = inputEl.ej2_instances && inputEl.ej2_instances[0];
2192
+ if (ej2Inst) {
2193
+ if (isCheckable && typeof ej2Inst.checked !== 'undefined') {
2194
+ if (nativeInput.type === 'radio' && typeof ej2Inst.value !== 'undefined') {
2195
+ ej2Inst.checked = String(value) === String(ej2Inst.value);
2196
+ }
2197
+ else {
2198
+ ej2Inst.checked = FormRenderer_1.coerceChecked(value);
2199
+ }
2200
+ }
2201
+ else if (typeof ej2Inst.value !== 'undefined') {
2202
+ ej2Inst.value = value;
2203
+ }
2204
+ return;
2205
+ }
2206
+ if (inputEl instanceof HTMLSelectElement) {
2207
+ var strValue = (value === null || value === undefined) ? '' : String(value);
2208
+ inputEl.value = strValue;
2209
+ if (inputEl.value !== strValue && inputEl.options.length > 0) {
2210
+ for (var i = 0; i < inputEl.options.length; i++) {
2211
+ if (inputEl.options[i].text === strValue) {
2212
+ inputEl.value = inputEl.options[i].value;
2213
+ break;
2214
+ }
2215
+ }
2216
+ }
2217
+ }
2218
+ else if (nativeInput && nativeInput.type === 'radio') {
2219
+ var radios = this.element.querySelectorAll("input[type=\"radio\"][name=\"" + fieldId + "\"]");
2220
+ for (var i = 0; i < radios.length; i++) {
2221
+ radios[i].checked = String(value) === radios[i].value;
2222
+ }
2223
+ }
2224
+ else if (isCheckable) {
2225
+ nativeInput.checked = FormRenderer_1.coerceChecked(value);
2226
+ }
2227
+ else if (typeof inputEl.value !== 'undefined') {
2228
+ inputEl.value = (value === null || value === undefined) ? '' : String(value);
2229
+ }
2230
+ }
2231
+ catch (e) { /* ignore */ }
2232
+ };
2233
+ /**
2234
+ * @private
2235
+ */
2236
+ FormRenderer.coerceChecked = function (value) {
2237
+ if (typeof value === 'boolean') {
2238
+ return value;
2239
+ }
2240
+ if (typeof value === 'number') {
2241
+ return value !== 0;
2242
+ }
2243
+ if (typeof value === 'string') {
2244
+ return value !== '' && value !== 'false' && value !== '0';
2245
+ }
2246
+ return !!value;
2247
+ };
2248
+ /**
2156
2249
  * @private
2157
2250
  */
2158
2251
  FormRenderer.prototype.onPropertyChanged = function (newProps, oldProps) {
@@ -2160,6 +2253,9 @@ var FormRenderer = /** @class */ (function (_super) {
2160
2253
  if (newProps.schema !== oldProps.schema) {
2161
2254
  reRender = true;
2162
2255
  }
2256
+ if (newProps.dataModel !== oldProps.dataModel) {
2257
+ reRender = true;
2258
+ }
2163
2259
  if (newProps.locale !== oldProps.locale) {
2164
2260
  reRender = true;
2165
2261
  }
@@ -2169,13 +2265,15 @@ var FormRenderer = /** @class */ (function (_super) {
2169
2265
  if (newProps.layout !== oldProps.layout) {
2170
2266
  reRender = true;
2171
2267
  }
2172
- if (newProps.locale !== oldProps.locale) {
2268
+ if (newProps.customWidgetSettings !== oldProps.customWidgetSettings) {
2173
2269
  reRender = true;
2174
2270
  }
2175
2271
  if (!reRender) {
2176
2272
  return;
2177
2273
  }
2178
- // Tear down rendered children and re-render.
2274
+ if (this.isReact || this.isAngular) {
2275
+ this.clearTemplate();
2276
+ }
2179
2277
  this.refreshing = true;
2180
2278
  this.destroyRendered();
2181
2279
  this.removePreviousRoot();
@@ -2184,7 +2282,6 @@ var FormRenderer = /** @class */ (function (_super) {
2184
2282
  this.refreshing = false;
2185
2283
  };
2186
2284
  /**
2187
- * Destroy all child EJ2 instances, detach listeners, null refs.
2188
2285
  * @private
2189
2286
  */
2190
2287
  FormRenderer.prototype.destroyRendered = function () {
@@ -2217,7 +2314,6 @@ var FormRenderer = /** @class */ (function (_super) {
2217
2314
  this.pendingChangedFieldIds = new Set();
2218
2315
  };
2219
2316
  /**
2220
- * Remove persisted tab selection state for this form when it is fully destroyed.
2221
2317
  * @private
2222
2318
  */
2223
2319
  FormRenderer.prototype.clearPersistedTabSelections = function () {
@@ -2237,11 +2333,43 @@ var FormRenderer = /** @class */ (function (_super) {
2237
2333
  catch (_a) {
2238
2334
  }
2239
2335
  };
2336
+ FormRenderer.prototype.getTemplateFunction = function (template) {
2337
+ var templateFn = null;
2338
+ try {
2339
+ if (typeof template === 'string' && template.indexOf('#') !== -1 && document.querySelectorAll(template).length) {
2340
+ templateFn = compile(this.sanitizeTemplateValue(document.querySelector(template).innerHTML.trim()));
2341
+ }
2342
+ else if (typeof template === 'string') {
2343
+ templateFn = compile(this.sanitizeTemplateValue(template));
2344
+ }
2345
+ else {
2346
+ templateFn = compile(template);
2347
+ }
2348
+ }
2349
+ catch (e) {
2350
+ templateFn = compile(template);
2351
+ }
2352
+ return templateFn;
2353
+ };
2354
+ /**
2355
+ * @private
2356
+ */
2357
+ FormRenderer.prototype.sanitizeTemplateValue = function (value) {
2358
+ if (this.enableHtmlSanitizer && typeof value === 'string') {
2359
+ try {
2360
+ return SanitizeHtmlHelper.sanitize(value);
2361
+ }
2362
+ catch (e) { /* swallow */ }
2363
+ }
2364
+ return value;
2365
+ };
2240
2366
  /**
2241
- * Full component teardown.
2242
2367
  * @private
2243
2368
  */
2244
2369
  FormRenderer.prototype.destroy = function () {
2370
+ if (this.isReact || this.isAngular) {
2371
+ this.clearTemplate();
2372
+ }
2245
2373
  this.destroyRendered();
2246
2374
  this.formState = { values: {}, errors: {} };
2247
2375
  this.expressionEngine = null;
@@ -2274,24 +2402,27 @@ var FormRenderer = /** @class */ (function (_super) {
2274
2402
  }
2275
2403
  };
2276
2404
  var FormRenderer_1;
2277
- /**
2278
- * Component types eligible for DOM preservation across re-renders.
2279
- * These types either bind remote data (dataGrid, lookup-backed
2280
- * dropdown/multiselect) or render many child options (checkboxGroup)
2281
- * and are noticeably expensive / flicker-prone to rebuild.
2282
- */
2283
2405
  FormRenderer.PRESERVABLE_TYPES = new Set([
2284
2406
  'textbox', 'textarea', 'number', 'checkbox', 'checkboxGroup', 'radio', 'dropdown', 'multiselect', 'button', 'date', 'dateTime', 'time', 'dateRange', 'switch', 'signature', 'rating', 'imageEditor', 'fileUpload', 'rangeSlider', 'colorPicker', 'inputMask', 'message', 'panel', 'table', 'tabs', 'dataGrid', 'staticHtml', 'card', 'splitButton', 'richTextEditor'
2285
2407
  ]);
2286
2408
  __decorate([
2287
2409
  Property(null)
2288
2410
  ], FormRenderer.prototype, "schema", void 0);
2411
+ __decorate([
2412
+ Property(null)
2413
+ ], FormRenderer.prototype, "dataModel", void 0);
2289
2414
  __decorate([
2290
2415
  Property('SingleColumn')
2291
2416
  ], FormRenderer.prototype, "layout", void 0);
2292
2417
  __decorate([
2293
2418
  Property('')
2294
2419
  ], FormRenderer.prototype, "className", void 0);
2420
+ __decorate([
2421
+ Collection([], CustomWidgetSetting)
2422
+ ], FormRenderer.prototype, "customWidgetSettings", void 0);
2423
+ __decorate([
2424
+ Property(false)
2425
+ ], FormRenderer.prototype, "enableHtmlSanitizer", void 0);
2295
2426
  __decorate([
2296
2427
  Event()
2297
2428
  ], FormRenderer.prototype, "submit", void 0);