@acorex/platform 0.0.0-ACOREX

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 (116) hide show
  1. package/README.md +7 -0
  2. package/auth/README.md +3 -0
  3. package/common/README.md +3 -0
  4. package/core/README.md +4 -0
  5. package/fesm2022/acorex-platform-auth.mjs +1362 -0
  6. package/fesm2022/acorex-platform-auth.mjs.map +1 -0
  7. package/fesm2022/acorex-platform-common-common-settings.provider-G9XcXXOG.mjs +127 -0
  8. package/fesm2022/acorex-platform-common-common-settings.provider-G9XcXXOG.mjs.map +1 -0
  9. package/fesm2022/acorex-platform-common.mjs +4601 -0
  10. package/fesm2022/acorex-platform-common.mjs.map +1 -0
  11. package/fesm2022/acorex-platform-core.mjs +4374 -0
  12. package/fesm2022/acorex-platform-core.mjs.map +1 -0
  13. package/fesm2022/acorex-platform-domain.mjs +3234 -0
  14. package/fesm2022/acorex-platform-domain.mjs.map +1 -0
  15. package/fesm2022/acorex-platform-layout-builder.mjs +2847 -0
  16. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -0
  17. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs +121 -0
  18. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs.map +1 -0
  19. package/fesm2022/acorex-platform-layout-components.mjs +8583 -0
  20. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -0
  21. package/fesm2022/acorex-platform-layout-designer.mjs +2474 -0
  22. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -0
  23. package/fesm2022/acorex-platform-layout-entity.mjs +19150 -0
  24. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -0
  25. package/fesm2022/acorex-platform-layout-views.mjs +1468 -0
  26. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -0
  27. package/fesm2022/acorex-platform-layout-widget-core.mjs +2950 -0
  28. package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -0
  29. package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-Dy7jF-oD.mjs +72 -0
  30. package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-Dy7jF-oD.mjs.map +1 -0
  31. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-9uCkMxcc.mjs +158 -0
  32. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-9uCkMxcc.mjs.map +1 -0
  33. package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs +29 -0
  34. package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs.map +1 -0
  35. package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs +172 -0
  36. package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs.map +1 -0
  37. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BGQqY5Mw.mjs +111 -0
  38. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BGQqY5Mw.mjs.map +1 -0
  39. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-DmzNTYiS.mjs +274 -0
  40. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-DmzNTYiS.mjs.map +1 -0
  41. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-BNG_588B.mjs +64 -0
  42. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-BNG_588B.mjs.map +1 -0
  43. package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-Vo4fWHtX.mjs +34 -0
  44. package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-Vo4fWHtX.mjs.map +1 -0
  45. package/fesm2022/acorex-platform-layout-widgets.mjs +29791 -0
  46. package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -0
  47. package/fesm2022/acorex-platform-native.mjs +155 -0
  48. package/fesm2022/acorex-platform-native.mjs.map +1 -0
  49. package/fesm2022/acorex-platform-runtime-catalog-command-definition.mjs +20 -0
  50. package/fesm2022/acorex-platform-runtime-catalog-command-definition.mjs.map +1 -0
  51. package/fesm2022/acorex-platform-runtime-catalog-query-definition.mjs +20 -0
  52. package/fesm2022/acorex-platform-runtime-catalog-query-definition.mjs.map +1 -0
  53. package/fesm2022/acorex-platform-runtime.mjs +899 -0
  54. package/fesm2022/acorex-platform-runtime.mjs.map +1 -0
  55. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Cvvr4HnL.mjs +160 -0
  56. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Cvvr4HnL.mjs.map +1 -0
  57. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-TYoLN1Jq.mjs +120 -0
  58. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-TYoLN1Jq.mjs.map +1 -0
  59. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-C2z5Lq9y.mjs +237 -0
  60. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-C2z5Lq9y.mjs.map +1 -0
  61. package/fesm2022/acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs +31 -0
  62. package/fesm2022/acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs.map +1 -0
  63. package/fesm2022/acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs +25 -0
  64. package/fesm2022/acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs.map +1 -0
  65. package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs +19 -0
  66. package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs.map +1 -0
  67. package/fesm2022/acorex-platform-themes-default.mjs +2589 -0
  68. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -0
  69. package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs +55 -0
  70. package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs.map +1 -0
  71. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs +57 -0
  72. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs.map +1 -0
  73. package/fesm2022/acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs +168 -0
  74. package/fesm2022/acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs.map +1 -0
  75. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-CHfrTtol.mjs +65 -0
  76. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-CHfrTtol.mjs.map +1 -0
  77. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-BSmvnUVq.mjs +64 -0
  78. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-BSmvnUVq.mjs.map +1 -0
  79. package/fesm2022/acorex-platform-themes-shared.mjs +2125 -0
  80. package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -0
  81. package/fesm2022/acorex-platform-workflow.mjs +2501 -0
  82. package/fesm2022/acorex-platform-workflow.mjs.map +1 -0
  83. package/fesm2022/acorex-platform.mjs +6 -0
  84. package/fesm2022/acorex-platform.mjs.map +1 -0
  85. package/layout/builder/README.md +1578 -0
  86. package/layout/components/README.md +3 -0
  87. package/layout/designer/README.md +4 -0
  88. package/layout/entity/README.md +4 -0
  89. package/layout/views/README.md +3 -0
  90. package/layout/widget-core/README.md +4 -0
  91. package/layout/widgets/README.md +3 -0
  92. package/native/README.md +4 -0
  93. package/package.json +103 -0
  94. package/runtime/README.md +3 -0
  95. package/themes/default/README.md +3 -0
  96. package/themes/shared/README.md +3 -0
  97. package/types/acorex-platform-auth.d.ts +680 -0
  98. package/types/acorex-platform-common.d.ts +2926 -0
  99. package/types/acorex-platform-core.d.ts +2896 -0
  100. package/types/acorex-platform-domain.d.ts +2353 -0
  101. package/types/acorex-platform-layout-builder.d.ts +926 -0
  102. package/types/acorex-platform-layout-components.d.ts +2903 -0
  103. package/types/acorex-platform-layout-designer.d.ts +422 -0
  104. package/types/acorex-platform-layout-entity.d.ts +3189 -0
  105. package/types/acorex-platform-layout-views.d.ts +667 -0
  106. package/types/acorex-platform-layout-widget-core.d.ts +1086 -0
  107. package/types/acorex-platform-layout-widgets.d.ts +5478 -0
  108. package/types/acorex-platform-native.d.ts +28 -0
  109. package/types/acorex-platform-runtime-catalog-command-definition.d.ts +137 -0
  110. package/types/acorex-platform-runtime-catalog-query-definition.d.ts +125 -0
  111. package/types/acorex-platform-runtime.d.ts +470 -0
  112. package/types/acorex-platform-themes-default.d.ts +573 -0
  113. package/types/acorex-platform-themes-shared.d.ts +170 -0
  114. package/types/acorex-platform-workflow.d.ts +1806 -0
  115. package/types/acorex-platform.d.ts +2 -0
  116. package/workflow/README.md +4 -0
