@componyx/ui 0.0.0-stage → 1.0.3

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 (169) hide show
  1. package/AppSkin/AppSkin.css +1268 -0
  2. package/AppSkin/AppSkin.js +2748 -0
  3. package/AppSkin/Themes/Default.css +241 -0
  4. package/Base/Base.js +3407 -0
  5. package/Base/ComponentIcons.css +66 -0
  6. package/Base/Font/ComponentIcons.woff +0 -0
  7. package/Base/Font/UI.woff +0 -0
  8. package/Base/Library.js +8432 -0
  9. package/Base/NavigationManager.js +462 -0
  10. package/Base/ResponsiveTemplates.js +371 -0
  11. package/Base/Sanitizer.js +288 -0
  12. package/Base/Themes/Default.css +255 -0
  13. package/Base/UI.css +618 -0
  14. package/Base/UIResourcePath.js +6 -0
  15. package/Bindary/Bindary.js +2011 -0
  16. package/Bindary/Modules/Connection.js +216 -0
  17. package/Bindary/Modules/Core.js +854 -0
  18. package/Bindary/Modules/DataUpdater.js +351 -0
  19. package/Bindary/Modules/ExpressionEngine.js +347 -0
  20. package/Bindary/Modules/ProxyManager.js +482 -0
  21. package/Bindary/Modules/Renderer.js +605 -0
  22. package/Bindary/Modules/Router.js +291 -0
  23. package/Bindary/Modules/Scroller.js +89 -0
  24. package/Bindary/Modules/Template.js +1273 -0
  25. package/BookmarkSpy/BookmarkSpy.js +430 -0
  26. package/Box/Box.css +36 -0
  27. package/Box/Box.js +1685 -0
  28. package/Button/Button.css +470 -0
  29. package/Button/Button.js +1398 -0
  30. package/Button/Themes/Default.css +200 -0
  31. package/Carousel/Carousel.css +273 -0
  32. package/Carousel/Carousel.js +607 -0
  33. package/ColorButton/ColorButton.css +39 -0
  34. package/ColorButton/ColorButton.js +336 -0
  35. package/ColorPicker/ColorPicker.css +359 -0
  36. package/ColorPicker/ColorPicker.js +972 -0
  37. package/ComboBox/ComboBox.css +357 -0
  38. package/ComboBox/ComboBox.js +2342 -0
  39. package/ComboBox/Themes/Default.css +23 -0
  40. package/DataPager/DataPager.css +72 -0
  41. package/DataPager/DataPager.js +674 -0
  42. package/DatePicker/DatePicker.css +227 -0
  43. package/DatePicker/DatePicker.js +1531 -0
  44. package/DatePicker/Themes/Default.css +26 -0
  45. package/Dialog/Dialog.css +106 -0
  46. package/Dialog/Dialog.js +572 -0
  47. package/Dialog/Themes/Default.css +10 -0
  48. package/Editor/Data/Emoji.json +8285 -0
  49. package/Editor/Data/Special.json +1042 -0
  50. package/Editor/Editor.css +1562 -0
  51. package/Editor/Editor.js +4058 -0
  52. package/Editor/Font/Editor.woff +0 -0
  53. package/Editor/Modules/ComponentFactory.js +565 -0
  54. package/Editor/Modules/ContentManager.js +748 -0
  55. package/Editor/Modules/DialogManager.js +1234 -0
  56. package/Editor/Modules/EventManager.js +458 -0
  57. package/Editor/Modules/Format.js +950 -0
  58. package/Editor/Modules/History.js +191 -0
  59. package/Editor/Modules/LayoutState.js +379 -0
  60. package/Editor/Modules/ListManager.js +296 -0
  61. package/Editor/Modules/MenuManager.js +388 -0
  62. package/Editor/Modules/NodeManager.js +681 -0
  63. package/Editor/Modules/ParagraphButtons.js +122 -0
  64. package/Editor/Modules/Resizer.js +176 -0
  65. package/Editor/Modules/SelectionRange.js +564 -0
  66. package/Editor/Modules/SourceViewBuilder.js +212 -0
  67. package/Editor/Modules/SymbolPicker.js +208 -0
  68. package/Editor/Modules/Table.js +2327 -0
  69. package/Editor/Modules/TableDialog.js +757 -0
  70. package/Editor/Modules/Toolbar.js +375 -0
  71. package/Editor/Modules/TooltipMenu.js +125 -0
  72. package/Editor/Modules/Utility.js +131 -0
  73. package/Editor/Themes/Default.css +204 -0
  74. package/FileUpload/FileUpload.css +156 -0
  75. package/FileUpload/FileUpload.js +898 -0
  76. package/FileUpload/Themes/Default.css +17 -0
  77. package/Form/Form.css +1934 -0
  78. package/Form/Form.js +4943 -0
  79. package/Form/Modules/ActionManager.js +368 -0
  80. package/Form/Modules/BuildPanelManager.js +319 -0
  81. package/Form/Modules/ComponentFactory.js +468 -0
  82. package/Form/Modules/ComponentPanel.js +265 -0
  83. package/Form/Modules/ConfigPanelManager.js +685 -0
  84. package/Form/Modules/DataObserver.js +717 -0
  85. package/Form/Modules/Databinder.js +602 -0
  86. package/Form/Modules/Draggable.js +756 -0
  87. package/Form/Modules/OptionsPanel.js +342 -0
  88. package/Form/Modules/Renderer.js +1889 -0
  89. package/Form/Modules/RuleEngine.js +585 -0
  90. package/Form/Modules/RulesPanel.js +1158 -0
  91. package/Form/Modules/Types.js +1709 -0
  92. package/Form/Modules/ValidationManager.js +194 -0
  93. package/Form/Themes/Default.css +216 -0
  94. package/FormField/FormField.css +468 -0
  95. package/FormField/FormField.js +576 -0
  96. package/FormField/Themes/Default.css +99 -0
  97. package/Grid/Grid.css +544 -0
  98. package/Grid/Grid.js +3761 -0
  99. package/Grid/Themes/Default.css +43 -0
  100. package/LICENSE +126 -0
  101. package/MaskedTextBox/MaskedTextBox.css +28 -0
  102. package/MaskedTextBox/MaskedTextBox.js +642 -0
  103. package/MaskedTextBox/Themes/Default.css +6 -0
  104. package/Menu/Menu.css +328 -0
  105. package/Menu/Menu.js +2386 -0
  106. package/Menu/Themes/Default.css +24 -0
  107. package/NumericBox/NumericBox.css +120 -0
  108. package/NumericBox/NumericBox.js +984 -0
  109. package/PanelBar/PanelBar.css +123 -0
  110. package/PanelBar/PanelBar.js +505 -0
  111. package/PanelBar/Themes/Default.css +51 -0
  112. package/PieChart/PieChart.css +95 -0
  113. package/PieChart/PieChart.js +820 -0
  114. package/PieChart/Themes/Default.css +9 -0
  115. package/README.md +178 -3
  116. package/Slider/Slider.css +348 -0
  117. package/Slider/Slider.js +1306 -0
  118. package/Slider/Themes/Default.css +44 -0
  119. package/TabStrip/TabStrip.css +52 -0
  120. package/TabStrip/TabStrip.js +362 -0
  121. package/TabStrip/Themes/Default.css +35 -0
  122. package/TimePicker/Themes/Default.css +30 -0
  123. package/TimePicker/TimePicker.css +253 -0
  124. package/TimePicker/TimePicker.js +1485 -0
  125. package/TooltipManager/Themes/Default.css +21 -0
  126. package/TooltipManager/TooltipManager.css +227 -0
  127. package/TooltipManager/TooltipManager.js +791 -0
  128. package/Validator/Validator.css +54 -0
  129. package/Validator/Validator.js +2508 -0
  130. package/componyx.html-data.json +619 -0
  131. package/index.js +27 -0
  132. package/package.json +43 -4
  133. package/types/AppSkin.d.ts +842 -0
  134. package/types/Base.d.ts +1034 -0
  135. package/types/Bindary.d.ts +1196 -0
  136. package/types/BookmarkSpy.d.ts +112 -0
  137. package/types/Box.d.ts +374 -0
  138. package/types/Button.d.ts +455 -0
  139. package/types/Carousel.d.ts +136 -0
  140. package/types/ColorButton.d.ts +120 -0
  141. package/types/ColorPicker.d.ts +225 -0
  142. package/types/ComboBox.d.ts +507 -0
  143. package/types/DataPager.d.ts +152 -0
  144. package/types/DatePicker.d.ts +354 -0
  145. package/types/Dialog.d.ts +160 -0
  146. package/types/Editor.d.ts +1289 -0
  147. package/types/FileUpload.d.ts +206 -0
  148. package/types/Form.d.ts +3078 -0
  149. package/types/FormField.d.ts +204 -0
  150. package/types/Grid.d.ts +911 -0
  151. package/types/Library.d.ts +1899 -0
  152. package/types/MaskedTextBox.d.ts +91 -0
  153. package/types/Menu.d.ts +577 -0
  154. package/types/NumericBox.d.ts +310 -0
  155. package/types/PanelBar.d.ts +223 -0
  156. package/types/PieChart.d.ts +224 -0
  157. package/types/ResponsiveTemplates.d.ts +108 -0
  158. package/types/Slider.d.ts +227 -0
  159. package/types/TabStrip.d.ts +185 -0
  160. package/types/TimePicker.d.ts +265 -0
  161. package/types/TooltipManager.d.ts +178 -0
  162. package/types/UI.d.ts +29 -0
  163. package/types/Validator.d.ts +653 -0
  164. package/types/index.d.ts +59 -0
  165. package/ui.css +11783 -0
  166. package/ui.js +79477 -0
  167. package/ui.min.css +138 -0
  168. package/ui.min.js +264 -0
  169. package/ui.min.js.map +1 -0
