@syncfusion/ej2-react-form-builder 0.1.0-beta

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 (145) hide show
  1. package/Common/CheckboxGroup.d.ts +13 -0
  2. package/Common/CheckboxGroup.js +50 -0
  3. package/Common/ConditionalRuleEngine.d.ts +296 -0
  4. package/Common/ConditionalRuleEngine.js +566 -0
  5. package/Common/CustomTabComponent.d.ts +17 -0
  6. package/Common/CustomTabComponent.js +30 -0
  7. package/Common/CustomValidationEngine.d.ts +58 -0
  8. package/Common/CustomValidationEngine.js +146 -0
  9. package/Common/DataGridComponent.d.ts +20 -0
  10. package/Common/DataGridComponent.js +273 -0
  11. package/Common/FormValidator.d.ts +485 -0
  12. package/Common/FormValidator.js +575 -0
  13. package/Common/MinMaxRuleEngine.d.ts +105 -0
  14. package/Common/MinMaxRuleEngine.js +365 -0
  15. package/Common/StaticHtmlRenderer.d.ts +14 -0
  16. package/Common/StaticHtmlRenderer.js +24 -0
  17. package/Common/expressions/DependencyTracker.d.ts +30 -0
  18. package/Common/expressions/DependencyTracker.js +128 -0
  19. package/Common/expressions/ExpressionEngine.d.ts +95 -0
  20. package/Common/expressions/ExpressionEngine.js +506 -0
  21. package/Common/expressions/ExpressionParser.d.ts +41 -0
  22. package/Common/expressions/ExpressionParser.js +269 -0
  23. package/Common/expressions/useGridExpressions.d.ts +12 -0
  24. package/Common/expressions/useGridExpressions.js +71 -0
  25. package/Common/globalFormId.d.ts +26 -0
  26. package/Common/globalFormId.js +45 -0
  27. package/Common/json-converter.d.ts +444 -0
  28. package/Common/json-converter.js +1184 -0
  29. package/Common/parser.d.ts +98 -0
  30. package/Common/parser.js +753 -0
  31. package/Common/utils.d.ts +130 -0
  32. package/Common/utils.js +574 -0
  33. package/README.md +53 -0
  34. package/index.d.ts +6 -0
  35. package/index.js +6 -0
  36. package/license +13 -0
  37. package/package.json +54 -0
  38. package/src/FormBuilder.d.ts +211 -0
  39. package/src/FormBuilder.js +1299 -0
  40. package/src/components/Database/ConnectionForm.d.ts +8 -0
  41. package/src/components/Database/ConnectionForm.js +28 -0
  42. package/src/components/TopBar.d.ts +10 -0
  43. package/src/components/TopBar.js +7 -0
  44. package/src/components/icons/ComponentIcons.d.ts +44 -0
  45. package/src/components/icons/ComponentIcons.js +40 -0
  46. package/src/components/layout/FormFieldWrapper.d.ts +41 -0
  47. package/src/components/layout/FormFieldWrapper.js +112 -0
  48. package/src/components/layout/LeftPane.d.ts +23 -0
  49. package/src/components/layout/LeftPane.js +310 -0
  50. package/src/components/layout/ListBoxPane.d.ts +24 -0
  51. package/src/components/layout/ListBoxPane.js +94 -0
  52. package/src/components/layout/MainSection.d.ts +39 -0
  53. package/src/components/layout/MainSection.js +1766 -0
  54. package/src/components/layout/Preview.d.ts +12 -0
  55. package/src/components/layout/Preview.js +337 -0
  56. package/src/components/layout/RightPane.d.ts +22 -0
  57. package/src/components/layout/RightPane.js +370 -0
  58. package/src/components/theme/ThemeSwitcher.d.ts +14 -0
  59. package/src/components/theme/ThemeSwitcher.js +24 -0
  60. package/src/components/theme/theme-constant.d.ts +37 -0
  61. package/src/components/theme/theme-constant.js +23 -0
  62. package/src/config/component-properties.json +4929 -0
  63. package/src/config/form-setting.json +56 -0
  64. package/src/config/locale.d.ts +449 -0
  65. package/src/config/locale.js +449 -0
  66. package/src/context/FormSchemaContext.d.ts +32 -0
  67. package/src/context/FormSchemaContext.js +155 -0
  68. package/src/context/LocalizationContext.d.ts +27 -0
  69. package/src/context/LocalizationContext.js +43 -0
  70. package/src/context/ThemeContext.d.ts +23 -0
  71. package/src/context/ThemeContext.js +161 -0
  72. package/src/context/contexts.d.ts +6 -0
  73. package/src/context/contexts.js +6 -0
  74. package/src/context/defaultFormSchema.d.ts +6 -0
  75. package/src/context/defaultFormSchema.js +20 -0
  76. package/src/defaultPalette.d.ts +9 -0
  77. package/src/defaultPalette.js +45 -0
  78. package/src/defaultTemplate.d.ts +3 -0
  79. package/src/defaultTemplate.js +185 -0
  80. package/src/import/schemaImportUtils.d.ts +24 -0
  81. package/src/import/schemaImportUtils.js +121 -0
  82. package/src/index.d.ts +16 -0
  83. package/src/index.js +6 -0
  84. package/src/types/ActionButtons.d.ts +44 -0
  85. package/src/types/ActionButtons.js +27 -0
  86. package/src/types/ComponentProperties.d.ts +33 -0
  87. package/src/types/ComponentProperties.js +2 -0
  88. package/src/types/FormSchema.d.ts +585 -0
  89. package/src/types/FormSchema.js +147 -0
  90. package/src/types/connection.d.ts +19 -0
  91. package/src/types/connection.js +9 -0
  92. package/src/utils/AttributesEditor.d.ts +13 -0
  93. package/src/utils/AttributesEditor.js +117 -0
  94. package/src/utils/ButtonGroupEditor.d.ts +15 -0
  95. package/src/utils/ButtonGroupEditor.js +141 -0
  96. package/src/utils/ChoiceBasedFieldEditor.d.ts +16 -0
  97. package/src/utils/ChoiceBasedFieldEditor.js +87 -0
  98. package/src/utils/ClipboardHelper.d.ts +26 -0
  99. package/src/utils/ClipboardHelper.js +83 -0
  100. package/src/utils/ColumnBuilder.d.ts +11 -0
  101. package/src/utils/ColumnBuilder.js +153 -0
  102. package/src/utils/ColumnSpanEditor.d.ts +8 -0
  103. package/src/utils/ColumnSpanEditor.js +98 -0
  104. package/src/utils/ConditionDataEditor.d.ts +29 -0
  105. package/src/utils/ConditionDataEditor.js +177 -0
  106. package/src/utils/ConditionalEditorUtils.d.ts +27 -0
  107. package/src/utils/ConditionalEditorUtils.js +310 -0
  108. package/src/utils/ConditionsEditor.d.ts +20 -0
  109. package/src/utils/ConditionsEditor.js +571 -0
  110. package/src/utils/CustomAccordion.d.ts +13 -0
  111. package/src/utils/CustomAccordion.js +38 -0
  112. package/src/utils/CustomValidationEditor.d.ts +11 -0
  113. package/src/utils/CustomValidationEditor.js +208 -0
  114. package/src/utils/DataSourceCollector.d.ts +3 -0
  115. package/src/utils/DataSourceCollector.js +252 -0
  116. package/src/utils/ExpressionEditor.d.ts +13 -0
  117. package/src/utils/ExpressionEditor.js +99 -0
  118. package/src/utils/FormSettingsPanel.d.ts +9 -0
  119. package/src/utils/FormSettingsPanel.js +60 -0
  120. package/src/utils/LookupConfig.d.ts +11 -0
  121. package/src/utils/LookupConfig.js +159 -0
  122. package/src/utils/MinMaxValueEditor.d.ts +25 -0
  123. package/src/utils/MinMaxValueEditor.js +188 -0
  124. package/src/utils/OptionsEditor.d.ts +8 -0
  125. package/src/utils/OptionsEditor.js +79 -0
  126. package/src/utils/PropertyRenderer.d.ts +22 -0
  127. package/src/utils/PropertyRenderer.js +210 -0
  128. package/src/utils/ValueRenderer.d.ts +2 -0
  129. package/src/utils/ValueRenderer.js +91 -0
  130. package/src/utils/ej2DbAdaptor.d.ts +6 -0
  131. package/src/utils/ej2DbAdaptor.js +38 -0
  132. package/src/utils/mappingHeuristics.d.ts +10 -0
  133. package/src/utils/mappingHeuristics.js +33 -0
  134. package/src/utils/renderComponent.d.ts +18 -0
  135. package/src/utils/renderComponent.js +300 -0
  136. package/styles/tailwind3.css +67 -0
  137. package/styles/themes/action-buttons.css +110 -0
  138. package/styles/themes/datagrid.css +380 -0
  139. package/styles/themes/drag-reorder.css +248 -0
  140. package/styles/themes/import-dialog.css +292 -0
  141. package/styles/themes/index.css +658 -0
  142. package/styles/themes/left-pane.css +253 -0
  143. package/styles/themes/options-editor.css +63 -0
  144. package/styles/themes/preview.css +702 -0
  145. package/styles/themes/property-dialog.css +371 -0
