cloud-ide-layout 1.0.337 → 1.0.339

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 (24) hide show
  1. package/fesm2022/{cloud-ide-layout-api-endpoint-manager.component-CabJGesJ.mjs → cloud-ide-layout-api-endpoint-manager.component-b1M-QRv0.mjs} +2 -2
  2. package/fesm2022/{cloud-ide-layout-api-endpoint-manager.component-CabJGesJ.mjs.map → cloud-ide-layout-api-endpoint-manager.component-b1M-QRv0.mjs.map} +1 -1
  3. package/fesm2022/cloud-ide-layout-cide-lyt-drawer-base.class-fqh3uHtY.mjs +41 -0
  4. package/fesm2022/cloud-ide-layout-cide-lyt-drawer-base.class-fqh3uHtY.mjs.map +1 -0
  5. package/fesm2022/{cloud-ide-layout-cloud-ide-layout-CiGurNgW.mjs → cloud-ide-layout-cloud-ide-layout-BNs30VIP.mjs} +28 -25
  6. package/fesm2022/cloud-ide-layout-cloud-ide-layout-BNs30VIP.mjs.map +1 -0
  7. package/fesm2022/{cloud-ide-layout-dashboard-manager.component-BfA8oY0m.mjs → cloud-ide-layout-dashboard-manager.component-B92CXNIp.mjs} +2 -2
  8. package/fesm2022/{cloud-ide-layout-dashboard-manager.component-BfA8oY0m.mjs.map → cloud-ide-layout-dashboard-manager.component-B92CXNIp.mjs.map} +1 -1
  9. package/fesm2022/cloud-ide-layout-drawer-docs.component-dMNtwaEn.mjs +43 -0
  10. package/fesm2022/cloud-ide-layout-drawer-docs.component-dMNtwaEn.mjs.map +1 -0
  11. package/fesm2022/cloud-ide-layout-drawer-theme.component-Cx5KfJ8Y.mjs +346 -0
  12. package/fesm2022/cloud-ide-layout-drawer-theme.component-Cx5KfJ8Y.mjs.map +1 -0
  13. package/fesm2022/{cloud-ide-layout-home-wrapper.component-B-ZvfHeg.mjs → cloud-ide-layout-home-wrapper.component-C-uiRwZ_.mjs} +2 -2
  14. package/fesm2022/{cloud-ide-layout-home-wrapper.component-B-ZvfHeg.mjs.map → cloud-ide-layout-home-wrapper.component-C-uiRwZ_.mjs.map} +1 -1
  15. package/fesm2022/cloud-ide-layout-sidedrawer-notes.component-BgmT99VO.mjs +226 -0
  16. package/fesm2022/cloud-ide-layout-sidedrawer-notes.component-BgmT99VO.mjs.map +1 -0
  17. package/fesm2022/cloud-ide-layout.mjs +1 -1
  18. package/index.d.ts +2 -0
  19. package/package.json +1 -1
  20. package/fesm2022/cloud-ide-layout-cloud-ide-layout-CiGurNgW.mjs.map +0 -1
  21. package/fesm2022/cloud-ide-layout-drawer-theme.component-NKRNKJw5.mjs +0 -346
  22. package/fesm2022/cloud-ide-layout-drawer-theme.component-NKRNKJw5.mjs.map +0 -1
  23. package/fesm2022/cloud-ide-layout-sidedrawer-notes.component-DEhojtjd.mjs +0 -256
  24. package/fesm2022/cloud-ide-layout-sidedrawer-notes.component-DEhojtjd.mjs.map +0 -1