@@ -0,0 +1,2125 @@
1
+ import * as i2 from '@acorex/components/button';
2
+ import { AXButtonModule } from '@acorex/components/button';
3
+ import * as i3 from '@acorex/components/decorators';
4
+ import { AXDecoratorModule } from '@acorex/components/decorators';
5
+ import * as i4 from '@acorex/components/dropdown';
6
+ import { AXDropdownModule } from '@acorex/components/dropdown';
7
+ import * as i1 from '@angular/common';
8
+ import { CommonModule } from '@angular/common';
9
+ import * as i0 from '@angular/core';
10
+ import { computed, inject, ChangeDetectionStrategy, Component, InjectionToken, Injectable, Input, signal, effect, Injector, NgModule } from '@angular/core';
11
+ import { AXPSettingsService, AXP_SETTING_DEFINITION_PROVIDER } from '@acorex/platform/common';
12
+ import * as i1$3 from '@acorex/platform/core';
13
+ import { AXPScreenSize, AXPPlatformScope, AXPComponentSlotModule } from '@acorex/platform/core';
14
+ import { HttpClient } from '@angular/common/http';
15
+ import { signalStore, withState, withComputed, withMethods, patchState, withHooks } from '@ngrx/signals';
16
+ import { timer, firstValueFrom, filter } from 'rxjs';
17
+ import * as i5 from '@acorex/core/translation';
18
+ import { AXTranslationModule } from '@acorex/core/translation';
19
+ import { AXPValueWidgetComponent, AXP_WIDGETS_LAYOUT_CATEGORY, AXPWidgetCoreModule, AXP_WIDGET_DEFINITION_PROVIDER } from '@acorex/platform/layout/widget-core';
20
+ import { AXPopupService } from '@acorex/components/popup';
21
+ import * as i2$1 from '@acorex/components/button-group';
22
+ import { AXButtonGroupModule } from '@acorex/components/button-group';
23
+ import { AXBasePageComponent } from '@acorex/components/page';
24
+ import * as i1$1 from '@acorex/components/search-box';
25
+ import { AXSearchBoxModule } from '@acorex/components/search-box';
26
+ import { AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_DISABLED_PROPERTY } from '@acorex/platform/layout/widgets';
27
+ import { AXSelectionCdkModule } from '@acorex/cdk/selection';
28
+ import * as i5$1 from '@angular/forms';
29
+ import { FormsModule } from '@angular/forms';
30
+ import * as i2$2 from '@acorex/components/form';
31
+ import { AXFormModule } from '@acorex/components/form';
32
+ import * as i1$2 from '@acorex/components/select-box';
33
+ import { AXSelectBoxModule } from '@acorex/components/select-box';
34
+
35
+ var AXPThemeLayoutSetting;
36
+ (function (AXPThemeLayoutSetting) {
37
+ AXPThemeLayoutSetting["Name"] = "Common:Setting:Layout.Name";
38
+ AXPThemeLayoutSetting["Layout"] = "Common:Setting:Layout.Layout";
39
+ AXPThemeLayoutSetting["Font"] = "Common:Setting:Layout.Font.Family";
40
+ AXPThemeLayoutSetting["FontSize"] = "Common:Setting:Layout.Font.Size";
41
+ AXPThemeLayoutSetting["Palette"] = "Common:Setting:Layout.Palette";
42
+ AXPThemeLayoutSetting["Mode"] = "Common:Setting:Layout.Mode";
43
+ AXPThemeLayoutSetting["SideMenuStatus"] = "Common:Setting:Layout.SideMenu.Status";
44
+ AXPThemeLayoutSetting["SideMenuWidth"] = "Common:Setting:Layout.SideMenu.Width";
45
+ AXPThemeLayoutSetting["MenuOrientation"] = "Common:Setting:Layout.RootMenu.Direction";
46
+ AXPThemeLayoutSetting["MenuBadgeVisible"] = "Common:Setting:Layout.RootMenu.Badge";
47
+ })(AXPThemeLayoutSetting || (AXPThemeLayoutSetting = {}));
48
+
49
+ // Theme Enum
50
+ var AXPThemeMode;
51
+ (function (AXPThemeMode) {
52
+ AXPThemeMode["Light"] = "light";
53
+ AXPThemeMode["Dark"] = "dark";
54
+ AXPThemeMode["System"] = "system";
55
+ })(AXPThemeMode || (AXPThemeMode = {}));
56
+ // Side Menu State Enum
57
+ var AXPSideMenuState;
58
+ (function (AXPSideMenuState) {
59
+ AXPSideMenuState["Opened"] = "opened";
60
+ AXPSideMenuState["Closed"] = "closed";
61
+ })(AXPSideMenuState || (AXPSideMenuState = {}));
62
+ // Menu Orientation Enum
63
+ var AXPMenuOrientation;
64
+ (function (AXPMenuOrientation) {
65
+ AXPMenuOrientation["Vertical"] = "vertical";
66
+ AXPMenuOrientation["Horizontal"] = "horizontal";
67
+ })(AXPMenuOrientation || (AXPMenuOrientation = {}));
68
+
69
+ // ThemeStore - Manages theme settings, system changes, and loading states
70
+ const AXPLayoutThemeService = signalStore({ providedIn: 'root' },
71
+ // Initial State
72
+ withState(() => {
73
+ const isSystemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
74
+ // Helper function to get the initial screen size for side menu initialization
75
+ const getInitialScreenSize = () => {
76
+ const width = window.innerWidth;
77
+ if (width <= 600)
78
+ return AXPScreenSize.Small;
79
+ if (width <= 1024)
80
+ return AXPScreenSize.Medium;
81
+ return AXPScreenSize.Large;
82
+ };
83
+ const state = {
84
+ currentMode: AXPThemeMode.System,
85
+ currentPalette: 'default',
86
+ systemThemeMode: (isSystemDark ? AXPThemeMode.Dark : AXPThemeMode.Light),
87
+ font: {
88
+ family: 'system-ui',
89
+ size: 'medium',
90
+ },
91
+ overlayLoading: false,
92
+ navigationLoading: false,
93
+ overlayLoadingTaskCount: 0,
94
+ navigationLoadingTaskCount: 0,
95
+ sideMenuState: (getInitialScreenSize() === AXPScreenSize.Large
96
+ ? AXPSideMenuState.Opened
97
+ : AXPSideMenuState.Closed),
98
+ sideMenuWidth: 288,
99
+ menuOrientation: 'vertical',
100
+ _listener: null,
101
+ isPrinting: false,
102
+ };
103
+ return state;
104
+ }),
105
+ // Computed Signals
106
+ withComputed(({ currentMode: currentTheme, systemThemeMode: systemTheme, sideMenuState, overlayLoading, navigationLoading, menuOrientation, isPrinting, }) => ({
107
+ isDarkMode: computed(() => {
108
+ if (isPrinting()) {
109
+ return false;
110
+ }
111
+ return (currentTheme() === AXPThemeMode.Dark ||
112
+ (currentTheme() === AXPThemeMode.System && systemTheme() === AXPThemeMode.Dark));
113
+ }),
114
+ isLightMode: computed(() => currentTheme() === AXPThemeMode.Light ||
115
+ (currentTheme() === AXPThemeMode.System && systemTheme() === AXPThemeMode.Light)),
116
+ isSystemMode: computed(() => currentTheme() === AXPThemeMode.System),
117
+ isSideMenuOpen: computed(() => sideMenuState() === AXPSideMenuState.Opened),
118
+ isOverlayLoading: computed(() => overlayLoading()),
119
+ isNavigationLoading: computed(() => navigationLoading()),
120
+ isMenuHorizontal: computed(() => menuOrientation() === AXPMenuOrientation.Horizontal),
121
+ })),
122
+ // Methods for State Management
123
+ withMethods((store, http = inject(HttpClient), settingsService = inject(AXPSettingsService)) => {
124
+ const _applySettings = async () => {
125
+ // Initialize theme and side menu setting from storage
126
+ const settingThemeMode = (await settingsService.get(AXPThemeLayoutSetting.Mode)) ?? AXPThemeMode.Light;
127
+ patchState(store, { currentMode: settingThemeMode });
128
+ //
129
+ const settingThemePallete = (await settingsService.get(AXPThemeLayoutSetting.Palette)) ?? 'default';
130
+ patchState(store, { currentPalette: settingThemePallete });
131
+ //
132
+ const settingSideMenu = (await settingsService.get(AXPThemeLayoutSetting.SideMenuStatus)) ?? store.sideMenuState();
133
+ patchState(store, { sideMenuState: settingSideMenu });
134
+ //
135
+ const settingMenuOrientation = (await settingsService.get(AXPThemeLayoutSetting.MenuOrientation)) ??
136
+ store.menuOrientation();
137
+ patchState(store, { menuOrientation: settingMenuOrientation });
138
+ //
139
+ const fontFamily = await settingsService.get(AXPThemeLayoutSetting.Font);
140
+ const fontSize = await settingsService.get(AXPThemeLayoutSetting.FontSize);
141
+ patchState(store, { font: { family: fontFamily, size: fontSize } });
142
+ //
143
+ const sideMenuWidth = await settingsService.get(AXPThemeLayoutSetting.SideMenuWidth);
144
+ patchState(store, { sideMenuWidth });
145
+ await _updateHtmlClass();
146
+ };
147
+ // Update HTML class based on theme
148
+ const _updateHtmlClass = async () => {
149
+ const html = document.getElementsByTagName('html')[0];
150
+ //
151
+ store.isDarkMode() ? html.classList.add('ax-dark') : html.classList.remove('ax-dark');
152
+ //
153
+ html.style.fontFamily = store.font().family;
154
+ html.style.fontSize = store.font().size;
155
+ //
156
+ await _applyThemePalette(store.currentPalette());
157
+ };
158
+ const _setOverlayLoading = async (value, delay = 0) => {
159
+ if (value) {
160
+ let timeoutId = null;
161
+ if (delay > 0) {
162
+ timeoutId = window.setTimeout(() => {
163
+ patchState(store, { overlayLoadingTaskCount: store.overlayLoadingTaskCount() + 1 });
164
+ patchState(store, { overlayLoading: true });
165
+ }, delay);
166
+ }
167
+ else {
168
+ patchState(store, { overlayLoadingTaskCount: store.overlayLoadingTaskCount() + 1 });
169
+ patchState(store, { overlayLoading: true });
170
+ }
171
+ // Store timeout ID to clear it if the loading ends before delay
172
+ store._loadingTimeoutId = timeoutId;
173
+ }
174
+ else {
175
+ if (store.overlayLoadingTaskCount() > 0) {
176
+ patchState(store, { overlayLoadingTaskCount: store.overlayLoadingTaskCount() - 1 });
177
+ }
178
+ if (store.overlayLoadingTaskCount() === 0) {
179
+ const timeoutId = store._loadingTimeoutId;
180
+ if (timeoutId) {
181
+ clearTimeout(timeoutId);
182
+ store._loadingTimeoutId = null;
183
+ }
184
+ timer(minimumDisplayTime).subscribe(() => {
185
+ if (store.overlayLoadingTaskCount() === 0) {
186
+ patchState(store, { overlayLoading: false });
187
+ }
188
+ });
189
+ }
190
+ }
191
+ };
192
+ const _setNavigationLoading = (value, delay) => {
193
+ if (value) {
194
+ patchState(store, { navigationLoadingTaskCount: store.navigationLoadingTaskCount() + 1 });
195
+ patchState(store, { navigationLoading: true });
196
+ }
197
+ else {
198
+ if (store.navigationLoadingTaskCount() > 0) {
199
+ patchState(store, { navigationLoadingTaskCount: store.navigationLoadingTaskCount() - 1 });
200
+ }
201
+ if (store.navigationLoadingTaskCount() === 0) {
202
+ timer(minimumDisplayTime).subscribe(() => {
203
+ if (store.navigationLoadingTaskCount() === 0) {
204
+ patchState(store, { navigationLoading: false });
205
+ }
206
+ });
207
+ }
208
+ }
209
+ };
210
+ // Helper method to apply a cached theme palette
211
+ const _applyThemePalette = async (name) => {
212
+ // TODO: Get the path from the palette provider token
213
+ const path = `/assets/themes/palettes/css/${name}.css`;
214
+ // Check if the current theme is already applied
215
+ const existingStyle = document.querySelector(`style[data-theme="${name}"]`);
216
+ if (existingStyle) {
217
+ return; // Theme is already applied, no need to reapply
218
+ }
219
+ _setNavigationLoading(true);
220
+ try {
221
+ // Fetch the CSS file via HttpClient
222
+ const cssText = await firstValueFrom(http.get(path, { responseType: 'text' }));
223
+ // Create a new <style> tag and apply the CSS
224
+ const style = document.createElement('style');
225
+ style.setAttribute('data-theme', name);
226
+ style.textContent = cssText;
227
+ document.head.appendChild(style);
228
+ // Remove any other outdated theme styles
229
+ document.querySelectorAll('style[data-theme]').forEach((existing) => {
230
+ if (existing !== style) {
231
+ existing.remove();
232
+ }
233
+ });
234
+ }
235
+ catch (error) {
236
+ console.error(`Error loading theme CSS:`, error);
237
+ }
238
+ finally {
239
+ _setNavigationLoading(false);
240
+ }
241
+ };
242
+ const minimumDisplayTime = 500; // milliseconds
243
+ return {
244
+ // Change theme and update HTML class
245
+ changeThemeMode(theme) {
246
+ settingsService.scope(AXPPlatformScope.User).set(AXPThemeLayoutSetting.Mode, theme);
247
+ patchState(store, { currentMode: theme });
248
+ _updateHtmlClass();
249
+ },
250
+ // Open side menu
251
+ openSideMenu() {
252
+ patchState(store, { sideMenuState: AXPSideMenuState.Opened });
253
+ settingsService.scope(AXPPlatformScope.User).set(AXPThemeLayoutSetting.SideMenuStatus, AXPSideMenuState.Opened);
254
+ },
255
+ // Close side menu
256
+ closeSideMenu() {
257
+ patchState(store, { sideMenuState: AXPSideMenuState.Closed });
258
+ settingsService.scope(AXPPlatformScope.User).set(AXPThemeLayoutSetting.SideMenuStatus, AXPSideMenuState.Closed);
259
+ },
260
+ // Set side menu width
261
+ setSideMenuWidth(width) {
262
+ patchState(store, { sideMenuWidth: width });
263
+ settingsService.scope(AXPPlatformScope.User).set(AXPThemeLayoutSetting.SideMenuWidth, width);
264
+ },
265
+ // Toggle side menu state
266
+ toggleSideMenu() {
267
+ const newSideMenuState = store.sideMenuState() === AXPSideMenuState.Opened ? AXPSideMenuState.Closed : AXPSideMenuState.Opened;
268
+ patchState(store, { sideMenuState: newSideMenuState });
269
+ settingsService.scope(AXPPlatformScope.User).set(AXPThemeLayoutSetting.SideMenuStatus, newSideMenuState);
270
+ },
271
+ // Set navigation loading state with a task counter
272
+ setNavigationLoading(value, delay) {
273
+ _setNavigationLoading(value, delay);
274
+ },
275
+ // Set overlay loading state with a task counter
276
+ setOverlayLoading(value, delay) {
277
+ _setOverlayLoading(value, delay);
278
+ },
279
+ async loadSettings() {
280
+ await _applySettings();
281
+ },
282
+ // This is for internal use to react to print mode changes
283
+ _internal_updateHtmlClass: _updateHtmlClass,
284
+ // Set up event listener for system theme changes
285
+ _setupSystemColorListener() {
286
+ const mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');
287
+ const listener = (e) => {
288
+ patchState(store, { systemThemeMode: e.matches ? AXPThemeMode.Dark : AXPThemeMode.Light });
289
+ _updateHtmlClass();
290
+ };
291
+ mediaQueryList.addEventListener('change', listener);
292
+ return listener;
293
+ },
294
+ // Remove event listener for system theme changes
295
+ _removeSystemColorListener(listener) {
296
+ const mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');
297
+ mediaQueryList.removeEventListener('change', listener);
298
+ },
299
+ };
300
+ }),
301
+ // Lifecycle Hooks
302
+ withHooks((store, settingsService = inject(AXPSettingsService)) => ({
303
+ onInit() {
304
+ //
305
+ settingsService.onChanged.pipe(filter((c) => c.scope == AXPPlatformScope.User)).subscribe(async (changes) => {
306
+ const keys = Object.values(AXPThemeLayoutSetting);
307
+ if (changes.keys.some((key) => keys.includes(key))) {
308
+ await store['loadSettings']();
309
+ }
310
+ });
311
+ //
312
+ settingsService.onLoaded.subscribe(async () => {
313
+ await store['loadSettings']();
314
+ });
315
+ // Set up event listener for system theme changes
316
+ const listener = store['_setupSystemColorListener']();
317
+ patchState(store, { _listener: listener });
318
+ window.addEventListener('beforeprint', () => {
319
+ patchState(store, { isPrinting: true });
320
+ store._internal_updateHtmlClass();
321
+ });
322
+ window.addEventListener('afterprint', () => {
323
+ patchState(store, { isPrinting: false });
324
+ store._internal_updateHtmlClass();
325
+ });
326
+ },
327
+ onDestroy() {
328
+ // Clean up event listeners when store is destroyed
329
+ const { _listener: listener } = store;
330
+ if (listener) {
331
+ store['_removeSystemColorListener'](listener);
332
+ }
333
+ },
334
+ })));
335
+
336
+ class AXPThemeSlotComponent {
337
+ constructor() {
338
+ this.store = inject(AXPLayoutThemeService);
339
+ this.variants = AXPThemeMode;
340
+ }
341
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPThemeSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
342
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: AXPThemeSlotComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: `
343
+ <ax-button color="primary">
344
+ <ax-icon
345
+ class="fa-regular "
346
+ [ngClass]="{
347
+ 'fa-desktop':store.isSystemMode(),
348
+ 'fa-moon':!store.isSystemMode() && store.isDarkMode(),
349
+ 'fa-brightness':!store.isSystemMode() && !store.isDarkMode(),
350
+ }"
351
+ >
352
+ </ax-icon>
353
+ <ax-dropdown-panel *translate="let t">
354
+ <ax-button-item-list>
355
+ <ax-button-item
356
+ (onClick)="store.changeThemeMode(variants.Light)"
357
+ [text]="('@layout:terms.theme-modes.light' | translate | async)!"
358
+ [selected]="!store.isSystemMode() && !store.isDarkMode()"
359
+ >
360
+ <ax-prefix>
361
+ <ax-icon icon="fa-light fa-brightness"> </ax-icon>
362
+ </ax-prefix>
363
+ </ax-button-item>
364
+ <ax-button-item
365
+ (onClick)="store.changeThemeMode(variants.Dark)"
366
+ [text]="('@layout:terms.theme-modes.dark' | translate | async)!"
367
+ [selected]="!store.isSystemMode() && store.isDarkMode()"
368
+ >
369
+ <ax-prefix>
370
+ <ax-icon icon="fa-light fa-moon"> </ax-icon>
371
+ </ax-prefix>
372
+ </ax-button-item>
373
+ <ax-button-item
374
+ (onClick)="store.changeThemeMode(variants.System)"
375
+ [text]="('@layout:terms.theme-modes.system' | translate | async)!"
376
+ [selected]="store.isSystemMode()"
377
+ >
378
+ <ax-prefix>
379
+ <ax-icon icon="fa-light fa-desktop"> </ax-icon>
380
+ </ax-prefix>
381
+ </ax-button-item>
382
+ </ax-button-item-list>
383
+ </ax-dropdown-panel>
384
+ </ax-button>
385
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i4.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i5.AXTranslatorDirective, selector: "[translate]" }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
386
+ }
387
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPThemeSlotComponent, decorators: [{
388
+ type: Component,
389
+ args: [{
390
+ template: `
391
+ <ax-button color="primary">
392
+ <ax-icon
393
+ class="fa-regular "
394
+ [ngClass]="{
395
+ 'fa-desktop':store.isSystemMode(),
396
+ 'fa-moon':!store.isSystemMode() && store.isDarkMode(),
397
+ 'fa-brightness':!store.isSystemMode() && !store.isDarkMode(),
398
+ }"
399
+ >
400
+ </ax-icon>
401
+ <ax-dropdown-panel *translate="let t">
402
+ <ax-button-item-list>
403
+ <ax-button-item
404
+ (onClick)="store.changeThemeMode(variants.Light)"
405
+ [text]="('@layout:terms.theme-modes.light' | translate | async)!"
406
+ [selected]="!store.isSystemMode() && !store.isDarkMode()"
407
+ >
408
+ <ax-prefix>
409
+ <ax-icon icon="fa-light fa-brightness"> </ax-icon>
410
+ </ax-prefix>
411
+ </ax-button-item>
412
+ <ax-button-item
413
+ (onClick)="store.changeThemeMode(variants.Dark)"
414
+ [text]="('@layout:terms.theme-modes.dark' | translate | async)!"
415
+ [selected]="!store.isSystemMode() && store.isDarkMode()"
416
+ >
417
+ <ax-prefix>
418
+ <ax-icon icon="fa-light fa-moon"> </ax-icon>
419
+ </ax-prefix>
420
+ </ax-button-item>
421
+ <ax-button-item
422
+ (onClick)="store.changeThemeMode(variants.System)"
423
+ [text]="('@layout:terms.theme-modes.system' | translate | async)!"
424
+ [selected]="store.isSystemMode()"
425
+ >
426
+ <ax-prefix>
427
+ <ax-icon icon="fa-light fa-desktop"> </ax-icon>
428
+ </ax-prefix>
429
+ </ax-button-item>
430
+ </ax-button-item-list>
431
+ </ax-dropdown-panel>
432
+ </ax-button>
433
+ `,
434
+ imports: [CommonModule, AXButtonModule, AXDecoratorModule, AXDropdownModule, AXTranslationModule],
435
+ changeDetection: ChangeDetectionStrategy.OnPush,
436
+ }]
437
+ }] });
438
+
439
+ const AXP_THEME_PALETTE_PROVIDER = new InjectionToken('AXP_THEME_PALETTE_PROVIDER', {
440
+ providedIn: 'root',
441
+ factory: async () => {
442
+ return new AXPThemePaletteProviderDefault();
443
+ },
444
+ });
445
+ class AXPThemePaletteProviderDefault {
446
+ getList() {
447
+ return Promise.resolve([
448
+ {
449
+ name: 'default',
450
+ title: 'Default',
451
+ path: '/assets/themes/palletes/default.css',
452
+ colors: {
453
+ primary: '#113b53',
454
+ secondary: '#1a6ab1',
455
+ neutral: '#606c76',
456
+ success: '#2d9c67',
457
+ warning: '#e9a01b',
458
+ danger: '#c02f1d',
459
+ accents: ['#d6a7a6', '#a0897e', '#8bf4d9'],
460
+ dark: '#2a2d30',
461
+ light: '#ffffff',
462
+ },
463
+ },
464
+ ]);
465
+ }
466
+ }
467
+
468
+ //#region ---- Injection Tokens ----
469
+ /**
470
+ * Injection token for icon providers.
471
+ * Use multi: true to register multiple providers.
472
+ */
473
+ const AXP_ICON_PROVIDER = new InjectionToken('AXP_ICON_PROVIDER');
474
+ /**
475
+ * Injection token for icon style providers.
476
+ * Use multi: true to register multiple providers.
477
+ */
478
+ const AXP_ICON_STYLE_PROVIDER = new InjectionToken('AXP_ICON_STYLE_PROVIDER');
479
+ //#endregion
480
+
481
+ //#endregion
482
+ //#region ---- Abstract Providers ----
483
+ class AXPIconProvider {
484
+ }
485
+ class AXPIconStyleProvider {
486
+ }
487
+ //#endregion
488
+ //#region ---- Service ----
489
+ class AXPIconChooserService {
490
+ constructor() {
491
+ //#region ---- Properties ----
492
+ this.iconProviders = inject(AXP_ICON_PROVIDER, { optional: true }) ?? [];
493
+ this.styleProviders = inject(AXP_ICON_STYLE_PROVIDER, { optional: true }) ?? [];
494
+ this.iconsCache = null;
495
+ this.stylesCache = null;
496
+ }
497
+ //#endregion
498
+ //#region ---- Public Methods ----
499
+ /**
500
+ * Get all available icon styles from registered providers.
501
+ * Results are cached after first call.
502
+ */
503
+ async getStyles() {
504
+ if (this.stylesCache) {
505
+ return this.stylesCache;
506
+ }
507
+ const allStyles = [];
508
+ for (const provider of this.styleProviders) {
509
+ const result = await provider.provide();
510
+ allStyles.push(...result);
511
+ }
512
+ // Remove duplicates based on style name
513
+ const uniqueStyles = allStyles.filter((style, index, self) => index === self.findIndex((s) => s.name === style.name));
514
+ this.stylesCache = uniqueStyles;
515
+ return uniqueStyles;
516
+ }
517
+ /**
518
+ * Get all available icons from registered providers.
519
+ * Icons from multiple providers are merged, with duplicates removed.
520
+ * Results are cached after first call.
521
+ */
522
+ async getIcons() {
523
+ if (this.iconsCache) {
524
+ return this.iconsCache;
525
+ }
526
+ const allIcons = [];
527
+ for (const provider of this.iconProviders) {
528
+ const result = await provider.provide();
529
+ allIcons.push(...result);
530
+ }
531
+ // Remove duplicates based on icon name, keeping first occurrence
532
+ const uniqueIcons = allIcons.filter((icon, index, self) => index === self.findIndex((i) => i.name === icon.name));
533
+ this.iconsCache = uniqueIcons;
534
+ return uniqueIcons;
535
+ }
536
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPIconChooserService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
537
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPIconChooserService, providedIn: 'root' }); }
538
+ }
539
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPIconChooserService, decorators: [{
540
+ type: Injectable,
541
+ args: [{ providedIn: 'root' }]
542
+ }] });
543
+
544
+ class AXPIconChooserPopupComponent extends AXBasePageComponent {
545
+ constructor() {
546
+ super(...arguments);
547
+ this.icons = [];
548
+ this.filteredIcons = [];
549
+ this.searchQuery = '';
550
+ this.viewModes = [
551
+ { value: 'square', text: '@general:widgets.icon-chooser.view-mode.square', icon: 'fa-solid fa-border-all' },
552
+ {
553
+ value: 'rectangle',
554
+ text: '@general:widgets.icon-chooser.view-mode.rectangle',
555
+ icon: 'fa-solid fa-list',
556
+ },
557
+ ];
558
+ this.selectedViewMode = 'square';
559
+ this.iconTypes = [];
560
+ this.selectedIconType = 'fa-solid';
561
+ this.popupService = inject(AXPIconChooserService);
562
+ }
563
+ async ngOnInit() {
564
+ this.iconTypes = await this.popupService.getStyles();
565
+ this.icons = await this.popupService.getIcons();
566
+ this.applyFilters();
567
+ this.cdr.detectChanges();
568
+ }
569
+ handleSearch(event) {
570
+ this.searchQuery = event.value?.toLowerCase();
571
+ this.applyFilters();
572
+ }
573
+ handleViewModeChange(mode) {
574
+ this.selectedViewMode = mode.value;
575
+ }
576
+ handleIconTypeChange(type) {
577
+ this.selectedIconType = type.name;
578
+ this.applyFilters();
579
+ }
580
+ applyFilters() {
581
+ let result = this.icons;
582
+ if (this.searchQuery) {
583
+ result = result.filter((icon) => icon.label.toLowerCase().includes(this.searchQuery) ||
584
+ icon.tags?.some((tag) => tag.toLowerCase().includes(this.searchQuery)));
585
+ }
586
+ result = result.filter((icon) => {
587
+ if (!icon.supportedStyle || icon.supportedStyle.length === 0) {
588
+ return true;
589
+ }
590
+ return icon.supportedStyle.includes(this.selectedIconType);
591
+ });
592
+ this.filteredIcons = result;
593
+ }
594
+ selectIcon(icon) {
595
+ this.close({
596
+ label: icon.label,
597
+ styleClass: this.selectedIconType,
598
+ iconClass: `fa-${icon.name}`,
599
+ });
600
+ }
601
+ getIconClass(icon) {
602
+ return `${this.selectedIconType} fa-${icon.name}`;
603
+ }
604
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPIconChooserPopupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
605
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPIconChooserPopupComponent, isStandalone: true, selector: "ng-component", inputs: { value: "value" }, usesInheritance: true, ngImport: i0, template: `
606
+ <div class="ax-flex ax-flex-col ax-h-full ax-bg-lightest">
607
+ <!-- Fixed Header Section -->
608
+ <div class="ax-sticky ax-top-0 ax-z-10 ax-bg-lightest ax-border-b ax-p-4 ax-gap-4 ax-flex ax-flex-col">
609
+ <!-- Search Bar -->
610
+ <div class="ax-flex ax-justify-center">
611
+ <ax-search-box
612
+ class="ax-w-full"
613
+ (onValueChanged)="handleSearch($event)"
614
+ [placeholder]="'@general:widgets.icon-chooser.search-placeholder' | translate | async"
615
+ ></ax-search-box>
616
+ </div>
617
+
618
+ <!-- Controls Row -->
619
+ <div class="ax-flex ax-justify-between ax-items-center ax-flex-wrap ax-gap-2">
620
+ <!-- Icon Style Filter -->
621
+ <ax-button-group selection="single" look="outline">
622
+ @for (item of iconTypes; track item.name) {
623
+ <ax-button-group-item
624
+ [text]="item.label"
625
+ [selected]="item.name === selectedIconType"
626
+ (onClick)="handleIconTypeChange(item)"
627
+ >
628
+ </ax-button-group-item>
629
+ }
630
+ </ax-button-group>
631
+
632
+ <!-- View Mode Toggle -->
633
+ <ax-button-group selection="single" look="outline">
634
+ @for (item of viewModes; track item.value) {
635
+ <ax-button-group-item
636
+ [title]="item.text | translate | async"
637
+ [selected]="item.value === selectedViewMode"
638
+ (onClick)="handleViewModeChange(item)"
639
+ >
640
+ <ax-icon [class]="item.icon"></ax-icon>
641
+ </ax-button-group-item>
642
+ }
643
+ </ax-button-group>
644
+ </div>
645
+ </div>
646
+
647
+ <!-- Scrollable Content Area -->
648
+ <div class="ax-flex-1 ax-overflow-y-auto ax-p-4 ax-pt-2">
649
+ <div
650
+ class="ax-grid ax-gap-1"
651
+ [ngClass]="
652
+ selectedViewMode === 'square'
653
+ ? 'ax-grid-cols-[repeat(auto-fill,minmax(6rem,1fr))]'
654
+ : 'ax-grid-cols-1 md:ax-grid-cols-2'
655
+ "
656
+ >
657
+ @for (icon of filteredIcons; track icon) {
658
+ <div
659
+ class="ax-p-4 ax-border ax-border-transparent ax-rounded-lg ax-flex ax-items-center ax-justify-center ax-gap-2 ax-cursor-pointer ax-transition-all ax-duration-200 ax-ease-in-out hover:ax-border-primary hover:ax-shadow-md"
660
+ [ngClass]="{
661
+ 'ax-flex-col': selectedViewMode === 'square',
662
+ 'ax-flex-row ax-justify-start': selectedViewMode === 'rectangle',
663
+ }"
664
+ (click)="selectIcon(icon)"
665
+ >
666
+ <i [class]="getIconClass(icon) + ' ax-text-3xl'"></i>
667
+ <span
668
+ class="ax-text-xs ax-w-full ax-overflow-hidden ax-text-ellipsis ax-whitespace-nowrap"
669
+ [ngClass]="{
670
+ 'ax-text-center': selectedViewMode === 'square',
671
+ 'ax-text-left': selectedViewMode === 'rectangle',
672
+ }"
673
+ >{{ icon.label }}</span
674
+ >
675
+ </div>
676
+ }
677
+ </div>
678
+ </div>
679
+ </div>
680
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i1$1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXButtonGroupModule }, { kind: "component", type: i2$1.AXButtonGroupComponent, selector: "ax-button-group", inputs: ["disabled", "color", "look", "fitParent", "selection"], outputs: ["onBlur", "onFocus", "lookChange", "colorChange", "disabledChange", "onClick", "selectionChange", "selectedButtonChange"] }, { kind: "component", type: i2$1.AXButtonGroupItemComponent, selector: "ax-button-group-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
681
+ }
682
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPIconChooserPopupComponent, decorators: [{
683
+ type: Component,
684
+ args: [{
685
+ template: `
686
+ <div class="ax-flex ax-flex-col ax-h-full ax-bg-lightest">
687
+ <!-- Fixed Header Section -->
688
+ <div class="ax-sticky ax-top-0 ax-z-10 ax-bg-lightest ax-border-b ax-p-4 ax-gap-4 ax-flex ax-flex-col">
689
+ <!-- Search Bar -->
690
+ <div class="ax-flex ax-justify-center">
691
+ <ax-search-box
692
+ class="ax-w-full"
693
+ (onValueChanged)="handleSearch($event)"
694
+ [placeholder]="'@general:widgets.icon-chooser.search-placeholder' | translate | async"
695
+ ></ax-search-box>
696
+ </div>
697
+
698
+ <!-- Controls Row -->
699
+ <div class="ax-flex ax-justify-between ax-items-center ax-flex-wrap ax-gap-2">
700
+ <!-- Icon Style Filter -->
701
+ <ax-button-group selection="single" look="outline">
702
+ @for (item of iconTypes; track item.name) {
703
+ <ax-button-group-item
704
+ [text]="item.label"
705
+ [selected]="item.name === selectedIconType"
706
+ (onClick)="handleIconTypeChange(item)"
707
+ >
708
+ </ax-button-group-item>
709
+ }
710
+ </ax-button-group>
711
+
712
+ <!-- View Mode Toggle -->
713
+ <ax-button-group selection="single" look="outline">
714
+ @for (item of viewModes; track item.value) {
715
+ <ax-button-group-item
716
+ [title]="item.text | translate | async"
717
+ [selected]="item.value === selectedViewMode"
718
+ (onClick)="handleViewModeChange(item)"
719
+ >
720
+ <ax-icon [class]="item.icon"></ax-icon>
721
+ </ax-button-group-item>
722
+ }
723
+ </ax-button-group>
724
+ </div>
725
+ </div>
726
+
727
+ <!-- Scrollable Content Area -->
728
+ <div class="ax-flex-1 ax-overflow-y-auto ax-p-4 ax-pt-2">
729
+ <div
730
+ class="ax-grid ax-gap-1"
731
+ [ngClass]="
732
+ selectedViewMode === 'square'
733
+ ? 'ax-grid-cols-[repeat(auto-fill,minmax(6rem,1fr))]'
734
+ : 'ax-grid-cols-1 md:ax-grid-cols-2'
735
+ "
736
+ >
737
+ @for (icon of filteredIcons; track icon) {
738
+ <div
739
+ class="ax-p-4 ax-border ax-border-transparent ax-rounded-lg ax-flex ax-items-center ax-justify-center ax-gap-2 ax-cursor-pointer ax-transition-all ax-duration-200 ax-ease-in-out hover:ax-border-primary hover:ax-shadow-md"
740
+ [ngClass]="{
741
+ 'ax-flex-col': selectedViewMode === 'square',
742
+ 'ax-flex-row ax-justify-start': selectedViewMode === 'rectangle',
743
+ }"
744
+ (click)="selectIcon(icon)"
745
+ >
746
+ <i [class]="getIconClass(icon) + ' ax-text-3xl'"></i>
747
+ <span
748
+ class="ax-text-xs ax-w-full ax-overflow-hidden ax-text-ellipsis ax-whitespace-nowrap"
749
+ [ngClass]="{
750
+ 'ax-text-center': selectedViewMode === 'square',
751
+ 'ax-text-left': selectedViewMode === 'rectangle',
752
+ }"
753
+ >{{ icon.label }}</span
754
+ >
755
+ </div>
756
+ }
757
+ </div>
758
+ </div>
759
+ </div>
760
+ `,
761
+ imports: [AXSearchBoxModule, AXButtonGroupModule, CommonModule, AXDecoratorModule, AXTranslationModule],
762
+ changeDetection: ChangeDetectionStrategy.OnPush,
763
+ }]
764
+ }], propDecorators: { value: [{
765
+ type: Input
766
+ }] } });
767
+
768
+ class AXPIconChooserWidgetEditComponent extends AXPValueWidgetComponent {
769
+ constructor() {
770
+ super(...arguments);
771
+ this.popupService = inject(AXPopupService);
772
+ this.computedValue = computed(() => {
773
+ const value = this.getValue();
774
+ if (typeof value === 'string') {
775
+ const parts = value.split(' ');
776
+ if (parts.length === 1) {
777
+ return { styleClass: 'fa-solid', iconClass: parts[0] };
778
+ }
779
+ else if (parts.length === 2) {
780
+ return { styleClass: parts[0], iconClass: parts[1] };
781
+ }
782
+ else {
783
+ throw new Error(`Invalid icon format: "${value}". Expected format: "icon-class" or "style-class icon-class"`);
784
+ }
785
+ }
786
+ return value;
787
+ }, ...(ngDevMode ? [{ debugName: "computedValue" }] : /* istanbul ignore next */ []));
788
+ }
789
+ async openPopup() {
790
+ const result = await this.popupService.open(AXPIconChooserPopupComponent, {
791
+ title: 'Choose Icon',
792
+ size: 'md',
793
+ data: {
794
+ value: this.getValue(),
795
+ },
796
+ });
797
+ if (result?.data) {
798
+ this.setValue(result.data.styleClass + ' ' + result.data.iconClass);
799
+ }
800
+ }
801
+ addIcon() {
802
+ if (!this.getValue()) {
803
+ this.openPopup();
804
+ }
805
+ }
806
+ deleteIcon() {
807
+ this.setValue(undefined);
808
+ }
809
+ editIcon() {
810
+ this.openPopup();
811
+ }
812
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPIconChooserWidgetEditComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
813
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPIconChooserWidgetEditComponent, isStandalone: true, selector: "ax-icon-chooser-edit", usesInheritance: true, ngImport: i0, template: `
814
+ <div
815
+ class="ax-grid ax-grid-cols-[6rem_auto] ax-items-center ax-rounded-md ax-text-3xl ax-w-fit"
816
+ [class.ax-border]="getValue()"
817
+ >
818
+ <!-- Left: Add or Selected Icon -->
819
+ <div
820
+ class="ax-grid ax-place-items-center ax-w-24 ax-h-24 "
821
+ [class]="getValue() ? 'ax-border-e ax-cursor-default' : 'icon-container ax-cursor-pointer'"
822
+ (click)="addIcon()"
823
+ >
824
+ <i [class]="getValue() ? computedValue().styleClass + ' ' + computedValue().iconClass : 'fa-solid fa-plus'"></i>
825
+ </div>
826
+
827
+ <!-- Right: Edit & Delete (only if value exists) -->
828
+ @if (getValue()) {
829
+ <div class="ax-flex ax-flex-col ax-w-16 ax-text-2xl">
830
+ <div class="ax-h-12 ax-grid ax-place-items-center ax-cursor-pointer hover:ax-bg-surface" (click)="editIcon()">
831
+ <i class="fa-light fa-edit ax-text-primary-400"></i>
832
+ </div>
833
+ <div
834
+ class="ax-h-12 ax-grid ax-place-items-center ax-cursor-pointer ax-border-t hover:ax-bg-surface"
835
+ (click)="deleteIcon()"
836
+ >
837
+ <i class="fa-light fa-trash-can ax-text-danger-400"></i>
838
+ </div>
839
+ </div>
840
+ }
841
+ </div>
842
+ `, isInline: true, styles: [".icon-container{background-color:rgba(var(--ax-sys-color-primary-300),10%);background-image:linear-gradient(135deg,rgba(var(--ax-sys-color-primary-300),50%) 10%,transparent 0,transparent 50%,rgba(var(--ax-sys-color-primary-300),50%) 0,rgba(var(--ax-sys-color-primary-300),50%) 60%,transparent 0,transparent);background-size:7.5px 7.5px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
843
+ }
844
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPIconChooserWidgetEditComponent, decorators: [{
845
+ type: Component,
846
+ args: [{ selector: 'ax-icon-chooser-edit', template: `
847
+ <div
848
+ class="ax-grid ax-grid-cols-[6rem_auto] ax-items-center ax-rounded-md ax-text-3xl ax-w-fit"
849
+ [class.ax-border]="getValue()"
850
+ >
851
+ <!-- Left: Add or Selected Icon -->
852
+ <div
853
+ class="ax-grid ax-place-items-center ax-w-24 ax-h-24 "
854
+ [class]="getValue() ? 'ax-border-e ax-cursor-default' : 'icon-container ax-cursor-pointer'"
855
+ (click)="addIcon()"
856
+ >
857
+ <i [class]="getValue() ? computedValue().styleClass + ' ' + computedValue().iconClass : 'fa-solid fa-plus'"></i>
858
+ </div>
859
+
860
+ <!-- Right: Edit & Delete (only if value exists) -->
861
+ @if (getValue()) {
862
+ <div class="ax-flex ax-flex-col ax-w-16 ax-text-2xl">
863
+ <div class="ax-h-12 ax-grid ax-place-items-center ax-cursor-pointer hover:ax-bg-surface" (click)="editIcon()">
864
+ <i class="fa-light fa-edit ax-text-primary-400"></i>
865
+ </div>
866
+ <div
867
+ class="ax-h-12 ax-grid ax-place-items-center ax-cursor-pointer ax-border-t hover:ax-bg-surface"
868
+ (click)="deleteIcon()"
869
+ >
870
+ <i class="fa-light fa-trash-can ax-text-danger-400"></i>
871
+ </div>
872
+ </div>
873
+ }
874
+ </div>
875
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".icon-container{background-color:rgba(var(--ax-sys-color-primary-300),10%);background-image:linear-gradient(135deg,rgba(var(--ax-sys-color-primary-300),50%) 10%,transparent 0,transparent 50%,rgba(var(--ax-sys-color-primary-300),50%) 0,rgba(var(--ax-sys-color-primary-300),50%) 60%,transparent 0,transparent);background-size:7.5px 7.5px}\n"] }]
876
+ }] });
877
+
878
+ var iconChooserEdit_component = /*#__PURE__*/Object.freeze({
879
+ __proto__: null,
880
+ AXPIconChooserWidgetEditComponent: AXPIconChooserWidgetEditComponent
881
+ });
882
+
883
+ const AXPIconChooserWidget = {
884
+ name: 'icon-chooser',
885
+ title: 'Icon Chooser',
886
+ icon: 'fa-solid fa-icons',
887
+ type: 'editor',
888
+ categories: AXP_WIDGETS_LAYOUT_CATEGORY,
889
+ properties: [AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_DISABLED_PROPERTY],
890
+ components: {
891
+ edit: {
892
+ component: () => Promise.resolve().then(function () { return iconChooserEdit_component; }).then((c) => c.AXPIconChooserWidgetEditComponent),
893
+ },
894
+ column: {
895
+ component: () => import('./acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs').then((c) => c.AXPIconChooserWidgetColumnComponent),
896
+ },
897
+ view: {
898
+ component: () => import('./acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs').then((c) => c.AXPIconChooserWidgetViewComponent),
899
+ },
900
+ },
901
+ };
902
+
903
+ //#region ---- Default Icon Styles ----
904
+ const DEFAULT_ICON_STYLES = [
905
+ { name: 'fa-regular', label: 'Regular' },
906
+ { name: 'fa-solid', label: 'Solid' },
907
+ ];
908
+ //#endregion
909
+ //#region ---- Default Icons ----
910
+ const DEFAULT_ICONS = [
911
+ // Navigation & Actions
912
+ { name: 'house', label: 'House', tags: ['home', 'building', 'house'] },
913
+ { name: 'magnifying-glass', label: 'Search', tags: ['find', 'zoom'] },
914
+ { name: 'user', label: 'User', tags: ['person', 'account'] },
915
+ { name: 'users', label: 'Users', tags: ['people', 'group', 'team'] },
916
+ { name: 'user-group', label: 'User Group', tags: ['team', 'group', 'people'] },
917
+ { name: 'check', label: 'Check', tags: ['confirm', 'done', 'tick'] },
918
+ { name: 'check-circle', label: 'Check Circle', tags: ['confirm', 'success', 'done'] },
919
+ { name: 'check-double', label: 'Check Double', tags: ['verified', 'confirmed'] },
920
+ { name: 'xmark', label: 'Close', tags: ['cancel', 'exit', 'remove'] },
921
+ { name: 'circle-xmark', label: 'Circle Close', tags: ['cancel', 'error', 'remove'] },
922
+ { name: 'plus', label: 'Add', tags: ['create', 'new', 'plus'] },
923
+ { name: 'circle-plus', label: 'Circle Plus', tags: ['add', 'create', 'new'] },
924
+ { name: 'minus', label: 'Remove', tags: ['delete', 'subtract', 'minus'] },
925
+ { name: 'circle-minus', label: 'Circle Minus', tags: ['remove', 'subtract'] },
926
+ { name: 'edit', label: 'Edit', tags: ['modify', 'change', 'pencil'] },
927
+ { name: 'pen-to-square', label: 'Edit Square', tags: ['edit', 'modify', 'write'] },
928
+ { name: 'trash', label: 'Delete', tags: ['remove', 'delete', 'bin'] },
929
+ { name: 'trash-can', label: 'Trash Can', tags: ['delete', 'remove', 'garbage'] },
930
+ { name: 'copy', label: 'Copy', tags: ['duplicate', 'clone'] },
931
+ { name: 'clone', label: 'Clone', tags: ['duplicate', 'copy'] },
932
+ { name: 'download', label: 'Download', tags: ['save', 'export'] },
933
+ { name: 'upload', label: 'Upload', tags: ['import', 'send'] },
934
+ { name: 'print', label: 'Print', tags: ['printer', 'document'] },
935
+ { name: 'share', label: 'Share', tags: ['send', 'distribute'] },
936
+ { name: 'share-nodes', label: 'Share Network', tags: ['share', 'distribute', 'network'] },
937
+ { name: 'link', label: 'Link', tags: ['url', 'connection'] },
938
+ { name: 'link-slash', label: 'Unlink', tags: ['disconnect', 'remove'] },
939
+ { name: 'external-link', label: 'External Link', tags: ['open', 'external'] },
940
+ { name: 'arrows-rotate', label: 'Refresh', tags: ['reload', 'sync', 'update'] },
941
+ { name: 'rotate-right', label: 'Rotate Right', tags: ['refresh', 'reload'] },
942
+ { name: 'arrows-left-right', label: 'Arrows Horizontal', tags: ['swap', 'exchange'] },
943
+ { name: 'arrow-up', label: 'Arrow Up', tags: ['up', 'direction'] },
944
+ { name: 'arrow-down', label: 'Arrow Down', tags: ['down', 'direction'] },
945
+ { name: 'arrow-left', label: 'Arrow Left', tags: ['left', 'back', 'previous'] },
946
+ { name: 'arrow-right', label: 'Arrow Right', tags: ['right', 'forward', 'next'] },
947
+ { name: 'chevron-up', label: 'Chevron Up', tags: ['up', 'collapse'] },
948
+ { name: 'chevron-down', label: 'Chevron Down', tags: ['down', 'expand'] },
949
+ { name: 'chevron-left', label: 'Chevron Left', tags: ['left', 'previous'] },
950
+ { name: 'chevron-right', label: 'Chevron Right', tags: ['right', 'next'] },
951
+ { name: 'angle-up', label: 'Angle Up', tags: ['up', 'caret'] },
952
+ { name: 'angle-down', label: 'Angle Down', tags: ['down', 'caret'] },
953
+ { name: 'angle-left', label: 'Angle Left', tags: ['left', 'caret'] },
954
+ { name: 'angle-right', label: 'Angle Right', tags: ['right', 'caret'] },
955
+ { name: 'bars', label: 'Menu', tags: ['hamburger', 'menu', 'navigation'] },
956
+ { name: 'ellipsis', label: 'Ellipsis', tags: ['more', 'options', 'menu'] },
957
+ { name: 'ellipsis-vertical', label: 'Ellipsis Vertical', tags: ['more', 'options', 'menu'] },
958
+ { name: 'grip', label: 'Grip', tags: ['drag', 'handle', 'move'] },
959
+ { name: 'grip-vertical', label: 'Grip Vertical', tags: ['drag', 'handle', 'move'] },
960
+ { name: 'filter', label: 'Filter', tags: ['sort', 'search', 'refine'] },
961
+ { name: 'sliders', label: 'Settings', tags: ['adjust', 'options', 'preferences'] },
962
+ // Media & Files
963
+ { name: 'star', label: 'Star', tags: ['favorite', 'rate'] },
964
+ { name: 'star-half', label: 'Star Half', tags: ['rating', 'half'] },
965
+ { name: 'heart', label: 'Heart', tags: ['love', 'like', 'favorite'] },
966
+ { name: 'heart-pulse', label: 'Heart Pulse', tags: ['health', 'medical', 'heartbeat'] },
967
+ { name: 'cloud', label: 'Cloud', tags: ['weather', 'sky', 'storage'] },
968
+ { name: 'cloud-arrow-up', label: 'Cloud Upload', tags: ['upload', 'backup', 'save'] },
969
+ { name: 'cloud-arrow-down', label: 'Cloud Download', tags: ['download', 'restore'] },
970
+ { name: 'envelope', label: 'Envelope', tags: ['mail', 'message', 'email'] },
971
+ { name: 'envelope-open', label: 'Envelope Open', tags: ['mail', 'read', 'message'] },
972
+ { name: 'paper-plane', label: 'Send', tags: ['send', 'message', 'email'] },
973
+ { name: 'folder', label: 'Folder', tags: ['directory', 'files'] },
974
+ { name: 'folder-open', label: 'Folder Open', tags: ['directory', 'files', 'open'] },
975
+ { name: 'folder-plus', label: 'New Folder', tags: ['create', 'directory', 'add'] },
976
+ { name: 'folder-tree', label: 'Folder Tree', tags: ['structure', 'hierarchy', 'files'] },
977
+ { name: 'gear', label: 'Gear', tags: ['settings', 'options', 'config'] },
978
+ { name: 'gears', label: 'Gears', tags: ['settings', 'configuration', 'system'] },
979
+ { name: 'camera', label: 'Camera', tags: ['photo', 'image', 'picture'] },
980
+ { name: 'camera-retro', label: 'Camera Retro', tags: ['photo', 'vintage'] },
981
+ { name: 'video', label: 'Video', tags: ['film', 'movie', 'camera'] },
982
+ { name: 'video-slash', label: 'Video Off', tags: ['disabled', 'mute', 'off'] },
983
+ { name: 'music', label: 'Music', tags: ['sound', 'audio', 'song'] },
984
+ { name: 'file', label: 'File', tags: ['document', 'file'] },
985
+ { name: 'file-lines', label: 'File Text', tags: ['document', 'text'] },
986
+ { name: 'file-pdf', label: 'PDF', tags: ['document', 'pdf'] },
987
+ { name: 'file-word', label: 'Word Document', tags: ['document', 'word', 'doc'] },
988
+ { name: 'file-excel', label: 'Excel', tags: ['spreadsheet', 'excel', 'xls'] },
989
+ { name: 'file-powerpoint', label: 'PowerPoint', tags: ['presentation', 'powerpoint', 'ppt'] },
990
+ { name: 'file-image', label: 'Image File', tags: ['picture', 'photo', 'image'] },
991
+ { name: 'file-video', label: 'Video File', tags: ['movie', 'clip', 'video'] },
992
+ { name: 'file-audio', label: 'Audio File', tags: ['sound', 'music', 'audio'] },
993
+ { name: 'file-code', label: 'Code File', tags: ['code', 'programming', 'source'] },
994
+ { name: 'file-zipper', label: 'Archive', tags: ['zip', 'compressed', 'archive'] },
995
+ { name: 'file-csv', label: 'CSV File', tags: ['spreadsheet', 'data', 'csv'] },
996
+ { name: 'image', label: 'Image', tags: ['picture', 'photo'] },
997
+ { name: 'images', label: 'Images', tags: ['gallery', 'photos', 'pictures'] },
998
+ { name: 'photo-film', label: 'Photo Film', tags: ['gallery', 'images', 'media'] },
999
+ { name: 'microphone', label: 'Microphone', tags: ['audio', 'voice', 'record'] },
1000
+ { name: 'microphone-slash', label: 'Microphone Off', tags: ['mute', 'audio', 'off'] },
1001
+ { name: 'volume-high', label: 'Volume High', tags: ['sound', 'audio', 'loud'] },
1002
+ { name: 'volume-low', label: 'Volume Low', tags: ['sound', 'audio', 'quiet'] },
1003
+ { name: 'volume-xmark', label: 'Mute', tags: ['mute', 'silent', 'off'] },
1004
+ // Communication & Social
1005
+ { name: 'phone', label: 'Phone', tags: ['call', 'telephone', 'contact'] },
1006
+ { name: 'phone-flip', label: 'Phone Flip', tags: ['call', 'mobile', 'flip'] },
1007
+ { name: 'mobile', label: 'Mobile', tags: ['cell', 'smartphone', 'phone'] },
1008
+ { name: 'mobile-screen', label: 'Mobile Screen', tags: ['smartphone', 'device'] },
1009
+ { name: 'fax', label: 'Fax', tags: ['document', 'send', 'print'] },
1010
+ { name: 'comment', label: 'Comment', tags: ['message', 'chat', 'text'] },
1011
+ { name: 'comments', label: 'Comments', tags: ['messages', 'discussion', 'chat'] },
1012
+ { name: 'comment-dots', label: 'Comment Typing', tags: ['message', 'typing', 'chat'] },
1013
+ { name: 'message', label: 'Message', tags: ['chat', 'text', 'communication'] },
1014
+ { name: 'inbox', label: 'Inbox', tags: ['mail', 'messages', 'receive'] },
1015
+ { name: 'at', label: 'At Symbol', tags: ['email', 'mention', 'tag'] },
1016
+ { name: 'hashtag', label: 'Hashtag', tags: ['tag', 'social', 'topic'] },
1017
+ { name: 'thumbs-up', label: 'Like', tags: ['approve', 'good', 'positive'] },
1018
+ { name: 'thumbs-down', label: 'Dislike', tags: ['disapprove', 'bad', 'negative'] },
1019
+ { name: 'bell', label: 'Notification', tags: ['alert', 'reminder', 'notification'] },
1020
+ { name: 'bell-slash', label: 'Notifications Off', tags: ['mute', 'silent', 'off'] },
1021
+ { name: 'flag', label: 'Flag', tags: ['mark', 'report', 'bookmark'] },
1022
+ { name: 'flag-checkered', label: 'Flag Checkered', tags: ['finish', 'end', 'goal'] },
1023
+ { name: 'bookmark', label: 'Bookmark', tags: ['save', 'favorite', 'mark'] },
1024
+ { name: 'calendar', label: 'Calendar', tags: ['date', 'schedule', 'event'] },
1025
+ { name: 'calendar-days', label: 'Calendar Days', tags: ['date', 'month', 'schedule'] },
1026
+ { name: 'calendar-check', label: 'Calendar Check', tags: ['event', 'confirmed', 'scheduled'] },
1027
+ { name: 'calendar-plus', label: 'Calendar Add', tags: ['event', 'create', 'schedule'] },
1028
+ { name: 'clock', label: 'Clock', tags: ['time', 'schedule', 'hour'] },
1029
+ { name: 'hourglass', label: 'Hourglass', tags: ['time', 'waiting', 'timer'] },
1030
+ { name: 'stopwatch', label: 'Stopwatch', tags: ['timer', 'time', 'track'] },
1031
+ { name: 'rss', label: 'RSS', tags: ['feed', 'news', 'subscribe'] },
1032
+ // Business & Finance
1033
+ { name: 'chart-line', label: 'Chart Line', tags: ['graph', 'analytics', 'trending'] },
1034
+ { name: 'chart-bar', label: 'Bar Chart', tags: ['graph', 'statistics', 'data'] },
1035
+ { name: 'chart-pie', label: 'Pie Chart', tags: ['graph', 'percentage', 'data'] },
1036
+ { name: 'chart-area', label: 'Area Chart', tags: ['graph', 'analytics', 'data'] },
1037
+ { name: 'chart-column', label: 'Column Chart', tags: ['graph', 'statistics'] },
1038
+ { name: 'chart-simple', label: 'Simple Chart', tags: ['graph', 'data', 'analytics'] },
1039
+ { name: 'calculator', label: 'Calculator', tags: ['math', 'compute', 'calculate'] },
1040
+ { name: 'percent', label: 'Percent', tags: ['percentage', 'discount', 'rate'] },
1041
+ { name: 'dollar-sign', label: 'Dollar', tags: ['money', 'currency', 'usd'] },
1042
+ { name: 'euro-sign', label: 'Euro', tags: ['money', 'currency', 'eur'] },
1043
+ { name: 'sterling-sign', label: 'Pound', tags: ['money', 'currency', 'gbp'] },
1044
+ { name: 'yen-sign', label: 'Yen', tags: ['money', 'currency', 'jpy'] },
1045
+ { name: 'coins', label: 'Coins', tags: ['money', 'cash', 'currency'] },
1046
+ { name: 'money-bill', label: 'Money Bill', tags: ['cash', 'currency', 'payment'] },
1047
+ { name: 'wallet', label: 'Wallet', tags: ['money', 'payment', 'cash'] },
1048
+ { name: 'credit-card', label: 'Credit Card', tags: ['payment', 'card', 'bank'] },
1049
+ { name: 'money-check', label: 'Check', tags: ['payment', 'bank', 'check'] },
1050
+ { name: 'receipt', label: 'Receipt', tags: ['bill', 'invoice', 'payment'] },
1051
+ { name: 'file-invoice', label: 'Invoice', tags: ['bill', 'receipt', 'document'] },
1052
+ { name: 'file-invoice-dollar', label: 'Invoice Dollar', tags: ['bill', 'payment', 'money'] },
1053
+ { name: 'briefcase', label: 'Briefcase', tags: ['business', 'work', 'professional'] },
1054
+ { name: 'suitcase', label: 'Suitcase', tags: ['travel', 'business', 'luggage'] },
1055
+ { name: 'building', label: 'Building', tags: ['office', 'company', 'business'] },
1056
+ { name: 'building-columns', label: 'Bank', tags: ['bank', 'government', 'institution'] },
1057
+ { name: 'store', label: 'Store', tags: ['shop', 'retail', 'business'] },
1058
+ { name: 'handshake', label: 'Handshake', tags: ['agreement', 'partnership', 'deal'] },
1059
+ { name: 'scale-balanced', label: 'Balance', tags: ['law', 'justice', 'legal'] },
1060
+ { name: 'gavel', label: 'Gavel', tags: ['law', 'court', 'legal'] },
1061
+ // Technology & Tools
1062
+ { name: 'laptop', label: 'Laptop', tags: ['computer', 'notebook', 'device'] },
1063
+ { name: 'laptop-code', label: 'Laptop Code', tags: ['programming', 'development'] },
1064
+ { name: 'desktop', label: 'Desktop', tags: ['computer', 'monitor', 'screen'] },
1065
+ { name: 'tablet', label: 'Tablet', tags: ['ipad', 'device', 'mobile'] },
1066
+ { name: 'tablet-screen-button', label: 'Tablet Button', tags: ['device', 'touch'] },
1067
+ { name: 'keyboard', label: 'Keyboard', tags: ['input', 'typing', 'keys'] },
1068
+ { name: 'mouse', label: 'Mouse', tags: ['pointer', 'click', 'input'] },
1069
+ { name: 'display', label: 'Display', tags: ['monitor', 'screen', 'computer'] },
1070
+ { name: 'wifi', label: 'WiFi', tags: ['internet', 'connection', 'wireless'] },
1071
+ { name: 'ethernet', label: 'Ethernet', tags: ['network', 'connection', 'cable'] },
1072
+ { name: 'signal', label: 'Signal', tags: ['network', 'connection', 'wifi'] },
1073
+ { name: 'network-wired', label: 'Network', tags: ['connection', 'lan', 'ethernet'] },
1074
+ { name: 'database', label: 'Database', tags: ['data', 'storage', 'sql'] },
1075
+ { name: 'hard-drive', label: 'Hard Drive', tags: ['storage', 'disk', 'hdd'] },
1076
+ { name: 'server', label: 'Server', tags: ['hosting', 'backend', 'computer'] },
1077
+ { name: 'memory', label: 'Memory', tags: ['ram', 'chip', 'hardware'] },
1078
+ { name: 'microchip', label: 'Microchip', tags: ['chip', 'processor', 'cpu'] },
1079
+ { name: 'code', label: 'Code', tags: ['programming', 'development', 'coding'] },
1080
+ { name: 'code-branch', label: 'Git Branch', tags: ['version', 'git', 'branch'] },
1081
+ { name: 'code-commit', label: 'Commit', tags: ['git', 'version', 'save'] },
1082
+ { name: 'code-merge', label: 'Merge', tags: ['git', 'branch', 'combine'] },
1083
+ { name: 'code-pull-request', label: 'Pull Request', tags: ['git', 'pr', 'review'] },
1084
+ { name: 'terminal', label: 'Terminal', tags: ['console', 'command', 'cli'] },
1085
+ { name: 'window-maximize', label: 'Maximize', tags: ['window', 'expand', 'fullscreen'] },
1086
+ { name: 'window-minimize', label: 'Minimize', tags: ['window', 'collapse'] },
1087
+ { name: 'window-restore', label: 'Restore', tags: ['window', 'resize'] },
1088
+ { name: 'bug', label: 'Bug', tags: ['error', 'debug', 'issue'] },
1089
+ { name: 'wrench', label: 'Wrench', tags: ['tools', 'settings', 'fix'] },
1090
+ { name: 'screwdriver-wrench', label: 'Tools', tags: ['repair', 'fix', 'settings'] },
1091
+ { name: 'hammer', label: 'Hammer', tags: ['tool', 'build', 'construct'] },
1092
+ { name: 'shield', label: 'Shield', tags: ['security', 'protection', 'defense'] },
1093
+ { name: 'shield-halved', label: 'Shield Half', tags: ['security', 'protection'] },
1094
+ { name: 'lock', label: 'Lock', tags: ['security', 'private', 'secure'] },
1095
+ { name: 'lock-open', label: 'Lock Open', tags: ['unlocked', 'open'] },
1096
+ { name: 'unlock', label: 'Unlock', tags: ['open', 'access', 'unlock'] },
1097
+ { name: 'key', label: 'Key', tags: ['access', 'password', 'security'] },
1098
+ { name: 'user-lock', label: 'User Lock', tags: ['security', 'private', 'protected'] },
1099
+ { name: 'user-shield', label: 'User Shield', tags: ['security', 'protected', 'admin'] },
1100
+ { name: 'qrcode', label: 'QR Code', tags: ['code', 'scan', 'barcode'] },
1101
+ { name: 'barcode', label: 'Barcode', tags: ['scan', 'code', 'product'] },
1102
+ // Transportation & Location
1103
+ { name: 'car', label: 'Car', tags: ['vehicle', 'automobile', 'transport'] },
1104
+ { name: 'car-side', label: 'Car Side', tags: ['vehicle', 'automobile'] },
1105
+ { name: 'taxi', label: 'Taxi', tags: ['cab', 'transport', 'vehicle'] },
1106
+ { name: 'bus', label: 'Bus', tags: ['transport', 'public', 'vehicle'] },
1107
+ { name: 'van-shuttle', label: 'Van', tags: ['transport', 'vehicle'] },
1108
+ { name: 'truck', label: 'Truck', tags: ['vehicle', 'delivery', 'transport'] },
1109
+ { name: 'truck-fast', label: 'Fast Delivery', tags: ['shipping', 'express', 'delivery'] },
1110
+ { name: 'motorcycle', label: 'Motorcycle', tags: ['bike', 'vehicle', 'transport'] },
1111
+ { name: 'plane', label: 'Plane', tags: ['aircraft', 'travel', 'flight'] },
1112
+ { name: 'plane-departure', label: 'Departure', tags: ['flight', 'travel', 'takeoff'] },
1113
+ { name: 'plane-arrival', label: 'Arrival', tags: ['flight', 'travel', 'landing'] },
1114
+ { name: 'helicopter', label: 'Helicopter', tags: ['aircraft', 'flight'] },
1115
+ { name: 'rocket', label: 'Rocket', tags: ['space', 'launch', 'fast'] },
1116
+ { name: 'train', label: 'Train', tags: ['railway', 'transport', 'travel'] },
1117
+ { name: 'subway', label: 'Subway', tags: ['metro', 'underground', 'transport'] },
1118
+ { name: 'ship', label: 'Ship', tags: ['boat', 'vessel', 'water'] },
1119
+ { name: 'anchor', label: 'Anchor', tags: ['ship', 'marine', 'boat'] },
1120
+ { name: 'bicycle', label: 'Bicycle', tags: ['bike', 'cycle', 'transport'] },
1121
+ { name: 'road', label: 'Road', tags: ['street', 'path', 'route'] },
1122
+ { name: 'map', label: 'Map', tags: ['location', 'navigation', 'directions'] },
1123
+ { name: 'map-location', label: 'Map Location', tags: ['pin', 'marker', 'place'] },
1124
+ { name: 'map-pin', label: 'Location Pin', tags: ['pin', 'marker', 'place'] },
1125
+ { name: 'location-dot', label: 'Location', tags: ['pin', 'marker', 'gps'] },
1126
+ { name: 'location-crosshairs', label: 'GPS', tags: ['location', 'position', 'gps'] },
1127
+ { name: 'route', label: 'Route', tags: ['directions', 'path', 'navigation'] },
1128
+ { name: 'globe', label: 'Globe', tags: ['world', 'earth', 'global'] },
1129
+ { name: 'earth-americas', label: 'Americas', tags: ['world', 'global', 'earth'] },
1130
+ { name: 'earth-europe', label: 'Europe', tags: ['world', 'global', 'earth'] },
1131
+ { name: 'earth-asia', label: 'Asia', tags: ['world', 'global', 'earth'] },
1132
+ { name: 'compass', label: 'Compass', tags: ['direction', 'navigation', 'north'] },
1133
+ { name: 'street-view', label: 'Street View', tags: ['location', 'map', 'view'] },
1134
+ // Health & Medical
1135
+ { name: 'heart-pulse', label: 'Heart Rate', tags: ['health', 'medical', 'heartbeat'] },
1136
+ { name: 'heart-circle-plus', label: 'Heart Plus', tags: ['health', 'add', 'medical'] },
1137
+ { name: 'stethoscope', label: 'Stethoscope', tags: ['medical', 'doctor', 'health'] },
1138
+ { name: 'user-doctor', label: 'Doctor', tags: ['medical', 'physician', 'healthcare'] },
1139
+ { name: 'user-nurse', label: 'Nurse', tags: ['medical', 'healthcare', 'hospital'] },
1140
+ { name: 'pills', label: 'Pills', tags: ['medicine', 'drugs', 'medication'] },
1141
+ { name: 'capsules', label: 'Capsules', tags: ['medicine', 'pills', 'medication'] },
1142
+ { name: 'prescription-bottle', label: 'Prescription', tags: ['medicine', 'pharmacy'] },
1143
+ { name: 'syringe', label: 'Syringe', tags: ['injection', 'medical', 'vaccine'] },
1144
+ { name: 'vial', label: 'Vial', tags: ['medicine', 'vaccine', 'medical'] },
1145
+ { name: 'bandage', label: 'Bandage', tags: ['first aid', 'wound', 'medical'] },
1146
+ { name: 'thermometer', label: 'Thermometer', tags: ['temperature', 'health', 'medical'] },
1147
+ { name: 'hospital', label: 'Hospital', tags: ['medical', 'healthcare', 'building'] },
1148
+ { name: 'hospital-user', label: 'Patient', tags: ['medical', 'healthcare', 'patient'] },
1149
+ { name: 'bed-pulse', label: 'Hospital Bed', tags: ['medical', 'patient', 'hospital'] },
1150
+ { name: 'wheelchair', label: 'Wheelchair', tags: ['accessibility', 'medical', 'disabled'] },
1151
+ { name: 'crutch', label: 'Crutch', tags: ['medical', 'injury', 'support'] },
1152
+ { name: 'smoking', label: 'Smoking', tags: ['cigarette', 'health', 'no-smoking'] },
1153
+ { name: 'smoking-ban', label: 'No Smoking', tags: ['prohibited', 'health'] },
1154
+ // Education & Learning
1155
+ { name: 'graduation-cap', label: 'Graduation', tags: ['education', 'degree', 'graduate'] },
1156
+ { name: 'user-graduate', label: 'Graduate', tags: ['student', 'education', 'degree'] },
1157
+ { name: 'chalkboard-user', label: 'Teacher', tags: ['education', 'teaching', 'classroom'] },
1158
+ { name: 'school', label: 'School', tags: ['education', 'building', 'learning'] },
1159
+ { name: 'book', label: 'Book', tags: ['reading', 'education', 'library'] },
1160
+ { name: 'book-open', label: 'Open Book', tags: ['reading', 'study', 'learn'] },
1161
+ { name: 'book-bookmark', label: 'Bookmark', tags: ['reading', 'save', 'mark'] },
1162
+ { name: 'books', label: 'Books', tags: ['reading', 'library', 'education'] },
1163
+ { name: 'bookmark', label: 'Bookmark', tags: ['save', 'mark', 'reading'] },
1164
+ { name: 'pen', label: 'Pen', tags: ['write', 'draw', 'writing'] },
1165
+ { name: 'pen-fancy', label: 'Fancy Pen', tags: ['write', 'signature'] },
1166
+ { name: 'pen-nib', label: 'Pen Nib', tags: ['write', 'calligraphy'] },
1167
+ { name: 'pencil', label: 'Pencil', tags: ['write', 'draw', 'edit'] },
1168
+ { name: 'highlighter', label: 'Highlighter', tags: ['mark', 'emphasize', 'note'] },
1169
+ { name: 'marker', label: 'Marker', tags: ['write', 'draw', 'mark'] },
1170
+ { name: 'eraser', label: 'Eraser', tags: ['delete', 'remove', 'erase'] },
1171
+ { name: 'ruler', label: 'Ruler', tags: ['measure', 'straight', 'tool'] },
1172
+ { name: 'ruler-combined', label: 'Rulers', tags: ['measure', 'geometry'] },
1173
+ { name: 'calculator', label: 'Calculator', tags: ['math', 'calculate', 'compute'] },
1174
+ { name: 'square-root-variable', label: 'Math', tags: ['mathematics', 'equation'] },
1175
+ { name: 'microscope', label: 'Microscope', tags: ['science', 'research', 'lab'] },
1176
+ { name: 'flask', label: 'Flask', tags: ['science', 'chemistry', 'lab'] },
1177
+ { name: 'atom', label: 'Atom', tags: ['science', 'physics', 'chemistry'] },
1178
+ { name: 'dna', label: 'DNA', tags: ['science', 'biology', 'genetics'] },
1179
+ { name: 'brain', label: 'Brain', tags: ['mind', 'think', 'intelligence'] },
1180
+ { name: 'certificate', label: 'Certificate', tags: ['award', 'achievement', 'diploma'] },
1181
+ { name: 'award', label: 'Award', tags: ['trophy', 'achievement', 'prize'] },
1182
+ { name: 'medal', label: 'Medal', tags: ['award', 'achievement', 'winner'] },
1183
+ { name: 'trophy', label: 'Trophy', tags: ['award', 'winner', 'achievement'] },
1184
+ // Food & Dining
1185
+ { name: 'utensils', label: 'Utensils', tags: ['food', 'dining', 'restaurant'] },
1186
+ { name: 'fork-knife', label: 'Fork Knife', tags: ['food', 'dining', 'restaurant'] },
1187
+ { name: 'plate-utensils', label: 'Plate', tags: ['food', 'dining', 'meal'] },
1188
+ { name: 'pizza-slice', label: 'Pizza', tags: ['food', 'slice', 'italian'] },
1189
+ { name: 'burger', label: 'Burger', tags: ['food', 'fast', 'hamburger'] },
1190
+ { name: 'hotdog', label: 'Hotdog', tags: ['food', 'fast'] },
1191
+ { name: 'drumstick-bite', label: 'Chicken', tags: ['food', 'meat', 'poultry'] },
1192
+ { name: 'ice-cream', label: 'Ice Cream', tags: ['dessert', 'sweet', 'frozen'] },
1193
+ { name: 'mug-hot', label: 'Hot Beverage', tags: ['drink', 'coffee', 'tea'] },
1194
+ { name: 'coffee', label: 'Coffee', tags: ['drink', 'beverage', 'cafe'] },
1195
+ { name: 'mug-saucer', label: 'Coffee Cup', tags: ['drink', 'coffee', 'tea'] },
1196
+ { name: 'glass-water', label: 'Water', tags: ['drink', 'beverage', 'glass'] },
1197
+ { name: 'wine-glass', label: 'Wine', tags: ['drink', 'alcohol', 'beverage'] },
1198
+ { name: 'champagne-glasses', label: 'Champagne', tags: ['celebrate', 'drink', 'toast'] },
1199
+ { name: 'martini-glass', label: 'Martini', tags: ['drink', 'alcohol', 'cocktail'] },
1200
+ { name: 'beer-mug-empty', label: 'Beer', tags: ['drink', 'alcohol', 'beverage'] },
1201
+ { name: 'cake', label: 'Cake', tags: ['dessert', 'sweet', 'birthday'] },
1202
+ { name: 'cake-candles', label: 'Birthday Cake', tags: ['birthday', 'celebration', 'party'] },
1203
+ { name: 'cookie', label: 'Cookie', tags: ['food', 'dessert', 'sweet'] },
1204
+ { name: 'candy-cane', label: 'Candy Cane', tags: ['candy', 'sweet', 'christmas'] },
1205
+ { name: 'apple-whole', label: 'Apple', tags: ['fruit', 'healthy', 'food'] },
1206
+ { name: 'lemon', label: 'Lemon', tags: ['fruit', 'citrus', 'food'] },
1207
+ { name: 'carrot', label: 'Carrot', tags: ['vegetable', 'healthy', 'food'] },
1208
+ { name: 'pepper-hot', label: 'Pepper', tags: ['spicy', 'food', 'hot'] },
1209
+ // Sports & Recreation
1210
+ { name: 'football', label: 'Football', tags: ['sport', 'soccer', 'game'] },
1211
+ { name: 'futbol', label: 'Soccer Ball', tags: ['sport', 'football', 'ball'] },
1212
+ { name: 'basketball', label: 'Basketball', tags: ['sport', 'ball', 'game'] },
1213
+ { name: 'baseball', label: 'Baseball', tags: ['sport', 'ball', 'game'] },
1214
+ { name: 'baseball-bat-ball', label: 'Baseball Bat', tags: ['sport', 'baseball'] },
1215
+ { name: 'volleyball', label: 'Volleyball', tags: ['sport', 'ball', 'game'] },
1216
+ { name: 'table-tennis-paddle-ball', label: 'Table Tennis', tags: ['sport', 'ping-pong'] },
1217
+ { name: 'golf-ball-tee', label: 'Golf', tags: ['sport', 'golf', 'game'] },
1218
+ { name: 'hockey-puck', label: 'Hockey', tags: ['sport', 'ice', 'game'] },
1219
+ { name: 'bowling-ball', label: 'Bowling', tags: ['sport', 'game', 'ball'] },
1220
+ { name: 'person-running', label: 'Running', tags: ['sport', 'exercise', 'fitness'] },
1221
+ { name: 'person-biking', label: 'Biking', tags: ['sport', 'exercise', 'cycling'] },
1222
+ { name: 'person-swimming', label: 'Swimming', tags: ['sport', 'water', 'exercise'] },
1223
+ { name: 'person-skiing', label: 'Skiing', tags: ['sport', 'winter', 'snow'] },
1224
+ { name: 'dumbbell', label: 'Dumbbell', tags: ['fitness', 'weight', 'gym'] },
1225
+ { name: 'weight-hanging', label: 'Weight', tags: ['fitness', 'gym', 'exercise'] },
1226
+ { name: 'heart', label: 'Heart', tags: ['health', 'fitness', 'cardio'] },
1227
+ { name: 'stopwatch-20', label: 'Timer', tags: ['time', 'sport', 'track'] },
1228
+ // Weather & Nature
1229
+ { name: 'sun', label: 'Sun', tags: ['weather', 'bright', 'sunny'] },
1230
+ { name: 'moon', label: 'Moon', tags: ['night', 'dark', 'lunar'] },
1231
+ { name: 'star', label: 'Star', tags: ['night', 'sky', 'favorite'] },
1232
+ { name: 'cloud', label: 'Cloud', tags: ['weather', 'sky', 'cloudy'] },
1233
+ { name: 'cloud-sun', label: 'Partly Cloudy', tags: ['weather', 'mixed'] },
1234
+ { name: 'cloud-moon', label: 'Cloudy Night', tags: ['weather', 'night'] },
1235
+ { name: 'cloud-rain', label: 'Rain', tags: ['weather', 'precipitation', 'rainy'] },
1236
+ { name: 'cloud-showers-heavy', label: 'Heavy Rain', tags: ['weather', 'storm', 'rain'] },
1237
+ { name: 'umbrella', label: 'Umbrella', tags: ['rain', 'weather', 'protection'] },
1238
+ { name: 'snowflake', label: 'Snow', tags: ['weather', 'cold', 'winter'] },
1239
+ { name: 'icicles', label: 'Icicles', tags: ['winter', 'cold', 'ice'] },
1240
+ { name: 'temperature-high', label: 'Hot', tags: ['weather', 'temperature', 'heat'] },
1241
+ { name: 'temperature-low', label: 'Cold', tags: ['weather', 'temperature', 'cool'] },
1242
+ { name: 'bolt', label: 'Lightning', tags: ['weather', 'storm', 'thunder'] },
1243
+ { name: 'bolt-lightning', label: 'Thunder', tags: ['weather', 'storm', 'lightning'] },
1244
+ { name: 'wind', label: 'Wind', tags: ['weather', 'breeze', 'air'] },
1245
+ { name: 'tornado', label: 'Tornado', tags: ['weather', 'storm', 'cyclone'] },
1246
+ { name: 'water', label: 'Water', tags: ['nature', 'liquid', 'sea'] },
1247
+ { name: 'droplet', label: 'Droplet', tags: ['water', 'liquid', 'drop'] },
1248
+ { name: 'fire', label: 'Fire', tags: ['hot', 'burn', 'flame'] },
1249
+ { name: 'fire-flame-curved', label: 'Flame', tags: ['fire', 'hot', 'burn'] },
1250
+ { name: 'tree', label: 'Tree', tags: ['nature', 'plant', 'forest'] },
1251
+ { name: 'seedling', label: 'Seedling', tags: ['plant', 'grow', 'nature'] },
1252
+ { name: 'leaf', label: 'Leaf', tags: ['nature', 'plant', 'green'] },
1253
+ { name: 'clover', label: 'Clover', tags: ['nature', 'plant', 'lucky'] },
1254
+ { name: 'flower', label: 'Flower', tags: ['nature', 'plant', 'blossom'] },
1255
+ { name: 'feather', label: 'Feather', tags: ['nature', 'bird', 'light'] },
1256
+ { name: 'mountain', label: 'Mountain', tags: ['nature', 'landscape', 'peak'] },
1257
+ // Shopping & Commerce
1258
+ { name: 'shopping-cart', label: 'Shopping Cart', tags: ['buy', 'purchase', 'shop'] },
1259
+ { name: 'cart-plus', label: 'Add to Cart', tags: ['shopping', 'add', 'buy'] },
1260
+ { name: 'cart-shopping', label: 'Cart', tags: ['shop', 'buy', 'store'] },
1261
+ { name: 'bag-shopping', label: 'Shopping Bag', tags: ['buy', 'store', 'retail'] },
1262
+ { name: 'basket-shopping', label: 'Basket', tags: ['shopping', 'buy', 'cart'] },
1263
+ { name: 'store', label: 'Store', tags: ['shop', 'retail', 'business'] },
1264
+ { name: 'shop', label: 'Shop', tags: ['store', 'retail', 'business'] },
1265
+ { name: 'cash-register', label: 'Cash Register', tags: ['payment', 'checkout', 'pos'] },
1266
+ { name: 'tags', label: 'Tags', tags: ['price', 'label', 'sale'] },
1267
+ { name: 'tag', label: 'Tag', tags: ['price', 'label', 'sale'] },
1268
+ { name: 'barcode', label: 'Barcode', tags: ['scan', 'product', 'price'] },
1269
+ { name: 'percent', label: 'Percent', tags: ['discount', 'sale', 'offer'] },
1270
+ { name: 'gift', label: 'Gift', tags: ['present', 'surprise', 'celebration'] },
1271
+ { name: 'gifts', label: 'Gifts', tags: ['presents', 'celebration'] },
1272
+ { name: 'box', label: 'Box', tags: ['package', 'container', 'shipping'] },
1273
+ { name: 'box-open', label: 'Open Box', tags: ['unpack', 'delivery', 'package'] },
1274
+ { name: 'boxes-stacked', label: 'Boxes', tags: ['inventory', 'storage', 'warehouse'] },
1275
+ // Security & Safety
1276
+ { name: 'eye', label: 'Eye', tags: ['view', 'watch', 'visible'] },
1277
+ { name: 'eye-slash', label: 'Hide', tags: ['hidden', 'invisible', 'password'] },
1278
+ { name: 'eye-low-vision', label: 'Low Vision', tags: ['accessibility', 'vision'] },
1279
+ { name: 'user-secret', label: 'Secret User', tags: ['anonymous', 'hidden', 'spy'] },
1280
+ { name: 'fingerprint', label: 'Fingerprint', tags: ['biometric', 'identity', 'security'] },
1281
+ { name: 'id-card', label: 'ID Card', tags: ['identity', 'badge', 'credential'] },
1282
+ { name: 'id-badge', label: 'Badge', tags: ['identity', 'credential', 'staff'] },
1283
+ { name: 'fire', label: 'Fire', tags: ['hot', 'burn', 'danger'] },
1284
+ { name: 'fire-extinguisher', label: 'Fire Extinguisher', tags: ['safety', 'emergency'] },
1285
+ { name: 'triangle-exclamation', label: 'Warning', tags: ['alert', 'caution', 'danger'] },
1286
+ { name: 'exclamation', label: 'Exclamation', tags: ['alert', 'important', 'warning'] },
1287
+ { name: 'circle-exclamation', label: 'Alert', tags: ['warning', 'important'] },
1288
+ { name: 'ban', label: 'Ban', tags: ['prohibited', 'forbidden', 'stop'] },
1289
+ { name: 'circle-radiation', label: 'Radiation', tags: ['danger', 'hazard', 'warning'] },
1290
+ { name: 'skull-crossbones', label: 'Danger', tags: ['hazard', 'poison', 'warning'] },
1291
+ { name: 'biohazard', label: 'Biohazard', tags: ['danger', 'hazard', 'warning'] },
1292
+ // Miscellaneous
1293
+ { name: 'circle', label: 'Circle', tags: ['shape', 'round', 'dot'] },
1294
+ { name: 'square', label: 'Square', tags: ['shape', 'box'] },
1295
+ { name: 'square-full', label: 'Full Square', tags: ['shape', 'filled'] },
1296
+ { name: 'circle-dot', label: 'Dot', tags: ['point', 'marker', 'bullet'] },
1297
+ { name: 'question', label: 'Question', tags: ['help', 'ask', 'faq'] },
1298
+ { name: 'circle-question', label: 'Help', tags: ['question', 'support', 'info'] },
1299
+ { name: 'circle-info', label: 'Info', tags: ['information', 'details', 'about'] },
1300
+ { name: 'info', label: 'Information', tags: ['info', 'details', 'help'] },
1301
+ { name: 'lightbulb', label: 'Lightbulb', tags: ['idea', 'bright', 'innovation'] },
1302
+ { name: 'bolt', label: 'Bolt', tags: ['lightning', 'fast', 'power'] },
1303
+ { name: 'wand-magic', label: 'Magic Wand', tags: ['magic', 'wizard', 'sparkle'] },
1304
+ { name: 'wand-magic-sparkles', label: 'Magic', tags: ['wizard', 'sparkle', 'enchant'] },
1305
+ { name: 'puzzle-piece', label: 'Puzzle', tags: ['piece', 'solve', 'game'] },
1306
+ { name: 'gamepad', label: 'Gamepad', tags: ['gaming', 'controller', 'play'] },
1307
+ { name: 'dice', label: 'Dice', tags: ['game', 'random', 'chance'] },
1308
+ { name: 'dice-d20', label: 'D20 Dice', tags: ['game', 'tabletop', 'rpg'] },
1309
+ { name: 'chess', label: 'Chess', tags: ['game', 'strategy', 'board'] },
1310
+ { name: 'spade', label: 'Spade', tags: ['cards', 'game', 'suit'] },
1311
+ { name: 'heart', label: 'Heart Card', tags: ['cards', 'game', 'suit'] },
1312
+ { name: 'diamond', label: 'Diamond', tags: ['cards', 'game', 'suit'] },
1313
+ { name: 'club', label: 'Club', tags: ['cards', 'game', 'suit'] },
1314
+ { name: 'palette', label: 'Palette', tags: ['color', 'art', 'paint'] },
1315
+ { name: 'brush', label: 'Brush', tags: ['paint', 'art', 'draw'] },
1316
+ { name: 'paintbrush', label: 'Paintbrush', tags: ['art', 'paint', 'draw'] },
1317
+ { name: 'scissors', label: 'Scissors', tags: ['cut', 'trim', 'tool'] },
1318
+ { name: 'crown', label: 'Crown', tags: ['king', 'royal', 'premium'] },
1319
+ { name: 'gem', label: 'Gem', tags: ['diamond', 'jewel', 'precious'] },
1320
+ { name: 'ring', label: 'Ring', tags: ['jewelry', 'wedding', 'engagement'] },
1321
+ { name: 'mug-hot', label: 'Hot Drink', tags: ['coffee', 'tea', 'beverage'] },
1322
+ { name: 'battery-full', label: 'Battery Full', tags: ['power', 'charge', 'energy'] },
1323
+ { name: 'battery-half', label: 'Battery Half', tags: ['power', 'charge'] },
1324
+ { name: 'battery-empty', label: 'Battery Empty', tags: ['power', 'low', 'charge'] },
1325
+ { name: 'plug', label: 'Plug', tags: ['power', 'electricity', 'connect'] },
1326
+ { name: 'magnet', label: 'Magnet', tags: ['attract', 'magnetic', 'pull'] },
1327
+ { name: 'compass-drafting', label: 'Drafting Compass', tags: ['geometry', 'draw', 'circle'] },
1328
+ { name: 'rotate', label: 'Rotate', tags: ['spin', 'turn', 'refresh'] },
1329
+ { name: 'infinity', label: 'Infinity', tags: ['unlimited', 'endless', 'loop'] },
1330
+ ];
1331
+ //#endregion
1332
+ //#region ---- Default Providers ----
1333
+ /**
1334
+ * Default icon provider that provides the base set of FontAwesome icons.
1335
+ */
1336
+ class AXPIconProviderDefault extends AXPIconProvider {
1337
+ async provide() {
1338
+ return DEFAULT_ICONS;
1339
+ }
1340
+ }
1341
+ /**
1342
+ * Default icon style provider that provides the base set of FontAwesome styles.
1343
+ */
1344
+ class AXPIconStyleProviderDefault extends AXPIconStyleProvider {
1345
+ async provide() {
1346
+ return DEFAULT_ICON_STYLES;
1347
+ }
1348
+ }
1349
+ //#endregion
1350
+
1351
+ //#region ---- Provider Functions ----
1352
+ /**
1353
+ * Provides the default icon provider to the application.
1354
+ * This should be registered in your app module or config.
1355
+ */
1356
+ function provideDefaultIconProvider() {
1357
+ return {
1358
+ provide: AXP_ICON_PROVIDER,
1359
+ useClass: AXPIconProviderDefault,
1360
+ multi: true,
1361
+ };
1362
+ }
1363
+ /**
1364
+ * Provides the default icon style provider to the application.
1365
+ * This should be registered in your app module or config.
1366
+ */
1367
+ function provideDefaultIconStyleProvider() {
1368
+ return {
1369
+ provide: AXP_ICON_STYLE_PROVIDER,
1370
+ useClass: AXPIconStyleProviderDefault,
1371
+ multi: true,
1372
+ };
1373
+ }
1374
+ /**
1375
+ * Provides both default icon and style providers to the application.
1376
+ * This is a convenience function that combines provideDefaultIconProvider() and provideDefaultIconStyleProvider().
1377
+ */
1378
+ function provideDefaultIconChooser() {
1379
+ return [provideDefaultIconProvider(), provideDefaultIconStyleProvider()];
1380
+ }
1381
+ /**
1382
+ * Provides a custom icon provider to the application.
1383
+ * This ADDS additional icons alongside the default icon set.
1384
+ *
1385
+ * @param providerClass - The custom icon provider class
1386
+ *
1387
+ * @example
1388
+ * ```typescript
1389
+ * class MyCustomIconProvider extends AXPIconProvider {
1390
+ * async provide(): Promise<AXPFontAwesomeIcon[]> {
1391
+ * return [
1392
+ * { name: 'custom-icon', label: 'Custom Icon' }
1393
+ * ];
1394
+ * }
1395
+ * }
1396
+ *
1397
+ * export const appConfig: ApplicationConfig = {
1398
+ * providers: [
1399
+ * provideCustomIconProvider(MyCustomIconProvider),
1400
+ * ]
1401
+ * };
1402
+ * ```
1403
+ */
1404
+ function provideCustomIconProvider(providerClass) {
1405
+ return {
1406
+ provide: AXP_ICON_PROVIDER,
1407
+ useClass: providerClass,
1408
+ multi: true,
1409
+ };
1410
+ }
1411
+ /**
1412
+ * Provides a custom icon style provider to the application.
1413
+ * This ADDS additional icon styles alongside the default styles.
1414
+ *
1415
+ * @param providerClass - The custom icon style provider class
1416
+ *
1417
+ * @example
1418
+ * ```typescript
1419
+ * class MyCustomIconStyleProvider extends AXPIconStyleProvider {
1420
+ * async provide(): Promise<AXPFontAwesomeIconStyle[]> {
1421
+ * return [
1422
+ * { name: 'fa-custom', label: 'Custom' }
1423
+ * ];
1424
+ * }
1425
+ * }
1426
+ *
1427
+ * export const appConfig: ApplicationConfig = {
1428
+ * providers: [
1429
+ * provideCustomIconStyleProvider(MyCustomIconStyleProvider),
1430
+ * ]
1431
+ * };
1432
+ * ```
1433
+ */
1434
+ function provideCustomIconStyleProvider(providerClass) {
1435
+ return {
1436
+ provide: AXP_ICON_STYLE_PROVIDER,
1437
+ useClass: providerClass,
1438
+ multi: true,
1439
+ };
1440
+ }
1441
+ //#endregion
1442
+
1443
+ class AXPFontSizeChooserWidgetComponent extends AXPValueWidgetComponent {
1444
+ constructor() {
1445
+ super(...arguments);
1446
+ this.sizes = signal(['small', 'medium', 'large', 'x-large'], ...(ngDevMode ? [{ debugName: "sizes" }] : /* istanbul ignore next */ []));
1447
+ this.selectedSize = signal(null, ...(ngDevMode ? [{ debugName: "selectedSize" }] : /* istanbul ignore next */ []));
1448
+ this.#eff = effect(() => {
1449
+ if (this.getValue()) {
1450
+ this.selectedSize.set(this.sizes().find((s) => s === this.getValue()) ?? this.sizes()[0]);
1451
+ }
1452
+ }, ...(ngDevMode ? [{ debugName: "#eff" }] : /* istanbul ignore next */ []));
1453
+ }
1454
+ #eff;
1455
+ onSizeClick(size) {
1456
+ this.setValue(size);
1457
+ }
1458
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFontSizeChooserWidgetComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1459
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPFontSizeChooserWidgetComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: `
1460
+ @for (size of sizes(); track size) {
1461
+ <div (click)="onSizeClick(size)" [style.font-size]="size" [class.--selected]="size === selectedSize()">
1462
+ <div>
1463
+ <span>{{ '@layout:terms.font-sizes.' + size | translate | async }}</span>
1464
+ </div>
1465
+ </div>
1466
+ }
1467
+ `, isInline: true, styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap;gap:.5rem}:host>div{display:flex;cursor:pointer;flex-direction:row;align-items:center;justify-content:space-between;gap:.5rem;border-radius:.5rem;padding:.5rem 1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}:host>div:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));border-color:rgb(var(--ax-sys-color-border-surface))}:host>div{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}:host>div:hover{background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}:host>div.--selected{background-color:rgb(var(--ax-sys-color-primary-lighter-surface));color:rgb(var(--ax-sys-color-on-primary-lighter-surface));border-color:rgb(var(--ax-sys-color-border-primary-lighter-surface))}:host>div>div{display:flex;align-items:center;justify-content:center}:host>div>div i{font-size:1.25rem;line-height:1.75rem}:host>div>span{font-size:.875rem;line-height:1.25rem;font-weight:600;line-height:1.625}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXSelectionCdkModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1468
+ }
1469
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFontSizeChooserWidgetComponent, decorators: [{
1470
+ type: Component,
1471
+ args: [{ template: `
1472
+ @for (size of sizes(); track size) {
1473
+ <div (click)="onSizeClick(size)" [style.font-size]="size" [class.--selected]="size === selectedSize()">
1474
+ <div>
1475
+ <span>{{ '@layout:terms.font-sizes.' + size | translate | async }}</span>
1476
+ </div>
1477
+ </div>
1478
+ }
1479
+ `, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, FormsModule, AXSelectionCdkModule, AXTranslationModule], styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap;gap:.5rem}:host>div{display:flex;cursor:pointer;flex-direction:row;align-items:center;justify-content:space-between;gap:.5rem;border-radius:.5rem;padding:.5rem 1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}:host>div:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));border-color:rgb(var(--ax-sys-color-border-surface))}:host>div{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}:host>div:hover{background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}:host>div.--selected{background-color:rgb(var(--ax-sys-color-primary-lighter-surface));color:rgb(var(--ax-sys-color-on-primary-lighter-surface));border-color:rgb(var(--ax-sys-color-border-primary-lighter-surface))}:host>div>div{display:flex;align-items:center;justify-content:center}:host>div>div i{font-size:1.25rem;line-height:1.75rem}:host>div>span{font-size:.875rem;line-height:1.25rem;font-weight:600;line-height:1.625}\n"] }]
1480
+ }] });
1481
+
1482
+ var fontSizeChooserWidget_component = /*#__PURE__*/Object.freeze({
1483
+ __proto__: null,
1484
+ AXPFontSizeChooserWidgetComponent: AXPFontSizeChooserWidgetComponent
1485
+ });
1486
+
1487
+ const AXPFontSizeChooserWidget = {
1488
+ name: "font-size-chooser",
1489
+ title: "Font Size Chooser",
1490
+ icon: "fa-light fa-text-size",
1491
+ type: 'editor',
1492
+ categories: AXP_WIDGETS_LAYOUT_CATEGORY,
1493
+ properties: [
1494
+ AXP_NAME_PROPERTY,
1495
+ AXP_DATA_PATH_PROPERTY,
1496
+ AXP_DISABLED_PROPERTY,
1497
+ ],
1498
+ components: {
1499
+ edit: {
1500
+ component: () => Promise.resolve().then(function () { return fontSizeChooserWidget_component; }).then((c) => c.AXPFontSizeChooserWidgetComponent),
1501
+ },
1502
+ }
1503
+ };
1504
+
1505
+ class AXPFontStyleChooserWidgetComponent extends AXPValueWidgetComponent {
1506
+ constructor() {
1507
+ super(...arguments);
1508
+ this.fonts = signal([
1509
+ { id: 'system-ui', title: 'Default' },
1510
+ { id: 'serif', title: 'Serif' },
1511
+ { id: 'sans-serif', title: 'Sans-serif' },
1512
+ { id: 'monospace', title: 'Monospace' },
1513
+ { id: 'arial', title: 'Arial' },
1514
+ { id: 'verdana', title: 'Verdana' },
1515
+ { id: 'tahoma', title: 'Tahoma' },
1516
+ { id: 'times-new-roman', title: 'Times New Roman' },
1517
+ { id: 'georgia', title: 'Georgia' },
1518
+ { id: 'helvetica', title: 'Helvetica' },
1519
+ { id: 'calibri', title: 'Calibri' },
1520
+ { id: 'cursive', title: 'Cursive' },
1521
+ { id: 'vazirmatn', title: 'Vazir وزیر' },
1522
+ ], ...(ngDevMode ? [{ debugName: "fonts" }] : /* istanbul ignore next */ []));
1523
+ this.selectedFont = signal(null, ...(ngDevMode ? [{ debugName: "selectedFont" }] : /* istanbul ignore next */ []));
1524
+ this.#eff = effect(() => {
1525
+ if (this.getValue()) {
1526
+ this.selectedFont.set(this.fonts().find((f) => f.id === this.getValue()) ?? this.fonts()[0]);
1527
+ }
1528
+ }, ...(ngDevMode ? [{ debugName: "#eff" }] : /* istanbul ignore next */ []));
1529
+ }
1530
+ #eff;
1531
+ onFontClick(font) {
1532
+ this.setValue(font.id);
1533
+ }
1534
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFontStyleChooserWidgetComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1535
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPFontStyleChooserWidgetComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: `
1536
+ @for (font of fonts(); track font.id) {
1537
+ <div
1538
+ (click)="onFontClick(font)"
1539
+ [class.--selected]="font.id === selectedFont()?.id"
1540
+ [style.font-family]="font.id"
1541
+ >
1542
+ <div>
1543
+ <span>{{ font.title }}</span>
1544
+ </div>
1545
+ </div>
1546
+ }
1547
+ `, isInline: true, styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap;gap:.5rem}:host>div{display:flex;cursor:pointer;flex-direction:row;align-items:center;justify-content:space-between;gap:.5rem;border-radius:.5rem;padding:.5rem 1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}:host>div:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));border-color:rgb(var(--ax-sys-color-border-surface))}:host>div{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}:host>div:hover{background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}:host>div.--selected{background-color:rgb(var(--ax-sys-color-primary-lighter-surface));color:rgb(var(--ax-sys-color-on-primary-lighter-surface));border-color:rgb(var(--ax-sys-color-border-primary-lighter-surface))}:host>div>div{display:flex;align-items:center;justify-content:center}:host>div>div i{font-size:1.25rem;line-height:1.75rem}:host>div>span{font-size:.875rem;line-height:1.25rem;font-weight:600;line-height:1.625}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXSelectionCdkModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1548
+ }
1549
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFontStyleChooserWidgetComponent, decorators: [{
1550
+ type: Component,
1551
+ args: [{ template: `
1552
+ @for (font of fonts(); track font.id) {
1553
+ <div
1554
+ (click)="onFontClick(font)"
1555
+ [class.--selected]="font.id === selectedFont()?.id"
1556
+ [style.font-family]="font.id"
1557
+ >
1558
+ <div>
1559
+ <span>{{ font.title }}</span>
1560
+ </div>
1561
+ </div>
1562
+ }
1563
+ `, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, AXSelectionCdkModule], styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap;gap:.5rem}:host>div{display:flex;cursor:pointer;flex-direction:row;align-items:center;justify-content:space-between;gap:.5rem;border-radius:.5rem;padding:.5rem 1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}:host>div:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));border-color:rgb(var(--ax-sys-color-border-surface))}:host>div{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}:host>div:hover{background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}:host>div.--selected{background-color:rgb(var(--ax-sys-color-primary-lighter-surface));color:rgb(var(--ax-sys-color-on-primary-lighter-surface));border-color:rgb(var(--ax-sys-color-border-primary-lighter-surface))}:host>div>div{display:flex;align-items:center;justify-content:center}:host>div>div i{font-size:1.25rem;line-height:1.75rem}:host>div>span{font-size:.875rem;line-height:1.25rem;font-weight:600;line-height:1.625}\n"] }]
1564
+ }] });
1565
+
1566
+ var fontStyleChooserWidget_component = /*#__PURE__*/Object.freeze({
1567
+ __proto__: null,
1568
+ AXPFontStyleChooserWidgetComponent: AXPFontStyleChooserWidgetComponent
1569
+ });
1570
+
1571
+ const AXPFontStyleChooserWidget = {
1572
+ name: "font-style-chooser",
1573
+ title: "Font Style Chooser",
1574
+ icon: "fa-light fa-font",
1575
+ type: 'editor',
1576
+ categories: AXP_WIDGETS_LAYOUT_CATEGORY,
1577
+ properties: [
1578
+ AXP_NAME_PROPERTY,
1579
+ AXP_DATA_PATH_PROPERTY,
1580
+ AXP_DISABLED_PROPERTY,
1581
+ ],
1582
+ components: {
1583
+ edit: {
1584
+ component: () => Promise.resolve().then(function () { return fontStyleChooserWidget_component; }).then((c) => c.AXPFontStyleChooserWidgetComponent),
1585
+ },
1586
+ }
1587
+ };
1588
+
1589
+ class AXPMenuOrientationChooserWidgetComponent extends AXPValueWidgetComponent {
1590
+ constructor() {
1591
+ super(...arguments);
1592
+ this.orientations = signal([
1593
+ { id: 'vertical', icon: 'fa-regular fa-square-ellipsis-vertical' },
1594
+ { id: 'horizontal', icon: 'fa-regular fa-square-ellipsis' },
1595
+ ], ...(ngDevMode ? [{ debugName: "orientations" }] : /* istanbul ignore next */ []));
1596
+ this.selectedOrientation = signal(null, ...(ngDevMode ? [{ debugName: "selectedOrientation" }] : /* istanbul ignore next */ []));
1597
+ this.#eff = effect(() => {
1598
+ if (this.getValue()) {
1599
+ this.selectedOrientation.set(this.orientations().find((o) => o.id === this.getValue()) ?? this.orientations()[0]);
1600
+ }
1601
+ }, ...(ngDevMode ? [{ debugName: "#eff" }] : /* istanbul ignore next */ []));
1602
+ }
1603
+ #eff;
1604
+ onOrientationClick(orientation) {
1605
+ this.setValue(orientation.id);
1606
+ }
1607
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPMenuOrientationChooserWidgetComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1608
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPMenuOrientationChooserWidgetComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: `
1609
+ @for (orientation of orientations(); track orientation.id) {
1610
+ <div (click)="onOrientationClick(orientation)" [class.--selected]="orientation.id === selectedOrientation()?.id">
1611
+ <div>
1612
+ <i [class]="orientation.icon"></i>
1613
+ </div>
1614
+ <span>{{ '@layout:terms.menu-modes.' + orientation.id | translate | async }}</span>
1615
+ </div>
1616
+ }
1617
+ `, isInline: true, styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap;gap:.5rem}:host>div{display:flex;cursor:pointer;flex-direction:row;align-items:center;justify-content:space-between;gap:.5rem;border-radius:.5rem;padding:.5rem 1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}:host>div:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));border-color:rgb(var(--ax-sys-color-border-surface))}:host>div{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}:host>div:hover{background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}:host>div.--selected{background-color:rgb(var(--ax-sys-color-primary-lighter-surface));color:rgb(var(--ax-sys-color-on-primary-lighter-surface));border-color:rgb(var(--ax-sys-color-border-primary-lighter-surface))}:host>div>div{display:flex;align-items:center;justify-content:center}:host>div>div i{font-size:1.25rem;line-height:1.75rem}:host>div>span{font-size:.875rem;line-height:1.25rem;font-weight:600;line-height:1.625}:host>div{padding-top:.25rem!important;padding-bottom:.25rem!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXSelectionCdkModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1618
+ }
1619
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPMenuOrientationChooserWidgetComponent, decorators: [{
1620
+ type: Component,
1621
+ args: [{ template: `
1622
+ @for (orientation of orientations(); track orientation.id) {
1623
+ <div (click)="onOrientationClick(orientation)" [class.--selected]="orientation.id === selectedOrientation()?.id">
1624
+ <div>
1625
+ <i [class]="orientation.icon"></i>
1626
+ </div>
1627
+ <span>{{ '@layout:terms.menu-modes.' + orientation.id | translate | async }}</span>
1628
+ </div>
1629
+ }
1630
+ `, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, FormsModule, AXSelectionCdkModule, AXTranslationModule], styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap;gap:.5rem}:host>div{display:flex;cursor:pointer;flex-direction:row;align-items:center;justify-content:space-between;gap:.5rem;border-radius:.5rem;padding:.5rem 1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}:host>div:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));border-color:rgb(var(--ax-sys-color-border-surface))}:host>div{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}:host>div:hover{background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}:host>div.--selected{background-color:rgb(var(--ax-sys-color-primary-lighter-surface));color:rgb(var(--ax-sys-color-on-primary-lighter-surface));border-color:rgb(var(--ax-sys-color-border-primary-lighter-surface))}:host>div>div{display:flex;align-items:center;justify-content:center}:host>div>div i{font-size:1.25rem;line-height:1.75rem}:host>div>span{font-size:.875rem;line-height:1.25rem;font-weight:600;line-height:1.625}:host>div{padding-top:.25rem!important;padding-bottom:.25rem!important}\n"] }]
1631
+ }] });
1632
+
1633
+ var menuOrientationChooserWidget_component = /*#__PURE__*/Object.freeze({
1634
+ __proto__: null,
1635
+ AXPMenuOrientationChooserWidgetComponent: AXPMenuOrientationChooserWidgetComponent
1636
+ });
1637
+
1638
+ const AXPMenuOrientationChooserWidget = {
1639
+ name: "menu-orientation-chooser",
1640
+ title: "Menu Orientation Chooser",
1641
+ icon: "fa-light fa-bars-staggered",
1642
+ type: 'editor',
1643
+ categories: AXP_WIDGETS_LAYOUT_CATEGORY,
1644
+ properties: [
1645
+ AXP_NAME_PROPERTY,
1646
+ AXP_DATA_PATH_PROPERTY,
1647
+ AXP_DISABLED_PROPERTY,
1648
+ ],
1649
+ components: {
1650
+ edit: {
1651
+ component: () => Promise.resolve().then(function () { return menuOrientationChooserWidget_component; }).then((c) => c.AXPMenuOrientationChooserWidgetComponent),
1652
+ },
1653
+ }
1654
+ };
1655
+
1656
+ class AXPColorProvider {
1657
+ }
1658
+ function titleCase(str) {
1659
+ return str.replace(/-/g, ' ').replace(/\w\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase());
1660
+ }
1661
+ function generateDefaultColors() {
1662
+ const colors = [];
1663
+ const styles = ['primary', 'secondary', 'success', 'warning', 'danger'];
1664
+ const variants = [
1665
+ 'lightest',
1666
+ 'lighter',
1667
+ 'light',
1668
+ 'surface',
1669
+ 'dark',
1670
+ 'darker',
1671
+ 'darkest',
1672
+ // ,'default'
1673
+ ];
1674
+ for (const style of styles) {
1675
+ for (const variant of variants) {
1676
+ let name;
1677
+ let colorClass;
1678
+ // if (variant === 'default') {
1679
+ // name = `${style}-${variant}`;
1680
+ // colorClass = `ax-text-${style}-${variant}`;
1681
+ // } else {
1682
+ name = `${style}-${variant}`;
1683
+ colorClass = `ax-text-${style}-on-${variant}`;
1684
+ // }
1685
+ colors.push({
1686
+ title: titleCase(variant === 'surface' ? style : titleCase(name)),
1687
+ name: name,
1688
+ color: colorClass,
1689
+ background: `ax-bg-${name}`,
1690
+ border: `ax-border-${name}`,
1691
+ });
1692
+ }
1693
+ }
1694
+ return colors;
1695
+ }
1696
+ const DEFAULT_COLORS = generateDefaultColors();
1697
+ class AXPColorProviderDefault extends AXPColorProvider {
1698
+ async provide() {
1699
+ return DEFAULT_COLORS;
1700
+ }
1701
+ }
1702
+ const AXP_COLOR_PROVIDER = new InjectionToken('AXP_COLOR_PROVIDER');
1703
+ class AXPColorChooserService {
1704
+ constructor() {
1705
+ this.defaultProvider = new AXPColorProviderDefault();
1706
+ this.providers = (() => {
1707
+ const injected = inject(AXP_COLOR_PROVIDER, { optional: true });
1708
+ if (!injected) {
1709
+ return [this.defaultProvider];
1710
+ }
1711
+ const providers = Array.isArray(injected) ? injected : [injected];
1712
+ return [...providers, this.defaultProvider];
1713
+ })();
1714
+ this.cache = null;
1715
+ }
1716
+ async getColors() {
1717
+ if (this.cache) {
1718
+ return this.cache;
1719
+ }
1720
+ const allColors = [];
1721
+ for (const resolver of this.providers) {
1722
+ const result = await resolver.provide();
1723
+ allColors.push(...result);
1724
+ }
1725
+ const uniqueColors = allColors.filter((color, index, self) => index === self.findIndex((c) => c.title === color.title));
1726
+ this.cache = uniqueColors;
1727
+ return uniqueColors;
1728
+ }
1729
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPColorChooserService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1730
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPColorChooserService, providedIn: 'root' }); }
1731
+ }
1732
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPColorChooserService, decorators: [{
1733
+ type: Injectable,
1734
+ args: [{
1735
+ providedIn: 'root',
1736
+ }]
1737
+ }] });
1738
+
1739
+ class AXPColorChooserWidgetEditComponent extends AXPValueWidgetComponent {
1740
+ constructor() {
1741
+ super(...arguments);
1742
+ this.colorService = inject(AXPColorChooserService);
1743
+ this.colors = signal([], ...(ngDevMode ? [{ debugName: "colors" }] : /* istanbul ignore next */ []));
1744
+ this.placeholder = computed(() => this.options()['placeholder'] ?? '', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
1745
+ this.selectedColor = computed(() => {
1746
+ const value = this.getValue();
1747
+ if (!value) {
1748
+ return this.colors()[0];
1749
+ }
1750
+ // If value is a string in the format: "ax-text-* ax-bg-* ax-border-*"
1751
+ if (typeof value === 'string') {
1752
+ const parsed = this.parseStringValue(value);
1753
+ if (parsed) {
1754
+ return parsed;
1755
+ }
1756
+ return this.colors()[0];
1757
+ }
1758
+ // Otherwise value is an object
1759
+ return value.name;
1760
+ }, ...(ngDevMode ? [{ debugName: "selectedColor" }] : /* istanbul ignore next */ []));
1761
+ }
1762
+ async ngOnInit() {
1763
+ const allColors = await this.colorService.getColors();
1764
+ this.colors.set(allColors);
1765
+ super.ngOnInit();
1766
+ }
1767
+ handleValueChange(event) {
1768
+ if (event.isUserInteraction) {
1769
+ if (!event.value) {
1770
+ this.setValue(undefined);
1771
+ return;
1772
+ }
1773
+ const color = event.component.selectedItems[0];
1774
+ // Always store as ordered string: "color background border"
1775
+ const stringValue = `${color.color} ${color.background} ${color.border}`;
1776
+ this.setValue(stringValue);
1777
+ }
1778
+ }
1779
+ parseStringValue(value) {
1780
+ const parts = value.trim().split(/\s+/);
1781
+ if (parts.length !== 3) {
1782
+ return null;
1783
+ }
1784
+ const [color, background, border] = parts;
1785
+ const match = this.colors().find((c) => c.color === color && c.background === background && c.border === border);
1786
+ return match?.name ?? null;
1787
+ }
1788
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPColorChooserWidgetEditComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1789
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: AXPColorChooserWidgetEditComponent, isStandalone: true, selector: "ax-color-chooser-widget", usesInheritance: true, ngImport: i0, template: `
1790
+ <ax-form [messageStyle]="'float'" [updateOn]="'change'">
1791
+ <ax-form-field>
1792
+ <ax-select-box
1793
+ [dataSource]="colors()"
1794
+ textField="title"
1795
+ valueField="name"
1796
+ [placeholder]="placeholder()"
1797
+ [itemTemplate]="customItemTemplate"
1798
+ [ngModel]="selectedColor()"
1799
+ (onValueChanged)="handleValueChange($event)"
1800
+ [selectedTemplate]="customItemTemplate"
1801
+ >
1802
+ <ng-template #customItemTemplate let-item>
1803
+ <div class="ax-flex ax-items-center ax-gap-2 ax-p-2">
1804
+ <div
1805
+ class="ax-w-6 ax-h-6 ax-rounded ax-flex ax-items-center ax-justify-center ax-border ax-border-dashed ax-border-black dark:ax-border-white"
1806
+ [ngClass]="item.data.background"
1807
+ >
1808
+ <span [ngClass]="item.data.color">Aa</span>
1809
+ </div>
1810
+ <span>{{ item.data.title }}</span>
1811
+ </div>
1812
+ </ng-template>
1813
+ <ax-search-box look="fill"></ax-search-box>
1814
+ <ax-validation-rule message="field can't be empty" rule="required"></ax-validation-rule>
1815
+ </ax-select-box>
1816
+ </ax-form-field>
1817
+ </ax-form>
1818
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i1$2.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2$2.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "component", type: i2$2.AXFormComponent, selector: "ax-form", inputs: ["disabled", "readonly", "labelMode", "look", "messageStyle", "updateOn", "inUserInteractionActive"], outputs: ["onValidate", "updateOnChange"] }, { kind: "directive", type: i2$2.AXValidationRuleDirective, selector: "ax-validation-rule", inputs: ["rule", "options", "message", "disabled"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i1$1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1819
+ }
1820
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPColorChooserWidgetEditComponent, decorators: [{
1821
+ type: Component,
1822
+ args: [{
1823
+ selector: 'ax-color-chooser-widget',
1824
+ template: `
1825
+ <ax-form [messageStyle]="'float'" [updateOn]="'change'">
1826
+ <ax-form-field>
1827
+ <ax-select-box
1828
+ [dataSource]="colors()"
1829
+ textField="title"
1830
+ valueField="name"
1831
+ [placeholder]="placeholder()"
1832
+ [itemTemplate]="customItemTemplate"
1833
+ [ngModel]="selectedColor()"
1834
+ (onValueChanged)="handleValueChange($event)"
1835
+ [selectedTemplate]="customItemTemplate"
1836
+ >
1837
+ <ng-template #customItemTemplate let-item>
1838
+ <div class="ax-flex ax-items-center ax-gap-2 ax-p-2">
1839
+ <div
1840
+ class="ax-w-6 ax-h-6 ax-rounded ax-flex ax-items-center ax-justify-center ax-border ax-border-dashed ax-border-black dark:ax-border-white"
1841
+ [ngClass]="item.data.background"
1842
+ >
1843
+ <span [ngClass]="item.data.color">Aa</span>
1844
+ </div>
1845
+ <span>{{ item.data.title }}</span>
1846
+ </div>
1847
+ </ng-template>
1848
+ <ax-search-box look="fill"></ax-search-box>
1849
+ <ax-validation-rule message="field can't be empty" rule="required"></ax-validation-rule>
1850
+ </ax-select-box>
1851
+ </ax-form-field>
1852
+ </ax-form>
1853
+ `,
1854
+ imports: [AXSelectBoxModule, AXFormModule, CommonModule, AXSearchBoxModule, AXButtonModule, FormsModule],
1855
+ changeDetection: ChangeDetectionStrategy.OnPush,
1856
+ }]
1857
+ }] });
1858
+
1859
+ var themeColorChooserEdit_component = /*#__PURE__*/Object.freeze({
1860
+ __proto__: null,
1861
+ AXPColorChooserWidgetEditComponent: AXPColorChooserWidgetEditComponent
1862
+ });
1863
+
1864
+ const AXPThemeColorChooserWidgetConfig = {
1865
+ name: 'theme-color-chooser',
1866
+ title: 'Theme Color Chooser',
1867
+ icon: 'fa-solid fa-palette',
1868
+ type: 'editor',
1869
+ categories: AXP_WIDGETS_LAYOUT_CATEGORY,
1870
+ properties: [AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_DISABLED_PROPERTY],
1871
+ components: {
1872
+ edit: {
1873
+ component: () => Promise.resolve().then(function () { return themeColorChooserEdit_component; }).then((c) => c.AXPColorChooserWidgetEditComponent),
1874
+ },
1875
+ column: {
1876
+ component: () => import('./acorex-platform-themes-shared-theme-color-chooser-column.component-CHfrTtol.mjs').then((c) => c.AXPColorChooserWidgetColumnComponent),
1877
+ },
1878
+ view: {
1879
+ component: () => import('./acorex-platform-themes-shared-theme-color-chooser-view.component-BSmvnUVq.mjs').then((c) => c.AXPColorChooserWidgetViewComponent),
1880
+ },
1881
+ },
1882
+ };
1883
+
1884
+ class AXPThemeModeChooserWidgetComponent extends AXPValueWidgetComponent {
1885
+ constructor() {
1886
+ super(...arguments);
1887
+ this.modes = signal([
1888
+ { id: AXPThemeMode.Light, icon: 'fa-light fa-brightness' },
1889
+ { id: AXPThemeMode.Dark, icon: 'fa-light fa-moon' },
1890
+ { id: AXPThemeMode.System, icon: 'fa-light fa-desktop' },
1891
+ ], ...(ngDevMode ? [{ debugName: "modes" }] : /* istanbul ignore next */ []));
1892
+ this.selectedMode = signal(null, ...(ngDevMode ? [{ debugName: "selectedMode" }] : /* istanbul ignore next */ []));
1893
+ this.#eff = effect(() => {
1894
+ if (this.getValue()) {
1895
+ this.selectedMode.set(this.modes().find((m) => m.id === this.getValue()) ?? this.modes()[0]);
1896
+ }
1897
+ }, ...(ngDevMode ? [{ debugName: "#eff" }] : /* istanbul ignore next */ []));
1898
+ }
1899
+ #eff;
1900
+ onModeClick(mode) {
1901
+ this.setValue(mode.id);
1902
+ }
1903
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPThemeModeChooserWidgetComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1904
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPThemeModeChooserWidgetComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: `
1905
+ @for (mode of modes(); track mode.id) {
1906
+ <div (click)="onModeClick(mode)" [class.--selected]="mode.id === selectedMode()?.id">
1907
+ <div>
1908
+ <i [class]="mode.icon"></i>
1909
+ </div>
1910
+ <span>{{ '@layout:terms.theme-modes.' + mode.id | translate | async }}</span>
1911
+ </div>
1912
+ }
1913
+ `, isInline: true, styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap;gap:.5rem}:host>div{display:flex;cursor:pointer;flex-direction:row;align-items:center;justify-content:space-between;gap:.5rem;border-radius:.5rem;padding:.5rem 1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}:host>div:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));border-color:rgb(var(--ax-sys-color-border-surface))}:host>div{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}:host>div:hover{background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}:host>div.--selected{background-color:rgb(var(--ax-sys-color-primary-lighter-surface));color:rgb(var(--ax-sys-color-on-primary-lighter-surface));border-color:rgb(var(--ax-sys-color-border-primary-lighter-surface))}:host>div>div{display:flex;align-items:center;justify-content:center}:host>div>div i{font-size:1.25rem;line-height:1.75rem}:host>div>span{font-size:.875rem;line-height:1.25rem;font-weight:600;line-height:1.625}:host>div{padding-top:.25rem!important;padding-bottom:.25rem!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXSelectionCdkModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1914
+ }
1915
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPThemeModeChooserWidgetComponent, decorators: [{
1916
+ type: Component,
1917
+ args: [{ template: `
1918
+ @for (mode of modes(); track mode.id) {
1919
+ <div (click)="onModeClick(mode)" [class.--selected]="mode.id === selectedMode()?.id">
1920
+ <div>
1921
+ <i [class]="mode.icon"></i>
1922
+ </div>
1923
+ <span>{{ '@layout:terms.theme-modes.' + mode.id | translate | async }}</span>
1924
+ </div>
1925
+ }
1926
+ `, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, FormsModule, AXSelectionCdkModule, AXTranslationModule], styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap;gap:.5rem}:host>div{display:flex;cursor:pointer;flex-direction:row;align-items:center;justify-content:space-between;gap:.5rem;border-radius:.5rem;padding:.5rem 1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}:host>div:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));border-color:rgb(var(--ax-sys-color-border-surface))}:host>div{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}:host>div:hover{background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}:host>div.--selected{background-color:rgb(var(--ax-sys-color-primary-lighter-surface));color:rgb(var(--ax-sys-color-on-primary-lighter-surface));border-color:rgb(var(--ax-sys-color-border-primary-lighter-surface))}:host>div>div{display:flex;align-items:center;justify-content:center}:host>div>div i{font-size:1.25rem;line-height:1.75rem}:host>div>span{font-size:.875rem;line-height:1.25rem;font-weight:600;line-height:1.625}:host>div{padding-top:.25rem!important;padding-bottom:.25rem!important}\n"] }]
1927
+ }] });
1928
+
1929
+ var themeModeChooserWidget_component = /*#__PURE__*/Object.freeze({
1930
+ __proto__: null,
1931
+ AXPThemeModeChooserWidgetComponent: AXPThemeModeChooserWidgetComponent
1932
+ });
1933
+
1934
+ const AXPThemeModeChooserWidget = {
1935
+ name: "theme-mode-chooser",
1936
+ title: "Theme Mode Chooser",
1937
+ icon: "fa-solid fa-square",
1938
+ type: 'editor',
1939
+ categories: AXP_WIDGETS_LAYOUT_CATEGORY,
1940
+ properties: [
1941
+ AXP_NAME_PROPERTY,
1942
+ AXP_DATA_PATH_PROPERTY,
1943
+ AXP_DISABLED_PROPERTY,
1944
+ ],
1945
+ components: {
1946
+ edit: {
1947
+ component: () => Promise.resolve().then(function () { return themeModeChooserWidget_component; }).then((c) => c.AXPThemeModeChooserWidgetComponent),
1948
+ },
1949
+ }
1950
+ };
1951
+
1952
+ class AXPThemePaletteChooserWidgetComponent extends AXPValueWidgetComponent {
1953
+ constructor() {
1954
+ super(...arguments);
1955
+ this.paletteService = inject(AXP_THEME_PALETTE_PROVIDER);
1956
+ this.palettes = signal([], ...(ngDevMode ? [{ debugName: "palettes" }] : /* istanbul ignore next */ []));
1957
+ this.selectedPalette = signal(null, ...(ngDevMode ? [{ debugName: "selectedPalette" }] : /* istanbul ignore next */ []));
1958
+ this.#eff = effect(() => {
1959
+ if (this.getValue()) {
1960
+ this.selectedPalette.set(this.palettes().find((p) => p.name === this.getValue()) ??
1961
+ this.palettes().find((p) => p.name === 'default') ??
1962
+ this.palettes()[0]);
1963
+ }
1964
+ }, ...(ngDevMode ? [{ debugName: "#eff" }] : /* istanbul ignore next */ []));
1965
+ }
1966
+ #eff;
1967
+ async ngOnInit() {
1968
+ super.ngOnInit();
1969
+ const palletsProviderInstance = await this.paletteService;
1970
+ this.palettes.set(await palletsProviderInstance.getList());
1971
+ }
1972
+ onPaletteClick(palette) {
1973
+ this.setValue(palette.name);
1974
+ }
1975
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPThemePaletteChooserWidgetComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1976
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPThemePaletteChooserWidgetComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: `
1977
+ @for (palette of palettes(); track palette.name) {
1978
+ <div (click)="onPaletteClick(palette)" [class.--selected]="palette.name === selectedPalette()?.name">
1979
+ <span>{{ palette.title }}</span>
1980
+ <div>
1981
+ <div [style.background-color]="palette.colors.primary" class="ax-end-7 ax-z-[2]"></div>
1982
+ <div [style.background-color]="palette.colors.secondary" class="ax-end-3.5 ax-z-[1]"></div>
1983
+ <div [style.background-color]="palette.colors.accents[0]" class="ax-end-0 ax-z-0"></div>
1984
+ </div>
1985
+ </div>
1986
+ }
1987
+ `, isInline: true, styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap;gap:.5rem}:host>div{display:flex;cursor:pointer;flex-direction:row;align-items:center;justify-content:space-between;gap:.5rem;border-radius:.5rem;padding:.5rem 1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}:host>div:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));border-color:rgb(var(--ax-sys-color-border-surface))}:host>div{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}:host>div:hover{background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}:host>div.--selected{background-color:rgb(var(--ax-sys-color-primary-lighter-surface));color:rgb(var(--ax-sys-color-on-primary-lighter-surface));border-color:rgb(var(--ax-sys-color-border-primary-lighter-surface))}:host>div>div{display:flex;align-items:center;justify-content:center}:host>div>div i{font-size:1.25rem;line-height:1.75rem}:host>div>span{font-size:.875rem;line-height:1.25rem;font-weight:600;line-height:1.625}:host>div{height:3rem;min-width:100%}@media(min-width:768px){:host>div{min-width:16rem}}:host>div>div{position:relative;height:100%;width:fit-content}:host>div>div div{position:absolute;height:2rem;width:2rem;border-radius:9999px;border-width:1px;border-color:#ffffff80;--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXSelectionCdkModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1988
+ }
1989
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPThemePaletteChooserWidgetComponent, decorators: [{
1990
+ type: Component,
1991
+ args: [{ template: `
1992
+ @for (palette of palettes(); track palette.name) {
1993
+ <div (click)="onPaletteClick(palette)" [class.--selected]="palette.name === selectedPalette()?.name">
1994
+ <span>{{ palette.title }}</span>
1995
+ <div>
1996
+ <div [style.background-color]="palette.colors.primary" class="ax-end-7 ax-z-[2]"></div>
1997
+ <div [style.background-color]="palette.colors.secondary" class="ax-end-3.5 ax-z-[1]"></div>
1998
+ <div [style.background-color]="palette.colors.accents[0]" class="ax-end-0 ax-z-0"></div>
1999
+ </div>
2000
+ </div>
2001
+ }
2002
+ `, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, AXSelectionCdkModule], styles: [":host{display:flex;flex-direction:row;flex-wrap:wrap;gap:.5rem}:host>div{display:flex;cursor:pointer;flex-direction:row;align-items:center;justify-content:space-between;gap:.5rem;border-radius:.5rem;padding:.5rem 1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}:host>div:is(.ax-dark *){background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));border-color:rgb(var(--ax-sys-color-border-surface))}:host>div{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}:host>div:hover{background-color:rgb(var(--ax-sys-color-dark-surface));color:rgb(var(--ax-sys-color-on-dark-surface));border-color:rgb(var(--ax-sys-color-border-dark-surface))}:host>div.--selected{background-color:rgb(var(--ax-sys-color-primary-lighter-surface));color:rgb(var(--ax-sys-color-on-primary-lighter-surface));border-color:rgb(var(--ax-sys-color-border-primary-lighter-surface))}:host>div>div{display:flex;align-items:center;justify-content:center}:host>div>div i{font-size:1.25rem;line-height:1.75rem}:host>div>span{font-size:.875rem;line-height:1.25rem;font-weight:600;line-height:1.625}:host>div{height:3rem;min-width:100%}@media(min-width:768px){:host>div{min-width:16rem}}:host>div>div{position:relative;height:100%;width:fit-content}:host>div>div div{position:absolute;height:2rem;width:2rem;border-radius:9999px;border-width:1px;border-color:#ffffff80;--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}\n"] }]
2003
+ }] });
2004
+
2005
+ var themePaletteChooserWidget_component = /*#__PURE__*/Object.freeze({
2006
+ __proto__: null,
2007
+ AXPThemePaletteChooserWidgetComponent: AXPThemePaletteChooserWidgetComponent
2008
+ });
2009
+
2010
+ const AXPThemePaletteChooserWidget = {
2011
+ name: "theme-palette-chooser",
2012
+ title: "Theme Palette Chooser",
2013
+ icon: "fa-solid fa-square",
2014
+ type: 'editor',
2015
+ categories: AXP_WIDGETS_LAYOUT_CATEGORY,
2016
+ properties: [
2017
+ AXP_NAME_PROPERTY,
2018
+ AXP_DATA_PATH_PROPERTY,
2019
+ AXP_DISABLED_PROPERTY,
2020
+ ],
2021
+ components: {
2022
+ edit: {
2023
+ component: () => Promise.resolve().then(function () { return themePaletteChooserWidget_component; }).then((c) => c.AXPThemePaletteChooserWidgetComponent),
2024
+ },
2025
+ }
2026
+ };
2027
+
2028
+ //#endregion
2029
+ //#region ---- Theme Widgets Provider ----
2030
+ const WIDGETS = [
2031
+ AXPThemePaletteChooserWidget,
2032
+ AXPThemeModeChooserWidget,
2033
+ AXPMenuOrientationChooserWidget,
2034
+ AXPFontSizeChooserWidget,
2035
+ AXPFontStyleChooserWidget,
2036
+ AXPIconChooserWidget,
2037
+ AXPThemeColorChooserWidgetConfig,
2038
+ ];
2039
+ class AXPThemesSharedWidgetsProvider {
2040
+ getWidgets() {
2041
+ return WIDGETS;
2042
+ }
2043
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPThemesSharedWidgetsProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2044
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPThemesSharedWidgetsProvider }); }
2045
+ }
2046
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPThemesSharedWidgetsProvider, decorators: [{
2047
+ type: Injectable
2048
+ }] });
2049
+
2050
+ class AXPThemesSharedModule {
2051
+ constructor(appInitService, injector) {
2052
+ const service = injector.get(AXPLayoutThemeService);
2053
+ appInitService.registerTask({
2054
+ name: 'layout-theme',
2055
+ statusText: 'Applying layout theme settings ...',
2056
+ priority: 100,
2057
+ run: async () => {
2058
+ await service.loadSettings();
2059
+ },
2060
+ });
2061
+ }
2062
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPThemesSharedModule, deps: [{ token: i1$3.AXPAppStartUpService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.NgModule }); }
2063
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: AXPThemesSharedModule, imports: [i1$3.AXPComponentSlotModule, AXPWidgetCoreModule] }); }
2064
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPThemesSharedModule, providers: [
2065
+ { provide: AXP_WIDGET_DEFINITION_PROVIDER, useClass: AXPThemesSharedWidgetsProvider, multi: true },
2066
+ {
2067
+ provide: AXP_SETTING_DEFINITION_PROVIDER,
2068
+ useFactory: async () => {
2069
+ const injector = inject(Injector);
2070
+ const provider = (await import('./acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs')).AXPThemeSettingProvider;
2071
+ return new provider(injector);
2072
+ },
2073
+ multi: true,
2074
+ },
2075
+ ...provideDefaultIconChooser(),
2076
+ ], imports: [AXPComponentSlotModule.forRoot({
2077
+ 'root-header-end': [
2078
+ {
2079
+ priority: 50,
2080
+ name: 'theme',
2081
+ component: AXPThemeSlotComponent,
2082
+ },
2083
+ ],
2084
+ }),
2085
+ AXPWidgetCoreModule] }); }
2086
+ }
2087
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPThemesSharedModule, decorators: [{
2088
+ type: NgModule,
2089
+ args: [{
2090
+ imports: [
2091
+ AXPComponentSlotModule.forRoot({
2092
+ 'root-header-end': [
2093
+ {
2094
+ priority: 50,
2095
+ name: 'theme',
2096
+ component: AXPThemeSlotComponent,
2097
+ },
2098
+ ],
2099
+ }),
2100
+ AXPWidgetCoreModule,
2101
+ ],
2102
+ exports: [],
2103
+ declarations: [],
2104
+ providers: [
2105
+ { provide: AXP_WIDGET_DEFINITION_PROVIDER, useClass: AXPThemesSharedWidgetsProvider, multi: true },
2106
+ {
2107
+ provide: AXP_SETTING_DEFINITION_PROVIDER,
2108
+ useFactory: async () => {
2109
+ const injector = inject(Injector);
2110
+ const provider = (await import('./acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs')).AXPThemeSettingProvider;
2111
+ return new provider(injector);
2112
+ },
2113
+ multi: true,
2114
+ },
2115
+ ...provideDefaultIconChooser(),
2116
+ ],
2117
+ }]
2118
+ }], ctorParameters: () => [{ type: i1$3.AXPAppStartUpService }, { type: i0.Injector }] });
2119
+
2120
+ /**
2121
+ * Generated bundle index. Do not edit.
2122
+ */
2123
+
2124
+ export { AXPLayoutThemeService, AXPMenuOrientation, AXPSideMenuState, AXPThemeLayoutSetting, AXPThemeMode, AXPThemePaletteProviderDefault, AXPThemeSlotComponent, AXPThemesSharedModule, AXP_THEME_PALETTE_PROVIDER };
2125
+ //# sourceMappingURL=acorex-platform-themes-shared.mjs.map