@atomng/ui 1.0.0
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.
- package/README.md +401 -0
- package/atomng-ui.d.ts.map +1 -0
- package/atoms/atomng-ui-atoms.d.ts.map +1 -0
- package/atoms/avatar/avatar.component.d.ts +24 -0
- package/atoms/avatar/avatar.component.d.ts.map +1 -0
- package/atoms/avatar/index.d.ts +3 -0
- package/atoms/avatar/index.d.ts.map +1 -0
- package/atoms/badge/badge.component.d.ts +23 -0
- package/atoms/badge/badge.component.d.ts.map +1 -0
- package/atoms/badge/index.d.ts +3 -0
- package/atoms/badge/index.d.ts.map +1 -0
- package/atoms/button/button.component.d.ts +47 -0
- package/atoms/button/button.component.d.ts.map +1 -0
- package/atoms/button/index.d.ts +3 -0
- package/atoms/button/index.d.ts.map +1 -0
- package/atoms/checkbox/checkbox.component.d.ts +28 -0
- package/atoms/checkbox/checkbox.component.d.ts.map +1 -0
- package/atoms/checkbox/index.d.ts +2 -0
- package/atoms/checkbox/index.d.ts.map +1 -0
- package/atoms/chip/chip.component.d.ts +17 -0
- package/atoms/chip/chip.component.d.ts.map +1 -0
- package/atoms/chip/index.d.ts +2 -0
- package/atoms/chip/index.d.ts.map +1 -0
- package/atoms/index.d.ts +14 -0
- package/atoms/index.d.ts.map +1 -0
- package/atoms/kbd/index.d.ts +2 -0
- package/atoms/kbd/index.d.ts.map +1 -0
- package/atoms/kbd/kbd.component.d.ts +14 -0
- package/atoms/kbd/kbd.component.d.ts.map +1 -0
- package/atoms/link/index.d.ts +2 -0
- package/atoms/link/index.d.ts.map +1 -0
- package/atoms/link/link.component.d.ts +15 -0
- package/atoms/link/link.component.d.ts.map +1 -0
- package/atoms/progress/index.d.ts +3 -0
- package/atoms/progress/index.d.ts.map +1 -0
- package/atoms/progress/progress.component.d.ts +20 -0
- package/atoms/progress/progress.component.d.ts.map +1 -0
- package/atoms/separator/index.d.ts +2 -0
- package/atoms/separator/index.d.ts.map +1 -0
- package/atoms/separator/separator.component.d.ts +13 -0
- package/atoms/separator/separator.component.d.ts.map +1 -0
- package/atoms/skeleton/index.d.ts +2 -0
- package/atoms/skeleton/index.d.ts.map +1 -0
- package/atoms/skeleton/skeleton.component.d.ts +13 -0
- package/atoms/skeleton/skeleton.component.d.ts.map +1 -0
- package/atoms/slider/index.d.ts +2 -0
- package/atoms/slider/index.d.ts.map +1 -0
- package/atoms/slider/slider.component.d.ts +27 -0
- package/atoms/slider/slider.component.d.ts.map +1 -0
- package/atoms/switch/index.d.ts +2 -0
- package/atoms/switch/index.d.ts.map +1 -0
- package/atoms/switch/switch.component.d.ts +25 -0
- package/atoms/switch/switch.component.d.ts.map +1 -0
- package/atoms/tooltip/index.d.ts +2 -0
- package/atoms/tooltip/index.d.ts.map +1 -0
- package/atoms/tooltip/tooltip.component.d.ts +15 -0
- package/atoms/tooltip/tooltip.component.d.ts.map +1 -0
- package/fesm2022/atomng-ui-atoms.mjs +778 -0
- package/fesm2022/atomng-ui-atoms.mjs.map +1 -0
- package/fesm2022/atomng-ui-molecules.mjs +1590 -0
- package/fesm2022/atomng-ui-molecules.mjs.map +1 -0
- package/fesm2022/atomng-ui-organisms.mjs +1346 -0
- package/fesm2022/atomng-ui-organisms.mjs.map +1 -0
- package/fesm2022/atomng-ui-tokens.mjs +499 -0
- package/fesm2022/atomng-ui-tokens.mjs.map +1 -0
- package/fesm2022/atomng-ui.mjs +4184 -0
- package/fesm2022/atomng-ui.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/index.d.ts.map +1 -0
- package/lib/atoms/avatar/avatar.component.d.ts +24 -0
- package/lib/atoms/avatar/avatar.component.d.ts.map +1 -0
- package/lib/atoms/avatar/index.d.ts +3 -0
- package/lib/atoms/avatar/index.d.ts.map +1 -0
- package/lib/atoms/badge/badge.component.d.ts +23 -0
- package/lib/atoms/badge/badge.component.d.ts.map +1 -0
- package/lib/atoms/badge/index.d.ts +3 -0
- package/lib/atoms/badge/index.d.ts.map +1 -0
- package/lib/atoms/button/button.component.d.ts +47 -0
- package/lib/atoms/button/button.component.d.ts.map +1 -0
- package/lib/atoms/button/index.d.ts +3 -0
- package/lib/atoms/button/index.d.ts.map +1 -0
- package/lib/atoms/checkbox/checkbox.component.d.ts +28 -0
- package/lib/atoms/checkbox/checkbox.component.d.ts.map +1 -0
- package/lib/atoms/checkbox/index.d.ts +2 -0
- package/lib/atoms/checkbox/index.d.ts.map +1 -0
- package/lib/atoms/chip/chip.component.d.ts +17 -0
- package/lib/atoms/chip/chip.component.d.ts.map +1 -0
- package/lib/atoms/chip/index.d.ts +2 -0
- package/lib/atoms/chip/index.d.ts.map +1 -0
- package/lib/atoms/index.d.ts +14 -0
- package/lib/atoms/index.d.ts.map +1 -0
- package/lib/atoms/kbd/index.d.ts +2 -0
- package/lib/atoms/kbd/index.d.ts.map +1 -0
- package/lib/atoms/kbd/kbd.component.d.ts +14 -0
- package/lib/atoms/kbd/kbd.component.d.ts.map +1 -0
- package/lib/atoms/link/index.d.ts +2 -0
- package/lib/atoms/link/index.d.ts.map +1 -0
- package/lib/atoms/link/link.component.d.ts +15 -0
- package/lib/atoms/link/link.component.d.ts.map +1 -0
- package/lib/atoms/progress/index.d.ts +3 -0
- package/lib/atoms/progress/index.d.ts.map +1 -0
- package/lib/atoms/progress/progress.component.d.ts +20 -0
- package/lib/atoms/progress/progress.component.d.ts.map +1 -0
- package/lib/atoms/separator/index.d.ts +2 -0
- package/lib/atoms/separator/index.d.ts.map +1 -0
- package/lib/atoms/separator/separator.component.d.ts +13 -0
- package/lib/atoms/separator/separator.component.d.ts.map +1 -0
- package/lib/atoms/skeleton/index.d.ts +2 -0
- package/lib/atoms/skeleton/index.d.ts.map +1 -0
- package/lib/atoms/skeleton/skeleton.component.d.ts +13 -0
- package/lib/atoms/skeleton/skeleton.component.d.ts.map +1 -0
- package/lib/atoms/slider/index.d.ts +2 -0
- package/lib/atoms/slider/index.d.ts.map +1 -0
- package/lib/atoms/slider/slider.component.d.ts +27 -0
- package/lib/atoms/slider/slider.component.d.ts.map +1 -0
- package/lib/atoms/switch/index.d.ts +2 -0
- package/lib/atoms/switch/index.d.ts.map +1 -0
- package/lib/atoms/switch/switch.component.d.ts +25 -0
- package/lib/atoms/switch/switch.component.d.ts.map +1 -0
- package/lib/atoms/tooltip/index.d.ts +2 -0
- package/lib/atoms/tooltip/index.d.ts.map +1 -0
- package/lib/atoms/tooltip/tooltip.component.d.ts +15 -0
- package/lib/atoms/tooltip/tooltip.component.d.ts.map +1 -0
- package/lib/molecules/alert/alert.component.d.ts +22 -0
- package/lib/molecules/alert/alert.component.d.ts.map +1 -0
- package/lib/molecules/alert/index.d.ts +2 -0
- package/lib/molecules/alert/index.d.ts.map +1 -0
- package/lib/molecules/avatar-group/avatar-group.component.d.ts +22 -0
- package/lib/molecules/avatar-group/avatar-group.component.d.ts.map +1 -0
- package/lib/molecules/avatar-group/index.d.ts +2 -0
- package/lib/molecules/avatar-group/index.d.ts.map +1 -0
- package/lib/molecules/breadcrumb/breadcrumb.component.d.ts +17 -0
- package/lib/molecules/breadcrumb/breadcrumb.component.d.ts.map +1 -0
- package/lib/molecules/breadcrumb/index.d.ts +2 -0
- package/lib/molecules/breadcrumb/index.d.ts.map +1 -0
- package/lib/molecules/button-group/button-group.component.d.ts +11 -0
- package/lib/molecules/button-group/button-group.component.d.ts.map +1 -0
- package/lib/molecules/button-group/index.d.ts +2 -0
- package/lib/molecules/button-group/index.d.ts.map +1 -0
- package/lib/molecules/form-field/form-field.component.d.ts +18 -0
- package/lib/molecules/form-field/form-field.component.d.ts.map +1 -0
- package/lib/molecules/form-field/index.d.ts +2 -0
- package/lib/molecules/form-field/index.d.ts.map +1 -0
- package/lib/molecules/index.d.ts +13 -0
- package/lib/molecules/index.d.ts.map +1 -0
- package/lib/molecules/input/index.d.ts +2 -0
- package/lib/molecules/input/index.d.ts.map +1 -0
- package/lib/molecules/input/input.component.d.ts +50 -0
- package/lib/molecules/input/input.component.d.ts.map +1 -0
- package/lib/molecules/pagination/index.d.ts +2 -0
- package/lib/molecules/pagination/index.d.ts.map +1 -0
- package/lib/molecules/pagination/pagination.component.d.ts +18 -0
- package/lib/molecules/pagination/pagination.component.d.ts.map +1 -0
- package/lib/molecules/select/index.d.ts +3 -0
- package/lib/molecules/select/index.d.ts.map +1 -0
- package/lib/molecules/select/select.component.d.ts +56 -0
- package/lib/molecules/select/select.component.d.ts.map +1 -0
- package/lib/molecules/select-search/index.d.ts +2 -0
- package/lib/molecules/select-search/index.d.ts.map +1 -0
- package/lib/molecules/select-search/select-search.component.d.ts +63 -0
- package/lib/molecules/select-search/select-search.component.d.ts.map +1 -0
- package/lib/molecules/tabs/index.d.ts +2 -0
- package/lib/molecules/tabs/index.d.ts.map +1 -0
- package/lib/molecules/tabs/tabs.component.d.ts +23 -0
- package/lib/molecules/tabs/tabs.component.d.ts.map +1 -0
- package/lib/molecules/textarea/index.d.ts +2 -0
- package/lib/molecules/textarea/index.d.ts.map +1 -0
- package/lib/molecules/textarea/textarea.component.d.ts +27 -0
- package/lib/molecules/textarea/textarea.component.d.ts.map +1 -0
- package/lib/molecules/toast/index.d.ts +2 -0
- package/lib/molecules/toast/index.d.ts.map +1 -0
- package/lib/molecules/toast/toast.component.d.ts +19 -0
- package/lib/molecules/toast/toast.component.d.ts.map +1 -0
- package/lib/organisms/accordion/accordion.component.d.ts +25 -0
- package/lib/organisms/accordion/accordion.component.d.ts.map +1 -0
- package/lib/organisms/card/card.component.d.ts +14 -0
- package/lib/organisms/card/card.component.d.ts.map +1 -0
- package/lib/organisms/dropdown-menu/dropdown-menu.component.d.ts +29 -0
- package/lib/organisms/dropdown-menu/dropdown-menu.component.d.ts.map +1 -0
- package/lib/organisms/index.d.ts +8 -0
- package/lib/organisms/index.d.ts.map +1 -0
- package/lib/organisms/modal/modal.component.d.ts +19 -0
- package/lib/organisms/modal/modal.component.d.ts.map +1 -0
- package/lib/organisms/navigation-menu/navigation-menu.component.d.ts +24 -0
- package/lib/organisms/navigation-menu/navigation-menu.component.d.ts.map +1 -0
- package/lib/organisms/sidebar/sidebar.component.d.ts +68 -0
- package/lib/organisms/sidebar/sidebar.component.d.ts.map +1 -0
- package/lib/organisms/table/index.d.ts +3 -0
- package/lib/organisms/table/index.d.ts.map +1 -0
- package/lib/organisms/table/table-cell.directive.d.ts +17 -0
- package/lib/organisms/table/table-cell.directive.d.ts.map +1 -0
- package/lib/organisms/table/table.component.d.ts +50 -0
- package/lib/organisms/table/table.component.d.ts.map +1 -0
- package/lib/tokens/index.d.ts +2 -0
- package/lib/tokens/index.d.ts.map +1 -0
- package/lib/tokens/theme/color-presets.d.ts +24 -0
- package/lib/tokens/theme/color-presets.d.ts.map +1 -0
- package/lib/tokens/theme/index.d.ts +6 -0
- package/lib/tokens/theme/index.d.ts.map +1 -0
- package/lib/tokens/theme/theme-picker.component.d.ts +11 -0
- package/lib/tokens/theme/theme-picker.component.d.ts.map +1 -0
- package/lib/tokens/theme/theme-toggle.component.d.ts +15 -0
- package/lib/tokens/theme/theme-toggle.component.d.ts.map +1 -0
- package/lib/tokens/theme/theme.provider.d.ts +4 -0
- package/lib/tokens/theme/theme.provider.d.ts.map +1 -0
- package/lib/tokens/theme/theme.service.d.ts +48 -0
- package/lib/tokens/theme/theme.service.d.ts.map +1 -0
- package/molecules/alert/alert.component.d.ts +22 -0
- package/molecules/alert/alert.component.d.ts.map +1 -0
- package/molecules/alert/index.d.ts +2 -0
- package/molecules/alert/index.d.ts.map +1 -0
- package/molecules/atomng-ui-molecules.d.ts.map +1 -0
- package/molecules/avatar-group/avatar-group.component.d.ts +22 -0
- package/molecules/avatar-group/avatar-group.component.d.ts.map +1 -0
- package/molecules/avatar-group/index.d.ts +2 -0
- package/molecules/avatar-group/index.d.ts.map +1 -0
- package/molecules/breadcrumb/breadcrumb.component.d.ts +17 -0
- package/molecules/breadcrumb/breadcrumb.component.d.ts.map +1 -0
- package/molecules/breadcrumb/index.d.ts +2 -0
- package/molecules/breadcrumb/index.d.ts.map +1 -0
- package/molecules/button-group/button-group.component.d.ts +11 -0
- package/molecules/button-group/button-group.component.d.ts.map +1 -0
- package/molecules/button-group/index.d.ts +2 -0
- package/molecules/button-group/index.d.ts.map +1 -0
- package/molecules/form-field/form-field.component.d.ts +18 -0
- package/molecules/form-field/form-field.component.d.ts.map +1 -0
- package/molecules/form-field/index.d.ts +2 -0
- package/molecules/form-field/index.d.ts.map +1 -0
- package/molecules/index.d.ts +13 -0
- package/molecules/index.d.ts.map +1 -0
- package/molecules/input/index.d.ts +2 -0
- package/molecules/input/index.d.ts.map +1 -0
- package/molecules/input/input.component.d.ts +50 -0
- package/molecules/input/input.component.d.ts.map +1 -0
- package/molecules/pagination/index.d.ts +2 -0
- package/molecules/pagination/index.d.ts.map +1 -0
- package/molecules/pagination/pagination.component.d.ts +18 -0
- package/molecules/pagination/pagination.component.d.ts.map +1 -0
- package/molecules/select/index.d.ts +3 -0
- package/molecules/select/index.d.ts.map +1 -0
- package/molecules/select/select.component.d.ts +56 -0
- package/molecules/select/select.component.d.ts.map +1 -0
- package/molecules/select-search/index.d.ts +2 -0
- package/molecules/select-search/index.d.ts.map +1 -0
- package/molecules/select-search/select-search.component.d.ts +63 -0
- package/molecules/select-search/select-search.component.d.ts.map +1 -0
- package/molecules/tabs/index.d.ts +2 -0
- package/molecules/tabs/index.d.ts.map +1 -0
- package/molecules/tabs/tabs.component.d.ts +23 -0
- package/molecules/tabs/tabs.component.d.ts.map +1 -0
- package/molecules/textarea/index.d.ts +2 -0
- package/molecules/textarea/index.d.ts.map +1 -0
- package/molecules/textarea/textarea.component.d.ts +27 -0
- package/molecules/textarea/textarea.component.d.ts.map +1 -0
- package/molecules/toast/index.d.ts +2 -0
- package/molecules/toast/index.d.ts.map +1 -0
- package/molecules/toast/toast.component.d.ts +19 -0
- package/molecules/toast/toast.component.d.ts.map +1 -0
- package/organisms/accordion/accordion.component.d.ts +25 -0
- package/organisms/accordion/accordion.component.d.ts.map +1 -0
- package/organisms/atomng-ui-organisms.d.ts.map +1 -0
- package/organisms/card/card.component.d.ts +14 -0
- package/organisms/card/card.component.d.ts.map +1 -0
- package/organisms/dropdown-menu/dropdown-menu.component.d.ts +29 -0
- package/organisms/dropdown-menu/dropdown-menu.component.d.ts.map +1 -0
- package/organisms/index.d.ts +8 -0
- package/organisms/index.d.ts.map +1 -0
- package/organisms/modal/modal.component.d.ts +19 -0
- package/organisms/modal/modal.component.d.ts.map +1 -0
- package/organisms/navigation-menu/navigation-menu.component.d.ts +24 -0
- package/organisms/navigation-menu/navigation-menu.component.d.ts.map +1 -0
- package/organisms/sidebar/sidebar.component.d.ts +68 -0
- package/organisms/sidebar/sidebar.component.d.ts.map +1 -0
- package/organisms/table/index.d.ts +3 -0
- package/organisms/table/index.d.ts.map +1 -0
- package/organisms/table/table-cell.directive.d.ts +17 -0
- package/organisms/table/table-cell.directive.d.ts.map +1 -0
- package/organisms/table/table.component.d.ts +50 -0
- package/organisms/table/table.component.d.ts.map +1 -0
- package/package.json +81 -0
- package/tokens/_colors.scss +150 -0
- package/tokens/_spacing.scss +98 -0
- package/tokens/_typography.scss +59 -0
- package/tokens/atomng-ui-tokens.d.ts.map +1 -0
- package/tokens/index.d.ts +2 -0
- package/tokens/index.d.ts.map +1 -0
- package/tokens/index.scss +8 -0
- package/tokens/theme/color-presets.d.ts +24 -0
- package/tokens/theme/color-presets.d.ts.map +1 -0
- package/tokens/theme/index.d.ts +6 -0
- package/tokens/theme/index.d.ts.map +1 -0
- package/tokens/theme/theme-picker.component.d.ts +11 -0
- package/tokens/theme/theme-picker.component.d.ts.map +1 -0
- package/tokens/theme/theme-toggle.component.d.ts +15 -0
- package/tokens/theme/theme-toggle.component.d.ts.map +1 -0
- package/tokens/theme/theme.provider.d.ts +4 -0
- package/tokens/theme/theme.provider.d.ts.map +1 -0
- package/tokens/theme/theme.service.d.ts +48 -0
- package/tokens/theme/theme.service.d.ts.map +1 -0
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, PLATFORM_ID, signal, computed, effect, Injectable, makeEnvironmentProviders, APP_INITIALIZER, output, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { isPlatformBrowser } from '@angular/common';
|
|
4
|
+
|
|
5
|
+
// ── Color presets ─────────────────────────────────────────────────────────────
|
|
6
|
+
// Full 11-step palettes (50→950).
|
|
7
|
+
// Colors sourced from Tailwind CSS v3 palette — production-grade, accessible.
|
|
8
|
+
// Each palette is keyed by a human-readable preset name.
|
|
9
|
+
// ── Palette definitions ───────────────────────────────────────────────────────
|
|
10
|
+
const COLOR_PRESETS = {
|
|
11
|
+
green: {
|
|
12
|
+
name: 'green', label: 'Green', swatch: '#22c55e',
|
|
13
|
+
palette: {
|
|
14
|
+
50: '#f0fdf4', 100: '#dcfce7', 200: '#bbf7d0', 300: '#86efac',
|
|
15
|
+
400: '#4ade80', 500: '#22c55e', 600: '#16a34a', 700: '#15803d',
|
|
16
|
+
800: '#166534', 900: '#14532d', 950: '#052e16',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
emerald: {
|
|
20
|
+
name: 'emerald', label: 'Emerald', swatch: '#10b981',
|
|
21
|
+
palette: {
|
|
22
|
+
50: '#ecfdf5', 100: '#d1fae5', 200: '#a7f3d0', 300: '#6ee7b7',
|
|
23
|
+
400: '#34d399', 500: '#10b981', 600: '#059669', 700: '#047857',
|
|
24
|
+
800: '#065f46', 900: '#064e3b', 950: '#022c22',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
teal: {
|
|
28
|
+
name: 'teal', label: 'Teal', swatch: '#14b8a6',
|
|
29
|
+
palette: {
|
|
30
|
+
50: '#f0fdfa', 100: '#ccfbf1', 200: '#99f6e4', 300: '#5eead4',
|
|
31
|
+
400: '#2dd4bf', 500: '#14b8a6', 600: '#0d9488', 700: '#0f766e',
|
|
32
|
+
800: '#115e59', 900: '#134e4a', 950: '#042f2e',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
cyan: {
|
|
36
|
+
name: 'cyan', label: 'Cyan', swatch: '#06b6d4',
|
|
37
|
+
palette: {
|
|
38
|
+
50: '#ecfeff', 100: '#cffafe', 200: '#a5f3fc', 300: '#67e8f9',
|
|
39
|
+
400: '#22d3ee', 500: '#06b6d4', 600: '#0891b2', 700: '#0e7490',
|
|
40
|
+
800: '#155e75', 900: '#164e63', 950: '#083344',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
sky: {
|
|
44
|
+
name: 'sky', label: 'Sky', swatch: '#0ea5e9',
|
|
45
|
+
palette: {
|
|
46
|
+
50: '#f0f9ff', 100: '#e0f2fe', 200: '#bae6fd', 300: '#7dd3fc',
|
|
47
|
+
400: '#38bdf8', 500: '#0ea5e9', 600: '#0284c7', 700: '#0369a1',
|
|
48
|
+
800: '#075985', 900: '#0c4a6e', 950: '#082f49',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
blue: {
|
|
52
|
+
name: 'blue', label: 'Blue', swatch: '#3b82f6',
|
|
53
|
+
palette: {
|
|
54
|
+
50: '#eff6ff', 100: '#dbeafe', 200: '#bfdbfe', 300: '#93c5fd',
|
|
55
|
+
400: '#60a5fa', 500: '#3b82f6', 600: '#2563eb', 700: '#1d4ed8',
|
|
56
|
+
800: '#1e40af', 900: '#1e3a8a', 950: '#172554',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
indigo: {
|
|
60
|
+
name: 'indigo', label: 'Indigo', swatch: '#6366f1',
|
|
61
|
+
palette: {
|
|
62
|
+
50: '#eef2ff', 100: '#e0e7ff', 200: '#c7d2fe', 300: '#a5b4fc',
|
|
63
|
+
400: '#818cf8', 500: '#6366f1', 600: '#4f46e5', 700: '#4338ca',
|
|
64
|
+
800: '#3730a3', 900: '#312e81', 950: '#1e1b4b',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
violet: {
|
|
68
|
+
name: 'violet', label: 'Violet', swatch: '#8b5cf6',
|
|
69
|
+
palette: {
|
|
70
|
+
50: '#f5f3ff', 100: '#ede9fe', 200: '#ddd6fe', 300: '#c4b5fd',
|
|
71
|
+
400: '#a78bfa', 500: '#8b5cf6', 600: '#7c3aed', 700: '#6d28d9',
|
|
72
|
+
800: '#5b21b6', 900: '#4c1d95', 950: '#2e1065',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
purple: {
|
|
76
|
+
name: 'purple', label: 'Purple', swatch: '#a855f7',
|
|
77
|
+
palette: {
|
|
78
|
+
50: '#faf5ff', 100: '#f3e8ff', 200: '#e9d5ff', 300: '#d8b4fe',
|
|
79
|
+
400: '#c084fc', 500: '#a855f7', 600: '#9333ea', 700: '#7e22ce',
|
|
80
|
+
800: '#6b21a8', 900: '#581c87', 950: '#3b0764',
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
fuchsia: {
|
|
84
|
+
name: 'fuchsia', label: 'Fuchsia', swatch: '#d946ef',
|
|
85
|
+
palette: {
|
|
86
|
+
50: '#fdf4ff', 100: '#fae8ff', 200: '#f5d0fe', 300: '#f0abfc',
|
|
87
|
+
400: '#e879f9', 500: '#d946ef', 600: '#c026d3', 700: '#a21caf',
|
|
88
|
+
800: '#86198f', 900: '#701a75', 950: '#4a044e',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
pink: {
|
|
92
|
+
name: 'pink', label: 'Pink', swatch: '#ec4899',
|
|
93
|
+
palette: {
|
|
94
|
+
50: '#fdf2f8', 100: '#fce7f3', 200: '#fbcfe8', 300: '#f9a8d4',
|
|
95
|
+
400: '#f472b6', 500: '#ec4899', 600: '#db2777', 700: '#be185d',
|
|
96
|
+
800: '#9d174d', 900: '#831843', 950: '#500724',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
rose: {
|
|
100
|
+
name: 'rose', label: 'Rose', swatch: '#f43f5e',
|
|
101
|
+
palette: {
|
|
102
|
+
50: '#fff1f2', 100: '#ffe4e6', 200: '#fecdd3', 300: '#fda4af',
|
|
103
|
+
400: '#fb7185', 500: '#f43f5e', 600: '#e11d48', 700: '#be123c',
|
|
104
|
+
800: '#9f1239', 900: '#881337', 950: '#4c0519',
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
red: {
|
|
108
|
+
name: 'red', label: 'Red', swatch: '#ef4444',
|
|
109
|
+
palette: {
|
|
110
|
+
50: '#fef2f2', 100: '#fee2e2', 200: '#fecaca', 300: '#fca5a5',
|
|
111
|
+
400: '#f87171', 500: '#ef4444', 600: '#dc2626', 700: '#b91c1c',
|
|
112
|
+
800: '#991b1b', 900: '#7f1d1d', 950: '#450a0a',
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
orange: {
|
|
116
|
+
name: 'orange', label: 'Orange', swatch: '#f97316',
|
|
117
|
+
palette: {
|
|
118
|
+
50: '#fff7ed', 100: '#ffedd5', 200: '#fed7aa', 300: '#fdba74',
|
|
119
|
+
400: '#fb923c', 500: '#f97316', 600: '#ea580c', 700: '#c2410c',
|
|
120
|
+
800: '#9a3412', 900: '#7c2d12', 950: '#431407',
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
amber: {
|
|
124
|
+
name: 'amber', label: 'Amber', swatch: '#f59e0b',
|
|
125
|
+
palette: {
|
|
126
|
+
50: '#fffbeb', 100: '#fef3c7', 200: '#fde68a', 300: '#fcd34d',
|
|
127
|
+
400: '#fbbf24', 500: '#f59e0b', 600: '#d97706', 700: '#b45309',
|
|
128
|
+
800: '#92400e', 900: '#78350f', 950: '#451a03',
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
lime: {
|
|
132
|
+
name: 'lime', label: 'Lime', swatch: '#84cc16',
|
|
133
|
+
palette: {
|
|
134
|
+
50: '#f7fee7', 100: '#ecfccb', 200: '#d9f99d', 300: '#bef264',
|
|
135
|
+
400: '#a3e635', 500: '#84cc16', 600: '#65a30d', 700: '#4d7c0f',
|
|
136
|
+
800: '#3f6212', 900: '#365314', 950: '#1a2e05',
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
slate: {
|
|
140
|
+
name: 'slate', label: 'Slate', swatch: '#64748b',
|
|
141
|
+
palette: {
|
|
142
|
+
50: '#f8fafc', 100: '#f1f5f9', 200: '#e2e8f0', 300: '#cbd5e1',
|
|
143
|
+
400: '#94a3b8', 500: '#64748b', 600: '#475569', 700: '#334155',
|
|
144
|
+
800: '#1e293b', 900: '#0f172a', 950: '#020617',
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
zinc: {
|
|
148
|
+
name: 'zinc', label: 'Zinc', swatch: '#71717a',
|
|
149
|
+
palette: {
|
|
150
|
+
50: '#fafafa', 100: '#f4f4f5', 200: '#e4e4e7', 300: '#d4d4d8',
|
|
151
|
+
400: '#a1a1aa', 500: '#71717a', 600: '#52525b', 700: '#3f3f46',
|
|
152
|
+
800: '#27272a', 900: '#18181b', 950: '#09090b',
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
/** Returns all preset metas sorted for display */
|
|
157
|
+
function getAllPresets() {
|
|
158
|
+
return Object.values(COLOR_PRESETS);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const STORAGE_KEY_MODE = 'ui-theme-mode';
|
|
162
|
+
const STORAGE_KEY_PRESET = 'ui-theme-preset';
|
|
163
|
+
// ── ThemeService ──────────────────────────────────────────────────────────────
|
|
164
|
+
// Single source of truth for:
|
|
165
|
+
// · Primary color palette → overrides --color-primary-* CSS vars on :root
|
|
166
|
+
// · Theme mode (light / dark / system) → sets data-theme attribute
|
|
167
|
+
//
|
|
168
|
+
// State is persisted to localStorage and restored on next page load.
|
|
169
|
+
//
|
|
170
|
+
// Usage (anywhere in the app):
|
|
171
|
+
// theme = inject(ThemeService);
|
|
172
|
+
// theme.setPrimary('violet');
|
|
173
|
+
// theme.setMode('dark');
|
|
174
|
+
class ThemeService {
|
|
175
|
+
// ── Constructor — restore from localStorage ───────────────────────────────
|
|
176
|
+
constructor() {
|
|
177
|
+
this.platformId = inject(PLATFORM_ID);
|
|
178
|
+
// ── Private state ─────────────────────────────────────────────────────────
|
|
179
|
+
this._preset = signal(null);
|
|
180
|
+
this._palette = signal(null);
|
|
181
|
+
this._mode = signal('light');
|
|
182
|
+
// ── Public read-only signals ──────────────────────────────────────────────
|
|
183
|
+
/** Currently active preset name (null when a custom palette was set) */
|
|
184
|
+
this.activePreset = this._preset.asReadonly();
|
|
185
|
+
/** Resolved full palette */
|
|
186
|
+
this.activePalette = computed(() => {
|
|
187
|
+
const custom = this._palette();
|
|
188
|
+
if (custom)
|
|
189
|
+
return custom;
|
|
190
|
+
const preset = this._preset();
|
|
191
|
+
return preset ? (COLOR_PRESETS[preset]?.palette ?? null) : null;
|
|
192
|
+
});
|
|
193
|
+
/** Currently active mode */
|
|
194
|
+
this.activeMode = this._mode.asReadonly();
|
|
195
|
+
/** Derived boolean — true when dark is currently active (including system→dark) */
|
|
196
|
+
this.isDark = computed(() => {
|
|
197
|
+
if (this._mode() === 'dark')
|
|
198
|
+
return true;
|
|
199
|
+
if (this._mode() === 'system' && isPlatformBrowser(this.platformId)) {
|
|
200
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
201
|
+
}
|
|
202
|
+
return false;
|
|
203
|
+
});
|
|
204
|
+
/** All available presets for rendering a picker */
|
|
205
|
+
this.presets = Object.values(COLOR_PRESETS);
|
|
206
|
+
if (!isPlatformBrowser(this.platformId))
|
|
207
|
+
return;
|
|
208
|
+
// Restore mode
|
|
209
|
+
const savedMode = localStorage.getItem(STORAGE_KEY_MODE);
|
|
210
|
+
const initialMode = (savedMode === 'light' || savedMode === 'dark' || savedMode === 'system')
|
|
211
|
+
? savedMode : 'light';
|
|
212
|
+
this._mode.set(initialMode);
|
|
213
|
+
this.applyMode(initialMode);
|
|
214
|
+
// Restore preset
|
|
215
|
+
const savedPreset = localStorage.getItem(STORAGE_KEY_PRESET);
|
|
216
|
+
if (savedPreset && COLOR_PRESETS[savedPreset]) {
|
|
217
|
+
this._preset.set(savedPreset);
|
|
218
|
+
this.applyPalette(COLOR_PRESETS[savedPreset].palette);
|
|
219
|
+
}
|
|
220
|
+
// Persist mode changes to localStorage
|
|
221
|
+
effect(() => {
|
|
222
|
+
localStorage.setItem(STORAGE_KEY_MODE, this._mode());
|
|
223
|
+
});
|
|
224
|
+
// Persist preset changes to localStorage
|
|
225
|
+
effect(() => {
|
|
226
|
+
const p = this._preset();
|
|
227
|
+
if (p)
|
|
228
|
+
localStorage.setItem(STORAGE_KEY_PRESET, p);
|
|
229
|
+
else
|
|
230
|
+
localStorage.removeItem(STORAGE_KEY_PRESET);
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
// ── Public API ─────────────────────────────────────────────────────────────
|
|
234
|
+
/**
|
|
235
|
+
* Set the primary color using a preset name or a full custom palette.
|
|
236
|
+
* Immediately applies CSS custom properties to :root and persists to localStorage.
|
|
237
|
+
*/
|
|
238
|
+
setPrimary(color) {
|
|
239
|
+
if (typeof color === 'string') {
|
|
240
|
+
if (!COLOR_PRESETS[color])
|
|
241
|
+
return;
|
|
242
|
+
this._preset.set(color);
|
|
243
|
+
this._palette.set(null);
|
|
244
|
+
this.applyPalette(COLOR_PRESETS[color].palette);
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
this._preset.set(null);
|
|
248
|
+
this._palette.set(color);
|
|
249
|
+
this.applyPalette(color);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Switch between light, dark, and system modes.
|
|
254
|
+
* Persisted to localStorage automatically.
|
|
255
|
+
*/
|
|
256
|
+
setMode(mode) {
|
|
257
|
+
this._mode.set(mode);
|
|
258
|
+
this.applyMode(mode);
|
|
259
|
+
}
|
|
260
|
+
/** Toggle between light ↔ dark (ignores system). */
|
|
261
|
+
toggleMode() {
|
|
262
|
+
this.setMode(this._mode() === 'dark' ? 'light' : 'dark');
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Apply a full ThemeConfig at once (used by provideSharedUiTheme).
|
|
266
|
+
* Does NOT override values already restored from localStorage unless
|
|
267
|
+
* the config explicitly provides them.
|
|
268
|
+
*/
|
|
269
|
+
applyConfig(config) {
|
|
270
|
+
// Only apply if nothing was already restored from localStorage
|
|
271
|
+
if (config.primaryColor !== undefined && this._preset() === null && this._palette() === null) {
|
|
272
|
+
this.setPrimary(config.primaryColor);
|
|
273
|
+
}
|
|
274
|
+
if (config.mode !== undefined) {
|
|
275
|
+
const saved = isPlatformBrowser(this.platformId)
|
|
276
|
+
? localStorage.getItem(STORAGE_KEY_MODE)
|
|
277
|
+
: null;
|
|
278
|
+
// Don't override a user's saved preference with the default config
|
|
279
|
+
if (!saved)
|
|
280
|
+
this.setMode(config.mode);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// ── Internal helpers ──────────────────────────────────────────────────────
|
|
284
|
+
applyPalette(palette) {
|
|
285
|
+
if (!isPlatformBrowser(this.platformId))
|
|
286
|
+
return;
|
|
287
|
+
const root = document.documentElement;
|
|
288
|
+
Object.entries(palette).forEach(([shade, value]) => {
|
|
289
|
+
root.style.setProperty(`--color-primary-${shade}`, value);
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
applyMode(mode) {
|
|
293
|
+
if (!isPlatformBrowser(this.platformId))
|
|
294
|
+
return;
|
|
295
|
+
const applyDark = (dark) => document.documentElement.setAttribute('data-theme', dark ? 'dark' : 'light');
|
|
296
|
+
// Remove any previous media-query listener
|
|
297
|
+
if (this._mqListener) {
|
|
298
|
+
window.matchMedia('(prefers-color-scheme: dark)')
|
|
299
|
+
.removeEventListener('change', this._mqListener);
|
|
300
|
+
this._mqListener = undefined;
|
|
301
|
+
}
|
|
302
|
+
if (mode === 'system') {
|
|
303
|
+
const mq = window.matchMedia('(prefers-color-scheme: dark)');
|
|
304
|
+
applyDark(mq.matches);
|
|
305
|
+
this._mqListener = (e) => { if (this._mode() === 'system')
|
|
306
|
+
applyDark(e.matches); };
|
|
307
|
+
mq.addEventListener('change', this._mqListener);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
applyDark(mode === 'dark');
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
314
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ThemeService, providedIn: 'root' }); }
|
|
315
|
+
}
|
|
316
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ThemeService, decorators: [{
|
|
317
|
+
type: Injectable,
|
|
318
|
+
args: [{ providedIn: 'root' }]
|
|
319
|
+
}], ctorParameters: () => [] });
|
|
320
|
+
|
|
321
|
+
// ── provideSharedUiTheme ──────────────────────────────────────────────────────
|
|
322
|
+
// Call in app.config.ts to configure the design system theme at bootstrap time.
|
|
323
|
+
//
|
|
324
|
+
// Usage:
|
|
325
|
+
// export const appConfig: ApplicationConfig = {
|
|
326
|
+
// providers: [
|
|
327
|
+
// provideSharedUiTheme({ primaryColor: 'indigo', mode: 'light' }),
|
|
328
|
+
// ],
|
|
329
|
+
// };
|
|
330
|
+
function provideSharedUiTheme(config = {}) {
|
|
331
|
+
return makeEnvironmentProviders([
|
|
332
|
+
{
|
|
333
|
+
provide: APP_INITIALIZER,
|
|
334
|
+
useFactory: (theme) => () => theme.applyConfig(config),
|
|
335
|
+
deps: [ThemeService],
|
|
336
|
+
multi: true,
|
|
337
|
+
},
|
|
338
|
+
]);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// ── ThemePickerComponent ──────────────────────────────────────────────────────
|
|
342
|
+
// Grid of color swatches — clicking one applies the preset immediately.
|
|
343
|
+
// Emits (change) for the host to react if needed.
|
|
344
|
+
//
|
|
345
|
+
// Usage:
|
|
346
|
+
// <ui-theme-picker />
|
|
347
|
+
// <ui-theme-picker (change)="onColorChange($event)" />
|
|
348
|
+
class ThemePickerComponent {
|
|
349
|
+
constructor() {
|
|
350
|
+
this.theme = inject(ThemeService);
|
|
351
|
+
this.change = output();
|
|
352
|
+
}
|
|
353
|
+
select(preset) {
|
|
354
|
+
this.theme.setPrimary(preset.name);
|
|
355
|
+
this.change.emit(preset.name);
|
|
356
|
+
}
|
|
357
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ThemePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
358
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: ThemePickerComponent, isStandalone: true, selector: "ui-theme-picker", outputs: { change: "change" }, ngImport: i0, template: `
|
|
359
|
+
<div class="tp" role="radiogroup" aria-label="Primary color">
|
|
360
|
+
@for (preset of theme.presets; track preset.name) {
|
|
361
|
+
<button
|
|
362
|
+
class="tp__swatch"
|
|
363
|
+
type="button"
|
|
364
|
+
role="radio"
|
|
365
|
+
[attr.aria-label]="preset.label"
|
|
366
|
+
[attr.aria-checked]="theme.activePreset() === preset.name"
|
|
367
|
+
[class.tp__swatch--active]="theme.activePreset() === preset.name"
|
|
368
|
+
[style.background]="preset.swatch"
|
|
369
|
+
[title]="preset.label"
|
|
370
|
+
(click)="select(preset)"
|
|
371
|
+
>
|
|
372
|
+
@if (theme.activePreset() === preset.name) {
|
|
373
|
+
<svg class="tp__check" viewBox="0 0 12 12" fill="none" aria-hidden="true">
|
|
374
|
+
<path d="M2 6l3 3 5-5" stroke="#fff" stroke-width="1.8"
|
|
375
|
+
stroke-linecap="round" stroke-linejoin="round"/>
|
|
376
|
+
</svg>
|
|
377
|
+
}
|
|
378
|
+
</button>
|
|
379
|
+
}
|
|
380
|
+
</div>
|
|
381
|
+
`, isInline: true, styles: [".tp{display:grid;grid-template-columns:repeat(6,28px);gap:8px;padding:4px}.tp__swatch{width:28px;height:28px;border-radius:50%;border:2px solid transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform .15s,border-color .15s;padding:0;&:hover{transform:scale(1.15)}}.tp__swatch--active{border-color:var(--color-border);box-shadow:0 0 0 2px var(--color-bg),0 0 0 4px currentColor}.tp__check{width:12px;height:12px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
382
|
+
}
|
|
383
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ThemePickerComponent, decorators: [{
|
|
384
|
+
type: Component,
|
|
385
|
+
args: [{ selector: 'ui-theme-picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
386
|
+
<div class="tp" role="radiogroup" aria-label="Primary color">
|
|
387
|
+
@for (preset of theme.presets; track preset.name) {
|
|
388
|
+
<button
|
|
389
|
+
class="tp__swatch"
|
|
390
|
+
type="button"
|
|
391
|
+
role="radio"
|
|
392
|
+
[attr.aria-label]="preset.label"
|
|
393
|
+
[attr.aria-checked]="theme.activePreset() === preset.name"
|
|
394
|
+
[class.tp__swatch--active]="theme.activePreset() === preset.name"
|
|
395
|
+
[style.background]="preset.swatch"
|
|
396
|
+
[title]="preset.label"
|
|
397
|
+
(click)="select(preset)"
|
|
398
|
+
>
|
|
399
|
+
@if (theme.activePreset() === preset.name) {
|
|
400
|
+
<svg class="tp__check" viewBox="0 0 12 12" fill="none" aria-hidden="true">
|
|
401
|
+
<path d="M2 6l3 3 5-5" stroke="#fff" stroke-width="1.8"
|
|
402
|
+
stroke-linecap="round" stroke-linejoin="round"/>
|
|
403
|
+
</svg>
|
|
404
|
+
}
|
|
405
|
+
</button>
|
|
406
|
+
}
|
|
407
|
+
</div>
|
|
408
|
+
`, styles: [".tp{display:grid;grid-template-columns:repeat(6,28px);gap:8px;padding:4px}.tp__swatch{width:28px;height:28px;border-radius:50%;border:2px solid transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform .15s,border-color .15s;padding:0;&:hover{transform:scale(1.15)}}.tp__swatch--active{border-color:var(--color-border);box-shadow:0 0 0 2px var(--color-bg),0 0 0 4px currentColor}.tp__check{width:12px;height:12px}\n"] }]
|
|
409
|
+
}] });
|
|
410
|
+
|
|
411
|
+
class ThemeToggleComponent {
|
|
412
|
+
constructor() {
|
|
413
|
+
this.theme = inject(ThemeService);
|
|
414
|
+
this.options = [
|
|
415
|
+
{
|
|
416
|
+
value: 'light',
|
|
417
|
+
label: 'Clair',
|
|
418
|
+
icon: `<circle cx="12" cy="12" r="4"/>
|
|
419
|
+
<path d="M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32 1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/>`,
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
value: 'system',
|
|
423
|
+
label: 'Auto',
|
|
424
|
+
icon: `<rect x="2" y="3" width="20" height="14" rx="2"/>
|
|
425
|
+
<path d="M8 21h8m-4-4v4"/>`,
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
value: 'dark',
|
|
429
|
+
label: 'Sombre',
|
|
430
|
+
icon: `<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>`,
|
|
431
|
+
},
|
|
432
|
+
];
|
|
433
|
+
}
|
|
434
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ThemeToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
435
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: ThemeToggleComponent, isStandalone: true, selector: "ui-theme-toggle", ngImport: i0, template: `
|
|
436
|
+
<div class="toggle" role="group" aria-label="Mode d'affichage">
|
|
437
|
+
@for (opt of options; track opt.value) {
|
|
438
|
+
<button
|
|
439
|
+
class="toggle__btn"
|
|
440
|
+
[class.toggle__btn--active]="theme.activeMode() === opt.value"
|
|
441
|
+
type="button"
|
|
442
|
+
[attr.aria-label]="opt.label"
|
|
443
|
+
[attr.title]="opt.label"
|
|
444
|
+
[attr.aria-pressed]="theme.activeMode() === opt.value"
|
|
445
|
+
(click)="theme.setMode(opt.value)"
|
|
446
|
+
>
|
|
447
|
+
<svg
|
|
448
|
+
width="15" height="15"
|
|
449
|
+
viewBox="0 0 24 24" fill="none"
|
|
450
|
+
stroke="currentColor" stroke-width="2"
|
|
451
|
+
stroke-linecap="round" stroke-linejoin="round"
|
|
452
|
+
aria-hidden="true"
|
|
453
|
+
[innerHTML]="opt.icon"
|
|
454
|
+
></svg>
|
|
455
|
+
<span class="toggle__label">{{ opt.label }}</span>
|
|
456
|
+
</button>
|
|
457
|
+
}
|
|
458
|
+
</div>
|
|
459
|
+
`, isInline: true, styles: [".toggle{display:inline-flex;align-items:center;background:var(--color-bg-subtle);border:1px solid var(--color-border);border-radius:var(--radius-lg, 10px);padding:3px;gap:2px}.toggle__btn{display:inline-flex;align-items:center;gap:5px;padding:5px 10px;border-radius:var(--radius-md, 8px);background:transparent;border:none;color:var(--color-text-muted);font-family:var(--font-sans);font-size:var(--text-xs, 11px);font-weight:var(--font-medium, 500);cursor:pointer;transition:background .15s,color .15s,box-shadow .15s;white-space:nowrap}.toggle__label{line-height:1}.toggle__btn:hover:not(.toggle__btn--active){background:var(--color-bg);color:var(--color-text)}.toggle__btn--active{background:var(--color-bg);color:var(--color-text);box-shadow:0 1px 3px #0000001a,0 0 0 1px var(--color-border)}:host-context([data-theme=\"dark\"]) .toggle__btn:hover:not(.toggle__btn--active){background:var(--color-neutral-700);color:var(--color-text)}:host-context([data-theme=\"dark\"]) .toggle__btn--active{background:var(--color-neutral-600);color:var(--color-text);box-shadow:0 1px 3px #00000059,0 0 0 1px var(--color-neutral-600)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
460
|
+
}
|
|
461
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ThemeToggleComponent, decorators: [{
|
|
462
|
+
type: Component,
|
|
463
|
+
args: [{ selector: 'ui-theme-toggle', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
464
|
+
<div class="toggle" role="group" aria-label="Mode d'affichage">
|
|
465
|
+
@for (opt of options; track opt.value) {
|
|
466
|
+
<button
|
|
467
|
+
class="toggle__btn"
|
|
468
|
+
[class.toggle__btn--active]="theme.activeMode() === opt.value"
|
|
469
|
+
type="button"
|
|
470
|
+
[attr.aria-label]="opt.label"
|
|
471
|
+
[attr.title]="opt.label"
|
|
472
|
+
[attr.aria-pressed]="theme.activeMode() === opt.value"
|
|
473
|
+
(click)="theme.setMode(opt.value)"
|
|
474
|
+
>
|
|
475
|
+
<svg
|
|
476
|
+
width="15" height="15"
|
|
477
|
+
viewBox="0 0 24 24" fill="none"
|
|
478
|
+
stroke="currentColor" stroke-width="2"
|
|
479
|
+
stroke-linecap="round" stroke-linejoin="round"
|
|
480
|
+
aria-hidden="true"
|
|
481
|
+
[innerHTML]="opt.icon"
|
|
482
|
+
></svg>
|
|
483
|
+
<span class="toggle__label">{{ opt.label }}</span>
|
|
484
|
+
</button>
|
|
485
|
+
}
|
|
486
|
+
</div>
|
|
487
|
+
`, styles: [".toggle{display:inline-flex;align-items:center;background:var(--color-bg-subtle);border:1px solid var(--color-border);border-radius:var(--radius-lg, 10px);padding:3px;gap:2px}.toggle__btn{display:inline-flex;align-items:center;gap:5px;padding:5px 10px;border-radius:var(--radius-md, 8px);background:transparent;border:none;color:var(--color-text-muted);font-family:var(--font-sans);font-size:var(--text-xs, 11px);font-weight:var(--font-medium, 500);cursor:pointer;transition:background .15s,color .15s,box-shadow .15s;white-space:nowrap}.toggle__label{line-height:1}.toggle__btn:hover:not(.toggle__btn--active){background:var(--color-bg);color:var(--color-text)}.toggle__btn--active{background:var(--color-bg);color:var(--color-text);box-shadow:0 1px 3px #0000001a,0 0 0 1px var(--color-border)}:host-context([data-theme=\"dark\"]) .toggle__btn:hover:not(.toggle__btn--active){background:var(--color-neutral-700);color:var(--color-text)}:host-context([data-theme=\"dark\"]) .toggle__btn--active{background:var(--color-neutral-600);color:var(--color-text);box-shadow:0 1px 3px #00000059,0 0 0 1px var(--color-neutral-600)}\n"] }]
|
|
488
|
+
}] });
|
|
489
|
+
|
|
490
|
+
// ── Tokens public API ─────────────────────────────────────────────────────────
|
|
491
|
+
// Re-exports all TypeScript theme utilities.
|
|
492
|
+
// SCSS tokens are imported separately via @use in your global styles.scss
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Generated bundle index. Do not edit.
|
|
496
|
+
*/
|
|
497
|
+
|
|
498
|
+
export { COLOR_PRESETS, ThemePickerComponent, ThemeService, ThemeToggleComponent, getAllPresets, provideSharedUiTheme };
|
|
499
|
+
//# sourceMappingURL=atomng-ui-tokens.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomng-ui-tokens.mjs","sources":["../../../../libs/shared-ui/src/lib/tokens/theme/color-presets.ts","../../../../libs/shared-ui/src/lib/tokens/theme/theme.service.ts","../../../../libs/shared-ui/src/lib/tokens/theme/theme.provider.ts","../../../../libs/shared-ui/src/lib/tokens/theme/theme-picker.component.ts","../../../../libs/shared-ui/src/lib/tokens/theme/theme-toggle.component.ts","../../../../libs/shared-ui/src/lib/tokens/index.ts","../../../../libs/shared-ui/src/lib/tokens/atomng-ui-tokens.ts"],"sourcesContent":["// ── Color presets ─────────────────────────────────────────────────────────────\n// Full 11-step palettes (50→950).\n// Colors sourced from Tailwind CSS v3 palette — production-grade, accessible.\n// Each palette is keyed by a human-readable preset name.\n\nexport interface ColorPalette {\n 50: string;\n 100: string;\n 200: string;\n 300: string;\n 400: string;\n 500: string;\n 600: string;\n 700: string;\n 800: string;\n 900: string;\n 950: string;\n}\n\nexport type PrimaryColorPreset =\n | 'green' | 'emerald' | 'teal' | 'cyan'\n | 'sky' | 'blue' | 'indigo' | 'violet'\n | 'purple' | 'fuchsia' | 'pink' | 'rose'\n | 'red' | 'orange' | 'amber'\n | 'lime' | 'slate' | 'zinc';\n\nexport interface ColorPresetMeta {\n name: PrimaryColorPreset;\n label: string;\n swatch: string; // The 500-shade preview color\n palette: ColorPalette;\n}\n\n// ── Palette definitions ───────────────────────────────────────────────────────\n\nexport const COLOR_PRESETS: Record<PrimaryColorPreset, ColorPresetMeta> = {\n\n green: {\n name: 'green', label: 'Green', swatch: '#22c55e',\n palette: {\n 50: '#f0fdf4', 100: '#dcfce7', 200: '#bbf7d0', 300: '#86efac',\n 400: '#4ade80', 500: '#22c55e', 600: '#16a34a', 700: '#15803d',\n 800: '#166534', 900: '#14532d', 950: '#052e16',\n },\n },\n\n emerald: {\n name: 'emerald', label: 'Emerald', swatch: '#10b981',\n palette: {\n 50: '#ecfdf5', 100: '#d1fae5', 200: '#a7f3d0', 300: '#6ee7b7',\n 400: '#34d399', 500: '#10b981', 600: '#059669', 700: '#047857',\n 800: '#065f46', 900: '#064e3b', 950: '#022c22',\n },\n },\n\n teal: {\n name: 'teal', label: 'Teal', swatch: '#14b8a6',\n palette: {\n 50: '#f0fdfa', 100: '#ccfbf1', 200: '#99f6e4', 300: '#5eead4',\n 400: '#2dd4bf', 500: '#14b8a6', 600: '#0d9488', 700: '#0f766e',\n 800: '#115e59', 900: '#134e4a', 950: '#042f2e',\n },\n },\n\n cyan: {\n name: 'cyan', label: 'Cyan', swatch: '#06b6d4',\n palette: {\n 50: '#ecfeff', 100: '#cffafe', 200: '#a5f3fc', 300: '#67e8f9',\n 400: '#22d3ee', 500: '#06b6d4', 600: '#0891b2', 700: '#0e7490',\n 800: '#155e75', 900: '#164e63', 950: '#083344',\n },\n },\n\n sky: {\n name: 'sky', label: 'Sky', swatch: '#0ea5e9',\n palette: {\n 50: '#f0f9ff', 100: '#e0f2fe', 200: '#bae6fd', 300: '#7dd3fc',\n 400: '#38bdf8', 500: '#0ea5e9', 600: '#0284c7', 700: '#0369a1',\n 800: '#075985', 900: '#0c4a6e', 950: '#082f49',\n },\n },\n\n blue: {\n name: 'blue', label: 'Blue', swatch: '#3b82f6',\n palette: {\n 50: '#eff6ff', 100: '#dbeafe', 200: '#bfdbfe', 300: '#93c5fd',\n 400: '#60a5fa', 500: '#3b82f6', 600: '#2563eb', 700: '#1d4ed8',\n 800: '#1e40af', 900: '#1e3a8a', 950: '#172554',\n },\n },\n\n indigo: {\n name: 'indigo', label: 'Indigo', swatch: '#6366f1',\n palette: {\n 50: '#eef2ff', 100: '#e0e7ff', 200: '#c7d2fe', 300: '#a5b4fc',\n 400: '#818cf8', 500: '#6366f1', 600: '#4f46e5', 700: '#4338ca',\n 800: '#3730a3', 900: '#312e81', 950: '#1e1b4b',\n },\n },\n\n violet: {\n name: 'violet', label: 'Violet', swatch: '#8b5cf6',\n palette: {\n 50: '#f5f3ff', 100: '#ede9fe', 200: '#ddd6fe', 300: '#c4b5fd',\n 400: '#a78bfa', 500: '#8b5cf6', 600: '#7c3aed', 700: '#6d28d9',\n 800: '#5b21b6', 900: '#4c1d95', 950: '#2e1065',\n },\n },\n\n purple: {\n name: 'purple', label: 'Purple', swatch: '#a855f7',\n palette: {\n 50: '#faf5ff', 100: '#f3e8ff', 200: '#e9d5ff', 300: '#d8b4fe',\n 400: '#c084fc', 500: '#a855f7', 600: '#9333ea', 700: '#7e22ce',\n 800: '#6b21a8', 900: '#581c87', 950: '#3b0764',\n },\n },\n\n fuchsia: {\n name: 'fuchsia', label: 'Fuchsia', swatch: '#d946ef',\n palette: {\n 50: '#fdf4ff', 100: '#fae8ff', 200: '#f5d0fe', 300: '#f0abfc',\n 400: '#e879f9', 500: '#d946ef', 600: '#c026d3', 700: '#a21caf',\n 800: '#86198f', 900: '#701a75', 950: '#4a044e',\n },\n },\n\n pink: {\n name: 'pink', label: 'Pink', swatch: '#ec4899',\n palette: {\n 50: '#fdf2f8', 100: '#fce7f3', 200: '#fbcfe8', 300: '#f9a8d4',\n 400: '#f472b6', 500: '#ec4899', 600: '#db2777', 700: '#be185d',\n 800: '#9d174d', 900: '#831843', 950: '#500724',\n },\n },\n\n rose: {\n name: 'rose', label: 'Rose', swatch: '#f43f5e',\n palette: {\n 50: '#fff1f2', 100: '#ffe4e6', 200: '#fecdd3', 300: '#fda4af',\n 400: '#fb7185', 500: '#f43f5e', 600: '#e11d48', 700: '#be123c',\n 800: '#9f1239', 900: '#881337', 950: '#4c0519',\n },\n },\n\n red: {\n name: 'red', label: 'Red', swatch: '#ef4444',\n palette: {\n 50: '#fef2f2', 100: '#fee2e2', 200: '#fecaca', 300: '#fca5a5',\n 400: '#f87171', 500: '#ef4444', 600: '#dc2626', 700: '#b91c1c',\n 800: '#991b1b', 900: '#7f1d1d', 950: '#450a0a',\n },\n },\n\n orange: {\n name: 'orange', label: 'Orange', swatch: '#f97316',\n palette: {\n 50: '#fff7ed', 100: '#ffedd5', 200: '#fed7aa', 300: '#fdba74',\n 400: '#fb923c', 500: '#f97316', 600: '#ea580c', 700: '#c2410c',\n 800: '#9a3412', 900: '#7c2d12', 950: '#431407',\n },\n },\n\n amber: {\n name: 'amber', label: 'Amber', swatch: '#f59e0b',\n palette: {\n 50: '#fffbeb', 100: '#fef3c7', 200: '#fde68a', 300: '#fcd34d',\n 400: '#fbbf24', 500: '#f59e0b', 600: '#d97706', 700: '#b45309',\n 800: '#92400e', 900: '#78350f', 950: '#451a03',\n },\n },\n\n lime: {\n name: 'lime', label: 'Lime', swatch: '#84cc16',\n palette: {\n 50: '#f7fee7', 100: '#ecfccb', 200: '#d9f99d', 300: '#bef264',\n 400: '#a3e635', 500: '#84cc16', 600: '#65a30d', 700: '#4d7c0f',\n 800: '#3f6212', 900: '#365314', 950: '#1a2e05',\n },\n },\n\n slate: {\n name: 'slate', label: 'Slate', swatch: '#64748b',\n palette: {\n 50: '#f8fafc', 100: '#f1f5f9', 200: '#e2e8f0', 300: '#cbd5e1',\n 400: '#94a3b8', 500: '#64748b', 600: '#475569', 700: '#334155',\n 800: '#1e293b', 900: '#0f172a', 950: '#020617',\n },\n },\n\n zinc: {\n name: 'zinc', label: 'Zinc', swatch: '#71717a',\n palette: {\n 50: '#fafafa', 100: '#f4f4f5', 200: '#e4e4e7', 300: '#d4d4d8',\n 400: '#a1a1aa', 500: '#71717a', 600: '#52525b', 700: '#3f3f46',\n 800: '#27272a', 900: '#18181b', 950: '#09090b',\n },\n },\n};\n\n/** Returns all preset metas sorted for display */\nexport function getAllPresets(): ColorPresetMeta[] {\n return Object.values(COLOR_PRESETS);\n}\n","import { Injectable, PLATFORM_ID, inject, signal, computed, effect } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n ColorPalette, PrimaryColorPreset,\n COLOR_PRESETS, ColorPresetMeta,\n} from './color-presets';\n\nexport type ThemeMode = 'light' | 'dark' | 'system';\n\nexport interface ThemeConfig {\n primaryColor?: PrimaryColorPreset | ColorPalette;\n mode?: ThemeMode;\n}\n\nconst STORAGE_KEY_MODE = 'ui-theme-mode';\nconst STORAGE_KEY_PRESET = 'ui-theme-preset';\n\n// ── ThemeService ──────────────────────────────────────────────────────────────\n// Single source of truth for:\n// · Primary color palette → overrides --color-primary-* CSS vars on :root\n// · Theme mode (light / dark / system) → sets data-theme attribute\n//\n// State is persisted to localStorage and restored on next page load.\n//\n// Usage (anywhere in the app):\n// theme = inject(ThemeService);\n// theme.setPrimary('violet');\n// theme.setMode('dark');\n\n@Injectable({ providedIn: 'root' })\nexport class ThemeService {\n private platformId = inject(PLATFORM_ID);\n\n // ── Private state ─────────────────────────────────────────────────────────\n private readonly _preset = signal<PrimaryColorPreset | null>(null);\n private readonly _palette = signal<ColorPalette | null>(null);\n private readonly _mode = signal<ThemeMode>('light');\n\n // ── Public read-only signals ──────────────────────────────────────────────\n\n /** Currently active preset name (null when a custom palette was set) */\n readonly activePreset = this._preset.asReadonly();\n\n /** Resolved full palette */\n readonly activePalette = computed<ColorPalette | null>(() => {\n const custom = this._palette();\n if (custom) return custom;\n const preset = this._preset();\n return preset ? (COLOR_PRESETS[preset]?.palette ?? null) : null;\n });\n\n /** Currently active mode */\n readonly activeMode = this._mode.asReadonly();\n\n /** Derived boolean — true when dark is currently active (including system→dark) */\n readonly isDark = computed(() => {\n if (this._mode() === 'dark') return true;\n if (this._mode() === 'system' && isPlatformBrowser(this.platformId)) {\n return window.matchMedia('(prefers-color-scheme: dark)').matches;\n }\n return false;\n });\n\n /** All available presets for rendering a picker */\n readonly presets: ColorPresetMeta[] = Object.values(COLOR_PRESETS);\n\n // ── Constructor — restore from localStorage ───────────────────────────────\n\n constructor() {\n if (!isPlatformBrowser(this.platformId)) return;\n\n // Restore mode\n const savedMode = localStorage.getItem(STORAGE_KEY_MODE) as ThemeMode | null;\n const initialMode: ThemeMode = (savedMode === 'light' || savedMode === 'dark' || savedMode === 'system')\n ? savedMode : 'light';\n this._mode.set(initialMode);\n this.applyMode(initialMode);\n\n // Restore preset\n const savedPreset = localStorage.getItem(STORAGE_KEY_PRESET) as PrimaryColorPreset | null;\n if (savedPreset && COLOR_PRESETS[savedPreset]) {\n this._preset.set(savedPreset);\n this.applyPalette(COLOR_PRESETS[savedPreset].palette);\n }\n\n // Persist mode changes to localStorage\n effect(() => {\n localStorage.setItem(STORAGE_KEY_MODE, this._mode());\n });\n\n // Persist preset changes to localStorage\n effect(() => {\n const p = this._preset();\n if (p) localStorage.setItem(STORAGE_KEY_PRESET, p);\n else localStorage.removeItem(STORAGE_KEY_PRESET);\n });\n }\n\n // ── Public API ─────────────────────────────────────────────────────────────\n\n /**\n * Set the primary color using a preset name or a full custom palette.\n * Immediately applies CSS custom properties to :root and persists to localStorage.\n */\n setPrimary(color: PrimaryColorPreset | ColorPalette): void {\n if (typeof color === 'string') {\n if (!COLOR_PRESETS[color]) return;\n this._preset.set(color);\n this._palette.set(null);\n this.applyPalette(COLOR_PRESETS[color].palette);\n } else {\n this._preset.set(null);\n this._palette.set(color);\n this.applyPalette(color);\n }\n }\n\n /**\n * Switch between light, dark, and system modes.\n * Persisted to localStorage automatically.\n */\n setMode(mode: ThemeMode): void {\n this._mode.set(mode);\n this.applyMode(mode);\n }\n\n /** Toggle between light ↔ dark (ignores system). */\n toggleMode(): void {\n this.setMode(this._mode() === 'dark' ? 'light' : 'dark');\n }\n\n /**\n * Apply a full ThemeConfig at once (used by provideSharedUiTheme).\n * Does NOT override values already restored from localStorage unless\n * the config explicitly provides them.\n */\n applyConfig(config: ThemeConfig): void {\n // Only apply if nothing was already restored from localStorage\n if (config.primaryColor !== undefined && this._preset() === null && this._palette() === null) {\n this.setPrimary(config.primaryColor);\n }\n if (config.mode !== undefined) {\n const saved = isPlatformBrowser(this.platformId)\n ? localStorage.getItem(STORAGE_KEY_MODE)\n : null;\n // Don't override a user's saved preference with the default config\n if (!saved) this.setMode(config.mode);\n }\n }\n\n // ── Internal helpers ──────────────────────────────────────────────────────\n\n private applyPalette(palette: ColorPalette): void {\n if (!isPlatformBrowser(this.platformId)) return;\n const root = document.documentElement;\n (Object.entries(palette) as unknown as [string, string][]).forEach(([shade, value]) => {\n root.style.setProperty(`--color-primary-${shade}`, value);\n });\n }\n\n private _mqListener?: (e: MediaQueryListEvent) => void;\n\n private applyMode(mode: ThemeMode): void {\n if (!isPlatformBrowser(this.platformId)) return;\n\n const applyDark = (dark: boolean) =>\n document.documentElement.setAttribute('data-theme', dark ? 'dark' : 'light');\n\n // Remove any previous media-query listener\n if (this._mqListener) {\n window.matchMedia('(prefers-color-scheme: dark)')\n .removeEventListener('change', this._mqListener);\n this._mqListener = undefined;\n }\n\n if (mode === 'system') {\n const mq = window.matchMedia('(prefers-color-scheme: dark)');\n applyDark(mq.matches);\n this._mqListener = (e) => { if (this._mode() === 'system') applyDark(e.matches); };\n mq.addEventListener('change', this._mqListener);\n } else {\n applyDark(mode === 'dark');\n }\n }\n}\n","import { APP_INITIALIZER, EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { ThemeService, ThemeConfig } from './theme.service';\n\n// ── provideSharedUiTheme ──────────────────────────────────────────────────────\n// Call in app.config.ts to configure the design system theme at bootstrap time.\n//\n// Usage:\n// export const appConfig: ApplicationConfig = {\n// providers: [\n// provideSharedUiTheme({ primaryColor: 'indigo', mode: 'light' }),\n// ],\n// };\n\nexport function provideSharedUiTheme(config: ThemeConfig = {}): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: APP_INITIALIZER,\n useFactory: (theme: ThemeService) => () => theme.applyConfig(config),\n deps: [ThemeService],\n multi: true,\n },\n ]);\n}\n","import {\n ChangeDetectionStrategy, Component, inject, output,\n} from '@angular/core';\nimport { ThemeService } from './theme.service';\nimport { ColorPresetMeta, PrimaryColorPreset } from './color-presets';\n\n// ── ThemePickerComponent ──────────────────────────────────────────────────────\n// Grid of color swatches — clicking one applies the preset immediately.\n// Emits (change) for the host to react if needed.\n//\n// Usage:\n// <ui-theme-picker />\n// <ui-theme-picker (change)=\"onColorChange($event)\" />\n\n@Component({\n selector: 'ui-theme-picker',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"tp\" role=\"radiogroup\" aria-label=\"Primary color\">\n @for (preset of theme.presets; track preset.name) {\n <button\n class=\"tp__swatch\"\n type=\"button\"\n role=\"radio\"\n [attr.aria-label]=\"preset.label\"\n [attr.aria-checked]=\"theme.activePreset() === preset.name\"\n [class.tp__swatch--active]=\"theme.activePreset() === preset.name\"\n [style.background]=\"preset.swatch\"\n [title]=\"preset.label\"\n (click)=\"select(preset)\"\n >\n @if (theme.activePreset() === preset.name) {\n <svg class=\"tp__check\" viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M2 6l3 3 5-5\" stroke=\"#fff\" stroke-width=\"1.8\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n }\n </button>\n }\n </div>\n `,\n styles: [`\n .tp {\n display: grid;\n grid-template-columns: repeat(6, 28px);\n gap: 8px;\n padding: 4px;\n }\n\n .tp__swatch {\n width: 28px;\n height: 28px;\n border-radius: 50%;\n border: 2px solid transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.15s, border-color 0.15s;\n padding: 0;\n\n &:hover {\n transform: scale(1.15);\n }\n }\n\n .tp__swatch--active {\n border-color: var(--color-border);\n box-shadow: 0 0 0 2px var(--color-bg), 0 0 0 4px currentColor;\n }\n\n .tp__check {\n width: 12px;\n height: 12px;\n }\n `],\n})\nexport class ThemePickerComponent {\n protected theme = inject(ThemeService);\n\n readonly change = output<PrimaryColorPreset>();\n\n protected select(preset: ColorPresetMeta): void {\n this.theme.setPrimary(preset.name);\n this.change.emit(preset.name);\n }\n}\n","import {\n ChangeDetectionStrategy, Component, inject,\n} from '@angular/core';\nimport { ThemeService, ThemeMode } from './theme.service';\n\n// ── ThemeToggleComponent ───────────────────────────────────────────────────────\n// A 3-segment pill that lets the user pick between Light / System / Dark modes.\n// Reads the current mode from ThemeService and writes back via setMode().\n//\n// Usage:\n// <ui-theme-toggle />\n\ninterface ModeOption {\n value: ThemeMode;\n label: string;\n icon: string; // inline SVG path content\n}\n\n@Component({\n selector: 'ui-theme-toggle',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"toggle\" role=\"group\" aria-label=\"Mode d'affichage\">\n @for (opt of options; track opt.value) {\n <button\n class=\"toggle__btn\"\n [class.toggle__btn--active]=\"theme.activeMode() === opt.value\"\n type=\"button\"\n [attr.aria-label]=\"opt.label\"\n [attr.title]=\"opt.label\"\n [attr.aria-pressed]=\"theme.activeMode() === opt.value\"\n (click)=\"theme.setMode(opt.value)\"\n >\n <svg\n width=\"15\" height=\"15\"\n viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n [innerHTML]=\"opt.icon\"\n ></svg>\n <span class=\"toggle__label\">{{ opt.label }}</span>\n </button>\n }\n </div>\n `,\n styles: [`\n /* ── Container ──────────────────────────────────────────── */\n .toggle {\n display: inline-flex;\n align-items: center;\n background: var(--color-bg-subtle);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg, 10px);\n padding: 3px;\n gap: 2px;\n }\n\n /* ── Base button ─────────────────────────────────────────── */\n .toggle__btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 10px;\n border-radius: var(--radius-md, 8px);\n background: transparent;\n border: none;\n color: var(--color-text-muted);\n font-family: var(--font-sans);\n font-size: var(--text-xs, 11px);\n font-weight: var(--font-medium, 500);\n cursor: pointer;\n transition: background 0.15s, color 0.15s, box-shadow 0.15s;\n white-space: nowrap;\n }\n\n .toggle__label {\n line-height: 1;\n }\n\n /* ── Light mode : hover & active (élévation = plus clair) ── */\n .toggle__btn:hover:not(.toggle__btn--active) {\n background: var(--color-bg); /* neutral-0 = blanc sur fond neutral-100 */\n color: var(--color-text);\n }\n\n .toggle__btn--active {\n background: var(--color-bg); /* blanc = surface élevée en clair */\n color: var(--color-text);\n box-shadow: 0 1px 3px rgb(0 0 0 / .10), 0 0 0 1px var(--color-border);\n }\n\n /* ── Dark mode : hover & active (élévation = plus clair) ─── */\n /* En sombre, --color-bg (neutral-950) est PLUS SOMBRE que le */\n /* conteneur (neutral-800). On utilise neutral-700/600 à la place. */\n :host-context([data-theme=\"dark\"]) .toggle__btn:hover:not(.toggle__btn--active) {\n background: var(--color-neutral-700); /* #374151 — plus clair que neutral-800 */\n color: var(--color-text);\n }\n\n :host-context([data-theme=\"dark\"]) .toggle__btn--active {\n background: var(--color-neutral-600); /* #4b5563 — encore plus clair = elevated */\n color: var(--color-text);\n box-shadow: 0 1px 3px rgb(0 0 0 / .35), 0 0 0 1px var(--color-neutral-600);\n }\n `],\n})\nexport class ThemeToggleComponent {\n protected theme = inject(ThemeService);\n\n protected options: ModeOption[] = [\n {\n value: 'light',\n label: 'Clair',\n icon: `<circle cx=\"12\" cy=\"12\" r=\"4\"/>\n <path d=\"M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32 1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"/>`,\n },\n {\n value: 'system',\n label: 'Auto',\n icon: `<rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\"/>\n <path d=\"M8 21h8m-4-4v4\"/>`,\n },\n {\n value: 'dark',\n label: 'Sombre',\n icon: `<path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\"/>`,\n },\n ];\n}\n","// ── Tokens public API ─────────────────────────────────────────────────────────\n// Re-exports all TypeScript theme utilities.\n// SCSS tokens are imported separately via @use in your global styles.scss\n\nexport * from './theme/index';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|