@@ -1,346 +0,0 @@
1
- import { NgFor, NgIf, NgClass } from '@angular/common';
2
- import * as i0 from '@angular/core';
3
- import { inject, PLATFORM_ID, Inject, Component } from '@angular/core';
4
- import * as i2 from '@angular/forms';
5
- import { FormsModule } from '@angular/forms';
6
- import { CideSelectComponent, CideEleButtonComponent } from 'cloud-ide-element';
7
- import { A as AppStateHelperService, s as setCSSVariable, c as CideLytThemeService } from './cloud-ide-layout-cloud-ide-layout-CiGurNgW.mjs';
8
- import { cloneDeep, isEqual } from 'lodash-es';
9
-
10
- class CideLytDrawerThemeComponent {
11
- themeService;
12
- platformId;
13
- appState = inject(AppStateHelperService);
14
- // Preset themes
15
- presetThemes = [];
16
- selectedTheme = '';
17
- isLoadingThemes = false;
18
- themeLoadError = '';
19
- mergedTheme = {};
20
- isRTL = false;
21
- originalThemeGroupValues = [];
22
- originalApiThemeValues = {}; // Store original API values
23
- themeGroups = [
24
- {
25
- label: 'Brand Colors',
26
- items: [
27
- { label: 'Primary', varName: '--cide-theme-color-brand-primary', value: '#4f46e5', type: 'text' },
28
- { label: 'Accent', varName: '--cide-theme-color-brand-accent', value: '#4338ca', type: 'text' },
29
- { label: 'Separator', varName: '--cide-theme-color-brand-separator', value: '#e5e7eb', type: 'text' }
30
- ]
31
- },
32
- {
33
- label: 'Text Colors',
34
- items: [
35
- { label: 'Body Text', varName: '--cide-theme-color-text-body', value: '#374151', type: 'text' },
36
- { label: 'Heading Text', varName: '--cide-theme-color-text-heading', value: '#111827', type: 'text' },
37
- { label: 'Link Text', varName: '--cide-theme-color-text-link', value: '#3b82f6', type: 'text' },
38
- { label: 'Muted Text', varName: '--cide-theme-color-text-muted', value: '#6b7280', type: 'text' }
39
- ]
40
- },
41
- {
42
- label: 'Background Colors',
43
- items: [
44
- { label: 'Body Background', varName: '--cide-theme-color-background-body', value: '#ffffff', type: 'text' }
45
- ]
46
- },
47
- {
48
- label: 'Layout Dimensions',
49
- items: [
50
- { label: 'Stack Wrapper Width', varName: '--cide-lyt-stack-wrapper-width', value: '60', type: 'number', min: 20, max: 120 }
51
- ]
52
- },
53
- {
54
- label: 'Responsive Scale',
55
- items: [
56
- { label: 'Font Scale', varName: '--cide-lyt-font-responsive-scale-base', value: '1.0', type: 'number', min: 0.5, max: 2.0, step: 0.01 }
57
- ]
58
- },
59
- {
60
- label: 'Line Heights',
61
- items: [
62
- { label: 'Body Line Height', varName: '--cide-theme-line-height-body', value: '1.6', type: 'number', min: 1, max: 3 },
63
- { label: 'Heading Line Height', varName: '--cide-theme-line-height-heading', value: '1.2', type: 'number', min: 1, max: 3 }
64
- ]
65
- }
66
- ];
67
- constructor(themeService, platformId) {
68
- this.themeService = themeService;
69
- this.platformId = platformId;
70
- }
71
- ngOnInit() {
72
- // Modern Angular v20 pattern: Use Signals directly
73
- this.selectedTheme = this.themeService.selectedTheme();
74
- // fetch the system themes list
75
- this.isLoadingThemes = true;
76
- this.themeService.fetchSystemThemesList().subscribe({
77
- next: (res) => {
78
- const themes = res?.data?.core_system_themes || [];
79
- this.presetThemes = themes.map((theme) => ({
80
- value: theme._id || '',
81
- label: theme.syth_theme_name || theme.syth_theme_id || '',
82
- theme
83
- }));
84
- this.isLoadingThemes = false;
85
- // If user has no theme set, select and apply the default theme
86
- if (!this.selectedTheme) {
87
- const defaultTheme = this.presetThemes.find(t => t.theme.syth_is_default);
88
- if (defaultTheme) {
89
- this.selectedTheme = defaultTheme.value;
90
- // Apply the default theme as CSS variables
91
- if (defaultTheme.theme.syth_properties) {
92
- Object.entries(defaultTheme.theme.syth_properties).forEach(([varName, value]) => {
93
- this.updateVar(varName, value);
94
- });
95
- }
96
- }
97
- }
98
- },
99
- error: () => {
100
- this.themeLoadError = 'Failed to load themes';
101
- this.isLoadingThemes = false;
102
- }
103
- });
104
- this.loadAndApplyUserTheme();
105
- }
106
- loadAndApplyUserTheme() {
107
- this.themeService.loadTheme().subscribe({
108
- next: (res) => {
109
- const base = res?.data?.core_system_themes;
110
- const org = res?.data?.core_system_organization_themes;
111
- const user = res?.data?.core_system_theme_user_preferences;
112
- // Start with base theme properties
113
- let merged = { ...(base?.syth_properties || {}) };
114
- // Override with org overrides
115
- if (org?.syoth_overrides) {
116
- merged = { ...merged, ...org.syoth_overrides };
117
- }
118
- // Override with user overrides
119
- if (user?.syupth_overrides) {
120
- merged = { ...merged, ...user.syupth_overrides };
121
- }
122
- this.mergedTheme = merged;
123
- // Store original API values for reset functionality
124
- this.originalApiThemeValues = { ...merged };
125
- // Apply merged theme as CSS variables
126
- Object.entries(this.mergedTheme).forEach(([varName, value]) => {
127
- this.updateVar(varName, value);
128
- // If API returns font-size without -base, create the -base version for backward compatibility
129
- if (varName.includes('font-size') && !varName.includes('-base') && !varName.includes('responsive-scale')) {
130
- const baseVarName = varName + '-base';
131
- // Only create if it doesn't already exist
132
- if (!this.mergedTheme[baseVarName] && !this.mergedTheme[baseVarName.replace(/-/g, '_')]) {
133
- this.updateVar(baseVarName, value);
134
- }
135
- }
136
- });
137
- for (const group of this.themeGroups) {
138
- for (const item of group.items) {
139
- const key = item.varName.replace(/-/g, '_');
140
- // Check both the exact varName and the key format
141
- // Also check for non-base version if looking for base (for backward compatibility)
142
- let foundValue = merged[item.varName] || merged[key];
143
- // For base font sizes, also check non-base version from API (backward compatibility)
144
- if (!foundValue && item.varName.includes('-base') && item.varName.includes('font-size')) {
145
- const nonBaseVarName = item.varName.replace('-base', '');
146
- const nonBaseKey = nonBaseVarName.replace(/-/g, '_');
147
- foundValue = merged[nonBaseVarName] || merged[nonBaseKey];
148
- }
149
- item.value = foundValue || item.value;
150
- // Parse numeric values for font sizes, line heights, and scale
151
- if (key.includes('font_size') || key.includes('line_height') || key.includes('responsive_scale')) {
152
- // Remove 'rem' if present to get numeric value
153
- const numericValue = typeof item.value === 'string' ? parseFloat(item.value.replace('rem', '')) : parseFloat(item.value);
154
- item.value = numericValue;
155
- }
156
- }
157
- }
158
- // Store a deep copy of the current values for reset
159
- this.originalThemeGroupValues = cloneDeep(this.themeGroups);
160
- },
161
- error: () => {
162
- // handle error if needed
163
- }
164
- });
165
- }
166
- // Update CSS variable in real time
167
- updateVar(varName, value) {
168
- // You can use either the utility function directly or the service method
169
- setCSSVariable(varName, value, this.platformId);
170
- // Alternative: this.themeService.updateCSSVariable(varName, value);
171
- }
172
- onThemeModelChange(value) {
173
- this.selectedTheme = value;
174
- const selected = this.presetThemes.find(t => t.value === this.selectedTheme);
175
- if (selected) {
176
- this.onThemeChange({ value: this.selectedTheme, label: selected.label });
177
- }
178
- }
179
- onThemeChange(event) {
180
- this.selectedTheme = event.value;
181
- const selected = this.presetThemes.find(t => t.value === this.selectedTheme);
182
- if (selected && selected.theme && selected.theme.syth_properties) {
183
- // here we will check the theme selected by organization is same if yes then overide also for user preferences
184
- if (this.themeService.selectedTheme() === selected.theme._id) {
185
- this.loadAndApplyUserTheme();
186
- }
187
- else {
188
- // Store original API values for the selected theme
189
- this.originalApiThemeValues = cloneDeep(selected.theme.syth_properties);
190
- // Update all group values from the selected theme
191
- for (const group of this.themeGroups) {
192
- for (const item of group.items) {
193
- const key = item.varName.replace(/-/g, '_');
194
- item.value = selected.theme.syth_properties[item.varName] ||
195
- selected.theme.syth_properties[key] ||
196
- item.value;
197
- this.updateVar(item.varName, item.value);
198
- if (key.includes('font_size') || key.includes('line_height') || key.includes('responsive_scale')) {
199
- // Remove 'rem' if present to get numeric value
200
- const numericValue = typeof item.value === 'string' ? parseFloat(item.value.replace('rem', '')) : parseFloat(item.value);
201
- item.value = numericValue;
202
- }
203
- }
204
- }
205
- // Store a deep copy of the current values for reset
206
- this.originalThemeGroupValues = cloneDeep(this.themeGroups);
207
- }
208
- }
209
- }
210
- onReset() {
211
- // Restore all values from the original API values
212
- for (const group of this.themeGroups) {
213
- for (const item of group.items) {
214
- const key = item.varName.replace(/-/g, '_');
215
- // Get the original API value
216
- const originalValue = this.originalApiThemeValues[item.varName] ||
217
- this.originalApiThemeValues[key] ||
218
- item.value;
219
- // Update the item value
220
- item.value = originalValue;
221
- // Apply the CSS variable
222
- this.updateVar(item.varName, item.value);
223
- // Note: Font sizes now directly use -base variables, so no need to create -base from non-base
224
- if (key.includes('font_size') || key.includes('line_height') || key.includes('responsive_scale')) {
225
- item.value = parseFloat(item.value);
226
- }
227
- }
228
- }
229
- // Update the originalThemeGroupValues to reflect the reset state
230
- this.originalThemeGroupValues = cloneDeep(this.themeGroups);
231
- }
232
- onSave() {
233
- // Collect all current values
234
- const themeVars = {};
235
- for (const group of this.themeGroups) {
236
- for (const item of group.items) {
237
- themeVars[item.varName?.replaceAll('-', '_')] = item.value;
238
- }
239
- }
240
- const systemThemePreferences = {
241
- syupth_overrides: {
242
- ...themeVars
243
- },
244
- syupth_system_theme_id_syth: this.selectedTheme, // LATER: need to upadate LATER
245
- syupth_user_id_user: this.appState.currentUser()?._id || '', // LATER: need to get user id from user
246
- syupth_entity_id_syen: this.appState.getActiveEntityId() || '', // LATER: need to get entity id from user
247
- syth_theme_id: "" // need to upadate LATER
248
- };
249
- // TODO: Send themeVars to backend or emit event by designConfigRoutesUrl?.systemThemeUserPreferences
250
- this.themeService.saveSystemThemeUserPreferences(systemThemePreferences).subscribe({
251
- next: (res) => {
252
- console.log('Theme saved:', res);
253
- // Modern Angular v20 pattern: Update Signal through service method
254
- // Note: The theme service should provide a method to update the selected theme
255
- // For now, we'll just log the change since the service doesn't expose a setter
256
- console.log('Theme selected:', this.selectedTheme);
257
- },
258
- error: (error) => {
259
- console.error('Error saving theme:', error);
260
- }
261
- });
262
- }
263
- hasUnsavedChanges() {
264
- // chec selected theme is different
265
- if (this.themeService.selectedTheme() !== this.selectedTheme) {
266
- return true;
267
- }
268
- // check the theme groups are different
269
- return !isEqual(this.themeGroups, this.originalThemeGroupValues);
270
- }
271
- /**
272
- * Check if current values differ from the original API values
273
- * This is useful for determining if reset should be enabled
274
- */
275
- hasChangesFromOriginal() {
276
- for (const group of this.themeGroups) {
277
- for (const item of group.items) {
278
- const key = item.varName.replace(/-/g, '_');
279
- const originalValue = this.originalApiThemeValues[item.varName] ||
280
- this.originalApiThemeValues[key];
281
- if (originalValue !== undefined && item.value !== originalValue) {
282
- return true;
283
- }
284
- }
285
- }
286
- return false;
287
- }
288
- onColorChange(event, color) {
289
- const input = event.target;
290
- color.value = input.value;
291
- this.updateVar(color.varName, color.value);
292
- }
293
- onTypographyChange(event, setting) {
294
- const input = event.target;
295
- setting.value = input.value;
296
- // Handle different variable types
297
- if (setting.varName.includes('font-responsive-scale') || setting.varName.includes('responsive-scale')) {
298
- // Scale variables are unitless, keep as-is
299
- this.updateVar(setting.varName, setting.value);
300
- }
301
- else if (setting.varName.includes('font-size')) {
302
- // Font size base variables get 'rem' unit
303
- const value = setting.type === 'number' ? setting.value + 'rem' : setting.value;
304
- this.updateVar(setting.varName, value);
305
- }
306
- else if (setting.varName.includes('line-height')) {
307
- // Line heights are unitless
308
- this.updateVar(setting.varName, setting.value);
309
- }
310
- else {
311
- // Default: add 'rem' for number types
312
- const value = setting.type === 'number' ? setting.value + 'rem' : setting.value;
313
- this.updateVar(setting.varName, value);
314
- }
315
- }
316
- onLayoutChange(event, setting) {
317
- const input = event.target;
318
- setting.value = input.value;
319
- // For layout dimensions, store base value and append 'px' unit
320
- const baseVarName = setting.varName + '-base';
321
- this.updateVar(baseVarName, setting.value);
322
- this.updateVar(setting.varName, setting.value + 'px');
323
- }
324
- onScaleChange(event, setting) {
325
- const input = event.target;
326
- setting.value = input.value;
327
- // For responsive scale, set as unitless number
328
- this.updateVar(setting.varName, setting.value);
329
- }
330
- onDirectionToggle(event) {
331
- this.isRTL = event.target.checked;
332
- document.documentElement.dir = this.isRTL ? 'rtl' : 'ltr';
333
- }
334
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CideLytDrawerThemeComponent, deps: [{ token: CideLytThemeService }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component });
335
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: CideLytDrawerThemeComponent, isStandalone: true, selector: "cide-lyt-drawer-theme", ngImport: i0, template: "<div class=\"tw-relative tw-w-full tw-min-w-0 tw-h-full tw-bg-white tw-overflow-hidden tw-flex tw-flex-col\">\n <!-- STICKY HEADER SECTION -->\n <div class=\"tw-bg-white tw-sticky tw-top-0 tw-border-b tw-border-gray-200 tw-z-10 tw-flex-shrink-0\">\n <!-- DYNAMIC HEADING -->\n <div class=\"tw-flex tw-justify-between tw-items-center tw-p-2 tw-bg-white tw-border-b tw-border-gray-200\">\n <h6 class=\"tw-font-semibold tw-text-gray-800\">Preset Theme</h6>\n </div>\n </div>\n\n <!-- SCROLLABLE CONTENT AREA -->\n <div class=\"tw-flex-1 tw-overflow-y-auto tw-scroll-smooth tw-p-2 tw-flex tw-flex-col tw-gap-5 tw-text-sm tw-pb-3 theme-scroll-container\">\n <!-- Preset Theme -->\n <section>\n <cide-ele-select id=\"theme-selector\" [ngModel]=\"selectedTheme\" (ngModelChange)=\"onThemeModelChange($event)\"\n [options]=\"presetThemes\" [size]=\"'sm'\"></cide-ele-select>\n </section>\n\n <!-- Direction Toggle -->\n <section>\n <div class=\"tw-flex tw-justify-between tw-items-center tw-mb-2\">\n <h2 class=\"tw-text-md tw-font-semibold tw-text-gray-800\">Text Direction</h2>\n <div class=\"tw-flex tw-items-center tw-gap-1\">\n <span class=\"tw-text-xs tw-text-gray-500\">LTR</span>\n <label for=\"direction-toggle\" class=\"tw-relative tw-inline-block tw-w-9 tw-h-5\">\n <input type=\"checkbox\" id=\"direction-toggle\" class=\"tw-opacity-0 tw-w-0 tw-h-0\" [(ngModel)]=\"isRTL\"\n (change)=\"onDirectionToggle($event)\">\n <span\n class=\"tw-absolute tw-cursor-pointer tw-top-0 tw-left-0 tw-right-0 tw-bottom-0 tw-bg-gray-300 tw-rounded-full tw-transition-colors checked:tw-bg-blue-500 before:tw-absolute before:tw-content-[''] before:tw-h-4 before:tw-w-4 before:tw-left-0.5 before:tw-bottom-0.5 before:tw-bg-white before:tw-rounded-full before:tw-transition-transform checked:before:tw-translate-x-4\"></span>\n </label>\n <span class=\"tw-text-xs tw-text-gray-500\">RTL</span>\n </div>\n </div>\n </section>\n\n <!-- Theme Property Groups (Brand, Text, Background, Font Sizes, Line Heights) -->\n <section *ngFor=\"let group of themeGroups\" class=\"theme-section\">\n <h2 class=\"tw-text-md tw-font-semibold tw-mb-2 tw-text-gray-800\">{{ group.label }}</h2>\n <div class=\"tw-grid tw-grid-cols-2 tw-gap-2 tw-gap-x-4\">\n <div *ngFor=\"let item of group.items\"\n class=\"tw-flex tw-items-center tw-gap-2 tw-p-1 tw-rounded-lg tw-bg-gray-50\"\n [ngClass]=\"{'tw-flex-col tw-items-stretch': (group.label === 'Line Heights' || group.label === 'Layout Dimensions' || group.label === 'Responsive Scale')}\">\n <!-- Line Heights: label on top, input and unit on same line -->\n <ng-container *ngIf=\"group.label === 'Line Heights'\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700 tw-text-left\">{{ item.label\n }}</label>\n <div class=\"tw-flex tw-items-start\">\n <input [id]=\"item.varName\" type=\"number\" step=\"0.1\" [min]=\"item.min ?? null\" [max]=\"item.max ?? null\"\n [(ngModel)]=\"item.value\" (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-18 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\">unitless</span>\n </div>\n </ng-container>\n <!-- Layout Dimensions: label on top, input in middle, px unit at bottom -->\n <ng-container *ngIf=\"group.label === 'Layout Dimensions'\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700 tw-text-left\">{{ item.label\n }}</label>\n <div class=\"tw-flex tw-items-start\">\n <input [id]=\"item.varName\" type=\"number\" step=\"1\" [min]=\"item.min ?? null\" [max]=\"item.max ?? null\"\n [(ngModel)]=\"item.value\" (input)=\"onLayoutChange($event, item)\"\n class=\"tw-w-18 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\">px</span>\n </div>\n </ng-container>\n <!-- Responsive Scale: label on top, input in middle, unitless at bottom -->\n <ng-container *ngIf=\"group.label === 'Responsive Scale'\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700 tw-text-left\">{{ item.label\n }}</label>\n <div class=\"tw-flex tw-items-start\">\n <input [id]=\"item.varName\" type=\"number\" step=\"0.01\" [min]=\"item.min ?? null\" [max]=\"item.max ?? null\"\n [(ngModel)]=\"item.value\" (input)=\"onScaleChange($event, item)\"\n class=\"tw-w-18 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\">scale</span>\n </div>\n </ng-container>\n <!-- Other groups: keep previous layout -->\n <ng-container *ngIf=\"group.label !== 'Line Heights' && group.label !== 'Layout Dimensions' && group.label !== 'Responsive Scale'\">\n <!-- Color input for color variables -->\n <ng-container *ngIf=\"item.varName.includes('color')\">\n <input [id]=\"item.varName\" [attr.data-variable]=\"item.varName\" type=\"color\" [(ngModel)]=\"item.value\"\n (input)=\"onColorChange($event, item)\"\n class=\"tw-appearance-none tw-border-2 tw-border-gray-200 tw-rounded tw-w-8 tw-h-8 tw-p-0 tw-bg-none tw-shadow-none tw-cursor-pointer tw-transition-colors focus:tw-border-blue-500 color-input\">\n </ng-container>\n <!-- Number input for line heights -->\n <ng-container\n *ngIf=\"!item.varName.includes('color') && item.type === 'number' && group.label !== 'Font Sizes'\">\n <input [id]=\"item.varName\" type=\"number\" [step]=\"item.varName.includes('line-height') ? 0.1 : 0.001\"\n [min]=\"item.min ?? null\" [max]=\"item.max ?? null\" [(ngModel)]=\"item.value\"\n (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-16 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\" *ngIf=\"!item.varName.includes('line-height')\">rem</span>\n </ng-container>\n <!-- Text input fallback (if needed) -->\n <ng-container *ngIf=\"!item.varName.includes('color') && item.type !== 'number'\">\n <input [id]=\"item.varName\" type=\"text\" [(ngModel)]=\"item.value\" (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-24 tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n </ng-container>\n <div class=\"tw-flex tw-flex-col tw-gap-0.5\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700\">{{ item.label }}</label>\n <span class=\"tw-text-xs tw-text-gray-500 tw-font-mono\">{{ item.value }}</span>\n </div>\n </ng-container>\n </div>\n </div>\n </section>\n </div>\n\n <!-- STICKY ACTION BUTTONS SECTION -->\n <div class=\"tw-bg-white tw-sticky tw-bottom-0 tw-border-t tw-border-gray-200 tw-z-10 tw-flex-shrink-0 tw-p-3 tw-shadow-lg sticky-action-buttons\">\n <div class=\"tw-flex tw-gap-2 tw-justify-end\">\n <button cideEleButton \n variant=\"outline\" \n size=\"xs\" \n (btnClick)=\"onReset()\" \n [disabled]=\"!hasChangesFromOriginal()\"\n class=\"tw-transition-all tw-duration-200 hover:tw-scale-105 action-button\">\n Reset to Original\n </button>\n <button cideEleButton \n variant=\"primary\" \n size=\"xs\" \n (btnClick)=\"onSave()\" \n [disabled]=\"!hasUnsavedChanges()\"\n class=\"tw-transition-all tw-duration-200 hover:tw-scale-105 action-button\">\n Save Changes\n </button>\n </div>\n </div>\n</div>", styles: [".theme-scroll-container{scroll-behavior:smooth;-webkit-overflow-scrolling:touch}.theme-scroll-container{scrollbar-width:thin;scrollbar-color:var(--cide-ele-scrollbar-thumb, #d1d5db) var(--cide-ele-scrollbar-track, #f9fafb)}.theme-scroll-container::-webkit-scrollbar{width:6px}.theme-scroll-container::-webkit-scrollbar-track{background:var(--cide-ele-scrollbar-track, #f9fafb);border-radius:3px}.theme-scroll-container::-webkit-scrollbar-thumb{background:var(--cide-ele-scrollbar-thumb, #d1d5db);border-radius:3px;transition:background-color .2s ease}.theme-scroll-container::-webkit-scrollbar-thumb:hover{background:var(--cide-ele-scrollbar-thumb-hover, #9ca3af)}.sticky-action-buttons{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background-color:#fffffff2;border-top:1px solid #e2e8f0;box-shadow:0 -4px 6px -1px #0000001a}.action-button{transition:all .2s ease-in-out}.action-button:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 4px 8px #00000026}.action-button:active:not(:disabled){transform:translateY(0)}.action-button:disabled{opacity:.5;cursor:not-allowed;transform:none!important;box-shadow:none!important}.theme-input:focus{transform:scale(1.02);transition:transform .2s ease-in-out}.color-input{transition:all .2s ease-in-out}.color-input:hover{transform:scale(1.1);box-shadow:0 4px 8px #0003}.theme-section{transition:all .3s ease-in-out}.theme-section:hover{background-color:#f8fafc;border-radius:8px;padding:8px;margin:-8px}@media (max-width: 640px){.sticky-action-buttons{padding:12px}.action-button{font-size:14px;padding:8px 12px}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i2.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: CideSelectComponent, selector: "cide-ele-select", inputs: ["label", "labelHide", "placeholder", "helperText", "errorText", "required", "disabled", "id", "ngModel", "size", "fill", "labelPlacement", "labelDir", "leadingIcon", "trailingIcon", "clearInput", "options", "multiple", "searchable", "showSearchInput", "loading", "valueKey", "labelKey", "treeView"], outputs: ["ngModelChange", "change", "searchChange"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton], cide-ele-button", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated", "adaptive"], outputs: ["btnClick", "doubleClick"] }] });
336
- }
337
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CideLytDrawerThemeComponent, decorators: [{
338
- type: Component,
339
- args: [{ selector: 'cide-lyt-drawer-theme', standalone: true, imports: [FormsModule, NgFor, NgIf, NgClass, CideSelectComponent, CideEleButtonComponent], template: "<div class=\"tw-relative tw-w-full tw-min-w-0 tw-h-full tw-bg-white tw-overflow-hidden tw-flex tw-flex-col\">\n <!-- STICKY HEADER SECTION -->\n <div class=\"tw-bg-white tw-sticky tw-top-0 tw-border-b tw-border-gray-200 tw-z-10 tw-flex-shrink-0\">\n <!-- DYNAMIC HEADING -->\n <div class=\"tw-flex tw-justify-between tw-items-center tw-p-2 tw-bg-white tw-border-b tw-border-gray-200\">\n <h6 class=\"tw-font-semibold tw-text-gray-800\">Preset Theme</h6>\n </div>\n </div>\n\n <!-- SCROLLABLE CONTENT AREA -->\n <div class=\"tw-flex-1 tw-overflow-y-auto tw-scroll-smooth tw-p-2 tw-flex tw-flex-col tw-gap-5 tw-text-sm tw-pb-3 theme-scroll-container\">\n <!-- Preset Theme -->\n <section>\n <cide-ele-select id=\"theme-selector\" [ngModel]=\"selectedTheme\" (ngModelChange)=\"onThemeModelChange($event)\"\n [options]=\"presetThemes\" [size]=\"'sm'\"></cide-ele-select>\n </section>\n\n <!-- Direction Toggle -->\n <section>\n <div class=\"tw-flex tw-justify-between tw-items-center tw-mb-2\">\n <h2 class=\"tw-text-md tw-font-semibold tw-text-gray-800\">Text Direction</h2>\n <div class=\"tw-flex tw-items-center tw-gap-1\">\n <span class=\"tw-text-xs tw-text-gray-500\">LTR</span>\n <label for=\"direction-toggle\" class=\"tw-relative tw-inline-block tw-w-9 tw-h-5\">\n <input type=\"checkbox\" id=\"direction-toggle\" class=\"tw-opacity-0 tw-w-0 tw-h-0\" [(ngModel)]=\"isRTL\"\n (change)=\"onDirectionToggle($event)\">\n <span\n class=\"tw-absolute tw-cursor-pointer tw-top-0 tw-left-0 tw-right-0 tw-bottom-0 tw-bg-gray-300 tw-rounded-full tw-transition-colors checked:tw-bg-blue-500 before:tw-absolute before:tw-content-[''] before:tw-h-4 before:tw-w-4 before:tw-left-0.5 before:tw-bottom-0.5 before:tw-bg-white before:tw-rounded-full before:tw-transition-transform checked:before:tw-translate-x-4\"></span>\n </label>\n <span class=\"tw-text-xs tw-text-gray-500\">RTL</span>\n </div>\n </div>\n </section>\n\n <!-- Theme Property Groups (Brand, Text, Background, Font Sizes, Line Heights) -->\n <section *ngFor=\"let group of themeGroups\" class=\"theme-section\">\n <h2 class=\"tw-text-md tw-font-semibold tw-mb-2 tw-text-gray-800\">{{ group.label }}</h2>\n <div class=\"tw-grid tw-grid-cols-2 tw-gap-2 tw-gap-x-4\">\n <div *ngFor=\"let item of group.items\"\n class=\"tw-flex tw-items-center tw-gap-2 tw-p-1 tw-rounded-lg tw-bg-gray-50\"\n [ngClass]=\"{'tw-flex-col tw-items-stretch': (group.label === 'Line Heights' || group.label === 'Layout Dimensions' || group.label === 'Responsive Scale')}\">\n <!-- Line Heights: label on top, input and unit on same line -->\n <ng-container *ngIf=\"group.label === 'Line Heights'\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700 tw-text-left\">{{ item.label\n }}</label>\n <div class=\"tw-flex tw-items-start\">\n <input [id]=\"item.varName\" type=\"number\" step=\"0.1\" [min]=\"item.min ?? null\" [max]=\"item.max ?? null\"\n [(ngModel)]=\"item.value\" (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-18 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\">unitless</span>\n </div>\n </ng-container>\n <!-- Layout Dimensions: label on top, input in middle, px unit at bottom -->\n <ng-container *ngIf=\"group.label === 'Layout Dimensions'\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700 tw-text-left\">{{ item.label\n }}</label>\n <div class=\"tw-flex tw-items-start\">\n <input [id]=\"item.varName\" type=\"number\" step=\"1\" [min]=\"item.min ?? null\" [max]=\"item.max ?? null\"\n [(ngModel)]=\"item.value\" (input)=\"onLayoutChange($event, item)\"\n class=\"tw-w-18 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\">px</span>\n </div>\n </ng-container>\n <!-- Responsive Scale: label on top, input in middle, unitless at bottom -->\n <ng-container *ngIf=\"group.label === 'Responsive Scale'\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700 tw-text-left\">{{ item.label\n }}</label>\n <div class=\"tw-flex tw-items-start\">\n <input [id]=\"item.varName\" type=\"number\" step=\"0.01\" [min]=\"item.min ?? null\" [max]=\"item.max ?? null\"\n [(ngModel)]=\"item.value\" (input)=\"onScaleChange($event, item)\"\n class=\"tw-w-18 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\">scale</span>\n </div>\n </ng-container>\n <!-- Other groups: keep previous layout -->\n <ng-container *ngIf=\"group.label !== 'Line Heights' && group.label !== 'Layout Dimensions' && group.label !== 'Responsive Scale'\">\n <!-- Color input for color variables -->\n <ng-container *ngIf=\"item.varName.includes('color')\">\n <input [id]=\"item.varName\" [attr.data-variable]=\"item.varName\" type=\"color\" [(ngModel)]=\"item.value\"\n (input)=\"onColorChange($event, item)\"\n class=\"tw-appearance-none tw-border-2 tw-border-gray-200 tw-rounded tw-w-8 tw-h-8 tw-p-0 tw-bg-none tw-shadow-none tw-cursor-pointer tw-transition-colors focus:tw-border-blue-500 color-input\">\n </ng-container>\n <!-- Number input for line heights -->\n <ng-container\n *ngIf=\"!item.varName.includes('color') && item.type === 'number' && group.label !== 'Font Sizes'\">\n <input [id]=\"item.varName\" type=\"number\" [step]=\"item.varName.includes('line-height') ? 0.1 : 0.001\"\n [min]=\"item.min ?? null\" [max]=\"item.max ?? null\" [(ngModel)]=\"item.value\"\n (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-16 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\" *ngIf=\"!item.varName.includes('line-height')\">rem</span>\n </ng-container>\n <!-- Text input fallback (if needed) -->\n <ng-container *ngIf=\"!item.varName.includes('color') && item.type !== 'number'\">\n <input [id]=\"item.varName\" type=\"text\" [(ngModel)]=\"item.value\" (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-24 tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n </ng-container>\n <div class=\"tw-flex tw-flex-col tw-gap-0.5\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700\">{{ item.label }}</label>\n <span class=\"tw-text-xs tw-text-gray-500 tw-font-mono\">{{ item.value }}</span>\n </div>\n </ng-container>\n </div>\n </div>\n </section>\n </div>\n\n <!-- STICKY ACTION BUTTONS SECTION -->\n <div class=\"tw-bg-white tw-sticky tw-bottom-0 tw-border-t tw-border-gray-200 tw-z-10 tw-flex-shrink-0 tw-p-3 tw-shadow-lg sticky-action-buttons\">\n <div class=\"tw-flex tw-gap-2 tw-justify-end\">\n <button cideEleButton \n variant=\"outline\" \n size=\"xs\" \n (btnClick)=\"onReset()\" \n [disabled]=\"!hasChangesFromOriginal()\"\n class=\"tw-transition-all tw-duration-200 hover:tw-scale-105 action-button\">\n Reset to Original\n </button>\n <button cideEleButton \n variant=\"primary\" \n size=\"xs\" \n (btnClick)=\"onSave()\" \n [disabled]=\"!hasUnsavedChanges()\"\n class=\"tw-transition-all tw-duration-200 hover:tw-scale-105 action-button\">\n Save Changes\n </button>\n </div>\n </div>\n</div>", styles: [".theme-scroll-container{scroll-behavior:smooth;-webkit-overflow-scrolling:touch}.theme-scroll-container{scrollbar-width:thin;scrollbar-color:var(--cide-ele-scrollbar-thumb, #d1d5db) var(--cide-ele-scrollbar-track, #f9fafb)}.theme-scroll-container::-webkit-scrollbar{width:6px}.theme-scroll-container::-webkit-scrollbar-track{background:var(--cide-ele-scrollbar-track, #f9fafb);border-radius:3px}.theme-scroll-container::-webkit-scrollbar-thumb{background:var(--cide-ele-scrollbar-thumb, #d1d5db);border-radius:3px;transition:background-color .2s ease}.theme-scroll-container::-webkit-scrollbar-thumb:hover{background:var(--cide-ele-scrollbar-thumb-hover, #9ca3af)}.sticky-action-buttons{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background-color:#fffffff2;border-top:1px solid #e2e8f0;box-shadow:0 -4px 6px -1px #0000001a}.action-button{transition:all .2s ease-in-out}.action-button:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 4px 8px #00000026}.action-button:active:not(:disabled){transform:translateY(0)}.action-button:disabled{opacity:.5;cursor:not-allowed;transform:none!important;box-shadow:none!important}.theme-input:focus{transform:scale(1.02);transition:transform .2s ease-in-out}.color-input{transition:all .2s ease-in-out}.color-input:hover{transform:scale(1.1);box-shadow:0 4px 8px #0003}.theme-section{transition:all .3s ease-in-out}.theme-section:hover{background-color:#f8fafc;border-radius:8px;padding:8px;margin:-8px}@media (max-width: 640px){.sticky-action-buttons{padding:12px}.action-button{font-size:14px;padding:8px 12px}}\n"] }]
340
- }], ctorParameters: () => [{ type: CideLytThemeService }, { type: undefined, decorators: [{
341
- type: Inject,
342
- args: [PLATFORM_ID]
343
- }] }] });
344
-
345
- export { CideLytDrawerThemeComponent };
346
- //# sourceMappingURL=cloud-ide-layout-drawer-theme.component-NKRNKJw5.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cloud-ide-layout-drawer-theme.component-NKRNKJw5.mjs","sources":["../../../projects/cloud-ide-layout/src/lib/layout/sidedrawer/drawer-theme/drawer-theme.component.ts","../../../projects/cloud-ide-layout/src/lib/layout/sidedrawer/drawer-theme/drawer-theme.component.html"],"sourcesContent":["import { NgFor, NgIf } from '@angular/common';\nimport { NgClass } from '@angular/common';\nimport { Component, OnInit, PLATFORM_ID, Inject, inject } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { CideSelectComponent, SelectOption, CideEleButtonComponent } from 'cloud-ide-element';\nimport { CideLytThemeService, Theme, setCSSVariable } from '../../../services/theme/theme.service';\nimport type { MSystemThemeUserPreferencesRequest, SystemThemesListControllerRespoonse, SystemThemeUserPreferencesControllerRespoonse } from 'cloud-ide-lms-model';\nimport type { SystemThemeControllerRespoonse } from 'cloud-ide-lms-model';\nimport type { ICoreSyth, ICoreSyoth, ICoreSyupth } from 'cloud-ide-lms-model';\nimport { isEqual, cloneDeep } from 'lodash-es';\nimport { AppStateHelperService } from '../../../services/app-state';\n\ninterface ThemeColor {\n label: string;\n varName: string;\n value: string;\n}\n\ninterface TypographySetting {\n label: string;\n varName: string;\n value: string;\n type: 'number' | 'text';\n min?: number;\n max?: number;\n step?: number;\n}\n\ntype ThemeGroup = {\n label: string;\n items: Array<{\n label: string;\n varName: string;\n value: string;\n type: 'number' | 'text';\n min?: number;\n max?: number;\n step?: number;\n }>;\n};\n\n@Component({\n selector: 'cide-lyt-drawer-theme',\n standalone: true,\n imports: [FormsModule, NgFor, NgIf, NgClass, CideSelectComponent, CideEleButtonComponent],\n templateUrl: './drawer-theme.component.html',\n styleUrl: './drawer-theme.component.scss'\n})\nexport class CideLytDrawerThemeComponent implements OnInit {\n private readonly appState = inject(AppStateHelperService);\n // Preset themes\n presetThemes: { value: string, label: string, theme: ICoreSyth }[] = [];\n selectedTheme = '';\n isLoadingThemes = false;\n themeLoadError = '';\n mergedTheme: { [key: string]: string } = {};\n isRTL = false;\n originalThemeGroupValues: ThemeGroup[] = [];\n originalApiThemeValues: { [key: string]: string } = {}; // Store original API values\n\n themeGroups: ThemeGroup[] = [\n {\n label: 'Brand Colors',\n items: [\n { label: 'Primary', varName: '--cide-theme-color-brand-primary', value: '#4f46e5', type: 'text' },\n { label: 'Accent', varName: '--cide-theme-color-brand-accent', value: '#4338ca', type: 'text' },\n { label: 'Separator', varName: '--cide-theme-color-brand-separator', value: '#e5e7eb', type: 'text' }\n ]\n },\n {\n label: 'Text Colors',\n items: [\n { label: 'Body Text', varName: '--cide-theme-color-text-body', value: '#374151', type: 'text' },\n { label: 'Heading Text', varName: '--cide-theme-color-text-heading', value: '#111827', type: 'text' },\n { label: 'Link Text', varName: '--cide-theme-color-text-link', value: '#3b82f6', type: 'text' },\n { label: 'Muted Text', varName: '--cide-theme-color-text-muted', value: '#6b7280', type: 'text' }\n ]\n },\n {\n label: 'Background Colors',\n items: [\n { label: 'Body Background', varName: '--cide-theme-color-background-body', value: '#ffffff', type: 'text' }\n ]\n },\n {\n label: 'Layout Dimensions',\n items: [\n { label: 'Stack Wrapper Width', varName: '--cide-lyt-stack-wrapper-width', value: '60', type: 'number', min: 20, max: 120 }\n ]\n },\n {\n label: 'Responsive Scale',\n items: [\n { label: 'Font Scale', varName: '--cide-lyt-font-responsive-scale-base', value: '1.0', type: 'number', min: 0.5, max: 2.0, step: 0.01 }\n ]\n },\n {\n label: 'Line Heights',\n items: [\n { label: 'Body Line Height', varName: '--cide-theme-line-height-body', value: '1.6', type: 'number', min: 1, max: 3 },\n { label: 'Heading Line Height', varName: '--cide-theme-line-height-heading', value: '1.2', type: 'number', min: 1, max: 3 }\n ]\n }\n ];\n\n constructor(\n private themeService: CideLytThemeService,\n @Inject(PLATFORM_ID) private platformId: object\n ) { }\n\n ngOnInit(): void {\n // Modern Angular v20 pattern: Use Signals directly\n this.selectedTheme = this.themeService.selectedTheme();\n\n // fetch the system themes list\n this.isLoadingThemes = true;\n this.themeService.fetchSystemThemesList().subscribe({\n next: (res: SystemThemesListControllerRespoonse) => {\n const themes: ICoreSyth[] = res?.data?.core_system_themes || [];\n this.presetThemes = themes.map((theme: ICoreSyth) => ({\n value: theme._id || '',\n label: theme.syth_theme_name || theme.syth_theme_id || '',\n theme\n }));\n this.isLoadingThemes = false;\n // If user has no theme set, select and apply the default theme\n if (!this.selectedTheme) {\n const defaultTheme = this.presetThemes.find(t => t.theme.syth_is_default);\n if (defaultTheme) {\n this.selectedTheme = defaultTheme.value;\n // Apply the default theme as CSS variables\n if (defaultTheme.theme.syth_properties) {\n Object.entries(defaultTheme.theme.syth_properties).forEach(([varName, value]) => {\n this.updateVar(varName, value as string);\n });\n }\n }\n }\n },\n error: () => {\n this.themeLoadError = 'Failed to load themes';\n this.isLoadingThemes = false;\n }\n });\n this.loadAndApplyUserTheme();\n }\n\n loadAndApplyUserTheme(): void {\n this.themeService.loadTheme().subscribe({\n next: (res: SystemThemeControllerRespoonse) => {\n const base: ICoreSyth | undefined = res?.data?.core_system_themes;\n const org: ICoreSyoth | undefined = res?.data?.core_system_organization_themes;\n const user: ICoreSyupth | undefined = res?.data?.core_system_theme_user_preferences;\n // Start with base theme properties\n let merged = { ...(base?.syth_properties || {}) };\n // Override with org overrides\n if (org?.syoth_overrides) {\n merged = { ...merged, ...org.syoth_overrides };\n }\n // Override with user overrides\n if (user?.syupth_overrides) {\n merged = { ...merged, ...user.syupth_overrides };\n }\n this.mergedTheme = merged;\n\n // Store original API values for reset functionality\n this.originalApiThemeValues = { ...merged };\n\n // Apply merged theme as CSS variables\n Object.entries(this.mergedTheme).forEach(([varName, value]) => {\n this.updateVar(varName, value as string);\n \n // If API returns font-size without -base, create the -base version for backward compatibility\n if (varName.includes('font-size') && !varName.includes('-base') && !varName.includes('responsive-scale')) {\n const baseVarName = varName + '-base';\n // Only create if it doesn't already exist\n if (!this.mergedTheme[baseVarName] && !this.mergedTheme[baseVarName.replace(/-/g, '_')]) {\n this.updateVar(baseVarName, value as string);\n }\n }\n });\n\n for (const group of this.themeGroups) {\n for (const item of group.items) {\n const key = item.varName.replace(/-/g, '_');\n // Check both the exact varName and the key format\n // Also check for non-base version if looking for base (for backward compatibility)\n let foundValue = merged[item.varName] || merged[key];\n \n // For base font sizes, also check non-base version from API (backward compatibility)\n if (!foundValue && item.varName.includes('-base') && item.varName.includes('font-size')) {\n const nonBaseVarName = item.varName.replace('-base', '');\n const nonBaseKey = nonBaseVarName.replace(/-/g, '_');\n foundValue = merged[nonBaseVarName] || merged[nonBaseKey];\n }\n \n item.value = foundValue || item.value;\n\n // Parse numeric values for font sizes, line heights, and scale\n if (key.includes('font_size') || key.includes('line_height') || key.includes('responsive_scale')) {\n // Remove 'rem' if present to get numeric value\n const numericValue = typeof item.value === 'string' ? parseFloat(item.value.replace('rem', '')) : parseFloat(item.value);\n item.value = numericValue as unknown as string;\n }\n }\n }\n // Store a deep copy of the current values for reset\n this.originalThemeGroupValues = cloneDeep(this.themeGroups);\n },\n error: () => {\n // handle error if needed\n }\n });\n }\n\n // Update CSS variable in real time\n updateVar(varName: string, value: string) {\n // You can use either the utility function directly or the service method\n setCSSVariable(varName, value, this.platformId);\n // Alternative: this.themeService.updateCSSVariable(varName, value);\n }\n\n onThemeModelChange(value: string | number | string[]): void {\n this.selectedTheme = value as string;\n const selected = this.presetThemes.find(t => t.value === this.selectedTheme);\n if (selected) {\n this.onThemeChange({ value: this.selectedTheme, label: selected.label });\n }\n }\n\n onThemeChange(event: SelectOption) {\n this.selectedTheme = event.value as string;\n const selected = this.presetThemes.find(t => t.value === this.selectedTheme);\n if (selected && selected.theme && selected.theme.syth_properties) {\n // here we will check the theme selected by organization is same if yes then overide also for user preferences\n if (this.themeService.selectedTheme() === selected.theme._id) {\n this.loadAndApplyUserTheme();\n } else {\n // Store original API values for the selected theme\n this.originalApiThemeValues = cloneDeep(selected.theme.syth_properties);\n\n // Update all group values from the selected theme\n for (const group of this.themeGroups) {\n for (const item of group.items) {\n const key = item.varName.replace(/-/g, '_');\n item.value = selected.theme.syth_properties[item.varName] ||\n selected.theme.syth_properties[key] ||\n item.value;\n\n this.updateVar(item.varName, item.value);\n\n if (key.includes('font_size') || key.includes('line_height') || key.includes('responsive_scale')) {\n // Remove 'rem' if present to get numeric value\n const numericValue = typeof item.value === 'string' ? parseFloat(item.value.replace('rem', '')) : parseFloat(item.value);\n item.value = numericValue as unknown as string;\n }\n }\n }\n // Store a deep copy of the current values for reset\n this.originalThemeGroupValues = cloneDeep(this.themeGroups);\n }\n }\n }\n\n onReset() {\n // Restore all values from the original API values\n for (const group of this.themeGroups) {\n for (const item of group.items) {\n const key = item.varName.replace(/-/g, '_');\n // Get the original API value\n const originalValue = this.originalApiThemeValues[item.varName] ||\n this.originalApiThemeValues[key] ||\n item.value;\n\n // Update the item value\n item.value = originalValue;\n\n // Apply the CSS variable\n this.updateVar(item.varName, item.value);\n \n // Note: Font sizes now directly use -base variables, so no need to create -base from non-base\n\n if (key.includes('font_size') || key.includes('line_height') || key.includes('responsive_scale')) {\n item.value = parseFloat(item.value) as unknown as string;\n }\n }\n }\n\n // Update the originalThemeGroupValues to reflect the reset state\n this.originalThemeGroupValues = cloneDeep(this.themeGroups);\n }\n\n onSave() {\n // Collect all current values\n const themeVars: Theme = {\n\n };\n for (const group of this.themeGroups) {\n for (const item of group.items) {\n themeVars[item.varName?.replaceAll('-', '_')] = item.value;\n }\n }\n\n const systemThemePreferences: MSystemThemeUserPreferencesRequest = {\n syupth_overrides: {\n ...themeVars\n },\n syupth_system_theme_id_syth: this.selectedTheme, // LATER: need to upadate LATER\n syupth_user_id_user: this.appState.currentUser()?._id || '', // LATER: need to get user id from user\n syupth_entity_id_syen: this.appState.getActiveEntityId() || '', // LATER: need to get entity id from user\n syth_theme_id: \"\" // need to upadate LATER\n };\n\n // TODO: Send themeVars to backend or emit event by designConfigRoutesUrl?.systemThemeUserPreferences\n this.themeService.saveSystemThemeUserPreferences(systemThemePreferences).subscribe({\n next: (res: SystemThemeUserPreferencesControllerRespoonse) => {\n console.log('Theme saved:', res);\n // Modern Angular v20 pattern: Update Signal through service method\n // Note: The theme service should provide a method to update the selected theme\n // For now, we'll just log the change since the service doesn't expose a setter\n console.log('Theme selected:', this.selectedTheme);\n },\n error: (error) => {\n console.error('Error saving theme:', error);\n }\n });\n }\n\n hasUnsavedChanges(): boolean {\n // chec selected theme is different\n if (this.themeService.selectedTheme() !== this.selectedTheme) {\n return true;\n }\n // check the theme groups are different\n return !isEqual(this.themeGroups, this.originalThemeGroupValues);\n }\n\n /**\n * Check if current values differ from the original API values\n * This is useful for determining if reset should be enabled\n */\n hasChangesFromOriginal(): boolean {\n for (const group of this.themeGroups) {\n for (const item of group.items) {\n const key = item.varName.replace(/-/g, '_');\n const originalValue = this.originalApiThemeValues[item.varName] ||\n this.originalApiThemeValues[key];\n\n if (originalValue !== undefined && item.value !== originalValue) {\n return true;\n }\n }\n }\n return false;\n }\n\n onColorChange(event: Event, color: ThemeColor) {\n const input = event.target as HTMLInputElement;\n color.value = input.value;\n this.updateVar(color.varName, color.value);\n }\n\n onTypographyChange(event: Event, setting: TypographySetting) {\n const input = event.target as HTMLInputElement;\n setting.value = input.value;\n \n // Handle different variable types\n if (setting.varName.includes('font-responsive-scale') || setting.varName.includes('responsive-scale')) {\n // Scale variables are unitless, keep as-is\n this.updateVar(setting.varName, setting.value);\n } else if (setting.varName.includes('font-size')) {\n // Font size base variables get 'rem' unit\n const value = setting.type === 'number' ? setting.value + 'rem' : setting.value;\n this.updateVar(setting.varName, value);\n } else if (setting.varName.includes('line-height')) {\n // Line heights are unitless\n this.updateVar(setting.varName, setting.value);\n } else {\n // Default: add 'rem' for number types\n const value = setting.type === 'number' ? setting.value + 'rem' : setting.value;\n this.updateVar(setting.varName, value);\n }\n }\n\n onLayoutChange(event: Event, setting: TypographySetting) {\n const input = event.target as HTMLInputElement;\n setting.value = input.value;\n // For layout dimensions, store base value and append 'px' unit\n const baseVarName = setting.varName + '-base';\n this.updateVar(baseVarName, setting.value);\n this.updateVar(setting.varName, setting.value + 'px');\n }\n\n onScaleChange(event: Event, setting: TypographySetting) {\n const input = event.target as HTMLInputElement;\n setting.value = input.value;\n // For responsive scale, set as unitless number\n this.updateVar(setting.varName, setting.value);\n }\n\n onDirectionToggle(event: Event) {\n this.isRTL = (event.target as HTMLInputElement).checked;\n document.documentElement.dir = this.isRTL ? 'rtl' : 'ltr';\n }\n}\n","<div class=\"tw-relative tw-w-full tw-min-w-0 tw-h-full tw-bg-white tw-overflow-hidden tw-flex tw-flex-col\">\n <!-- STICKY HEADER SECTION -->\n <div class=\"tw-bg-white tw-sticky tw-top-0 tw-border-b tw-border-gray-200 tw-z-10 tw-flex-shrink-0\">\n <!-- DYNAMIC HEADING -->\n <div class=\"tw-flex tw-justify-between tw-items-center tw-p-2 tw-bg-white tw-border-b tw-border-gray-200\">\n <h6 class=\"tw-font-semibold tw-text-gray-800\">Preset Theme</h6>\n </div>\n </div>\n\n <!-- SCROLLABLE CONTENT AREA -->\n <div class=\"tw-flex-1 tw-overflow-y-auto tw-scroll-smooth tw-p-2 tw-flex tw-flex-col tw-gap-5 tw-text-sm tw-pb-3 theme-scroll-container\">\n <!-- Preset Theme -->\n <section>\n <cide-ele-select id=\"theme-selector\" [ngModel]=\"selectedTheme\" (ngModelChange)=\"onThemeModelChange($event)\"\n [options]=\"presetThemes\" [size]=\"'sm'\"></cide-ele-select>\n </section>\n\n <!-- Direction Toggle -->\n <section>\n <div class=\"tw-flex tw-justify-between tw-items-center tw-mb-2\">\n <h2 class=\"tw-text-md tw-font-semibold tw-text-gray-800\">Text Direction</h2>\n <div class=\"tw-flex tw-items-center tw-gap-1\">\n <span class=\"tw-text-xs tw-text-gray-500\">LTR</span>\n <label for=\"direction-toggle\" class=\"tw-relative tw-inline-block tw-w-9 tw-h-5\">\n <input type=\"checkbox\" id=\"direction-toggle\" class=\"tw-opacity-0 tw-w-0 tw-h-0\" [(ngModel)]=\"isRTL\"\n (change)=\"onDirectionToggle($event)\">\n <span\n class=\"tw-absolute tw-cursor-pointer tw-top-0 tw-left-0 tw-right-0 tw-bottom-0 tw-bg-gray-300 tw-rounded-full tw-transition-colors checked:tw-bg-blue-500 before:tw-absolute before:tw-content-[''] before:tw-h-4 before:tw-w-4 before:tw-left-0.5 before:tw-bottom-0.5 before:tw-bg-white before:tw-rounded-full before:tw-transition-transform checked:before:tw-translate-x-4\"></span>\n </label>\n <span class=\"tw-text-xs tw-text-gray-500\">RTL</span>\n </div>\n </div>\n </section>\n\n <!-- Theme Property Groups (Brand, Text, Background, Font Sizes, Line Heights) -->\n <section *ngFor=\"let group of themeGroups\" class=\"theme-section\">\n <h2 class=\"tw-text-md tw-font-semibold tw-mb-2 tw-text-gray-800\">{{ group.label }}</h2>\n <div class=\"tw-grid tw-grid-cols-2 tw-gap-2 tw-gap-x-4\">\n <div *ngFor=\"let item of group.items\"\n class=\"tw-flex tw-items-center tw-gap-2 tw-p-1 tw-rounded-lg tw-bg-gray-50\"\n [ngClass]=\"{'tw-flex-col tw-items-stretch': (group.label === 'Line Heights' || group.label === 'Layout Dimensions' || group.label === 'Responsive Scale')}\">\n <!-- Line Heights: label on top, input and unit on same line -->\n <ng-container *ngIf=\"group.label === 'Line Heights'\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700 tw-text-left\">{{ item.label\n }}</label>\n <div class=\"tw-flex tw-items-start\">\n <input [id]=\"item.varName\" type=\"number\" step=\"0.1\" [min]=\"item.min ?? null\" [max]=\"item.max ?? null\"\n [(ngModel)]=\"item.value\" (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-18 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\">unitless</span>\n </div>\n </ng-container>\n <!-- Layout Dimensions: label on top, input in middle, px unit at bottom -->\n <ng-container *ngIf=\"group.label === 'Layout Dimensions'\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700 tw-text-left\">{{ item.label\n }}</label>\n <div class=\"tw-flex tw-items-start\">\n <input [id]=\"item.varName\" type=\"number\" step=\"1\" [min]=\"item.min ?? null\" [max]=\"item.max ?? null\"\n [(ngModel)]=\"item.value\" (input)=\"onLayoutChange($event, item)\"\n class=\"tw-w-18 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\">px</span>\n </div>\n </ng-container>\n <!-- Responsive Scale: label on top, input in middle, unitless at bottom -->\n <ng-container *ngIf=\"group.label === 'Responsive Scale'\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700 tw-text-left\">{{ item.label\n }}</label>\n <div class=\"tw-flex tw-items-start\">\n <input [id]=\"item.varName\" type=\"number\" step=\"0.01\" [min]=\"item.min ?? null\" [max]=\"item.max ?? null\"\n [(ngModel)]=\"item.value\" (input)=\"onScaleChange($event, item)\"\n class=\"tw-w-18 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\">scale</span>\n </div>\n </ng-container>\n <!-- Other groups: keep previous layout -->\n <ng-container *ngIf=\"group.label !== 'Line Heights' && group.label !== 'Layout Dimensions' && group.label !== 'Responsive Scale'\">\n <!-- Color input for color variables -->\n <ng-container *ngIf=\"item.varName.includes('color')\">\n <input [id]=\"item.varName\" [attr.data-variable]=\"item.varName\" type=\"color\" [(ngModel)]=\"item.value\"\n (input)=\"onColorChange($event, item)\"\n class=\"tw-appearance-none tw-border-2 tw-border-gray-200 tw-rounded tw-w-8 tw-h-8 tw-p-0 tw-bg-none tw-shadow-none tw-cursor-pointer tw-transition-colors focus:tw-border-blue-500 color-input\">\n </ng-container>\n <!-- Number input for line heights -->\n <ng-container\n *ngIf=\"!item.varName.includes('color') && item.type === 'number' && group.label !== 'Font Sizes'\">\n <input [id]=\"item.varName\" type=\"number\" [step]=\"item.varName.includes('line-height') ? 0.1 : 0.001\"\n [min]=\"item.min ?? null\" [max]=\"item.max ?? null\" [(ngModel)]=\"item.value\"\n (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-16 tw-text-right tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n <span class=\"tw-text-xs tw-text-gray-400\" *ngIf=\"!item.varName.includes('line-height')\">rem</span>\n </ng-container>\n <!-- Text input fallback (if needed) -->\n <ng-container *ngIf=\"!item.varName.includes('color') && item.type !== 'number'\">\n <input [id]=\"item.varName\" type=\"text\" [(ngModel)]=\"item.value\" (input)=\"onTypographyChange($event, item)\"\n class=\"tw-w-24 tw-text-sm tw-border tw-border-gray-300 tw-rounded tw-px-2 tw-py-1 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-blue-500 focus:tw-border-transparent theme-input\">\n </ng-container>\n <div class=\"tw-flex tw-flex-col tw-gap-0.5\">\n <label [for]=\"item.varName\" class=\"tw-text-sm tw-font-medium tw-text-gray-700\">{{ item.label }}</label>\n <span class=\"tw-text-xs tw-text-gray-500 tw-font-mono\">{{ item.value }}</span>\n </div>\n </ng-container>\n </div>\n </div>\n </section>\n </div>\n\n <!-- STICKY ACTION BUTTONS SECTION -->\n <div class=\"tw-bg-white tw-sticky tw-bottom-0 tw-border-t tw-border-gray-200 tw-z-10 tw-flex-shrink-0 tw-p-3 tw-shadow-lg sticky-action-buttons\">\n <div class=\"tw-flex tw-gap-2 tw-justify-end\">\n <button cideEleButton \n variant=\"outline\" \n size=\"xs\" \n (btnClick)=\"onReset()\" \n [disabled]=\"!hasChangesFromOriginal()\"\n class=\"tw-transition-all tw-duration-200 hover:tw-scale-105 action-button\">\n Reset to Original\n </button>\n <button cideEleButton \n variant=\"primary\" \n size=\"xs\" \n (btnClick)=\"onSave()\" \n [disabled]=\"!hasUnsavedChanges()\"\n class=\"tw-transition-all tw-duration-200 hover:tw-scale-105 action-button\">\n Save Changes\n </button>\n </div>\n </div>\n</div>"],"names":[],"mappings":"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"}