@pi-spi/app 1.5.1 → 2.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 +64 -30
- package/example/App.tsx +27 -24
- package/lib/module/core/assets.js +0 -7
- package/lib/module/core/assets.js.map +1 -1
- package/lib/module/core/di.js +17 -8
- package/lib/module/core/di.js.map +1 -1
- package/lib/module/core/pi_spi_custom_theme.js +22 -10
- package/lib/module/core/pi_spi_custom_theme.js.map +1 -1
- package/lib/module/core/pi_spi_sdk_config.js +22 -8
- package/lib/module/core/pi_spi_sdk_config.js.map +1 -1
- package/lib/module/core/theme.js +345 -225
- package/lib/module/core/theme.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/l10n/app_localizations.js.map +1 -1
- package/lib/module/l10n/app_localizations_en.js +26 -1
- package/lib/module/l10n/app_localizations_en.js.map +1 -1
- package/lib/module/l10n/app_localizations_fr.js +26 -1
- package/lib/module/l10n/app_localizations_fr.js.map +1 -1
- package/lib/module/l10n/app_localizations_pt.js +26 -1
- package/lib/module/l10n/app_localizations_pt.js.map +1 -1
- package/lib/module/modules/alias/presentation/pages/alias_delete_btn_widget.js +15 -19
- package/lib/module/modules/alias/presentation/pages/alias_delete_btn_widget.js.map +1 -1
- package/lib/module/modules/alias/presentation/pages/alias_page_claim.js +4 -11
- package/lib/module/modules/alias/presentation/pages/alias_page_claim.js.map +1 -1
- package/lib/module/modules/compte/presentation/pages/compte_details_widget.js +6 -7
- package/lib/module/modules/compte/presentation/pages/compte_details_widget.js.map +1 -1
- package/lib/module/modules/config/domain/models/config_keys.js +3 -1
- package/lib/module/modules/config/domain/models/config_keys.js.map +1 -1
- package/lib/module/modules/config/domain/services/config_service.js +31 -2
- package/lib/module/modules/config/domain/services/config_service.js.map +1 -1
- package/lib/module/modules/home/presentation/pages/home_tab_compte.js +0 -1
- package/lib/module/modules/home/presentation/pages/home_tab_compte.js.map +1 -1
- package/lib/module/modules/home/presentation/pages/home_tab_compte_more_menu.js +38 -37
- package/lib/module/modules/home/presentation/pages/home_tab_compte_more_menu.js.map +1 -1
- package/lib/module/modules/profile/presentation/pages/compte/profile_compte_page.js +25 -11
- package/lib/module/modules/profile/presentation/pages/compte/profile_compte_page.js.map +1 -1
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page.js +14 -20
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page.js.map +1 -1
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page_notifications.js +109 -103
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page_notifications.js.map +1 -1
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page_notifications_son.js +55 -72
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page_notifications_son.js.map +1 -1
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page_qrcode.js +31 -45
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page_qrcode.js.map +1 -1
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page_theme.js +175 -203
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page_theme.js.map +1 -1
- package/lib/module/modules/profile/presentation/pages/profile_app_bar.js +26 -0
- package/lib/module/modules/profile/presentation/pages/profile_app_bar.js.map +1 -0
- package/lib/module/modules/profile/presentation/pages/profile_menu.js +144 -34
- package/lib/module/modules/profile/presentation/pages/profile_menu.js.map +1 -1
- package/lib/module/modules/profile/presentation/pages/profile_page.js +95 -63
- package/lib/module/modules/profile/presentation/pages/profile_page.js.map +1 -1
- package/lib/module/modules/profile/presentation/pages/profile_page_avatar.js +97 -45
- package/lib/module/modules/profile/presentation/pages/profile_page_avatar.js.map +1 -1
- package/lib/module/modules/profile/presentation/pages/profile_page_contacts.js +9 -8
- package/lib/module/modules/profile/presentation/pages/profile_page_contacts.js.map +1 -1
- package/lib/module/modules/search/presentation/pages/search_fonctionnalites.js +26 -2
- package/lib/module/modules/search/presentation/pages/search_fonctionnalites.js.map +1 -1
- package/lib/module/modules/search/presentation/pages/search_page.js +0 -1
- package/lib/module/modules/search/presentation/pages/search_page.js.map +1 -1
- package/lib/module/modules/transactions/presentation/pages/transaction_details/transaction_details_page_recu.js +3 -1
- package/lib/module/modules/transactions/presentation/pages/transaction_details/transaction_details_page_recu.js.map +1 -1
- package/lib/module/modules/transactions/presentation/pages/transaction_rtp/transaction_rtp_page.js +4 -11
- package/lib/module/modules/transactions/presentation/pages/transaction_rtp/transaction_rtp_page.js.map +1 -1
- package/lib/module/modules/transactions/presentation/pages/transaction_rtp/transaction_rtp_page_actions.js +13 -10
- package/lib/module/modules/transactions/presentation/pages/transaction_rtp/transaction_rtp_page_actions.js.map +1 -1
- package/lib/module/modules/transactions/presentation/pages/transaction_search/transaction_search_page_filters.js +5 -4
- package/lib/module/modules/transactions/presentation/pages/transaction_search/transaction_search_page_filters.js.map +1 -1
- package/lib/module/modules/transactions/presentation/pages/transaction_split/transaction_split_page_repartition.js +2 -2
- package/lib/module/modules/transactions/presentation/pages/transaction_split/transaction_split_page_repartition.js.map +1 -1
- package/lib/module/pi_spi_sdk_entry.js +7 -2
- package/lib/module/pi_spi_sdk_entry.js.map +1 -1
- package/lib/module/shared/utils/color.js +15 -0
- package/lib/module/shared/utils/color.js.map +1 -0
- package/lib/module/shared/widgets/custom_progressbar.js +3 -2
- package/lib/module/shared/widgets/custom_progressbar.js.map +1 -1
- package/lib/module/shared/widgets/error_card_widget.js +70 -0
- package/lib/module/shared/widgets/error_card_widget.js.map +1 -0
- package/lib/module/shared/widgets/selection.js +136 -0
- package/lib/module/shared/widgets/selection.js.map +1 -0
- package/lib/typescript/src/core/assets.d.ts +0 -7
- package/lib/typescript/src/core/assets.d.ts.map +1 -1
- package/lib/typescript/src/core/di.d.ts.map +1 -1
- package/lib/typescript/src/core/pi_spi_custom_theme.d.ts +17 -8
- package/lib/typescript/src/core/pi_spi_custom_theme.d.ts.map +1 -1
- package/lib/typescript/src/core/pi_spi_sdk_config.d.ts +22 -8
- package/lib/typescript/src/core/pi_spi_sdk_config.d.ts.map +1 -1
- package/lib/typescript/src/core/theme.d.ts +123 -53
- package/lib/typescript/src/core/theme.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/l10n/app_localizations.d.ts +50 -0
- package/lib/typescript/src/l10n/app_localizations.d.ts.map +1 -1
- package/lib/typescript/src/l10n/app_localizations_en.d.ts.map +1 -1
- package/lib/typescript/src/l10n/app_localizations_fr.d.ts.map +1 -1
- package/lib/typescript/src/l10n/app_localizations_pt.d.ts.map +1 -1
- package/lib/typescript/src/modules/alias/presentation/pages/alias_delete_btn_widget.d.ts.map +1 -1
- package/lib/typescript/src/modules/alias/presentation/pages/alias_page_claim.d.ts.map +1 -1
- package/lib/typescript/src/modules/compte/presentation/pages/compte_details_widget.d.ts.map +1 -1
- package/lib/typescript/src/modules/config/domain/models/config_keys.d.ts +3 -1
- package/lib/typescript/src/modules/config/domain/models/config_keys.d.ts.map +1 -1
- package/lib/typescript/src/modules/config/domain/services/config_service.d.ts +7 -0
- package/lib/typescript/src/modules/config/domain/services/config_service.d.ts.map +1 -1
- package/lib/typescript/src/modules/home/presentation/pages/home_tab_compte_more_menu.d.ts +2 -0
- package/lib/typescript/src/modules/home/presentation/pages/home_tab_compte_more_menu.d.ts.map +1 -1
- package/lib/typescript/src/modules/profile/presentation/pages/compte/profile_compte_page.d.ts.map +1 -1
- package/lib/typescript/src/modules/profile/presentation/pages/parametre/profile_parametre_page.d.ts.map +1 -1
- package/lib/typescript/src/modules/profile/presentation/pages/parametre/profile_parametre_page_notifications.d.ts.map +1 -1
- package/lib/typescript/src/modules/profile/presentation/pages/parametre/profile_parametre_page_notifications_son.d.ts.map +1 -1
- package/lib/typescript/src/modules/profile/presentation/pages/parametre/profile_parametre_page_qrcode.d.ts.map +1 -1
- package/lib/typescript/src/modules/profile/presentation/pages/parametre/profile_parametre_page_theme.d.ts +1 -1
- package/lib/typescript/src/modules/profile/presentation/pages/parametre/profile_parametre_page_theme.d.ts.map +1 -1
- package/lib/typescript/src/modules/profile/presentation/pages/profile_app_bar.d.ts +5 -0
- package/lib/typescript/src/modules/profile/presentation/pages/profile_app_bar.d.ts.map +1 -0
- package/lib/typescript/src/modules/profile/presentation/pages/profile_menu.d.ts +31 -4
- package/lib/typescript/src/modules/profile/presentation/pages/profile_menu.d.ts.map +1 -1
- package/lib/typescript/src/modules/profile/presentation/pages/profile_page.d.ts +4 -1
- package/lib/typescript/src/modules/profile/presentation/pages/profile_page.d.ts.map +1 -1
- package/lib/typescript/src/modules/profile/presentation/pages/profile_page_avatar.d.ts +1 -1
- package/lib/typescript/src/modules/profile/presentation/pages/profile_page_avatar.d.ts.map +1 -1
- package/lib/typescript/src/modules/profile/presentation/pages/profile_page_contacts.d.ts.map +1 -1
- package/lib/typescript/src/modules/search/presentation/pages/search_fonctionnalites.d.ts.map +1 -1
- package/lib/typescript/src/modules/transactions/presentation/pages/transaction_rtp/transaction_rtp_page.d.ts.map +1 -1
- package/lib/typescript/src/modules/transactions/presentation/pages/transaction_rtp/transaction_rtp_page_actions.d.ts.map +1 -1
- package/lib/typescript/src/shared/utils/color.d.ts +7 -0
- package/lib/typescript/src/shared/utils/color.d.ts.map +1 -0
- package/lib/typescript/src/shared/widgets/custom_progressbar.d.ts.map +1 -1
- package/lib/typescript/src/shared/widgets/error_card_widget.d.ts +11 -0
- package/lib/typescript/src/shared/widgets/error_card_widget.d.ts.map +1 -0
- package/lib/typescript/src/shared/widgets/selection.d.ts +21 -0
- package/lib/typescript/src/shared/widgets/selection.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/core/assets.ts +0 -7
- package/src/core/di.ts +13 -8
- package/src/core/pi_spi_custom_theme.ts +22 -15
- package/src/core/pi_spi_sdk_config.ts +27 -9
- package/src/core/theme.ts +381 -269
- package/src/index.ts +1 -1
- package/src/l10n/app_localizations.ts +50 -0
- package/src/l10n/app_localizations_en.ts +25 -0
- package/src/l10n/app_localizations_fr.ts +25 -0
- package/src/l10n/app_localizations_pt.ts +25 -0
- package/src/modules/alias/presentation/pages/alias_delete_btn_widget.tsx +13 -12
- package/src/modules/alias/presentation/pages/alias_page_claim.tsx +5 -4
- package/src/modules/compte/presentation/pages/compte_details_widget.tsx +3 -4
- package/src/modules/config/domain/models/config_keys.ts +3 -1
- package/src/modules/config/domain/services/config_service.ts +31 -2
- package/src/modules/home/presentation/pages/home_tab_compte.tsx +1 -1
- package/src/modules/home/presentation/pages/home_tab_compte_more_menu.tsx +34 -42
- package/src/modules/profile/presentation/pages/compte/profile_compte_page.tsx +15 -7
- package/src/modules/profile/presentation/pages/parametre/profile_parametre_page.tsx +12 -17
- package/src/modules/profile/presentation/pages/parametre/profile_parametre_page_notifications.tsx +89 -68
- package/src/modules/profile/presentation/pages/parametre/profile_parametre_page_notifications_son.tsx +84 -54
- package/src/modules/profile/presentation/pages/parametre/profile_parametre_page_qrcode.tsx +28 -24
- package/src/modules/profile/presentation/pages/parametre/profile_parametre_page_theme.tsx +121 -131
- package/src/modules/profile/presentation/pages/profile_app_bar.tsx +21 -0
- package/src/modules/profile/presentation/pages/profile_menu.tsx +126 -33
- package/src/modules/profile/presentation/pages/profile_page.tsx +90 -66
- package/src/modules/profile/presentation/pages/profile_page_avatar.tsx +69 -28
- package/src/modules/profile/presentation/pages/profile_page_contacts.tsx +5 -4
- package/src/modules/search/presentation/pages/search_fonctionnalites.ts +40 -7
- package/src/modules/search/presentation/pages/search_page.tsx +1 -1
- package/src/modules/transactions/presentation/pages/transaction_details/transaction_details_page_recu.tsx +3 -1
- package/src/modules/transactions/presentation/pages/transaction_rtp/transaction_rtp_page.tsx +2 -4
- package/src/modules/transactions/presentation/pages/transaction_rtp/transaction_rtp_page_actions.tsx +13 -6
- package/src/modules/transactions/presentation/pages/transaction_search/transaction_search_page_filters.tsx +4 -4
- package/src/modules/transactions/presentation/pages/transaction_split/transaction_split_page_repartition.tsx +2 -2
- package/src/pi_spi_sdk_entry.tsx +9 -2
- package/src/shared/utils/color.ts +14 -0
- package/src/shared/widgets/custom_progressbar.tsx +3 -2
- package/src/shared/widgets/error_card_widget.tsx +58 -0
- package/src/shared/widgets/selection.tsx +98 -0
- package/assets/images/theme_light_blue.jpeg +0 -0
- package/assets/images/theme_light_green.jpeg +0 -0
- package/assets/images/theme_light_orange.jpeg +0 -0
- package/assets/images/theme_light_pink.jpeg +0 -0
- package/assets/images/theme_light_purple.jpeg +0 -0
- package/assets/images/theme_light_red.jpeg +0 -0
- package/assets/images/theme_light_yellow.jpeg +0 -0
package/src/core/theme.ts
CHANGED
|
@@ -3,18 +3,11 @@ import { Appearance, type ColorSchemeName, type TextStyle } from 'react-native';
|
|
|
3
3
|
|
|
4
4
|
import type { AppLocalizations } from '../l10n/app_localizations';
|
|
5
5
|
|
|
6
|
-
/**
|
|
6
|
+
/** Thème d'affichage du SDK : celui du téléphone, clair ou sombre. La valeur de chaque membre est sa codification (persistée dans les préférences). */
|
|
7
7
|
export enum Themes {
|
|
8
8
|
system = 'System',
|
|
9
9
|
light = 'lightTheme',
|
|
10
10
|
dark = 'darkTheme',
|
|
11
|
-
yellow = 'yellowTheme',
|
|
12
|
-
green = 'greenTheme',
|
|
13
|
-
blue = 'blueTheme',
|
|
14
|
-
red = 'redTheme',
|
|
15
|
-
orange = 'orangeTheme',
|
|
16
|
-
purple = 'purpleTheme',
|
|
17
|
-
pink = 'pinkTheme',
|
|
18
11
|
}
|
|
19
12
|
|
|
20
13
|
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
@@ -26,18 +19,7 @@ export namespace Themes {
|
|
|
26
19
|
}
|
|
27
20
|
|
|
28
21
|
export function list(): Themes[] {
|
|
29
|
-
return [
|
|
30
|
-
Themes.system,
|
|
31
|
-
Themes.light,
|
|
32
|
-
Themes.dark,
|
|
33
|
-
Themes.yellow,
|
|
34
|
-
Themes.green,
|
|
35
|
-
Themes.blue,
|
|
36
|
-
Themes.red,
|
|
37
|
-
Themes.orange,
|
|
38
|
-
Themes.purple,
|
|
39
|
-
Themes.pink,
|
|
40
|
-
];
|
|
22
|
+
return [Themes.system, Themes.light, Themes.dark];
|
|
41
23
|
}
|
|
42
24
|
|
|
43
25
|
/** Libellé traduit du thème. */
|
|
@@ -47,26 +29,173 @@ export namespace Themes {
|
|
|
47
29
|
return traductions.appSettingPageMenuThemeLight;
|
|
48
30
|
case Themes.dark:
|
|
49
31
|
return traductions.appSettingPageMenuThemeDark;
|
|
50
|
-
case Themes.yellow:
|
|
51
|
-
return traductions.appSettingPageMenuThemeYellow;
|
|
52
|
-
case Themes.green:
|
|
53
|
-
return traductions.appSettingPageMenuThemeGreen;
|
|
54
|
-
case Themes.blue:
|
|
55
|
-
return traductions.appSettingPageMenuThemeBlue;
|
|
56
|
-
case Themes.red:
|
|
57
|
-
return traductions.appSettingPageMenuThemeRed;
|
|
58
|
-
case Themes.orange:
|
|
59
|
-
return traductions.appSettingPageMenuThemeOrange;
|
|
60
|
-
case Themes.purple:
|
|
61
|
-
return traductions.appSettingPageMenuThemePurple;
|
|
62
|
-
case Themes.pink:
|
|
63
|
-
return traductions.appSettingPageMenuThemePink;
|
|
64
32
|
default:
|
|
65
33
|
return traductions.appSettingPageMenuThemeDefault;
|
|
66
34
|
}
|
|
67
35
|
}
|
|
68
36
|
}
|
|
69
37
|
|
|
38
|
+
/** Teintes d'une couleur d'accentuation pour un thème clair ou sombre. */
|
|
39
|
+
export type AccentTeintes = {
|
|
40
|
+
/** Boutons, interrupteurs, champ actif */
|
|
41
|
+
accent: string;
|
|
42
|
+
/** Texte et icônes posés sur [accent] (noir ou blanc selon le contraste) */
|
|
43
|
+
surAccent: string;
|
|
44
|
+
/** [accent] quand le bouton est pressé */
|
|
45
|
+
appui: string;
|
|
46
|
+
/** Liens et textes en couleur sur le fond de page */
|
|
47
|
+
texte: string;
|
|
48
|
+
/** Fonds teintés : pastilles, puces choisies */
|
|
49
|
+
conteneur: string;
|
|
50
|
+
/** Texte et icônes posés sur [conteneur] */
|
|
51
|
+
surConteneur: string;
|
|
52
|
+
/** Boutons secondaires (feuilles d'erreur, de succès…) */
|
|
53
|
+
tertiaire: string;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Couleur d'accentuation, indépendante du thème clair ou sombre. Chaque
|
|
58
|
+
* couleur a une teinte pour le clair et une, plus lumineuse, pour le
|
|
59
|
+
* sombre ; contrastes vérifiés (texte ≥ 4,5:1, bouton ≥ 3:1).
|
|
60
|
+
*/
|
|
61
|
+
export enum Accents {
|
|
62
|
+
pispi = 'pispi',
|
|
63
|
+
vert = 'vert',
|
|
64
|
+
bleu = 'bleu',
|
|
65
|
+
rouge = 'rouge',
|
|
66
|
+
orange = 'orange',
|
|
67
|
+
violet = 'violet',
|
|
68
|
+
rose = 'rose',
|
|
69
|
+
turquoise = 'turquoise',
|
|
70
|
+
terracotta = 'terracotta',
|
|
71
|
+
bordeaux = 'bordeaux',
|
|
72
|
+
ardoise = 'ardoise',
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const teintes = (
|
|
76
|
+
accent: string,
|
|
77
|
+
surAccent: string,
|
|
78
|
+
appui: string,
|
|
79
|
+
texte: string,
|
|
80
|
+
conteneur: string,
|
|
81
|
+
surConteneur: string,
|
|
82
|
+
tertiaire: string,
|
|
83
|
+
): AccentTeintes => ({ accent, surAccent, appui, texte, conteneur, surConteneur, tertiaire });
|
|
84
|
+
|
|
85
|
+
const ACCENTS: Record<Accents, { clair: AccentTeintes; sombre: AccentTeintes }> = {
|
|
86
|
+
[Accents.pispi]: {
|
|
87
|
+
clair: teintes('#F2A900', '#000000', '#E1A009', '#9A6B00', '#F9EBC2', '#000000', '#FFD573'),
|
|
88
|
+
sombre: teintes('#F2A900', '#1B1916', '#D99A06', '#F2A900', '#4A3B1C', '#FFDE9A', '#4A3B1C'),
|
|
89
|
+
},
|
|
90
|
+
[Accents.vert]: {
|
|
91
|
+
clair: teintes('#43A047', '#000000', '#388E3C', '#2E7D32', '#D9F2D6', '#1B4D1E', '#A5D6A7'),
|
|
92
|
+
sombre: teintes('#66BB6A', '#1B1916', '#57A85B', '#66BB6A', '#1F3A20', '#B4E6B1', '#1F3A20'),
|
|
93
|
+
},
|
|
94
|
+
[Accents.bleu]: {
|
|
95
|
+
clair: teintes('#3B63DB', '#FFFFFF', '#3254BA', '#3B63DB', '#DCE4FB', '#1C3378', '#7390E6'),
|
|
96
|
+
sombre: teintes('#7B9BFF', '#1B1916', '#6A88E6', '#7B9BFF', '#1F2A4D', '#C7D3FF', '#1F2A4D'),
|
|
97
|
+
},
|
|
98
|
+
[Accents.rouge]: {
|
|
99
|
+
clair: teintes('#C62828', '#FFFFFF', '#A82222', '#C62828', '#F9D3D3', '#6E1414', '#E57373'),
|
|
100
|
+
sombre: teintes('#EF6F6C', '#1B1916', '#D96260', '#EF6F6C', '#4A1F1E', '#FFC9C7', '#4A1F1E'),
|
|
101
|
+
},
|
|
102
|
+
[Accents.orange]: {
|
|
103
|
+
clair: teintes('#EF6C00', '#000000', '#D45F00', '#B85300', '#FFE0B2', '#6B3300', '#FFB74D'),
|
|
104
|
+
sombre: teintes('#FF9A3D', '#1B1916', '#E6893A', '#FF9A3D', '#4A2E14', '#FFD3A8', '#4A2E14'),
|
|
105
|
+
},
|
|
106
|
+
[Accents.violet]: {
|
|
107
|
+
clair: teintes('#6A1B9A', '#FFFFFF', '#5A1783', '#6A1B9A', '#EBD7F3', '#3D0E5A', '#BA68C8'),
|
|
108
|
+
sombre: teintes('#C08BE0', '#1B1916', '#AD7BCB', '#C08BE0', '#37224A', '#EAD2FA', '#37224A'),
|
|
109
|
+
},
|
|
110
|
+
[Accents.rose]: {
|
|
111
|
+
clair: teintes('#AD1457', '#FFFFFF', '#93114A', '#AD1457', '#F8D3E1', '#5E0B2F', '#F06292'),
|
|
112
|
+
sombre: teintes('#F06C9B', '#1B1916', '#D85F8A', '#F06C9B', '#4A1E30', '#FFC8DB', '#4A1E30'),
|
|
113
|
+
},
|
|
114
|
+
[Accents.turquoise]: {
|
|
115
|
+
clair: teintes('#00897B', '#000000', '#00796B', '#00796B', '#D2EEEB', '#004D45', '#80CBC4'),
|
|
116
|
+
sombre: teintes('#4DB6AC', '#1B1916', '#42A39A', '#4DB6AC', '#173A37', '#B2E8E2', '#173A37'),
|
|
117
|
+
},
|
|
118
|
+
[Accents.terracotta]: {
|
|
119
|
+
clair: teintes('#C2562E', '#000000', '#A8461F', '#A8461F', '#F8DDD2', '#6B2A12', '#F4A585'),
|
|
120
|
+
sombre: teintes('#F08A62', '#1B1916', '#D97A55', '#F08A62', '#4A2A1E', '#FFD2C0', '#4A2A1E'),
|
|
121
|
+
},
|
|
122
|
+
[Accents.bordeaux]: {
|
|
123
|
+
clair: teintes('#8E2440', '#FFFFFF', '#761E35', '#8E2440', '#F3D3DC', '#4F1022', '#D98EA2'),
|
|
124
|
+
sombre: teintes('#E57A95', '#1B1916', '#CE6D85', '#E57A95', '#47212B', '#FFCCD9', '#47212B'),
|
|
125
|
+
},
|
|
126
|
+
[Accents.ardoise]: {
|
|
127
|
+
clair: teintes('#546E7A', '#FFFFFF', '#455A64', '#546E7A', '#DDE5E9', '#263238', '#B0BEC5'),
|
|
128
|
+
sombre: teintes('#90A4AE', '#1B1916', '#7F929B', '#90A4AE', '#2C3438', '#D6E2E8', '#2C3438'),
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
133
|
+
export namespace Accents {
|
|
134
|
+
/** Couleur de base de PI-SPI */
|
|
135
|
+
export const parDefaut = Accents.pispi;
|
|
136
|
+
|
|
137
|
+
/** Couleur correspondant à [code] (`Accents.pispi` si inconnu ou absent). */
|
|
138
|
+
export function fromCode(code: string | null | undefined): Accents {
|
|
139
|
+
if (code == null) return parDefaut;
|
|
140
|
+
return (list() as string[]).includes(code) ? (code as Accents) : parDefaut;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function list(): Accents[] {
|
|
144
|
+
return [
|
|
145
|
+
Accents.pispi,
|
|
146
|
+
Accents.vert,
|
|
147
|
+
Accents.bleu,
|
|
148
|
+
Accents.rouge,
|
|
149
|
+
Accents.orange,
|
|
150
|
+
Accents.violet,
|
|
151
|
+
Accents.rose,
|
|
152
|
+
Accents.turquoise,
|
|
153
|
+
Accents.terracotta,
|
|
154
|
+
Accents.bordeaux,
|
|
155
|
+
Accents.ardoise,
|
|
156
|
+
];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Teintes en thème clair */
|
|
160
|
+
export function clair(accent: Accents): AccentTeintes {
|
|
161
|
+
return ACCENTS[accent].clair;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** Teintes en thème sombre */
|
|
165
|
+
export function sombre(accent: Accents): AccentTeintes {
|
|
166
|
+
return ACCENTS[accent].sombre;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** Libellé traduit de la couleur. */
|
|
170
|
+
export function label(accent: Accents, traductions: AppLocalizations): string {
|
|
171
|
+
switch (accent) {
|
|
172
|
+
case Accents.vert:
|
|
173
|
+
return traductions.appSettingPageAccentVert;
|
|
174
|
+
case Accents.bleu:
|
|
175
|
+
return traductions.appSettingPageAccentBleu;
|
|
176
|
+
case Accents.rouge:
|
|
177
|
+
return traductions.appSettingPageAccentRouge;
|
|
178
|
+
case Accents.orange:
|
|
179
|
+
return traductions.appSettingPageAccentOrange;
|
|
180
|
+
case Accents.violet:
|
|
181
|
+
return traductions.appSettingPageAccentViolet;
|
|
182
|
+
case Accents.rose:
|
|
183
|
+
return traductions.appSettingPageAccentRose;
|
|
184
|
+
case Accents.turquoise:
|
|
185
|
+
return traductions.appSettingPageAccentTurquoise;
|
|
186
|
+
case Accents.terracotta:
|
|
187
|
+
return traductions.appSettingPageAccentTerracotta;
|
|
188
|
+
case Accents.bordeaux:
|
|
189
|
+
return traductions.appSettingPageAccentBordeaux;
|
|
190
|
+
case Accents.ardoise:
|
|
191
|
+
return traductions.appSettingPageAccentArdoise;
|
|
192
|
+
default:
|
|
193
|
+
// Couleur de base de PI-SPI, proposée comme « Défaut »
|
|
194
|
+
return traductions.appSettingPageAccentDefaut;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
70
199
|
export type Brightness = 'light' | 'dark';
|
|
71
200
|
|
|
72
201
|
export interface ColorScheme {
|
|
@@ -172,26 +301,6 @@ export interface ThemeData {
|
|
|
172
301
|
chipTheme: { borderRadius: number; labelStyle: TextStyle };
|
|
173
302
|
}
|
|
174
303
|
|
|
175
|
-
/** Valeurs qui varient d'un thème à l'autre (le reste est commun, comme dans theme.dart). */
|
|
176
|
-
type ThemeSpec = {
|
|
177
|
-
dark: boolean;
|
|
178
|
-
primaryColor: string;
|
|
179
|
-
primaryColorDark: string;
|
|
180
|
-
secondaryHeaderColor: string;
|
|
181
|
-
schemePrimary: string;
|
|
182
|
-
schemeOnPrimary: string;
|
|
183
|
-
schemeSecondary: string;
|
|
184
|
-
schemeTertiary: string;
|
|
185
|
-
iconColor: string;
|
|
186
|
-
focusedBorderColor: string;
|
|
187
|
-
buttonPressed: string;
|
|
188
|
-
buttonBackground: string;
|
|
189
|
-
buttonForeground: string;
|
|
190
|
-
textButtonColor: string;
|
|
191
|
-
textButtonOverlay: string;
|
|
192
|
-
switchActiveTrack: string;
|
|
193
|
-
};
|
|
194
|
-
|
|
195
304
|
const fontSize = (size: number, weight: TextStyle['fontWeight'], height?: number): TextStyle => ({
|
|
196
305
|
fontSize: size,
|
|
197
306
|
fontWeight: weight,
|
|
@@ -214,20 +323,53 @@ export class Themer {
|
|
|
214
323
|
/** Couleur jaune */
|
|
215
324
|
static readonly amberColor = '#F2A900';
|
|
216
325
|
|
|
217
|
-
|
|
218
|
-
static readonly
|
|
326
|
+
// Nuances neutres du thème clair (du plus clair au plus foncé)
|
|
327
|
+
private static readonly neural01Light = '#E6E4E2';
|
|
328
|
+
private static readonly neural02Light = '#BDBDBB';
|
|
329
|
+
private static readonly neural03Light = '#8B887E';
|
|
330
|
+
private static readonly neural04Light = '#615D52';
|
|
331
|
+
private static readonly neural05Light = '#5C5451';
|
|
332
|
+
|
|
333
|
+
// Les mêmes nuances en thème sombre, inversées : 01 reste la nuance
|
|
334
|
+
// discrète (traits, fonds), 03 et 04 les textes secondaires
|
|
335
|
+
private static readonly neural01Dark = '#4A453E';
|
|
336
|
+
private static readonly neural02Dark = '#6F6A60';
|
|
337
|
+
private static readonly neural03Dark = '#A8A297';
|
|
338
|
+
private static readonly neural04Dark = '#BDB7AC';
|
|
339
|
+
private static readonly neural05Dark = '#C4BDB2';
|
|
340
|
+
|
|
341
|
+
/** Luminosité du thème affiché, mise à jour par {@link suivreLuminosite} */
|
|
342
|
+
private static luminosite: Brightness = 'light';
|
|
343
|
+
|
|
344
|
+
/** À appeler avec la luminosité du thème affiché : adapte les couleurs neutres ci-dessous. */
|
|
345
|
+
static suivreLuminosite(luminosite: Brightness): void {
|
|
346
|
+
Themer.luminosite = luminosite;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/** Couleur neural 01 : traits et fonds discrets */
|
|
350
|
+
static get neural01Color(): string {
|
|
351
|
+
return Themer.luminosite === 'dark' ? Themer.neural01Dark : Themer.neural01Light;
|
|
352
|
+
}
|
|
219
353
|
|
|
220
|
-
/** Couleur neural 02 */
|
|
221
|
-
static
|
|
354
|
+
/** Couleur neural 02 : textes désactivés, indications */
|
|
355
|
+
static get neural02Color(): string {
|
|
356
|
+
return Themer.luminosite === 'dark' ? Themer.neural02Dark : Themer.neural02Light;
|
|
357
|
+
}
|
|
222
358
|
|
|
223
|
-
/** Couleur neural 03 */
|
|
224
|
-
static
|
|
359
|
+
/** Couleur neural 03 : textes secondaires */
|
|
360
|
+
static get neural03Color(): string {
|
|
361
|
+
return Themer.luminosite === 'dark' ? Themer.neural03Dark : Themer.neural03Light;
|
|
362
|
+
}
|
|
225
363
|
|
|
226
|
-
/** Couleur neural 04 */
|
|
227
|
-
static
|
|
364
|
+
/** Couleur neural 04 : textes secondaires plus marqués */
|
|
365
|
+
static get neural04Color(): string {
|
|
366
|
+
return Themer.luminosite === 'dark' ? Themer.neural04Dark : Themer.neural04Light;
|
|
367
|
+
}
|
|
228
368
|
|
|
229
369
|
/** Couleur neural 05 */
|
|
230
|
-
static
|
|
370
|
+
static get neural05Color(): string {
|
|
371
|
+
return Themer.luminosite === 'dark' ? Themer.neural05Dark : Themer.neural05Light;
|
|
372
|
+
}
|
|
231
373
|
|
|
232
374
|
/** Primary */
|
|
233
375
|
static readonly primary = '#F2A900';
|
|
@@ -257,41 +399,52 @@ export class Themer {
|
|
|
257
399
|
/** primary small btn height */
|
|
258
400
|
static readonly btnSmallHeight = 38;
|
|
259
401
|
|
|
260
|
-
|
|
402
|
+
// Thème sombre « soft » : fonds brun-gris chauds qui s'éclaircissent avec
|
|
403
|
+
// l'élévation (page < feuille < carte < champ), texte blanc cassé
|
|
404
|
+
private static readonly darkBackground = '#1B1916';
|
|
405
|
+
private static readonly darkSurface = '#24211E';
|
|
406
|
+
private static readonly darkCard = '#2C2925';
|
|
407
|
+
private static readonly darkInput = '#35312C';
|
|
408
|
+
private static readonly darkOutline = '#4A453E';
|
|
409
|
+
private static readonly darkText = '#ECE8E1';
|
|
410
|
+
private static readonly darkTextSecondary = '#A8A297';
|
|
411
|
+
private static readonly darkTextDisabled = '#6F6A60';
|
|
412
|
+
|
|
413
|
+
/** Thème clair ou sombre teinté par la couleur d'accentuation [a]. */
|
|
414
|
+
private static build(dark: boolean, a: AccentTeintes): ThemeData {
|
|
261
415
|
const T = Themer;
|
|
262
|
-
const
|
|
263
|
-
const
|
|
264
|
-
const
|
|
265
|
-
const
|
|
266
|
-
const card = dark ? '#23211D' : '#FAF8F6';
|
|
416
|
+
const textColor = dark ? T.darkText : T.blackColor;
|
|
417
|
+
const surface = dark ? T.darkSurface : T.whiteColor;
|
|
418
|
+
const card = dark ? T.darkCard : '#FAF8F6';
|
|
419
|
+
const background = dark ? T.darkBackground : T.whiteColor;
|
|
267
420
|
const text = (style: TextStyle): TextStyle => ({ color: textColor, ...style });
|
|
268
421
|
|
|
269
422
|
return {
|
|
270
423
|
brightness: dark ? 'dark' : 'light',
|
|
271
|
-
primaryColor:
|
|
272
|
-
primaryColorDark:
|
|
273
|
-
secondaryHeaderColor:
|
|
424
|
+
primaryColor: a.accent,
|
|
425
|
+
primaryColorDark: a.texte,
|
|
426
|
+
secondaryHeaderColor: a.conteneur,
|
|
274
427
|
cardColor: card,
|
|
275
|
-
scaffoldBackgroundColor:
|
|
276
|
-
dialogSurfaceTintColor: dark ?
|
|
428
|
+
scaffoldBackgroundColor: background,
|
|
429
|
+
dialogSurfaceTintColor: dark ? T.darkSurface : T.whiteColor,
|
|
277
430
|
colorScheme: {
|
|
278
431
|
brightness: dark ? 'dark' : 'light',
|
|
279
|
-
primary:
|
|
280
|
-
onPrimary:
|
|
281
|
-
secondary:
|
|
282
|
-
onSecondary:
|
|
283
|
-
tertiary:
|
|
284
|
-
onTertiary:
|
|
432
|
+
primary: a.accent,
|
|
433
|
+
onPrimary: a.surAccent,
|
|
434
|
+
secondary: a.conteneur,
|
|
435
|
+
onSecondary: a.surConteneur,
|
|
436
|
+
tertiary: a.tertiaire,
|
|
437
|
+
onTertiary: dark ? a.surConteneur : T.blackColor,
|
|
285
438
|
error: T.systemErrorColor,
|
|
286
|
-
onError:
|
|
439
|
+
onError: dark ? T.darkBackground : T.blackColor,
|
|
287
440
|
surface,
|
|
288
|
-
onSurface:
|
|
441
|
+
onSurface: textColor,
|
|
289
442
|
},
|
|
290
443
|
appBarTheme: {
|
|
291
|
-
backgroundColor:
|
|
444
|
+
backgroundColor: background,
|
|
292
445
|
foregroundColor: textColor,
|
|
293
446
|
},
|
|
294
|
-
primaryIconColor:
|
|
447
|
+
primaryIconColor: a.accent,
|
|
295
448
|
textTheme: {
|
|
296
449
|
titleLarge: text(fontSize(32, '600')),
|
|
297
450
|
titleMedium: text(fontSize(32, '400')),
|
|
@@ -304,7 +457,7 @@ export class Themer {
|
|
|
304
457
|
bodySmall: text(fontSize(15, '500')),
|
|
305
458
|
displayLarge: text(fontSize(15, '400', 1.4)),
|
|
306
459
|
displayMedium: text(fontSize(13, '500')),
|
|
307
|
-
displaySmall: { ...text(fontSize(13, '400', 1.4)), color: T.
|
|
460
|
+
displaySmall: { ...text(fontSize(13, '400', 1.4)), color: dark ? T.darkTextSecondary : T.neural04Light },
|
|
308
461
|
labelLarge: text(fontSize(12, '400')),
|
|
309
462
|
labelMedium: text(fontSize(11, '400')),
|
|
310
463
|
},
|
|
@@ -313,232 +466,184 @@ export class Themer {
|
|
|
313
466
|
inputDecorationTheme: {
|
|
314
467
|
paddingHorizontal: 16,
|
|
315
468
|
paddingVertical: 5,
|
|
316
|
-
fillColor: dark ?
|
|
469
|
+
fillColor: dark ? T.darkInput : '#FAF8F6',
|
|
317
470
|
borderRadius: 10,
|
|
318
|
-
focusedBorderColor:
|
|
471
|
+
focusedBorderColor: a.accent,
|
|
319
472
|
errorBorderColor: T.systemErrorColor,
|
|
320
|
-
floatingLabelStyle: { color: dark ?
|
|
321
|
-
labelStyle: { color: dark ?
|
|
322
|
-
hintStyle: { color: dark ?
|
|
473
|
+
floatingLabelStyle: { color: dark ? T.darkTextSecondary : T.neural04Light, fontSize: 13, fontWeight: '400' },
|
|
474
|
+
labelStyle: { color: dark ? T.darkTextSecondary : T.neural03Light, fontSize: 17 },
|
|
475
|
+
hintStyle: { color: dark ? T.darkTextDisabled : T.neural02Light, fontSize: 17 },
|
|
323
476
|
errorStyle: { color: T.systemErrorColor, fontSize: 12 },
|
|
324
477
|
errorMaxLines: 3,
|
|
325
|
-
suffixIconColor: dark ?
|
|
478
|
+
suffixIconColor: dark ? T.darkTextSecondary : '#8B887E',
|
|
326
479
|
},
|
|
327
480
|
elevatedButtonTheme: {
|
|
328
|
-
backgroundColor:
|
|
329
|
-
pressedBackgroundColor:
|
|
330
|
-
disabledBackgroundColor: dark ?
|
|
331
|
-
foregroundColor:
|
|
332
|
-
disabledForegroundColor: dark ?
|
|
481
|
+
backgroundColor: a.accent,
|
|
482
|
+
pressedBackgroundColor: a.appui,
|
|
483
|
+
disabledBackgroundColor: dark ? T.darkCard : '#F5F5F1',
|
|
484
|
+
foregroundColor: a.surAccent,
|
|
485
|
+
disabledForegroundColor: dark ? T.darkTextDisabled : T.neural03Light,
|
|
333
486
|
minHeight: T.btnNormalHeight,
|
|
334
487
|
borderRadius: 20,
|
|
335
|
-
textStyle: { color:
|
|
488
|
+
textStyle: { color: a.surAccent, fontSize: 17, fontWeight: '600' },
|
|
336
489
|
},
|
|
337
490
|
textButtonTheme: {
|
|
338
|
-
foregroundColor:
|
|
339
|
-
overlayColor:
|
|
340
|
-
textStyle: { color:
|
|
491
|
+
foregroundColor: a.texte,
|
|
492
|
+
overlayColor: dark ? `${a.accent}1F` : a.conteneur,
|
|
493
|
+
textStyle: { color: a.texte, fontSize: 17, fontWeight: '400' },
|
|
341
494
|
minWidth: 55,
|
|
342
495
|
minHeight: 26,
|
|
343
496
|
},
|
|
344
497
|
switchTheme: {
|
|
345
|
-
thumbColor: dark ?
|
|
346
|
-
activeTrackColor:
|
|
347
|
-
inactiveTrackColor: dark ? T.
|
|
498
|
+
thumbColor: dark ? T.darkTextSecondary : T.whiteColor,
|
|
499
|
+
activeTrackColor: a.accent,
|
|
500
|
+
inactiveTrackColor: dark ? T.darkOutline : T.neural01Light,
|
|
348
501
|
},
|
|
349
502
|
filledButtonTheme: {
|
|
350
|
-
foregroundColor:
|
|
351
|
-
disabledForegroundColor: dark ?
|
|
503
|
+
foregroundColor: a.surAccent,
|
|
504
|
+
disabledForegroundColor: dark ? T.darkTextDisabled : T.neural03Light,
|
|
352
505
|
minHeight: T.btnNormalHeight,
|
|
353
506
|
borderRadius: 20,
|
|
354
|
-
textStyle: { color:
|
|
507
|
+
textStyle: { color: a.surAccent, fontSize: 17, fontWeight: '600' },
|
|
355
508
|
},
|
|
356
509
|
snackBarTheme: { backgroundColor: T.systemErrorColor, margin: 10 },
|
|
357
510
|
checkboxTheme: {
|
|
358
511
|
borderRadius: 6,
|
|
359
|
-
checkColor:
|
|
360
|
-
borderColor: T.
|
|
512
|
+
checkColor: a.surAccent,
|
|
513
|
+
borderColor: dark ? T.darkTextDisabled : T.neural02Light,
|
|
361
514
|
borderWidth: 2,
|
|
362
515
|
},
|
|
363
516
|
chipTheme: { borderRadius: 16, labelStyle: { color: textColor, fontSize: 14, fontWeight: '500' } },
|
|
364
517
|
};
|
|
365
518
|
}
|
|
366
519
|
|
|
367
|
-
/**
|
|
368
|
-
private static readonly
|
|
369
|
-
dark: false,
|
|
370
|
-
primaryColor: Themer.primary,
|
|
371
|
-
primaryColorDark: Themer.primaryDark,
|
|
372
|
-
secondaryHeaderColor: Themer.primaryLight,
|
|
373
|
-
schemePrimary: Themer.primary,
|
|
374
|
-
schemeOnPrimary: Themer.blackColor,
|
|
375
|
-
schemeSecondary: Themer.primaryLight,
|
|
376
|
-
schemeTertiary: Themer.primaryStroke,
|
|
377
|
-
iconColor: Themer.primary,
|
|
378
|
-
focusedBorderColor: Themer.primary,
|
|
379
|
-
buttonPressed: '#E1A009',
|
|
380
|
-
buttonBackground: Themer.primary,
|
|
381
|
-
buttonForeground: Themer.blackColor,
|
|
382
|
-
textButtonColor: Themer.primaryDark,
|
|
383
|
-
textButtonOverlay: Themer.primaryLight,
|
|
384
|
-
switchActiveTrack: Themer.primary,
|
|
385
|
-
};
|
|
520
|
+
/** Thèmes déjà construits, par luminosité et couleur d'accentuation */
|
|
521
|
+
private static readonly themes = new Map<string, ThemeData>();
|
|
386
522
|
|
|
387
|
-
/**
|
|
388
|
-
static
|
|
523
|
+
/** Thème clair teinté par la couleur d'accentuation [accent] */
|
|
524
|
+
static clair(accent?: string | null): ThemeData {
|
|
525
|
+
const a = Accents.fromCode(accent);
|
|
526
|
+
const cle = `clair-${a}`;
|
|
527
|
+
if (!Themer.themes.has(cle)) Themer.themes.set(cle, Themer.build(false, Accents.clair(a)));
|
|
528
|
+
return Themer.themes.get(cle)!;
|
|
529
|
+
}
|
|
389
530
|
|
|
390
|
-
/** Thème
|
|
391
|
-
static
|
|
531
|
+
/** Thème sombre teinté par la couleur d'accentuation [accent] */
|
|
532
|
+
static sombre(accent?: string | null): ThemeData {
|
|
533
|
+
const a = Accents.fromCode(accent);
|
|
534
|
+
const cle = `sombre-${a}`;
|
|
535
|
+
if (!Themer.themes.has(cle)) Themer.themes.set(cle, Themer.build(true, Accents.sombre(a)));
|
|
536
|
+
return Themer.themes.get(cle)!;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/** Code enregistré comme couleur d'accentuation quand l'hôte fournit un thème personnalisé (`PiSpiAppConfig.customTheme`). */
|
|
540
|
+
static readonly customAccentCode = 'application';
|
|
541
|
+
|
|
542
|
+
/** Teintes de la couleur de l'hôte (claire puis sombre), définies à l'ouverture du SDK (voir `Di.init`) ; `null` sans thème personnalisé. */
|
|
543
|
+
static customAccent: { clair: AccentTeintes; sombre: AccentTeintes } | null = null;
|
|
544
|
+
|
|
545
|
+
/** Thème complet fourni par l'hôte (`PiSpiCustomTheme.themeData`) : il remplace alors les thèmes clair et sombre du SDK. */
|
|
546
|
+
static customThemeData: ThemeData | null = null;
|
|
547
|
+
|
|
548
|
+
/** L'hôte a fourni un thème personnalisé */
|
|
549
|
+
static get hasCustomTheme(): boolean {
|
|
550
|
+
return Themer.customAccent != null || Themer.customThemeData != null;
|
|
551
|
+
}
|
|
392
552
|
|
|
393
553
|
/**
|
|
394
|
-
*
|
|
395
|
-
*
|
|
396
|
-
*
|
|
397
|
-
* luminosité de [primary].
|
|
554
|
+
* Teintes claire et sombre dérivées des couleurs de l'hôte : texte posé
|
|
555
|
+
* sur la couleur en noir ou blanc selon son contraste, teinte plus
|
|
556
|
+
* lumineuse en sombre.
|
|
398
557
|
*/
|
|
399
|
-
static
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
)
|
|
558
|
+
static teintesDepuis(
|
|
559
|
+
primary: string,
|
|
560
|
+
secondary?: string,
|
|
561
|
+
tertiary?: string,
|
|
562
|
+
pressed?: string,
|
|
563
|
+
): { clair: AccentTeintes; sombre: AccentTeintes } {
|
|
564
|
+
const sur = (fond: string, fonce: string) =>
|
|
565
|
+
contrast(fonce, fond) >= contrast(Themer.whiteColor, fond) ? fonce : Themer.whiteColor;
|
|
566
|
+
// Lien lisible sur fond blanc (4,5:1), sinon couleur assombrie
|
|
567
|
+
let texte = primary;
|
|
568
|
+
for (let i = 1; i <= 6 && contrast(texte, Themer.whiteColor) < 4.5; i++) {
|
|
569
|
+
texte = lerpColor(primary, Themer.blackColor, i * 0.1);
|
|
570
|
+
}
|
|
571
|
+
const clair: AccentTeintes = {
|
|
572
|
+
accent: primary,
|
|
573
|
+
surAccent: sur(primary, Themer.blackColor),
|
|
574
|
+
appui: pressed ?? lerpColor(primary, Themer.blackColor, 0.2),
|
|
575
|
+
texte,
|
|
576
|
+
conteneur: secondary ?? lerpColor(primary, Themer.whiteColor, 0.75),
|
|
577
|
+
surConteneur: Themer.blackColor,
|
|
578
|
+
tertiaire: tertiary ?? lerpColor(primary, Themer.whiteColor, 0.4),
|
|
579
|
+
};
|
|
580
|
+
// En sombre : couleur éclaircie jusqu'à 3:1 sur le fond
|
|
581
|
+
let fonce = primary;
|
|
582
|
+
for (let i = 1; i <= 6 && contrast(fonce, Themer.darkBackground) < 3; i++) {
|
|
583
|
+
fonce = lerpColor(primary, Themer.whiteColor, i * 0.1);
|
|
584
|
+
}
|
|
585
|
+
const conteneur = lerpColor(Themer.darkBackground, primary, 0.3);
|
|
586
|
+
const sombre: AccentTeintes = {
|
|
587
|
+
accent: fonce,
|
|
588
|
+
surAccent: sur(fonce, Themer.darkBackground),
|
|
589
|
+
appui: lerpColor(fonce, Themer.blackColor, 0.1),
|
|
590
|
+
texte: fonce,
|
|
591
|
+
conteneur,
|
|
592
|
+
surConteneur: lerpColor(fonce, Themer.whiteColor, 0.6),
|
|
593
|
+
tertiaire: conteneur,
|
|
594
|
+
};
|
|
595
|
+
return { clair, sombre };
|
|
408
596
|
}
|
|
409
597
|
|
|
410
|
-
/**
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
secondary: string,
|
|
414
|
-
tertiary: string,
|
|
415
|
-
options: Partial<ThemeSpec> = {},
|
|
416
|
-
): ThemeSpec {
|
|
417
|
-
return {
|
|
418
|
-
...Themer.defaultSpec,
|
|
419
|
-
primaryColor: main,
|
|
420
|
-
primaryColorDark: main,
|
|
421
|
-
secondaryHeaderColor: secondary,
|
|
422
|
-
schemePrimary: main,
|
|
423
|
-
schemeSecondary: secondary,
|
|
424
|
-
schemeTertiary: tertiary,
|
|
425
|
-
iconColor: main,
|
|
426
|
-
focusedBorderColor: main,
|
|
427
|
-
buttonPressed: main,
|
|
428
|
-
buttonBackground: main,
|
|
429
|
-
textButtonColor: main,
|
|
430
|
-
textButtonOverlay: main,
|
|
431
|
-
switchActiveTrack: main,
|
|
432
|
-
...options,
|
|
433
|
-
};
|
|
598
|
+
/** Thème construit sur les teintes [a] (clair, ou sombre si [dark]) */
|
|
599
|
+
static depuisTeintes(a: AccentTeintes, dark = false): ThemeData {
|
|
600
|
+
return Themer.build(dark, a);
|
|
434
601
|
}
|
|
435
602
|
|
|
436
|
-
/**
|
|
437
|
-
static
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
buttonForeground: Themer.whiteColor,
|
|
447
|
-
});
|
|
603
|
+
/** Libellé de la couleur d'accentuation [code], y compris celle de l'hôte */
|
|
604
|
+
static accentLabel(traductions: AppLocalizations, code: string | null | undefined): string {
|
|
605
|
+
if (code === Themer.customAccentCode && Themer.hasCustomTheme) return traductions.appSettingPageMenuThemeCustom;
|
|
606
|
+
return Accents.label(Accents.fromCode(code), traductions);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/** Thème clair avec la couleur PI-SPI */
|
|
610
|
+
static get lightTheme(): ThemeData {
|
|
611
|
+
return Themer.clair();
|
|
612
|
+
}
|
|
448
613
|
|
|
449
|
-
/**
|
|
450
|
-
static
|
|
451
|
-
Themer.
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
/** Light Blue theme data */
|
|
455
|
-
static readonly lightBlueTheme: ThemeData = Themer.build(
|
|
456
|
-
Themer.coloredSpec('#3B63DB', '#A5B9F7', '#7390E6', { schemeOnPrimary: Themer.whiteColor }),
|
|
457
|
-
);
|
|
458
|
-
|
|
459
|
-
/** Light Green theme data */
|
|
460
|
-
static readonly lightGreenTheme: ThemeData = Themer.build(
|
|
461
|
-
Themer.coloredSpec('#9FF796', '#D9FDD6', '#BAFAB6', {
|
|
462
|
-
primaryColor: '#7FC077',
|
|
463
|
-
primaryColorDark: '#7FC077',
|
|
464
|
-
buttonPressed: '#E1A009',
|
|
465
|
-
textButtonColor: '#7FC077',
|
|
466
|
-
textButtonOverlay: '#7FC077',
|
|
467
|
-
}),
|
|
468
|
-
);
|
|
469
|
-
|
|
470
|
-
/** Light Red theme data */
|
|
471
|
-
static readonly lightRedTheme: ThemeData = Themer.build(
|
|
472
|
-
Themer.coloredSpec('#C62828', '#F9CFCF', '#E57373', {
|
|
473
|
-
schemeOnPrimary: Themer.whiteColor,
|
|
474
|
-
buttonPressed: '#B71C1C',
|
|
475
|
-
buttonForeground: Themer.whiteColor,
|
|
476
|
-
}),
|
|
477
|
-
);
|
|
478
|
-
|
|
479
|
-
/** Light Orange theme data */
|
|
480
|
-
static readonly lightOrangeTheme: ThemeData = Themer.build(
|
|
481
|
-
Themer.coloredSpec('#EF6C00', '#FFE0B2', '#FFB74D', {
|
|
482
|
-
schemeOnPrimary: Themer.whiteColor,
|
|
483
|
-
buttonPressed: '#E65100',
|
|
484
|
-
buttonForeground: Themer.whiteColor,
|
|
485
|
-
}),
|
|
486
|
-
);
|
|
487
|
-
|
|
488
|
-
/** Light Purple theme data */
|
|
489
|
-
static readonly lightPurpleTheme: ThemeData = Themer.build(
|
|
490
|
-
Themer.coloredSpec('#6A1B9A', '#E1BEE7', '#BA68C8', {
|
|
491
|
-
schemeOnPrimary: Themer.whiteColor,
|
|
492
|
-
buttonPressed: '#4A148C',
|
|
493
|
-
buttonForeground: Themer.whiteColor,
|
|
494
|
-
}),
|
|
495
|
-
);
|
|
496
|
-
|
|
497
|
-
/** Light Pink theme data */
|
|
498
|
-
static readonly lightPinkTheme: ThemeData = Themer.build(
|
|
499
|
-
Themer.coloredSpec('#AD1457', '#F8BBD0', '#F06292', {
|
|
500
|
-
schemeOnPrimary: Themer.whiteColor,
|
|
501
|
-
buttonPressed: '#880E4F',
|
|
502
|
-
buttonForeground: Themer.whiteColor,
|
|
503
|
-
}),
|
|
504
|
-
);
|
|
614
|
+
/** Thème sombre avec la couleur PI-SPI */
|
|
615
|
+
static get darkTheme(): ThemeData {
|
|
616
|
+
return Themer.sombre();
|
|
617
|
+
}
|
|
505
618
|
|
|
506
619
|
/**
|
|
507
|
-
*
|
|
508
|
-
* [
|
|
509
|
-
* ponctuellement via
|
|
620
|
+
* Thème à afficher : [code] (système, clair ou sombre) teinté par la
|
|
621
|
+
* couleur d'accentuation [accent]. Pour `Themes.system`, [systemScheme]
|
|
622
|
+
* (ex. `useColorScheme()`) prime sur la valeur lue ponctuellement via
|
|
623
|
+
* `Appearance`.
|
|
510
624
|
*/
|
|
511
|
-
static get(code: string | null | undefined, systemScheme?: ColorSchemeName | null): ThemeData {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
case Themes.red:
|
|
526
|
-
return Themer.lightRedTheme;
|
|
527
|
-
case Themes.orange:
|
|
528
|
-
return Themer.lightOrangeTheme;
|
|
529
|
-
case Themes.purple:
|
|
530
|
-
return Themer.lightPurpleTheme;
|
|
531
|
-
case Themes.pink:
|
|
532
|
-
return Themer.lightPinkTheme;
|
|
533
|
-
// Système
|
|
534
|
-
case Themes.system: {
|
|
535
|
-
const brightness = systemScheme === 'light' || systemScheme === 'dark' ? systemScheme : Appearance.getColorScheme();
|
|
536
|
-
return brightness === 'dark' ? Themer.darkTheme : Themer.lightTheme;
|
|
537
|
-
}
|
|
538
|
-
// Default theme
|
|
539
|
-
default:
|
|
540
|
-
return Themer.lightTheme;
|
|
625
|
+
static get(code: string | null | undefined, accent?: string | null, systemScheme?: ColorSchemeName | null): ThemeData {
|
|
626
|
+
const theme = Themes.fromCode(code);
|
|
627
|
+
let dark = theme === Themes.dark;
|
|
628
|
+
if (theme === Themes.system) {
|
|
629
|
+
const brightness = systemScheme === 'light' || systemScheme === 'dark' ? systemScheme : Appearance.getColorScheme();
|
|
630
|
+
dark = brightness === 'dark';
|
|
631
|
+
}
|
|
632
|
+
// Thème complet ou couleur du thème personnalisé de l'hôte
|
|
633
|
+
if (accent === Themer.customAccentCode && Themer.customThemeData != null) return Themer.customThemeData;
|
|
634
|
+
const perso = Themer.customAccent;
|
|
635
|
+
if (accent === Themer.customAccentCode && perso != null) {
|
|
636
|
+
const cle = `${dark ? 'sombre' : 'clair'}-${Themer.customAccentCode}`;
|
|
637
|
+
if (!Themer.themes.has(cle)) Themer.themes.set(cle, Themer.build(dark, dark ? perso.sombre : perso.clair));
|
|
638
|
+
return Themer.themes.get(cle)!;
|
|
541
639
|
}
|
|
640
|
+
return dark ? Themer.sombre(accent) : Themer.clair(accent);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/** Oublie les thèmes construits avec la couleur de l'hôte (nouvelle ouverture du SDK) */
|
|
644
|
+
static resetCustomThemes(): void {
|
|
645
|
+
Themer.themes.delete(`clair-${Themer.customAccentCode}`);
|
|
646
|
+
Themer.themes.delete(`sombre-${Themer.customAccentCode}`);
|
|
542
647
|
}
|
|
543
648
|
}
|
|
544
649
|
|
|
@@ -576,3 +681,10 @@ export function relativeLuminance(hex: string): number {
|
|
|
576
681
|
});
|
|
577
682
|
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
578
683
|
}
|
|
684
|
+
|
|
685
|
+
/** Ratio de contraste WCAG entre deux couleurs */
|
|
686
|
+
export function contrast(a: string, b: string): number {
|
|
687
|
+
const la = relativeLuminance(a);
|
|
688
|
+
const lb = relativeLuminance(b);
|
|
689
|
+
return (Math.max(la, lb) + 0.05) / (Math.min(la, lb) + 0.05);
|
|
690
|
+
}
|