@ojiepermana/angular 0.0.2

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 (51) hide show
  1. package/README.md +237 -0
  2. package/fesm2022/ojiepermana-angular-internal.mjs +58 -0
  3. package/fesm2022/ojiepermana-angular-internal.mjs.map +1 -0
  4. package/fesm2022/ojiepermana-angular-layout.mjs +471 -0
  5. package/fesm2022/ojiepermana-angular-layout.mjs.map +1 -0
  6. package/fesm2022/ojiepermana-angular-shell.mjs +14 -0
  7. package/fesm2022/ojiepermana-angular-shell.mjs.map +1 -0
  8. package/fesm2022/ojiepermana-angular-theme-component.mjs +249 -0
  9. package/fesm2022/ojiepermana-angular-theme-component.mjs.map +1 -0
  10. package/fesm2022/ojiepermana-angular-theme-directive.mjs +29 -0
  11. package/fesm2022/ojiepermana-angular-theme-directive.mjs.map +1 -0
  12. package/fesm2022/ojiepermana-angular-theme-service.mjs +243 -0
  13. package/fesm2022/ojiepermana-angular-theme-service.mjs.map +1 -0
  14. package/fesm2022/ojiepermana-angular-theme.mjs +6 -0
  15. package/fesm2022/ojiepermana-angular-theme.mjs.map +1 -0
  16. package/fesm2022/ojiepermana-angular.mjs +6 -0
  17. package/fesm2022/ojiepermana-angular.mjs.map +1 -0
  18. package/layout/README.md +143 -0
  19. package/layout/styles/index.css +157 -0
  20. package/package.json +59 -0
  21. package/shell/README.md +37 -0
  22. package/styles/index.css +2 -0
  23. package/styles/resets.css +22 -0
  24. package/theme/README.md +382 -0
  25. package/theme/styles/adapters/material-ui/index.css +210 -0
  26. package/theme/styles/index.css +8 -0
  27. package/theme/styles/layout/index.css +1 -0
  28. package/theme/styles/modes/dark.css +84 -0
  29. package/theme/styles/presets/colors/blue.css +10 -0
  30. package/theme/styles/presets/colors/brand.css +11 -0
  31. package/theme/styles/presets/colors/cyan.css +10 -0
  32. package/theme/styles/presets/colors/green.css +10 -0
  33. package/theme/styles/presets/colors/index.css +7 -0
  34. package/theme/styles/presets/colors/orange.css +10 -0
  35. package/theme/styles/presets/colors/purple.css +10 -0
  36. package/theme/styles/presets/colors/red.css +10 -0
  37. package/theme/styles/presets/styles/flat.css +30 -0
  38. package/theme/styles/presets/styles/glass.css +34 -0
  39. package/theme/styles/presets/styles/index.css +2 -0
  40. package/theme/styles/roles/index.css +49 -0
  41. package/theme/styles/tokens/foundation.css +139 -0
  42. package/theme/styles/tokens/semantic.css +87 -0
  43. package/theme/styles/utilities/index.css +88 -0
  44. package/types/ojiepermana-angular-internal.d.ts +26 -0
  45. package/types/ojiepermana-angular-layout.d.ts +90 -0
  46. package/types/ojiepermana-angular-shell.d.ts +12 -0
  47. package/types/ojiepermana-angular-theme-component.d.ts +46 -0
  48. package/types/ojiepermana-angular-theme-directive.d.ts +10 -0
  49. package/types/ojiepermana-angular-theme-service.d.ts +68 -0
  50. package/types/ojiepermana-angular-theme.d.ts +2 -0
  51. package/types/ojiepermana-angular.d.ts +2 -0