Binary file
@@ -0,0 +1,565 @@
1
+ /*! Componyx.UI | (c) E.H. Daanen / Componyx | BUSL-1.1 | componyx.com/license */
2
+ componyx.UI.editor_modules = componyx.UI.editor_modules || {};
3
+
4
+ /**
5
+ * ComponentFactory module - creates and configures UI components.
6
+ * @class ComponentFactory
7
+ * @memberof componyx.UI.editor_modules
8
+ * @ignore
9
+ */
10
+
11
+ componyx.UI.editor_modules.ComponentFactory = class ComponentFactory
12
+ {
13
+ #colorSwatchBox = null;
14
+ #colorPicker = null;
15
+ #swatch = null;
16
+ #activeColorButton = null;
17
+
18
+ constructor(editor)
19
+ {
20
+ this.editor = editor;
21
+ this.utility = editor.utility;
22
+
23
+ const boxExpandOption = componyx.UI.Box.ExpandDirectionOption,
24
+ expandDirection = (editor.toolbarDisplay == componyx.UI.Editor.ToolbarDisplayOption.FOOTER) ? boxExpandOption.DOWN : boxExpandOption.UP;
25
+
26
+ this.tooltipManager = this.createTooltipManager('buttonTooltipManager', editor.buttonTooltipManagerId, editor.element, { selectableTooltipContent: false, showOnFocus: false, expandDirection });
27
+ }
28
+
29
+ get colorSwatchBox()
30
+ {
31
+ return this.#colorSwatchBox;
32
+ }
33
+ get colorPicker()
34
+ {
35
+ return this.#colorPicker;
36
+ }
37
+
38
+ setActiveExpandButton(button)
39
+ {
40
+ this.#activeColorButton = button;
41
+ }
42
+
43
+ /**
44
+ * Creates and configures a Menu component.
45
+ * @param {string} id - The ID to assign to the new menu
46
+ * @param {string} cloneId - The store ID of the menu to clone from
47
+ * @param {HTMLElement} container - The container element to render into
48
+ * @param {Object} [settings={}] - Menu configuration options
49
+ * @param {boolean} [settings.expandOnClick=true] - Whether menu items expand on click
50
+ * @param {boolean} [settings.visibleRoot=false] - Whether the root menu is always visible
51
+ * @param {boolean} [settings.horizontalRoot=false] - Whether the root menu is rendered horizontally
52
+ * @param {boolean} [settings.collapseAllOnSelect=true] - Whether all submenus collapse after selection
53
+ * @returns {componyx.UI.Menu}
54
+ * @ignore
55
+ */
56
+ createMenu(id, cloneId, container, settings = {})
57
+ {
58
+ id = this.#getId(id);
59
+ const menu = $UI.createComponent(componyx.UI.Menu, { id: id, containerElement: container });
60
+
61
+ menu.clone($UI.store[cloneId], this.editor);
62
+ menu.expandOnClick = settings.expandOnClick ?? true;
63
+ menu.visibleRoot = settings.visibleRoot ?? false;
64
+ menu.horizontalRoot = settings.horizontalRoot ?? false;
65
+ menu.collapseAllOnSelect = settings.collapseAllOnSelect ?? true;
66
+ menu.autoFit = true;
67
+ menu.showing = true;
68
+ menu.events.onPostRender.priorityAdd(() =>
69
+ {
70
+ this.editor.isReady.apply(this.editor);
71
+ });
72
+
73
+ return menu;
74
+ }
75
+
76
+ /**
77
+ * Creates and configures a Box component.
78
+ * @param {string} id - The ID to assign to the new box
79
+ * @param {string} cloneId - The store ID of the box to clone from
80
+ * @param {HTMLElement} container - The container element to render into
81
+ * @param {Object} [settings={}] - Box configuration options
82
+ * @param {string} [settings.cssClass] - CSS class to apply to the box
83
+ * @param {boolean} [settings.hideOnOutsideClick=false] - Whether to hide when clicking outside
84
+ * @param {number} [settings.autoPositionOption] - Auto position option (default: EXPAND)
85
+ * @param {number} [settings.expandDirection] - Expand direction (default: DOWN)
86
+ * @param {number} [settings.alignXOption] - Horizontal alignment option (default: CENTER)
87
+ * @param {HTMLElement|HTMLElement[]} [settings.content] - Content template for the box
88
+ * @returns {componyx.UI.Box}
89
+ * @ignore
90
+ */
91
+ createBox(id, cloneId, container, settings = {})
92
+ {
93
+ id = this.#getId(id);
94
+
95
+ const editor = this.editor;
96
+ const box = $UI.createComponent(componyx.UI.Box, { id, containerElement: container });
97
+ box.clone($UI.store[cloneId], editor);
98
+ box.cssClass = settings.cssClass;
99
+ box.hideOnOutsideClick = settings.hideOnOutsideClick || false;
100
+ box.autoPosition = settings.autoPositionOption ?? componyx.UI.Box.AutoPositionOption.EXPAND;
101
+ box.expandDirection = settings.expandDirection ?? componyx.UI.Box.ExpandDirectionOption.DOWN;
102
+ box.alignX = settings.alignXOption || componyx.UI.Box.AlignXOption.CENTER;
103
+ box.autoInvertFit = true;
104
+ box.setContentTemplate(settings.content);
105
+
106
+ box.events.onPostRender.priorityAdd(() => { editor.isReady.apply(editor); }, null);
107
+ return box;
108
+ }
109
+
110
+ /**
111
+ * Creates and configures a TooltipManager component, creating an associated Box if one is not already defined.
112
+ * @param {string} id - The base ID to assign to the tooltip manager and its box
113
+ * @param {string} cloneId - The store ID of the tooltip manager to clone from
114
+ * @param {HTMLElement} container - The container element to render into
115
+ * @param {Object} [settings={}] - TooltipManager configuration options
116
+ * @param {string} [settings.cssClass] - CSS class to apply to the tooltip manager
117
+ * @param {boolean} [settings.selectableTooltipContent=true] - Whether tooltip content is selectable
118
+ * @param {boolean} [settings.showOnFocus=true] - Whether tooltips show on focus
119
+ * @param {number} [settings.expandDirection] - Expand direction for the tooltip box
120
+ * @param {string} [settings.showOnPointerEvent] - Pointer event type that triggers tooltip display
121
+ * @returns {componyx.UI.TooltipManager}
122
+ * @ignore
123
+ */
124
+ createTooltipManager(id, cloneId, container, settings = {})
125
+ {
126
+ let tooltipManager = $UI.createComponent(componyx.UI.TooltipManager, { id: this.#getId(id), containerElement: container });
127
+
128
+ tooltipManager.clone($UI.store[cloneId], this.editor, true, true, { triggers: '' });
129
+
130
+ if (!tooltipManager.boxId)
131
+ {
132
+ const box = this.createBox('_TooltipManagerBox', null, this.editor.element);
133
+ box.animation.showType = box.animation.hideType = 0;
134
+ tooltipManager.boxId = box.id;
135
+ }
136
+
137
+ tooltipManager.cssClass = settings.cssClass;
138
+ tooltipManager.selectableTooltipContent = (settings.selectableTooltipContent == false) ? false : true;
139
+ tooltipManager.showOnFocus = (settings.showOnFocus == false) ? false : true;
140
+ tooltipManager.showing = true;
141
+
142
+ if (!$lib.isEmpty(settings.showOnPointerEvent))
143
+ tooltipManager.showOnPointerEvent = settings.showOnPointerEvent;
144
+
145
+ tooltipManager.events.onPostRender.priorityAdd(() => { this.editor.isReady.apply(this.editor); }, null);
146
+ return tooltipManager;
147
+ }
148
+
149
+ /**
150
+ * Creates the validator component.
151
+ * @returns {componyx.UI.Validator}
152
+ * @ignore
153
+ */
154
+ createValidator()
155
+ {
156
+ const id = this.#getId('Validator'),
157
+ validator = $UI.createComponent(componyx.UI.Validator, { id: id, containerElement: this.editor.element });
158
+
159
+ validator.clone($UI.store[this.editor.validatorId], this.editor);
160
+
161
+ validator.events.onPreInit.priorityAdd(() =>
162
+ {
163
+ this.editor.isReady.apply(this.editor);
164
+ });
165
+
166
+ validator.events.onInvalid.priorityAdd(() =>
167
+ {
168
+ let activeDialog = this.editor.dialogManager.activeDialog;
169
+
170
+ if (activeDialog)
171
+ $UI.store[activeDialog.id + '_Confirm'].disable();
172
+ });
173
+
174
+ validator.events.onValid.priorityAdd(() =>
175
+ {
176
+ let activeDialog = this.editor.dialogManager.activeDialog;
177
+
178
+ if (activeDialog)
179
+ $UI.store[activeDialog.id + '_Confirm'].enable();
180
+ });
181
+
182
+ return validator;
183
+ }
184
+
185
+ /**
186
+ * Creates a dialog component.
187
+ * @param {string} id - The dialog ID
188
+ * @param {string} cloneId - The base dialog ID to clone from
189
+ * @param {Object} settings - Dialog configuration
190
+ * @param {string} settings.cssClass - CSS class for the dialog
191
+ * @param {HTMLElement} settings.header - Header content
192
+ * @param {HTMLElement} settings.content - Main content
193
+ * @param {HTMLElement} [settings.footer] - Footer content (optional)
194
+ * @param {boolean} [settings.modal] - Whether dialog is modal (default: true)
195
+ * @param {number} [settings.autoPosition] - Auto position option (default: 5)
196
+ * @param {Function} settings.onShowComplete - Callback when dialog is shown
197
+ * @param {Function} settings.onConfirm - Callback when confirmed
198
+ * @param {Function} settings.onHide - Callback when hidden
199
+ * @returns {componyx.UI.Dialog}
200
+ * @ignore
201
+ */
202
+ createDialog(id, cloneId, settings = {})
203
+ {
204
+ const dialog = $UI.createComponent(componyx.UI.Dialog, { id: this.#getId(id), containerElement: this.editor.element });
205
+
206
+ dialog.clone($UI.store[cloneId], this.editor);
207
+ dialog.cssClass = settings.cssClass || null;
208
+ dialog.autoFit = false;
209
+ dialog.buttons.deny = false;
210
+ dialog.buttons.cancelText = this.editor.labels.dialogCancel;
211
+ dialog.buttons.confirmText = this.editor.labels.dialogConfirm;
212
+ dialog.modal = settings.modal !== undefined ? settings.modal : true;
213
+ dialog.autoPosition = settings.autoPosition !== undefined ? settings.autoPosition : 5;
214
+
215
+ dialog.setHeaderTemplate(settings.header);
216
+ dialog.setContentTemplate(settings.content);
217
+
218
+ if (settings.footer)
219
+ dialog.setFooterTemplate(settings.footer);
220
+
221
+ dialog.events.onPostRender.priorityAdd(() =>
222
+ {
223
+ this.editor.isReady.apply(this.editor);
224
+ });
225
+
226
+ dialog.events.onShow.priorityAdd(() =>
227
+ {
228
+ this.editor.hideTooltips();
229
+ });
230
+
231
+ dialog.events.onShowComplete.priorityAdd(() =>
232
+ {
233
+ this.editor.hideTooltips();
234
+ this.editor.storeRange(this.editor.selectionRange.getRange().cloneRange());
235
+ this.editor.eventManager.disposeEvents();
236
+
237
+ if (settings.onShowComplete)
238
+ settings.onShowComplete();
239
+ });
240
+
241
+ dialog.events.onConfirm.priorityAdd(() =>
242
+ {
243
+ this.editor.cancelSelectionChange = false;
244
+ this.editor.activateDocument();
245
+ this.editor.selectionRange.restoreRange(this.editor.getStoredRange());
246
+ settings.onConfirm();
247
+ });
248
+
249
+ dialog.events.onHideComplete.priorityAdd(() =>
250
+ {
251
+ this.editor.cancelSelectionChange = false;
252
+ this.editor.activateDocument();
253
+ this.editor.eventManager.bindEvents();
254
+
255
+ if (settings.onHide)
256
+ settings.onHide();
257
+
258
+ this.editor.dialogManager.activeDialog = null;
259
+
260
+ requestAnimationFrame(() =>
261
+ {
262
+ this.editor.activateDocument();
263
+ const el = this.editor.getEditorElement();
264
+ this.editor.selectionRange.restoreRange(this.editor.getStoredRange());
265
+ el.focus();
266
+ });
267
+ });
268
+
269
+ return dialog;
270
+ }
271
+
272
+ /**
273
+ * Creates and configures a Button component.
274
+ * @param {string} id - The ID to assign to the new button
275
+ * @param {string} cloneId - The store ID of the button to clone from
276
+ * @param {HTMLElement} container - The container element to render into
277
+ * @param {Object} settings - Button configuration options
278
+ * @param {string} [settings.cssClass] - CSS class to apply to the button
279
+ * @param {string} [settings.cssClassIcon] - Icon CSS class appended to the base icon class
280
+ * @param {number} [settings.contentAlign] - Content alignment option (default: CENTER)
281
+ * @param {boolean} [settings.transparent=true] - Whether the button has a transparent background
282
+ * @param {boolean} [settings.transparentBorder=true] - Whether the button has a transparent border
283
+ * @param {number} [settings.type=0] - Button type option
284
+ * @param {string} [settings.menuItemId] - ID of the associated menu item
285
+ * @param {string} [settings.menuId] - ID of the associated menu; defaults to the editor menu if menuItemId is set
286
+ * @param {string} [settings.boxId] - ID of a box to associate with the button
287
+ * @param {string} [settings.radioGroupId] - Radio group ID; also sets button type to RADIOBUTTON
288
+ * @param {string} [settings.text] - Button label text
289
+ * @param {string} [settings.shortcutKey] - Keyboard shortcut key character
290
+ * @param {string} [settings.tooltip] - Tooltip text; falls back to name with shortcut if omitted
291
+ * @param {string} [settings.cssVariable] - CSS custom property name to update when a color is selected
292
+ * @param {Function} [settings.command] - Callback fired when the button is activated
293
+ * @param {Function} [settings.onSelect] - Callback fired on button select event
294
+ * @returns {componyx.UI.Button}
295
+ * @ignore
296
+ */
297
+ createButton(id, cloneId, container, settings = {})
298
+ {
299
+ let button = $UI.createComponent(componyx.UI.Button, { id: this.#getId(id), containerElement: container });
300
+
301
+ button.clone($UI.store[cloneId], this.editor);
302
+ button.cssClass = settings.cssClass;
303
+ button.cssClassIcon = 'icon ' + settings.cssClassIcon;
304
+ button.contentAlign = ($lib.isEmpty(settings.contentAlign)) ? componyx.UI.Button.AlignOption.CENTER : settings.contentAlign;
305
+ button.primary = false;
306
+ button.transparent = (settings.transparent === false) ? false : true;
307
+ button.transparentBorder = (settings.transparentBorder === false) ? false : true;
308
+ button.type = (settings.type) ? settings.type : 0;
309
+ button.hasIcon = (settings.cssClassIcon) ? true : false;
310
+ button.menuItemId = settings.menuItemId;
311
+ button.menuId = (settings.menuItemId && !settings.menuId) ? this.editor.id + '_Menu' : settings.menuId;
312
+ button.boxId = (settings.boxId) ? this.#getId(settings.boxId) : null;
313
+ button.radioGroupId = settings.radioGroupId || null;
314
+ button.text = settings.text || null;
315
+ button.tooltipManagerId = this.tooltipManager.id;
316
+ button.tooltipId = this.#addButtonTooltip(settings);
317
+ button.shortcutKey = settings.shortcutKey;
318
+ button.shortcutScope = () => this.editor.getEditorElement();
319
+
320
+ if (settings.radioGroupId)
321
+ button.type = componyx.UI.Button.TypeOption.RADIOBUTTON;
322
+
323
+ if (settings.command)
324
+ {
325
+ button.command = function (sender)
326
+ {
327
+ this.editor.paragraphButtons.destroy(this.editor.getEditorElement());
328
+ settings.command(settings, sender);
329
+ }.bind(this);
330
+ }
331
+
332
+ if (settings.onSelect)
333
+ button.events.onSelect.priorityAdd(settings.onSelect, null);
334
+
335
+ if (settings.boxId && settings.boxId == 'ColorSwatch')
336
+ button.expandCommand = () => { this.setActiveExpandButton(button); };
337
+
338
+ button.events.onPostRender.priorityAdd(() => { this.editor.isReady.apply(this.editor); }, null);
339
+ button.showing = true;
340
+
341
+ if (settings.cssVariable)
342
+ button.__cssVariable = settings.cssVariable;
343
+
344
+ return button;
345
+ }
346
+
347
+ /**
348
+ * Creates and configures a ComboBox component.
349
+ * @param {string} cloneId - The store ID of the combobox to clone from
350
+ * @param {HTMLElement} container - The container element to render into
351
+ * @param {Object} settings - ComboBox configuration options
352
+ * @param {string} settings.id - The ID to assign to the new combobox
353
+ * @param {string} [settings.cssClass] - CSS class to apply to the combobox
354
+ * @param {boolean} [settings.allowInput] - Whether free-text input is allowed
355
+ * @param {boolean} [settings.allowCustomValue] - Whether values outside the list are accepted
356
+ * @param {HTMLElement} [settings.noResultTemplate] - Template shown when no results match
357
+ * @param {Function} [settings.onItemSelect] - Callback fired when an item is selected
358
+ * @param {Function} [settings.onClear] - Callback fired when the value is cleared
359
+ * @returns {componyx.UI.ComboBox}
360
+ * @ignore
361
+ */
362
+ createComboBox(id, cloneId, container, settings = {})
363
+ {
364
+ let comboBox = $UI.createComponent(componyx.UI.ComboBox, { id: this.#getId(id), containerElement: container });
365
+
366
+ comboBox.clone($UI.store[cloneId], this.editor);
367
+ comboBox.cssClass = settings.cssClass;
368
+ comboBox.allowInput = settings.allowInput ?? false;
369
+ comboBox.allowCustomValue = settings.allowCustomValue ?? false;
370
+ comboBox.placeholder = (settings.allowInput) ? this.editor.labels.comboBoxPlaceholderEditable : this.editor.labels.comboBoxPlaceholderReadOnly;
371
+ comboBox.events.onPostRender.priorityAdd(() => { this.editor.isReady.apply(this.editor); });
372
+
373
+ if (settings.itemList)
374
+ comboBox.itemList = settings.itemList;
375
+
376
+ if (settings.noResultTemplate)
377
+ comboBox.setNoResultTemplate(settings.noResultTemplate);
378
+
379
+ if (settings.onItemSelect)
380
+ comboBox.events.onItemSelect.priorityAdd(() => { settings.onItemSelect(); });
381
+
382
+ if (settings.onClear)
383
+ comboBox.events.onClear.priorityAdd(() => { settings.onClear(); });
384
+
385
+ comboBox.show();
386
+
387
+ return comboBox;
388
+ }
389
+
390
+ /**
391
+ * Creates and configures a FormField component.
392
+ * @param {string} id - The ID to assign to the new form field
393
+ * @param {string} cloneId - The store ID of the form field to clone from
394
+ * @param {HTMLElement} container - The container element to render into
395
+ * @param {Object} settings - FormField configuration options
396
+ * @param {string} [settings.cssClass] - CSS class to apply to the form field
397
+ * @param {number} [settings.labelDisplay=3] - Label display mode
398
+ * @param {boolean} [settings.inline=false] - Whether the field renders inline
399
+ * @param {boolean} [settings.switch=false] - Whether the field renders as a toggle switch
400
+ * @param {HTMLElement} settings.label - Label template content
401
+ * @param {HTMLElement} settings.field - Field template content
402
+ * @returns {componyx.UI.FormField}
403
+ * @ignore
404
+ */
405
+ createFormField(id, cloneId, container, settings = {})
406
+ {
407
+ let fld = $UI.createComponent(componyx.UI.FormField, { id: this.#getId(id), containerElement: container });
408
+
409
+ fld.clone($UI.store[cloneId], this.editor);
410
+ fld.cssClass = settings.cssClass;
411
+ fld.labelDisplay = settings.labelDisplay || 3;
412
+ fld.inline = settings.inline || false;
413
+ fld.switch = settings.switch || false;
414
+ fld.setLabelTemplate(settings.label);
415
+ fld.setFieldTemplate(settings.field);
416
+ fld.show();
417
+
418
+ return fld;
419
+ }
420
+
421
+ createColorButton(id, cloneId, container, settings = {})
422
+ {
423
+ let colorButton = $UI.createComponent(componyx.UI.ColorButton, { id: this.#getId(id), containerElement: container });
424
+
425
+ if (settings.command) // we want to overwrite the command of the underlaying button
426
+ {
427
+ const button = $UI.createComponent(componyx.UI.Button, { id: id + '_Button', containerElement: this.editor.element, command: settings.command, primary: false, transparentBorder: false, transparent: true });
428
+ colorButton.buttonId = button.id;
429
+ }
430
+
431
+ colorButton.clone($UI.store[cloneId], this.editor);
432
+ colorButton.show();
433
+ return colorButton;
434
+ }
435
+
436
+ createColorSwatch()
437
+ {
438
+ let swatch = $lib.element('', '', '', '', { class: this.editor.getCssClass(this.editor.classOption.SWATCH) }),
439
+ footer = $lib.element('', '', 'footer'),
440
+ customColors = this.#getStoredColorSwatch(),
441
+ swatchCssClass = this.editor.getCssClass(this.editor.classOption.COLORSWATCH_BOX);
442
+
443
+ $lib.each(this.editor.colorSwatchColors.concat(customColors), (color, index) =>
444
+ {
445
+ $lib.element(swatch, '', 'a', '', { id: this.#getId(`swatch-color-${index}`), class: this.editor.getCssClass(this.editor.classOption.SWATCH_COLOR), style: `background:${color}` }, { onclick: this.#selectSwatchColor.bind(this, color) });
446
+ });
447
+
448
+ this.#colorSwatchBox = this.createBox('ColorSwatch', this.editor.colorSwatchBoxId, this.editor.element, { cssClass: swatchCssClass, content: [swatch, footer] });
449
+ this.#colorSwatchBox.render();
450
+ this.#swatch = swatch;
451
+
452
+ this.createButton('clearColor', this.editor.clearColorButtonId, footer, { command: () => this.#clearColor(), cssClass: this.editor.getCssClass(this.editor.classOption.CLEARCOLOR_BUTTON), cssClassIcon: 'ico-cross' });
453
+ this.createButton('toggleColorPicker', this.editor.colorPickerButtonId, footer, { command: () => this.#toggleColorPicker(), cssClass: this.editor.getCssClass(this.editor.classOption.COLORPICKER_BUTTON), cssClassIcon: this.utility.iconPrefix + 'palette' });
454
+ }
455
+
456
+ createColorPicker()
457
+ {
458
+ let id = this.#getId('ColorPicker'), box;
459
+
460
+ this.#colorPicker = $UI.createComponent(componyx.UI.ColorPicker, { id: id, containerElement: this.editor.element });
461
+ this.#colorPicker.clone($UI.store[this.editor.colorPickerId], this.editor);
462
+ this.#colorPicker.popupView = true;
463
+ this.#colorPicker.showing = true;
464
+
465
+ if (!this.#colorPicker.boxId)
466
+ {
467
+ box = $UI.createComponent(componyx.UI.Box, { id: id + '_ColorPickerBox', containerElement: this.editor.element });
468
+ this.#colorPicker.boxId = box.id;
469
+ }
470
+ else
471
+ box = $UI.store[this.#colorPicker.boxId];
472
+
473
+ box.events.onShowComplete.priorityAdd(() => { this.editor.eventManager.disposeEvents(); }, null);
474
+ box.events.onHideComplete.priorityAdd(() => { this.editor.eventManager.bindEvents(); }, null);
475
+
476
+ this.#colorPicker.events.onPostRender.priorityAdd(() => { this.editor.isReady.apply(this.editor); }, null);
477
+ }
478
+
479
+ /**
480
+ * Adds a tooltip to the tooltip manager.
481
+ * @param {Object} settings The command settings.
482
+ * @returns {string} The tooltip id.
483
+ * @ignore
484
+ */
485
+ #addButtonTooltip(settings)
486
+ {
487
+ let key = settings.shortcutKey,
488
+ id = settings.id,
489
+ name = settings.name,
490
+ text = settings.tooltip || name;
491
+
492
+ if (key && !settings.tooltip)
493
+ text += ` (Ctrl+${key.toUpperCase()})`;
494
+
495
+ if (text)
496
+ this.tooltipManager.addTooltip(id, text);
497
+
498
+ return id;
499
+ }
500
+
501
+ #selectSwatchColor(color)
502
+ {
503
+ this.#activeColorButton.__color = color;
504
+
505
+ if (this.#activeColorButton.__cssVariable)
506
+ this.editor.element.style.setProperty(this.#activeColorButton.__cssVariable, (color) ? color : 'none');
507
+
508
+ this.#colorSwatchBox.hide();
509
+ this.#activeColorButton.command();
510
+ }
511
+
512
+ #getStoredColorSwatch()
513
+ {
514
+ return window.JSON.parse(window.localStorage.getItem(this.editor.localStoragePrefix + 'CustomSwatch') || '[]');
515
+ }
516
+
517
+ #updateColorSwatch(color)
518
+ {
519
+ let isNew = true;
520
+
521
+ $lib.each(this.#swatch.childNodes, (n) =>
522
+ {
523
+ return isNew = (n.style.cssText.indexOf(color) == -1);
524
+ });
525
+
526
+ if (isNew)
527
+ $lib.element(this.#swatch, '', '', '', { id: this.#getId(`swatch-color-${this.#swatch.childNodes.length}`), class: this.editor.getCssClass(this.editor.classOption.SWATCH_COLOR), style: `background: ${color}` });
528
+
529
+ return isNew;
530
+ }
531
+
532
+ #clearColor()
533
+ {
534
+ this.#selectSwatchColor(null);
535
+ }
536
+
537
+ #toggleColorPicker()
538
+ {
539
+ this.#colorPicker.expand(null, null, (colorPicker, args) =>
540
+ {
541
+ let color = this.editor.utility.toCSSColor(args.rgba),
542
+ isNew = this.#updateColorSwatch(color);
543
+
544
+ if (isNew)
545
+ {
546
+ let swatch = this.#getStoredColorSwatch();
547
+ swatch.push(color);
548
+ window.localStorage.setItem(this.editor.localStoragePrefix + 'CustomSwatch', window.JSON.stringify(swatch));
549
+ }
550
+
551
+ this.editor.eventManager.bindEvents();
552
+ this.#selectSwatchColor(color);
553
+
554
+ }, null, true, true);
555
+ }
556
+
557
+ #getId(id)
558
+ {
559
+ return this.utility.getId(id);
560
+ }
561
+ };
562
+
563
+ var ComponentFactory = componyx.UI.editor_modules.ComponentFactory;
564
+
565
+ export { ComponentFactory as default };