@@ -0,0 +1,310 @@
1
+ /**
2
+ * ConditionalEditorUtils - Shared utility functions for Conditional and ConditionalData editors
3
+ * Exports field type inference, column templates, and helper functions
4
+ */
5
+ import { getComponent, Internationalization } from '@syncfusion/ej2-base';
6
+ import { DropDownList, MultiSelect } from '@syncfusion/ej2-dropdowns';
7
+ import { DatePicker, TimePicker, DateTimePicker, DateRangePicker } from '@syncfusion/ej2-calendars';
8
+ import { resolveOptions } from '../../Common/utils';
9
+ import { useLocalization } from '../context/LocalizationContext';
10
+ /**
11
+ * Infer field type from component type for QueryBuilder
12
+ */
13
+ export function inferFieldType(component) {
14
+ const type = component.type;
15
+ if (type === 'number' || type === 'rangeSlider' || type === 'rating') {
16
+ return 'number';
17
+ }
18
+ if (type === 'date') {
19
+ return 'date';
20
+ }
21
+ if (type === 'dateTime') {
22
+ return 'string';
23
+ }
24
+ if (type === 'time') {
25
+ return 'string';
26
+ }
27
+ if (type === 'dateRange') {
28
+ return 'string';
29
+ }
30
+ if (type === 'checkbox' || type === 'switch') {
31
+ return 'boolean';
32
+ }
33
+ if (type === 'multiselect' || type === 'checkboxGroup') {
34
+ return 'string';
35
+ }
36
+ return 'string';
37
+ }
38
+ /**
39
+ * Check if component is an array field type
40
+ */
41
+ export function isArrayField(component) {
42
+ return component.type === 'multiselect' || component.type === 'checkboxGroup' || component.type === 'dateRange';
43
+ }
44
+ /**
45
+ * Check if component has selectable options
46
+ */
47
+ export function hasSelectableOptions(component) {
48
+ const selectTypes = ['dropdown', 'radio', 'multiselect', 'checkboxGroup'];
49
+ return selectTypes.includes(component.type) && !!component.options;
50
+ }
51
+ /**
52
+ * Create column template for QueryBuilder with custom input widgets
53
+ * Supports date, time, multiselect, dropdown, and other input types
54
+ */
55
+ export function createColumnTemplate(component, qbRef, fetchedOptions = {}) {
56
+ const intl = new Internationalization();
57
+ const { locale } = useLocalization();
58
+ const isMultiple = component.type === 'multiselect' || component.type === 'checkboxGroup';
59
+ const isDateType = component.type === 'date';
60
+ const isTimeType = component.type === 'time';
61
+ const isDateTimeType = component.type === 'dateTime';
62
+ const isDateRangeType = component.type === 'dateRange';
63
+ const urlFetchedOptions = fetchedOptions[component.id] || [];
64
+ const resolvedOptions = Array.isArray(component.options)
65
+ ? component.options
66
+ : component.options?.type === 'url' ? resolveOptions(component.options, urlFetchedOptions) : [];
67
+ const dataSource = resolvedOptions ? resolvedOptions.map(opt => {
68
+ if (typeof opt === 'string') {
69
+ return { text: opt, value: opt };
70
+ }
71
+ else if (opt && typeof opt === 'object' && 'value' in opt) {
72
+ return {
73
+ text: opt.label || opt.text || opt.value,
74
+ value: opt.value
75
+ };
76
+ }
77
+ return { text: String(opt), value: String(opt) };
78
+ }) : [];
79
+ return {
80
+ create: () => {
81
+ const elem = document.createElement('input');
82
+ elem.setAttribute('type', 'text');
83
+ return elem;
84
+ },
85
+ destroy: (args) => {
86
+ const element = document.getElementById(args.elementId);
87
+ if (!element)
88
+ return;
89
+ if (isMultiple) {
90
+ const multiSelectObj = getComponent(element, 'multiselect');
91
+ if (multiSelectObj) {
92
+ multiSelectObj.destroy();
93
+ }
94
+ }
95
+ else if (isDateType) {
96
+ const datePickerObj = getComponent(element, 'datepicker');
97
+ if (datePickerObj) {
98
+ datePickerObj.destroy();
99
+ }
100
+ }
101
+ else if (isTimeType) {
102
+ const timePickerObj = getComponent(element, 'timepicker');
103
+ if (timePickerObj) {
104
+ timePickerObj.destroy();
105
+ }
106
+ }
107
+ else if (isDateTimeType) {
108
+ const dateTimePickerObj = getComponent(element, 'datetimepicker');
109
+ if (dateTimePickerObj) {
110
+ dateTimePickerObj.destroy();
111
+ }
112
+ }
113
+ else if (isDateRangeType) {
114
+ const dateRangePickerObj = getComponent(element, 'daterangepicker');
115
+ if (dateRangePickerObj) {
116
+ dateRangePickerObj.destroy();
117
+ }
118
+ }
119
+ else {
120
+ const dropDownObj = getComponent(element, 'dropdownlist');
121
+ if (dropDownObj) {
122
+ dropDownObj.destroy();
123
+ }
124
+ }
125
+ },
126
+ write: (args) => {
127
+ if (isMultiple) {
128
+ let initialValue = [];
129
+ if (args.values) {
130
+ if (typeof args.values === 'string') {
131
+ initialValue = args.values.split(',').map((v) => v.trim()).filter((v) => v);
132
+ }
133
+ else if (Array.isArray(args.values)) {
134
+ initialValue = args.values;
135
+ }
136
+ }
137
+ const multiSelectObj = new MultiSelect({
138
+ change: (e) => {
139
+ const valueStr = e.value && e.value.length > 0 ? e.value.join(', ') : '';
140
+ qbRef.current?.notifyChange(valueStr, e.element);
141
+ },
142
+ dataSource: dataSource,
143
+ fields: { text: 'text', value: 'value' },
144
+ placeholder: `Select ${component.label || component.id}`,
145
+ value: initialValue,
146
+ });
147
+ multiSelectObj.appendTo('#' + args.elements.id);
148
+ const elem = document.getElementById(args.elements.id);
149
+ if (elem) {
150
+ elem.setAttribute('data-component-id', component.id);
151
+ }
152
+ }
153
+ else if (isDateType) {
154
+ let initialDate = null;
155
+ if (args.values) {
156
+ if (typeof args.values === 'string') {
157
+ initialDate = new Date(args.values);
158
+ }
159
+ else if (args.values instanceof Date) {
160
+ initialDate = args.values;
161
+ }
162
+ }
163
+ const datePickerObj = new DatePicker({
164
+ locale: locale,
165
+ change: (e) => {
166
+ if (e.value) {
167
+ const dFormatter = intl.getDateFormat({
168
+ format: 'MM/dd/yyyy',
169
+ type: 'date'
170
+ });
171
+ const formattedValue = dFormatter(e.value);
172
+ qbRef.current?.notifyChange(formattedValue, e.element);
173
+ }
174
+ else {
175
+ qbRef.current?.notifyChange('', e.element);
176
+ }
177
+ },
178
+ format: 'MM/dd/yyyy',
179
+ placeholder: `Select ${component.label || component.id}`,
180
+ value: initialDate || undefined,
181
+ });
182
+ datePickerObj.appendTo('#' + args.elements.id);
183
+ }
184
+ else if (isTimeType) {
185
+ let initialTime = null;
186
+ if (args.values) {
187
+ if (typeof args.values === 'string') {
188
+ initialTime = new Date(`1970-01-01 ${args.values}`);
189
+ }
190
+ else if (args.values instanceof Date) {
191
+ initialTime = args.values;
192
+ }
193
+ }
194
+ const timePickerObj = new TimePicker({
195
+ locale: locale,
196
+ change: (e) => {
197
+ if (e.value) {
198
+ const tFormatter = intl.getDateFormat({
199
+ format: 'hh:mm a',
200
+ type: 'time'
201
+ });
202
+ const formattedValue = tFormatter(e.value);
203
+ qbRef.current?.notifyChange(formattedValue, e.element);
204
+ }
205
+ else {
206
+ qbRef.current?.notifyChange('', e.element);
207
+ }
208
+ },
209
+ format: 'hh:mm a',
210
+ placeholder: `Select ${component.label || component.id}`,
211
+ value: initialTime || undefined,
212
+ });
213
+ timePickerObj.appendTo('#' + args.elements.id);
214
+ }
215
+ else if (isDateTimeType) {
216
+ let initialDateTime = null;
217
+ if (args.values) {
218
+ if (typeof args.values === 'string') {
219
+ initialDateTime = new Date(args.values);
220
+ }
221
+ else if (args.values instanceof Date) {
222
+ initialDateTime = args.values;
223
+ }
224
+ }
225
+ const dateTimePickerObj = new DateTimePicker({
226
+ locale: locale,
227
+ change: (e) => {
228
+ if (e.value) {
229
+ const dtFormatter = intl.getDateFormat({
230
+ format: 'MM/dd/yyyy hh:mm a',
231
+ type: 'dateTime'
232
+ });
233
+ const formattedValue = dtFormatter(e.value);
234
+ const element = document.getElementById(args.elements.id);
235
+ qbRef.current?.notifyChange(formattedValue, element);
236
+ }
237
+ else {
238
+ const element = document.getElementById(args.elements.id);
239
+ qbRef.current?.notifyChange('', element);
240
+ }
241
+ },
242
+ format: 'MM/dd/yyyy hh:mm a',
243
+ placeholder: `Select ${component.label || component.id}`,
244
+ value: initialDateTime || undefined,
245
+ });
246
+ dateTimePickerObj.appendTo('#' + args.elements.id);
247
+ }
248
+ else if (isDateRangeType) {
249
+ let initialStartDate = null;
250
+ let initialEndDate = null;
251
+ if (args.values) {
252
+ if (typeof args.values === 'string') {
253
+ const dates = args.values.split(',').map((d) => d.trim());
254
+ if (dates[0])
255
+ initialStartDate = new Date(dates[0]);
256
+ if (dates[1])
257
+ initialEndDate = new Date(dates[1]);
258
+ }
259
+ else if (Array.isArray(args.values)) {
260
+ if (args.values[0])
261
+ initialStartDate = new Date(args.values[0]);
262
+ if (args.values[1])
263
+ initialEndDate = new Date(args.values[1]);
264
+ }
265
+ }
266
+ const dateRangePickerObj = new DateRangePicker({
267
+ locale: locale,
268
+ change: (e) => {
269
+ if (e.startDate && e.endDate) {
270
+ const dFormatter = intl.getDateFormat({
271
+ format: 'MM/dd/yyyy',
272
+ type: 'date'
273
+ });
274
+ const formattedStart = dFormatter(e.startDate);
275
+ const formattedEnd = dFormatter(e.endDate);
276
+ const formattedValue = `${formattedStart} , ${formattedEnd}`;
277
+ const element = document.getElementById(args.elements.id);
278
+ qbRef.current?.notifyChange(formattedValue, element);
279
+ }
280
+ else {
281
+ const element = document.getElementById(args.elements.id);
282
+ qbRef.current?.notifyChange('', element);
283
+ }
284
+ },
285
+ format: 'MM/dd/yyyy',
286
+ placeholder: `Select ${component.label || component.id}`,
287
+ startDate: initialStartDate || undefined,
288
+ endDate: initialEndDate || undefined,
289
+ });
290
+ dateRangePickerObj.appendTo('#' + args.elements.id);
291
+ }
292
+ else {
293
+ const dropDownObj = new DropDownList({
294
+ change: (e) => {
295
+ qbRef.current?.notifyChange(e.itemData?.value || e.value, e.element);
296
+ },
297
+ dataSource: dataSource,
298
+ fields: { text: 'text', value: 'value' },
299
+ placeholder: `Select ${component.label || component.id}`,
300
+ value: args.values || undefined
301
+ });
302
+ dropDownObj.appendTo('#' + args.elements.id);
303
+ const elem = document.getElementById(args.elements.id);
304
+ if (elem) {
305
+ elem.setAttribute('data-component-id', component.id);
306
+ }
307
+ }
308
+ }
309
+ };
310
+ }
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import type { FormComponent, FormComponentConditions } from '../types/FormSchema';
3
+ export interface ConditionsEditorProps {
4
+ /** Array of available form field names/components for condition rules */
5
+ componentFields: FormComponent[];
6
+ /** The component being edited (for determining value input type in setValueWhen) */
7
+ componentForEdit?: FormComponent;
8
+ /** ID of the component being edited - exclude this from columns to prevent self-reference */
9
+ excludeFieldId?: string;
10
+ /** Array of child component IDs to exclude (prevents circular dependencies with children) */
11
+ excludeChildIds?: string[];
12
+ /** Existing conditions to pre-populate QueryBuilders (for editing) */
13
+ existingConditions?: FormComponentConditions;
14
+ /** Callback when any condition changes */
15
+ onChange: (conditions: FormComponentConditions) => void;
16
+ /** Array of supported condition types for this component (default: all) */
17
+ supportedConditions?: ('visibleWhen' | 'hideWhen' | 'readOnlyWhen' | 'disabledWhen' | 'requiredWhen' | 'setValueWhen' | 'conditionalData' | 'choiceBasedField')[];
18
+ builderMode?: 'Simple' | 'Developer';
19
+ }
20
+ export declare const ConditionsEditor: React.FC<ConditionsEditorProps>;