@@ -0,0 +1,249 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, computed, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { MatIconButton } from '@angular/material/button';
4
+ import { MatTooltip } from '@angular/material/tooltip';
5
+ import { libraryLucideConfigProvider } from '@ojiepermana/angular/internal';
6
+ import { LucideBlend, LucideLayoutDashboard, LucideSun, LucideMoonStar, LucideMonitorCog } from '@lucide/angular';
7
+ import { ThemeService } from '@ojiepermana/angular/theme/service';
8
+ import { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';
9
+
10
+ class StyleSwitcherComponent {
11
+ theme = inject(ThemeService);
12
+ label = computed(() => this.theme.style() === 'glass' ? 'Glass style enabled' : 'Glass style disabled', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
13
+ toggle() {
14
+ this.theme.setStyle(this.theme.style() === 'flat' ? 'glass' : 'flat');
15
+ }
16
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: StyleSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
17
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: StyleSwitcherComponent, isStandalone: true, selector: "style-switcher", providers: [libraryLucideConfigProvider], ngImport: i0, template: `
18
+ <button
19
+ class="ngt-icon-button"
20
+ type="button"
21
+ mat-icon-button
22
+ aria-label="Glass style"
23
+ [attr.aria-pressed]="theme.style() === 'glass'"
24
+ [matTooltip]="label()"
25
+ (click)="toggle()"
26
+ >
27
+ @if (theme.style() === 'flat') {
28
+ <svg lucideLayoutDashboard aria-hidden="true"></svg>
29
+ } @else {
30
+ <svg lucideBlend aria-hidden="true"></svg>
31
+ }
32
+ </button>
33
+ `, isInline: true, dependencies: [{ kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: LucideBlend, selector: "svg[lucideBlend]" }, { kind: "component", type: LucideLayoutDashboard, selector: "svg[lucideLayoutDashboard]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
34
+ }
35
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: StyleSwitcherComponent, decorators: [{
36
+ type: Component,
37
+ args: [{
38
+ selector: 'style-switcher',
39
+ imports: [MatIconButton, MatTooltip, LucideBlend, LucideLayoutDashboard],
40
+ providers: [libraryLucideConfigProvider],
41
+ changeDetection: ChangeDetectionStrategy.OnPush,
42
+ template: `
43
+ <button
44
+ class="ngt-icon-button"
45
+ type="button"
46
+ mat-icon-button
47
+ aria-label="Glass style"
48
+ [attr.aria-pressed]="theme.style() === 'glass'"
49
+ [matTooltip]="label()"
50
+ (click)="toggle()"
51
+ >
52
+ @if (theme.style() === 'flat') {
53
+ <svg lucideLayoutDashboard aria-hidden="true"></svg>
54
+ } @else {
55
+ <svg lucideBlend aria-hidden="true"></svg>
56
+ }
57
+ </button>
58
+ `,
59
+ }]
60
+ }] });
61
+
62
+ class ColorPickerComponent {
63
+ theme = inject(ThemeService);
64
+ colors = this.theme.colorOptions;
65
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ColorPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
66
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: ColorPickerComponent, isStandalone: true, selector: "color-picker", ngImport: i0, template: `
67
+ <div class="flex items-center gap-1" role="group" aria-label="Theme colors">
68
+ @for (c of colors(); track c.value) {
69
+ <button
70
+ type="button"
71
+ class="color-picker-button focus-ring inline-flex size-11 items-center justify-center rounded-full p-1.5 transition-transform duration-150 hover:-translate-y-px"
72
+ [class.color-picker-button-selected]="theme.color() === c.value"
73
+ [attr.aria-label]="
74
+ theme.color() === c.value
75
+ ? 'Theme color: ' + c.label + ' (selected)'
76
+ : 'Theme color: ' + c.label
77
+ "
78
+ [attr.aria-pressed]="theme.color() === c.value"
79
+ [matTooltip]="c.label"
80
+ (click)="theme.setColor(c.value)"
81
+ >
82
+ <span
83
+ class="color-picker-swatch size-7 rounded-full border"
84
+ [attr.data-theme-color]="c.value"
85
+ aria-hidden="true"
86
+ ></span>
87
+ </button>
88
+ }
89
+ </div>
90
+ `, isInline: true, styles: [".color-picker-button{border:1px solid transparent;background:transparent}.color-picker-button-selected{border-color:color-mix(in oklab,var(--ring) 42%,var(--border));background:color-mix(in oklab,var(--accent) 60%,transparent);box-shadow:inset 0 0 0 1px color-mix(in oklab,var(--ring) 26%,transparent)}.color-picker-swatch{background:var(--theme-primary);border-color:color-mix(in oklab,var(--theme-primary) 42%,white 58%)}\n"], dependencies: [{ kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
91
+ }
92
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ColorPickerComponent, decorators: [{
93
+ type: Component,
94
+ args: [{ selector: 'color-picker', imports: [MatTooltip], changeDetection: ChangeDetectionStrategy.OnPush, template: `
95
+ <div class="flex items-center gap-1" role="group" aria-label="Theme colors">
96
+ @for (c of colors(); track c.value) {
97
+ <button
98
+ type="button"
99
+ class="color-picker-button focus-ring inline-flex size-11 items-center justify-center rounded-full p-1.5 transition-transform duration-150 hover:-translate-y-px"
100
+ [class.color-picker-button-selected]="theme.color() === c.value"
101
+ [attr.aria-label]="
102
+ theme.color() === c.value
103
+ ? 'Theme color: ' + c.label + ' (selected)'
104
+ : 'Theme color: ' + c.label
105
+ "
106
+ [attr.aria-pressed]="theme.color() === c.value"
107
+ [matTooltip]="c.label"
108
+ (click)="theme.setColor(c.value)"
109
+ >
110
+ <span
111
+ class="color-picker-swatch size-7 rounded-full border"
112
+ [attr.data-theme-color]="c.value"
113
+ aria-hidden="true"
114
+ ></span>
115
+ </button>
116
+ }
117
+ </div>
118
+ `, styles: [".color-picker-button{border:1px solid transparent;background:transparent}.color-picker-button-selected{border-color:color-mix(in oklab,var(--ring) 42%,var(--border));background:color-mix(in oklab,var(--accent) 60%,transparent);box-shadow:inset 0 0 0 1px color-mix(in oklab,var(--ring) 26%,transparent)}.color-picker-swatch{background:var(--theme-primary);border-color:color-mix(in oklab,var(--theme-primary) 42%,white 58%)}\n"] }]
119
+ }] });
120
+
121
+ class SchemeSwitcherComponent {
122
+ theme = inject(ThemeService);
123
+ options = [
124
+ { value: 'light', label: 'Light' },
125
+ { value: 'dark', label: 'Dark' },
126
+ { value: 'system', label: 'System' },
127
+ ];
128
+ currentOption = computed(() => this.options.find((option) => option.value === this.theme.scheme()) ?? this.options[2], ...(ngDevMode ? [{ debugName: "currentOption" }] : /* istanbul ignore next */ []));
129
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SchemeSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
130
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: SchemeSwitcherComponent, isStandalone: true, selector: "scheme-switcher", providers: [libraryLucideConfigProvider], ngImport: i0, template: `
131
+ <button
132
+ class="ngt-icon-button"
133
+ type="button"
134
+ mat-icon-button
135
+ [attr.aria-label]="'Color scheme: ' + currentOption().label"
136
+ [matTooltip]="'Color scheme: ' + currentOption().label"
137
+ [matMenuTriggerFor]="menu"
138
+ >
139
+ @switch (theme.scheme()) {
140
+ @case ('light') {
141
+ <svg lucideSun aria-hidden="true"></svg>
142
+ }
143
+ @case ('dark') {
144
+ <svg lucideMoonStar aria-hidden="true"></svg>
145
+ }
146
+ @default {
147
+ <svg lucideMonitorCog aria-hidden="true"></svg>
148
+ }
149
+ }
150
+ </button>
151
+
152
+ <mat-menu #menu="matMenu">
153
+ @for (option of options; track option.value) {
154
+ <button
155
+ type="button"
156
+ mat-menu-item
157
+ role="menuitemradio"
158
+ [attr.aria-checked]="theme.scheme() === option.value"
159
+ (click)="theme.setScheme(option.value)"
160
+ >
161
+ @switch (option.value) {
162
+ @case ('light') {
163
+ <svg lucideSun aria-hidden="true"></svg>
164
+ }
165
+ @case ('dark') {
166
+ <svg lucideMoonStar aria-hidden="true"></svg>
167
+ }
168
+ @default {
169
+ <svg lucideMonitorCog aria-hidden="true"></svg>
170
+ }
171
+ }
172
+ <span>{{ option.label }}</span>
173
+ </button>
174
+ }
175
+ </mat-menu>
176
+ `, isInline: true, dependencies: [{ kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: LucideSun, selector: "svg[lucideSun]" }, { kind: "component", type: LucideMoonStar, selector: "svg[lucideMoonStar]" }, { kind: "component", type: LucideMonitorCog, selector: "svg[lucideMonitorCog]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
177
+ }
178
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SchemeSwitcherComponent, decorators: [{
179
+ type: Component,
180
+ args: [{
181
+ selector: 'scheme-switcher',
182
+ imports: [
183
+ MatIconButton,
184
+ MatMenu,
185
+ MatMenuItem,
186
+ MatMenuTrigger,
187
+ MatTooltip,
188
+ LucideSun,
189
+ LucideMoonStar,
190
+ LucideMonitorCog,
191
+ ],
192
+ providers: [libraryLucideConfigProvider],
193
+ changeDetection: ChangeDetectionStrategy.OnPush,
194
+ template: `
195
+ <button
196
+ class="ngt-icon-button"
197
+ type="button"
198
+ mat-icon-button
199
+ [attr.aria-label]="'Color scheme: ' + currentOption().label"
200
+ [matTooltip]="'Color scheme: ' + currentOption().label"
201
+ [matMenuTriggerFor]="menu"
202
+ >
203
+ @switch (theme.scheme()) {
204
+ @case ('light') {
205
+ <svg lucideSun aria-hidden="true"></svg>
206
+ }
207
+ @case ('dark') {
208
+ <svg lucideMoonStar aria-hidden="true"></svg>
209
+ }
210
+ @default {
211
+ <svg lucideMonitorCog aria-hidden="true"></svg>
212
+ }
213
+ }
214
+ </button>
215
+
216
+ <mat-menu #menu="matMenu">
217
+ @for (option of options; track option.value) {
218
+ <button
219
+ type="button"
220
+ mat-menu-item
221
+ role="menuitemradio"
222
+ [attr.aria-checked]="theme.scheme() === option.value"
223
+ (click)="theme.setScheme(option.value)"
224
+ >
225
+ @switch (option.value) {
226
+ @case ('light') {
227
+ <svg lucideSun aria-hidden="true"></svg>
228
+ }
229
+ @case ('dark') {
230
+ <svg lucideMoonStar aria-hidden="true"></svg>
231
+ }
232
+ @default {
233
+ <svg lucideMonitorCog aria-hidden="true"></svg>
234
+ }
235
+ }
236
+ <span>{{ option.label }}</span>
237
+ </button>
238
+ }
239
+ </mat-menu>
240
+ `,
241
+ }]
242
+ }] });
243
+
244
+ /**
245
+ * Generated bundle index. Do not edit.
246
+ */
247
+
248
+ export { ColorPickerComponent, SchemeSwitcherComponent, StyleSwitcherComponent };
249
+ //# sourceMappingURL=ojiepermana-angular-theme-component.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ojiepermana-angular-theme-component.mjs","sources":["../../../projects/library/theme/component/src/style-switcher.ts","../../../projects/library/theme/component/src/color-picker.ts","../../../projects/library/theme/component/src/scheme-switcher.ts","../../../projects/library/theme/component/ojiepermana-angular-theme-component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';\nimport { MatIconButton } from '@angular/material/button';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { libraryLucideConfigProvider } from '@ojiepermana/angular/internal';\nimport { LucideBlend, LucideLayoutDashboard } from '@lucide/angular';\nimport { ThemeService } from '@ojiepermana/angular/theme/service';\n\n@Component({\n selector: 'style-switcher',\n imports: [MatIconButton, MatTooltip, LucideBlend, LucideLayoutDashboard],\n providers: [libraryLucideConfigProvider],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <button\n class=\"ngt-icon-button\"\n type=\"button\"\n mat-icon-button\n aria-label=\"Glass style\"\n [attr.aria-pressed]=\"theme.style() === 'glass'\"\n [matTooltip]=\"label()\"\n (click)=\"toggle()\"\n >\n @if (theme.style() === 'flat') {\n <svg lucideLayoutDashboard aria-hidden=\"true\"></svg>\n } @else {\n <svg lucideBlend aria-hidden=\"true\"></svg>\n }\n </button>\n `,\n})\nexport class StyleSwitcherComponent {\n protected readonly theme = inject(ThemeService);\n\n protected readonly label = computed(() =>\n this.theme.style() === 'glass' ? 'Glass style enabled' : 'Glass style disabled',\n );\n\n protected toggle(): void {\n this.theme.setStyle(this.theme.style() === 'flat' ? 'glass' : 'flat');\n }\n}","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { ThemeService } from '@ojiepermana/angular/theme/service';\n\n@Component({\n selector: 'color-picker',\n imports: [MatTooltip],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: `\n .color-picker-button {\n border: 1px solid transparent;\n background: transparent;\n }\n\n .color-picker-button-selected {\n border-color: color-mix(in oklab, var(--ring) 42%, var(--border));\n background: color-mix(in oklab, var(--accent) 60%, transparent);\n box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--ring) 26%, transparent);\n }\n\n .color-picker-swatch {\n background: var(--theme-primary);\n border-color: color-mix(in oklab, var(--theme-primary) 42%, white 58%);\n }\n `,\n template: `\n <div class=\"flex items-center gap-1\" role=\"group\" aria-label=\"Theme colors\">\n @for (c of colors(); track c.value) {\n <button\n type=\"button\"\n class=\"color-picker-button focus-ring inline-flex size-11 items-center justify-center rounded-full p-1.5 transition-transform duration-150 hover:-translate-y-px\"\n [class.color-picker-button-selected]=\"theme.color() === c.value\"\n [attr.aria-label]=\"\n theme.color() === c.value\n ? 'Theme color: ' + c.label + ' (selected)'\n : 'Theme color: ' + c.label\n \"\n [attr.aria-pressed]=\"theme.color() === c.value\"\n [matTooltip]=\"c.label\"\n (click)=\"theme.setColor(c.value)\"\n >\n <span\n class=\"color-picker-swatch size-7 rounded-full border\"\n [attr.data-theme-color]=\"c.value\"\n aria-hidden=\"true\"\n ></span>\n </button>\n }\n </div>\n `,\n})\nexport class ColorPickerComponent {\n protected readonly theme = inject(ThemeService);\n\n protected readonly colors = this.theme.colorOptions;\n}\n","import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';\nimport { MatIconButton } from '@angular/material/button';\nimport { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { libraryLucideConfigProvider } from '@ojiepermana/angular/internal';\nimport { LucideMonitorCog, LucideMoonStar, LucideSun } from '@lucide/angular';\nimport { ThemeService } from '@ojiepermana/angular/theme/service';\n\n@Component({\n selector: 'scheme-switcher',\n imports: [\n MatIconButton,\n MatMenu,\n MatMenuItem,\n MatMenuTrigger,\n MatTooltip,\n LucideSun,\n LucideMoonStar,\n LucideMonitorCog,\n ],\n providers: [libraryLucideConfigProvider],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <button\n class=\"ngt-icon-button\"\n type=\"button\"\n mat-icon-button\n [attr.aria-label]=\"'Color scheme: ' + currentOption().label\"\n [matTooltip]=\"'Color scheme: ' + currentOption().label\"\n [matMenuTriggerFor]=\"menu\"\n >\n @switch (theme.scheme()) {\n @case ('light') {\n <svg lucideSun aria-hidden=\"true\"></svg>\n }\n @case ('dark') {\n <svg lucideMoonStar aria-hidden=\"true\"></svg>\n }\n @default {\n <svg lucideMonitorCog aria-hidden=\"true\"></svg>\n }\n }\n </button>\n\n <mat-menu #menu=\"matMenu\">\n @for (option of options; track option.value) {\n <button\n type=\"button\"\n mat-menu-item\n role=\"menuitemradio\"\n [attr.aria-checked]=\"theme.scheme() === option.value\"\n (click)=\"theme.setScheme(option.value)\"\n >\n @switch (option.value) {\n @case ('light') {\n <svg lucideSun aria-hidden=\"true\"></svg>\n }\n @case ('dark') {\n <svg lucideMoonStar aria-hidden=\"true\"></svg>\n }\n @default {\n <svg lucideMonitorCog aria-hidden=\"true\"></svg>\n }\n }\n <span>{{ option.label }}</span>\n </button>\n }\n </mat-menu>\n `,\n})\nexport class SchemeSwitcherComponent {\n protected readonly theme = inject(ThemeService);\n\n protected readonly options = [\n { value: 'light' as const, label: 'Light' },\n { value: 'dark' as const, label: 'Dark' },\n { value: 'system' as const, label: 'System' },\n ];\n\n protected readonly currentOption = computed(\n () => this.options.find((option) => option.value === this.theme.scheme()) ?? this.options[2],\n );\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, Directive } from '@angular/core';
3
+ import { ThemeService } from '@ojiepermana/angular/theme/service';
4
+
5
+ class ThemeHostDirective {
6
+ theme = inject(ThemeService);
7
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ThemeHostDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
8
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: ThemeHostDirective, isStandalone: true, selector: "[ngtThemeHost]", host: { properties: { "class.dark": "theme.resolvedScheme() === \"dark\"", "style.color-scheme": "theme.resolvedScheme()", "attr.data-theme-scheme": "theme.scheme()", "attr.data-theme-color": "theme.color()", "attr.data-theme-style": "theme.style()" } }, ngImport: i0 });
9
+ }
10
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ThemeHostDirective, decorators: [{
11
+ type: Directive,
12
+ args: [{
13
+ selector: '[ngtThemeHost]',
14
+ host: {
15
+ '[class.dark]': 'theme.resolvedScheme() === "dark"',
16
+ '[style.color-scheme]': 'theme.resolvedScheme()',
17
+ '[attr.data-theme-scheme]': 'theme.scheme()',
18
+ '[attr.data-theme-color]': 'theme.color()',
19
+ '[attr.data-theme-style]': 'theme.style()',
20
+ },
21
+ }]
22
+ }] });
23
+
24
+ /**
25
+ * Generated bundle index. Do not edit.
26
+ */
27
+
28
+ export { ThemeHostDirective };
29
+ //# sourceMappingURL=ojiepermana-angular-theme-directive.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ojiepermana-angular-theme-directive.mjs","sources":["../../../projects/library/theme/directive/src/theme-host.directive.ts","../../../projects/library/theme/directive/ojiepermana-angular-theme-directive.ts"],"sourcesContent":["import { Directive, inject } from '@angular/core';\nimport { ThemeService } from '@ojiepermana/angular/theme/service';\n\n@Directive({\n selector: '[ngtThemeHost]',\n host: {\n '[class.dark]': 'theme.resolvedScheme() === \"dark\"',\n '[style.color-scheme]': 'theme.resolvedScheme()',\n '[attr.data-theme-scheme]': 'theme.scheme()',\n '[attr.data-theme-color]': 'theme.color()',\n '[attr.data-theme-style]': 'theme.style()',\n },\n})\nexport class ThemeHostDirective {\n protected readonly theme = inject(ThemeService);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;MAaa,kBAAkB,CAAA;AACV,IAAA,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC;uGADpC,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAlB,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,YAAA,EAAA,qCAAA,EAAA,oBAAA,EAAA,wBAAA,EAAA,wBAAA,EAAA,gBAAA,EAAA,uBAAA,EAAA,eAAA,EAAA,uBAAA,EAAA,eAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAlB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAV9B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,gBAAgB;AAC1B,oBAAA,IAAI,EAAE;AACJ,wBAAA,cAAc,EAAE,mCAAmC;AACnD,wBAAA,sBAAsB,EAAE,wBAAwB;AAChD,wBAAA,0BAA0B,EAAE,gBAAgB;AAC5C,wBAAA,yBAAyB,EAAE,eAAe;AAC1C,wBAAA,yBAAyB,EAAE,eAAe;AAC3C,qBAAA;AACF,iBAAA;;;ACZD;;AAEG;;;;"}
@@ -0,0 +1,243 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, inject, DestroyRef, PLATFORM_ID, signal, computed, effect, Injectable, isDevMode, makeEnvironmentProviders } from '@angular/core';
3
+ import { DOCUMENT, isPlatformBrowser } from '@angular/common';
4
+ import { LocalStorageStateAdapter } from '@ojiepermana/angular/internal';
5
+
6
+ const DEFAULT_NG_THEME_CONFIG = {
7
+ defaultScheme: 'system',
8
+ defaultColor: 'brand',
9
+ defaultStyle: 'flat',
10
+ };
11
+ const NG_THEME_CONFIG = new InjectionToken('NG_THEME_CONFIG', {
12
+ providedIn: 'root',
13
+ factory: () => ({ ...DEFAULT_NG_THEME_CONFIG }),
14
+ });
15
+
16
+ const THEME_SCHEMES = ['light', 'dark', 'system'];
17
+ const THEME_COLORS = ['brand', 'blue', 'green', 'red', 'cyan', 'purple', 'orange'];
18
+ const THEME_STYLES = ['flat', 'glass'];
19
+ const THEME_SCHEME_SET = new Set(THEME_SCHEMES);
20
+ const THEME_COLOR_SET = new Set(THEME_COLORS);
21
+ const THEME_STYLE_SET = new Set(THEME_STYLES);
22
+ function isThemeScheme(value) {
23
+ return typeof value === 'string' && THEME_SCHEME_SET.has(value);
24
+ }
25
+ function isThemeColor(value) {
26
+ return typeof value === 'string' && THEME_COLOR_SET.has(value);
27
+ }
28
+ function isThemeStyle(value) {
29
+ return typeof value === 'string' && THEME_STYLE_SET.has(value);
30
+ }
31
+
32
+ const THEME_COLOR_OPTIONS = [
33
+ { value: 'brand', label: 'Brand' },
34
+ { value: 'blue', label: 'Blue' },
35
+ { value: 'green', label: 'Green' },
36
+ { value: 'red', label: 'Red' },
37
+ { value: 'cyan', label: 'Cyan' },
38
+ { value: 'purple', label: 'Purple' },
39
+ { value: 'orange', label: 'Orange' },
40
+ ];
41
+ function createThemeColorOptions(allowedColors, colorLabels) {
42
+ const allowedSet = allowedColors ? new Set(allowedColors) : null;
43
+ return THEME_COLOR_OPTIONS.filter((option) => !allowedSet || allowedSet.has(option.value)).map((option) => ({
44
+ value: option.value,
45
+ label: colorLabels?.[option.value] ?? option.label,
46
+ }));
47
+ }
48
+ const STORAGE_KEYS = {
49
+ scheme: 'theme-scheme',
50
+ color: 'theme-color',
51
+ style: 'theme-style',
52
+ };
53
+ const LEGACY_STORAGE_PREFIX = 'ng-theme:v2';
54
+ class ThemeService {
55
+ config = inject(NG_THEME_CONFIG);
56
+ document = inject(DOCUMENT);
57
+ destroyRef = inject(DestroyRef);
58
+ isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
59
+ storage = new LocalStorageStateAdapter({
60
+ isBrowser: this.isBrowser,
61
+ storage: this.document.defaultView?.localStorage ?? null,
62
+ keys: STORAGE_KEYS,
63
+ legacyPrefix: LEGACY_STORAGE_PREFIX,
64
+ });
65
+ mediaQuery = this.isBrowser
66
+ ? (this.document.defaultView?.matchMedia('(prefers-color-scheme: dark)') ?? null)
67
+ : null;
68
+ systemPrefersDark = signal(this.mediaQuery?.matches ?? false, ...(ngDevMode ? [{ debugName: "systemPrefersDark" }] : /* istanbul ignore next */ []));
69
+ availableColorOptions = createThemeColorOptions(this.config.colors, this.config.colorLabels);
70
+ scheme = signal(this.storage.read('scheme', this.config.defaultScheme, isThemeScheme), ...(ngDevMode ? [{ debugName: "scheme" }] : /* istanbul ignore next */ []));
71
+ color = signal(this.storage.read('color', this.config.defaultColor, isThemeColor), ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
72
+ style = signal(this.storage.read('style', this.config.defaultStyle, isThemeStyle), ...(ngDevMode ? [{ debugName: "style" }] : /* istanbul ignore next */ []));
73
+ colorOptions = computed(() => this.availableColorOptions, ...(ngDevMode ? [{ debugName: "colorOptions" }] : /* istanbul ignore next */ []));
74
+ resolvedScheme = computed(() => {
75
+ if (this.scheme() !== 'system')
76
+ return this.scheme();
77
+ return this.systemPrefersDark() ? 'dark' : 'light';
78
+ }, ...(ngDevMode ? [{ debugName: "resolvedScheme" }] : /* istanbul ignore next */ []));
79
+ constructor() {
80
+ if (this.mediaQuery) {
81
+ const syncSystemPreference = (event) => {
82
+ this.systemPrefersDark.set(event.matches);
83
+ };
84
+ this.mediaQuery.addEventListener('change', syncSystemPreference);
85
+ this.destroyRef.onDestroy(() => {
86
+ this.mediaQuery?.removeEventListener('change', syncSystemPreference);
87
+ });
88
+ }
89
+ effect(() => {
90
+ if (this.isBrowser) {
91
+ this.applyToDOM();
92
+ }
93
+ });
94
+ }
95
+ /**
96
+ * Updates the selected theme scheme and persists the choice for future sessions.
97
+ */
98
+ setScheme(value) {
99
+ this.storage.persist('scheme', value);
100
+ this.scheme.set(value);
101
+ }
102
+ /**
103
+ * Updates the active theme color when it is part of the configured preset list.
104
+ */
105
+ setColor(value) {
106
+ if (!this.colorOptions().some((option) => option.value === value)) {
107
+ return;
108
+ }
109
+ this.storage.persist('color', value);
110
+ this.color.set(value);
111
+ }
112
+ /**
113
+ * Updates the active style preset and persists it to local storage.
114
+ */
115
+ setStyle(value) {
116
+ this.storage.persist('style', value);
117
+ this.style.set(value);
118
+ }
119
+ /**
120
+ * Cycles the scheme through light, dark, and system while keeping the DOM contract in sync.
121
+ */
122
+ toggleScheme() {
123
+ const next = this.scheme() === 'light' ? 'dark' : this.scheme() === 'dark' ? 'system' : 'light';
124
+ this.setScheme(next);
125
+ }
126
+ /**
127
+ * Clears persisted theme state and restores the configured defaults for all theme axes.
128
+ */
129
+ reset() {
130
+ this.storage.clear('scheme');
131
+ this.storage.clear('color');
132
+ this.storage.clear('style');
133
+ this.scheme.set(this.config.defaultScheme);
134
+ this.color.set(this.config.defaultColor);
135
+ this.style.set(this.config.defaultStyle);
136
+ }
137
+ applyToDOM() {
138
+ const element = this.document.documentElement;
139
+ element.classList.toggle('dark', this.resolvedScheme() === 'dark');
140
+ element.dataset['themeScheme'] = this.scheme();
141
+ element.dataset['themeColor'] = this.color();
142
+ element.dataset['themeStyle'] = this.style();
143
+ element.style.colorScheme = this.resolvedScheme();
144
+ }
145
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
146
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ThemeService, providedIn: 'root' });
147
+ }
148
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ThemeService, decorators: [{
149
+ type: Injectable,
150
+ args: [{ providedIn: 'root' }]
151
+ }], ctorParameters: () => [] });
152
+
153
+ function warnInvalidThemeConfig(message) {
154
+ if (isDevMode()) {
155
+ console.warn(`[provideNgTheme] ${message}`);
156
+ }
157
+ }
158
+ function normalizeThemeScheme(value) {
159
+ if (typeof value === 'undefined' || isThemeScheme(value)) {
160
+ return value ?? DEFAULT_NG_THEME_CONFIG.defaultScheme;
161
+ }
162
+ warnInvalidThemeConfig(`Ignoring invalid defaultScheme ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_THEME_CONFIG.defaultScheme)}.`);
163
+ return DEFAULT_NG_THEME_CONFIG.defaultScheme;
164
+ }
165
+ function normalizeThemeColor(value) {
166
+ if (typeof value === 'undefined' || isThemeColor(value)) {
167
+ return value ?? DEFAULT_NG_THEME_CONFIG.defaultColor;
168
+ }
169
+ warnInvalidThemeConfig(`Ignoring invalid defaultColor ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_THEME_CONFIG.defaultColor)}.`);
170
+ return DEFAULT_NG_THEME_CONFIG.defaultColor;
171
+ }
172
+ function normalizeThemeStyle(value) {
173
+ if (typeof value === 'undefined' || isThemeStyle(value)) {
174
+ return value ?? DEFAULT_NG_THEME_CONFIG.defaultStyle;
175
+ }
176
+ warnInvalidThemeConfig(`Ignoring invalid defaultStyle ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_THEME_CONFIG.defaultStyle)}.`);
177
+ return DEFAULT_NG_THEME_CONFIG.defaultStyle;
178
+ }
179
+ function normalizeThemeColors(value) {
180
+ if (typeof value === 'undefined') {
181
+ return undefined;
182
+ }
183
+ if (!Array.isArray(value)) {
184
+ warnInvalidThemeConfig('Ignoring invalid colors config because it is not an array.');
185
+ return undefined;
186
+ }
187
+ const normalizedColors = Array.from(new Set(value.filter(isThemeColor)));
188
+ if (normalizedColors.length !== value.length) {
189
+ warnInvalidThemeConfig('Ignoring unsupported values in colors config.');
190
+ }
191
+ return normalizedColors.length > 0 ? normalizedColors : undefined;
192
+ }
193
+ function normalizeThemeColorLabels(value) {
194
+ if (typeof value === 'undefined') {
195
+ return undefined;
196
+ }
197
+ if (!value || Array.isArray(value) || typeof value !== 'object') {
198
+ warnInvalidThemeConfig('Ignoring invalid colorLabels config because it is not an object map.');
199
+ return undefined;
200
+ }
201
+ const entries = Object.entries(value);
202
+ const normalizedEntries = entries.flatMap(([color, label]) => {
203
+ if (isThemeColor(color) && typeof label === 'string' && label.trim().length > 0) {
204
+ return [[color, label.trim()]];
205
+ }
206
+ return [];
207
+ });
208
+ if (normalizedEntries.length !== entries.length) {
209
+ warnInvalidThemeConfig('Ignoring unsupported entries in colorLabels config.');
210
+ }
211
+ return normalizedEntries.length > 0
212
+ ? Object.fromEntries(normalizedEntries)
213
+ : undefined;
214
+ }
215
+ function normalizeThemeConfig(config) {
216
+ const colors = normalizeThemeColors(config.colors);
217
+ const colorLabels = normalizeThemeColorLabels(config.colorLabels);
218
+ let defaultColor = normalizeThemeColor(config.defaultColor);
219
+ if (colors && !colors.includes(defaultColor)) {
220
+ warnInvalidThemeConfig(`Adjusting defaultColor ${JSON.stringify(defaultColor)} to ${JSON.stringify(colors[0])} so it stays within the configured colors list.`);
221
+ defaultColor = colors[0];
222
+ }
223
+ return {
224
+ ...DEFAULT_NG_THEME_CONFIG,
225
+ defaultScheme: normalizeThemeScheme(config.defaultScheme),
226
+ defaultColor,
227
+ defaultStyle: normalizeThemeStyle(config.defaultStyle),
228
+ ...(colors ? { colors } : {}),
229
+ ...(colorLabels ? { colorLabels } : {}),
230
+ };
231
+ }
232
+ function provideNgTheme(config = {}) {
233
+ return makeEnvironmentProviders([
234
+ { provide: NG_THEME_CONFIG, useValue: normalizeThemeConfig(config) },
235
+ ]);
236
+ }
237
+
238
+ /**
239
+ * Generated bundle index. Do not edit.
240
+ */
241
+
242
+ export { NG_THEME_CONFIG, ThemeService, provideNgTheme };
243
+ //# sourceMappingURL=ojiepermana-angular-theme-service.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ojiepermana-angular-theme-service.mjs","sources":["../../../projects/library/theme/service/src/theme.token.ts","../../../projects/library/theme/service/src/theme.types.ts","../../../projects/library/theme/service/src/theme.service.ts","../../../projects/library/theme/service/src/theme.provider.ts","../../../projects/library/theme/service/ojiepermana-angular-theme-service.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { NgThemeConfig } from './theme.types';\n\nexport const DEFAULT_NG_THEME_CONFIG: NgThemeConfig = {\n defaultScheme: 'system',\n defaultColor: 'brand',\n defaultStyle: 'flat',\n};\n\nexport const NG_THEME_CONFIG = new InjectionToken<NgThemeConfig>('NG_THEME_CONFIG', {\n providedIn: 'root',\n factory: () => ({ ...DEFAULT_NG_THEME_CONFIG }),\n});\n","export const THEME_SCHEMES = ['light', 'dark', 'system'] as const;\nexport type ThemeScheme = (typeof THEME_SCHEMES)[number];\n\nexport const THEME_COLORS = ['brand', 'blue', 'green', 'red', 'cyan', 'purple', 'orange'] as const;\nexport type ThemeColor = (typeof THEME_COLORS)[number];\n\nexport const THEME_STYLES = ['flat', 'glass'] as const;\nexport type ThemeStyle = (typeof THEME_STYLES)[number];\n\nconst THEME_SCHEME_SET = new Set<ThemeScheme>(THEME_SCHEMES);\nconst THEME_COLOR_SET = new Set<ThemeColor>(THEME_COLORS);\nconst THEME_STYLE_SET = new Set<ThemeStyle>(THEME_STYLES);\n\nexport function isThemeScheme(value: unknown): value is ThemeScheme {\n return typeof value === 'string' && THEME_SCHEME_SET.has(value as ThemeScheme);\n}\n\nexport function isThemeColor(value: unknown): value is ThemeColor {\n return typeof value === 'string' && THEME_COLOR_SET.has(value as ThemeColor);\n}\n\nexport function isThemeStyle(value: unknown): value is ThemeStyle {\n return typeof value === 'string' && THEME_STYLE_SET.has(value as ThemeStyle);\n}\n\nexport interface ThemeColorOption {\n readonly value: ThemeColor;\n readonly label: string;\n}\n\nexport type ThemeColorLabels = Partial<Record<ThemeColor, string>>;\n\nexport interface NgThemeConfig {\n defaultScheme: ThemeScheme;\n defaultColor: ThemeColor;\n defaultStyle: ThemeStyle;\n colors?: readonly ThemeColor[];\n colorLabels?: ThemeColorLabels;\n}\n","import {\n DestroyRef,\n Injectable,\n PLATFORM_ID,\n computed,\n effect,\n inject,\n signal,\n} from '@angular/core';\nimport { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { LocalStorageStateAdapter } from '@ojiepermana/angular/internal';\nimport { NG_THEME_CONFIG } from './theme.token';\nimport {\n isThemeColor,\n isThemeScheme,\n isThemeStyle,\n NgThemeConfig,\n ThemeStyle,\n ThemeColor,\n ThemeColorLabels,\n ThemeColorOption,\n ThemeScheme,\n} from './theme.types';\n\nconst THEME_COLOR_OPTIONS: readonly ThemeColorOption[] = [\n { value: 'brand', label: 'Brand' },\n { value: 'blue', label: 'Blue' },\n { value: 'green', label: 'Green' },\n { value: 'red', label: 'Red' },\n { value: 'cyan', label: 'Cyan' },\n { value: 'purple', label: 'Purple' },\n { value: 'orange', label: 'Orange' },\n] as const;\n\nfunction createThemeColorOptions(\n allowedColors: readonly ThemeColor[] | undefined,\n colorLabels: ThemeColorLabels | undefined,\n): readonly ThemeColorOption[] {\n const allowedSet = allowedColors ? new Set(allowedColors) : null;\n\n return THEME_COLOR_OPTIONS.filter((option) => !allowedSet || allowedSet.has(option.value)).map(\n (option) => ({\n value: option.value,\n label: colorLabels?.[option.value] ?? option.label,\n }),\n );\n}\n\nconst STORAGE_KEYS = {\n scheme: 'theme-scheme',\n color: 'theme-color',\n style: 'theme-style',\n} as const;\n\ntype ThemeStorageAxis = keyof typeof STORAGE_KEYS;\n\nconst LEGACY_STORAGE_PREFIX = 'ng-theme:v2';\n\n@Injectable({ providedIn: 'root' })\nexport class ThemeService {\n private readonly config = inject(NG_THEME_CONFIG);\n private readonly document = inject(DOCUMENT);\n private readonly destroyRef = inject(DestroyRef);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly storage = new LocalStorageStateAdapter<ThemeStorageAxis>({\n isBrowser: this.isBrowser,\n storage: this.document.defaultView?.localStorage ?? null,\n keys: STORAGE_KEYS,\n legacyPrefix: LEGACY_STORAGE_PREFIX,\n });\n private readonly mediaQuery = this.isBrowser\n ? (this.document.defaultView?.matchMedia('(prefers-color-scheme: dark)') ?? null)\n : null;\n private readonly systemPrefersDark = signal(this.mediaQuery?.matches ?? false);\n private readonly availableColorOptions = createThemeColorOptions(\n this.config.colors,\n this.config.colorLabels,\n );\n\n readonly scheme = signal<ThemeScheme>(\n this.storage.read('scheme', this.config.defaultScheme, isThemeScheme),\n );\n readonly color = signal<ThemeColor>(\n this.storage.read('color', this.config.defaultColor, isThemeColor),\n );\n readonly style = signal<ThemeStyle>(\n this.storage.read('style', this.config.defaultStyle, isThemeStyle),\n );\n readonly colorOptions = computed<readonly ThemeColorOption[]>(() => this.availableColorOptions);\n\n readonly resolvedScheme = computed<'light' | 'dark'>(() => {\n if (this.scheme() !== 'system') return this.scheme() as 'light' | 'dark';\n return this.systemPrefersDark() ? 'dark' : 'light';\n });\n\n constructor() {\n if (this.mediaQuery) {\n const syncSystemPreference = (event: MediaQueryListEvent): void => {\n this.systemPrefersDark.set(event.matches);\n };\n\n this.mediaQuery.addEventListener('change', syncSystemPreference);\n this.destroyRef.onDestroy(() => {\n this.mediaQuery?.removeEventListener('change', syncSystemPreference);\n });\n }\n\n effect(() => {\n if (this.isBrowser) {\n this.applyToDOM();\n }\n });\n }\n\n /**\n * Updates the selected theme scheme and persists the choice for future sessions.\n */\n setScheme(value: ThemeScheme): void {\n this.storage.persist('scheme', value);\n this.scheme.set(value);\n }\n\n /**\n * Updates the active theme color when it is part of the configured preset list.\n */\n setColor(value: ThemeColor): void {\n if (!this.colorOptions().some((option) => option.value === value)) {\n return;\n }\n\n this.storage.persist('color', value);\n this.color.set(value);\n }\n\n /**\n * Updates the active style preset and persists it to local storage.\n */\n setStyle(value: ThemeStyle): void {\n this.storage.persist('style', value);\n this.style.set(value);\n }\n\n /**\n * Cycles the scheme through light, dark, and system while keeping the DOM contract in sync.\n */\n toggleScheme(): void {\n const next: ThemeScheme =\n this.scheme() === 'light' ? 'dark' : this.scheme() === 'dark' ? 'system' : 'light';\n this.setScheme(next);\n }\n\n /**\n * Clears persisted theme state and restores the configured defaults for all theme axes.\n */\n reset(): void {\n this.storage.clear('scheme');\n this.storage.clear('color');\n this.storage.clear('style');\n this.scheme.set(this.config.defaultScheme);\n this.color.set(this.config.defaultColor);\n this.style.set(this.config.defaultStyle);\n }\n\n private applyToDOM(): void {\n const element = this.document.documentElement;\n\n element.classList.toggle('dark', this.resolvedScheme() === 'dark');\n element.dataset['themeScheme'] = this.scheme();\n element.dataset['themeColor'] = this.color();\n element.dataset['themeStyle'] = this.style();\n element.style.colorScheme = this.resolvedScheme();\n }\n}\n","import { EnvironmentProviders, isDevMode, makeEnvironmentProviders } from '@angular/core';\nimport { DEFAULT_NG_THEME_CONFIG, NG_THEME_CONFIG } from './theme.token';\nimport {\n isThemeColor,\n isThemeScheme,\n isThemeStyle,\n NgThemeConfig,\n ThemeColor,\n ThemeColorLabels,\n ThemeScheme,\n ThemeStyle,\n} from './theme.types';\n\nfunction warnInvalidThemeConfig(message: string): void {\n if (isDevMode()) {\n console.warn(`[provideNgTheme] ${message}`);\n }\n}\n\nfunction normalizeThemeScheme(value: unknown): ThemeScheme {\n if (typeof value === 'undefined' || isThemeScheme(value)) {\n return value ?? DEFAULT_NG_THEME_CONFIG.defaultScheme;\n }\n\n warnInvalidThemeConfig(\n `Ignoring invalid defaultScheme ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_THEME_CONFIG.defaultScheme)}.`,\n );\n\n return DEFAULT_NG_THEME_CONFIG.defaultScheme;\n}\n\nfunction normalizeThemeColor(value: unknown): ThemeColor {\n if (typeof value === 'undefined' || isThemeColor(value)) {\n return value ?? DEFAULT_NG_THEME_CONFIG.defaultColor;\n }\n\n warnInvalidThemeConfig(\n `Ignoring invalid defaultColor ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_THEME_CONFIG.defaultColor)}.`,\n );\n\n return DEFAULT_NG_THEME_CONFIG.defaultColor;\n}\n\nfunction normalizeThemeStyle(value: unknown): ThemeStyle {\n if (typeof value === 'undefined' || isThemeStyle(value)) {\n return value ?? DEFAULT_NG_THEME_CONFIG.defaultStyle;\n }\n\n warnInvalidThemeConfig(\n `Ignoring invalid defaultStyle ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_THEME_CONFIG.defaultStyle)}.`,\n );\n\n return DEFAULT_NG_THEME_CONFIG.defaultStyle;\n}\n\nfunction normalizeThemeColors(value: unknown): readonly ThemeColor[] | undefined {\n if (typeof value === 'undefined') {\n return undefined;\n }\n\n if (!Array.isArray(value)) {\n warnInvalidThemeConfig('Ignoring invalid colors config because it is not an array.');\n return undefined;\n }\n\n const normalizedColors = Array.from(new Set(value.filter(isThemeColor)));\n\n if (normalizedColors.length !== value.length) {\n warnInvalidThemeConfig('Ignoring unsupported values in colors config.');\n }\n\n return normalizedColors.length > 0 ? normalizedColors : undefined;\n}\n\nfunction normalizeThemeColorLabels(value: unknown): ThemeColorLabels | undefined {\n if (typeof value === 'undefined') {\n return undefined;\n }\n\n if (!value || Array.isArray(value) || typeof value !== 'object') {\n warnInvalidThemeConfig('Ignoring invalid colorLabels config because it is not an object map.');\n return undefined;\n }\n\n const entries = Object.entries(value);\n const normalizedEntries = entries.flatMap(([color, label]) => {\n if (isThemeColor(color) && typeof label === 'string' && label.trim().length > 0) {\n return [[color, label.trim()] as const];\n }\n\n return [];\n });\n\n if (normalizedEntries.length !== entries.length) {\n warnInvalidThemeConfig('Ignoring unsupported entries in colorLabels config.');\n }\n\n return normalizedEntries.length > 0\n ? (Object.fromEntries(normalizedEntries) as ThemeColorLabels)\n : undefined;\n}\n\nfunction normalizeThemeConfig(config: Partial<NgThemeConfig>): NgThemeConfig {\n const colors = normalizeThemeColors(config.colors);\n const colorLabels = normalizeThemeColorLabels(config.colorLabels);\n let defaultColor = normalizeThemeColor(config.defaultColor);\n\n if (colors && !colors.includes(defaultColor)) {\n warnInvalidThemeConfig(\n `Adjusting defaultColor ${JSON.stringify(defaultColor)} to ${JSON.stringify(colors[0])} so it stays within the configured colors list.`,\n );\n defaultColor = colors[0];\n }\n\n return {\n ...DEFAULT_NG_THEME_CONFIG,\n defaultScheme: normalizeThemeScheme(config.defaultScheme),\n defaultColor,\n defaultStyle: normalizeThemeStyle(config.defaultStyle),\n ...(colors ? { colors } : {}),\n ...(colorLabels ? { colorLabels } : {}),\n };\n}\n\nexport function provideNgTheme(config: Partial<NgThemeConfig> = {}): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: NG_THEME_CONFIG, useValue: normalizeThemeConfig(config) },\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /* Domain namespace marker for nested theme entry points. */
2
+
3
+ /**
4
+ * Generated bundle index. Do not edit.
5
+ */
6
+ //# sourceMappingURL=ojiepermana-angular-theme.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ojiepermana-angular-theme.mjs","sources":["../../../projects/library/theme/public-api.ts","../../../projects/library/theme/ojiepermana-angular-theme.ts"],"sourcesContent":["/* Domain namespace marker for nested theme entry points. */\n\nexport {};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"AAAA;;ACAA;;AAEG"}
@@ -0,0 +1,6 @@
1
+ /* Public API Surface of @ojiepermana/angular */
2
+
3
+ /**
4
+ * Generated bundle index. Do not edit.
5
+ */
6
+ //# sourceMappingURL=ojiepermana-angular.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ojiepermana-angular.mjs","sources":["../../../projects/library/public-api.ts","../../../projects/library/ojiepermana-angular.ts"],"sourcesContent":["/* Public API Surface of @ojiepermana/angular */\n\nexport {};","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"AAAA;;ACAA;;AAEG"}