@igo2/sdg-theme 2.0.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # @igo2/sdg-theme
2
+
3
+ Couche de personnalisation Material Design pour le Système de Design Gouvernemental du Québec (SDG).
4
+
5
+ ## Vue d'ensemble
6
+
7
+ Ce package regroupe tout ce qui est lié à Angular Material : la configuration du thème de couleurs, les overrides de composants Material, et les overrides de la librairie IGO2. Il s'utilise en complément de `@igo2/sdg-core` qui, lui, reste entièrement indépendant de Material.
8
+
9
+ ## Quand l'utiliser
10
+
11
+ Installez ce package si votre application :
12
+ - Utilise des composants `@angular/material`
13
+ - Veut les composants Material stylisés selon les spécifications SDG
14
+ - Utilise des composants de la librairie IGO2 (`igo-search-bar`, `igo-list`, etc.)
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @igo2/sdg-theme
20
+ ```
21
+
22
+ ## Utilisation
23
+
24
+ Exemple de référence : `projects/demo/src/theme/theme.scss`
25
+
26
+ ```scss
27
+ @use '@angular/material' as mat;
28
+ @use '@igo2/sdg-theme' as sdg-theme;
29
+
30
+ html {
31
+ color-scheme: light;
32
+
33
+ // Configure le thème de couleurs Material avec la palette SDG
34
+ @include mat.theme(sdg-theme.$material-theme);
35
+
36
+ // Applique les tokens système, la typographie, et tous les overrides
37
+ @include sdg-theme.theme(true);
38
+ }
39
+ ```
40
+
41
+ ## API publique
42
+
43
+ ### Variables
44
+
45
+ | Variable | Description |
46
+ |----------|-------------|
47
+ | `$material-theme` | Configuration du thème Material (couleurs, typographie, densité) à passer à `mat.theme()` |
48
+ | `$primary-palette` | Palette de couleurs primaire SDG (bleu gouvernemental) |
49
+
50
+ ### Mixins
51
+
52
+ | Mixin | Description |
53
+ |-------|-------------|
54
+ | `theme($withDarkMode: false)` | Point d'entrée principal. Applique les tokens système, la typographie, les overrides IGO2 et les overrides Material |
55
+ | `overrides()` | Applique uniquement les overrides de composants Material (sans tokens ni typographie) |
56
+
57
+ ## Migration depuis v1.x
58
+
59
+ ### Avant (v1.x)
60
+
61
+ ```scss
62
+ @use '@angular/material' as mat;
63
+ @use '@igo2/sdg-core' as sdg;
64
+
65
+ html {
66
+ @include mat.theme(sdg.$material-theme);
67
+ @include sdg.theme(true);
68
+ }
69
+ ```
70
+
71
+ ### Après (v2.x)
72
+
73
+ ```scss
74
+ @use '@angular/material' as mat;
75
+ @use '@igo2/sdg-theme' as sdg-theme;
76
+
77
+ html {
78
+ @include mat.theme(sdg-theme.$material-theme);
79
+ @include sdg-theme.theme(true);
80
+ }
81
+ ```
82
+
83
+ ### Étapes de migration
84
+
85
+ 1. Installer `@igo2/sdg-theme` : `npm install @igo2/sdg-theme`
86
+ 2. Remplacer `@use '@igo2/sdg-core' as sdg` par `@use '@igo2/sdg-theme' as sdg-theme` dans votre fichier de thème
87
+ 3. Remplacer `sdg.$material-theme` par `sdg-theme.$material-theme`
88
+ 4. Remplacer `sdg.theme(...)` par `sdg-theme.theme(...)`
89
+
90
+ ## Dépendances
91
+
92
+ - `@angular/material` (peerDependency) — ^21.0.0
93
+ - `@igo2/sdg-core` (peerDependency) — ^2.0.0
94
+
95
+ ## Packages associés
96
+
97
+ - [`@igo2/sdg-core`](../core/README.md) — Infrastructure pure : styles, services, utilitaires
package/_index.scss ADDED
@@ -0,0 +1,35 @@
1
+ /**
2
+ * SDG Material Theme Overrides
3
+ *
4
+ * This module provides Material Design component customizations aligned with
5
+ * the Système de Design Gouvernemental du Québec (SDG).
6
+ *
7
+ * Usage:
8
+ * @use '@igo2/sdg-theme' as theme;
9
+ * @include theme.theme();
10
+ */
11
+
12
+ @use './src/material' as material;
13
+ @use './src/igo2-lib' as igo2-lib;
14
+ @use '@igo2/sdg-core' as core;
15
+
16
+ $material-theme: material.$theme;
17
+ $primary-palette: material.$primary-palette;
18
+
19
+ @mixin theme($withDarkMode: false) {
20
+ @include core.system-tokens();
21
+
22
+ @if ($withDarkMode) {
23
+ body.dark-mode {
24
+ @include core.system-dark-colors();
25
+ }
26
+ }
27
+
28
+ body {
29
+ background-color: var(--sdg-color-background);
30
+ }
31
+
32
+ @include core.typo-base();
33
+ @include igo2-lib.overrides();
34
+ @include material.overrides();
35
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Public API Surface of sdg-theme
3
+ */
4
+ // Material theme overrides are exported as SCSS via _index.scss
5
+ // This file is required for ng-packagr
6
+ const SDG_THEME_VERSION = '1.0.0';
7
+
8
+ /**
9
+ * Generated bundle index. Do not edit.
10
+ */
11
+
12
+ export { SDG_THEME_VERSION };
13
+ //# sourceMappingURL=igo2-sdg-theme.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"igo2-sdg-theme.mjs","sources":["../../../packages/theme/src/public-api.ts","../../../packages/theme/src/igo2-sdg-theme.ts"],"sourcesContent":["/**\n * Public API Surface of sdg-theme\n */\n\n// Material theme overrides are exported as SCSS via _index.scss\n// This file is required for ng-packagr\nexport const SDG_THEME_VERSION = '1.0.0';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"AAAA;;AAEG;AAEH;AACA;AACO,MAAM,iBAAiB,GAAG;;ACNjC;;AAEG;;;;"}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@igo2/sdg-theme",
3
+ "version": "2.0.0-next.2",
4
+ "license": "LiLiQ-R",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/infra-geo-ouverte/sdg.git",
8
+ "directory": "packages/theme"
9
+ },
10
+ "engines": {
11
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
12
+ },
13
+ "exports": {
14
+ ".": {
15
+ "sass": "./_index.scss",
16
+ "types": "./types/igo2-sdg-theme.d.ts",
17
+ "default": "./fesm2022/igo2-sdg-theme.mjs"
18
+ },
19
+ "./package.json": {
20
+ "default": "./package.json"
21
+ }
22
+ },
23
+ "peerDependencies": {
24
+ "@angular/material": "^21.0.0",
25
+ "@igo2/sdg-core": "^2.0.0-next.2"
26
+ },
27
+ "dependencies": {
28
+ "tslib": "^2.6.0"
29
+ },
30
+ "sideEffects": false,
31
+ "module": "fesm2022/igo2-sdg-theme.mjs",
32
+ "typings": "types/igo2-sdg-theme.d.ts",
33
+ "type": "module"
34
+ }
@@ -0,0 +1,9 @@
1
+ @use './list';
2
+ @use './panel';
3
+ @use './search-bar';
4
+
5
+ @mixin overrides() {
6
+ @include list.overrides();
7
+ @include panel.overrides();
8
+ @include search-bar.overrides();
9
+ }
@@ -0,0 +1,22 @@
1
+ @mixin overrides() {
2
+ igo-search-results-item {
3
+ .mdc-list-item__primary-text {
4
+ white-space: normal;
5
+ overflow: hidden;
6
+ text-overflow: ellipsis;
7
+ max-height: unset !important;
8
+ line-height: 18px !important;
9
+ }
10
+ }
11
+
12
+ igo-list
13
+ [igolistitem][color='accent'].igo-list-item-selected
14
+ > mat-list-item {
15
+ background-color: var(--sdg-color-blue-pale);
16
+
17
+ h4,
18
+ small {
19
+ color: var(--sdg-color-blue-piv) !important;
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,7 @@
1
+ @mixin overrides() {
2
+ .igo-panel-header,
3
+ .igo-panel-header button,
4
+ .igo-panel-title {
5
+ color: var(--sdg-color-blue-piv) !important;
6
+ }
7
+ }
@@ -0,0 +1,72 @@
1
+ @use 'sass:map';
2
+ @use '@angular/material' as mat;
3
+
4
+ @mixin overrides() {
5
+ igo-search-bar {
6
+ background-color: var(--sdg-color-background);
7
+
8
+ // Workaroung, OPEN SANS font add a mysterious 1px for the height
9
+ .mat-mdc-form-field-infix {
10
+ max-height: 40px;
11
+ }
12
+
13
+ button[mat-icon-button] {
14
+ border-radius: 0;
15
+ background-color: var(--sdg-color-blue-piv);
16
+
17
+ &:hover {
18
+ background-color: var(--sdg-color-blue-normal);
19
+ }
20
+ }
21
+
22
+ mat-icon {
23
+ color: var(--sdg-color-white);
24
+ }
25
+
26
+ mat-form-field {
27
+ @include mat.form-field-overrides(
28
+ (
29
+ container-height: 40px,
30
+ container-vertical-padding: 8px
31
+ )
32
+ );
33
+ }
34
+
35
+ .mdc-icon-button.mat-mdc-button-base {
36
+ @include mat.icon-button-overrides(
37
+ (
38
+ state-layer-size: 40px
39
+ )
40
+ );
41
+ // reset the default padding of Material. Igo is overriding it
42
+ padding: calc(
43
+ calc(
44
+ var(--mat-icon-button-state-layer-size, 40px) - var(
45
+ --mat-icon-button-icon-size,
46
+ 24px
47
+ )
48
+ ) /
49
+ 2
50
+ );
51
+ }
52
+ }
53
+
54
+ igo-search-results {
55
+ igo-collapsible {
56
+ .mdc-list-item__primary-text {
57
+ color: var(--sdg-color-text);
58
+ font-weight: bold;
59
+ }
60
+ }
61
+
62
+ igo-search-results-item {
63
+ .mdc-list-item__primary-text {
64
+ font-weight: normal;
65
+ }
66
+ }
67
+
68
+ .mdc-list-item--with-leading-icon .mdc-list-item__start {
69
+ color: var(--sdg-color-text);
70
+ }
71
+ }
72
+ }
@@ -0,0 +1,137 @@
1
+ @use '@angular/material' as mat;
2
+
3
+ @mixin overrides() {
4
+ .mdc-button {
5
+ $height: 56px;
6
+ $font-size: var(--sdg-font-size-md);
7
+ $border-radius: 0;
8
+ $horizontal-padding: 16px;
9
+
10
+ min-width: calc($height * 2) !important;
11
+ max-width: 360px;
12
+ line-height: var(--sdg-line-height-md) !important;
13
+
14
+ @include mat.button-overrides(
15
+ (
16
+ filled-container-height: $height,
17
+ filled-label-text-size: $font-size,
18
+ filled-label-text-weight: bold,
19
+ filled-container-shape: $border-radius,
20
+ filled-horizontal-padding: $horizontal-padding,
21
+ outlined-container-height: $height,
22
+ outlined-label-text-size: $font-size,
23
+ outlined-label-text-weight: bold,
24
+ outlined-container-shape: $border-radius,
25
+ outlined-horizontal-padding: $horizontal-padding,
26
+ protected-container-height: $height,
27
+ protected-label-text-size: $font-size,
28
+ protected-label-text-weight: bold,
29
+ protected-container-shape: $border-radius,
30
+ protected-horizontal-padding: $horizontal-padding,
31
+ text-container-height: $height,
32
+ text-label-text-size: $font-size,
33
+ text-label-text-weight: bold,
34
+ text-container-shape: $border-radius,
35
+ text-horizontal-padding: $horizontal-padding
36
+ )
37
+ );
38
+
39
+ &[compact] {
40
+ $height: 40px;
41
+ @include mat.button-overrides(
42
+ (
43
+ filled-container-height: $height,
44
+ outlined-container-height: $height,
45
+ protected-container-height: $height,
46
+ text-container-height: $height
47
+ )
48
+ );
49
+
50
+ min-width: calc($height * 2) !important;
51
+ }
52
+ }
53
+
54
+ .mat-mdc-button-base {
55
+ &.on-primary {
56
+ @include mat.button-overrides(
57
+ (
58
+ filled-state-layer-color: var(--sdg-color-grey-pale),
59
+ outlined-state-layer-color: var(--sdg-color-grey-pale),
60
+ protected-state-layer-color: var(--sdg-color-grey-pale),
61
+ text-state-layer-color: var(--sdg-color-grey-pale)
62
+ )
63
+ );
64
+ @include mat.icon-button-overrides(
65
+ (
66
+ state-layer-color: var(--sdg-color-grey-pale)
67
+ )
68
+ );
69
+ }
70
+ }
71
+
72
+ .mat-mdc-outlined-button {
73
+ border-color: currentColor !important;
74
+ border-width: 2px !important;
75
+ background-color: var(--sdg-color-background) !important;
76
+
77
+ &[compact] {
78
+ border-width: 1px !important;
79
+ }
80
+ }
81
+
82
+ .mdc-fab {
83
+ $background: var(--sdg-color-blue-piv);
84
+ $foreground: var(--sdg-color-white);
85
+ $border-radius: 0;
86
+
87
+ @include mat.fab-overrides(
88
+ (
89
+ container-color: $background,
90
+ container-shape: $border-radius,
91
+ foreground-color: $foreground,
92
+ small-container-color: $background,
93
+ small-container-shape: $border-radius,
94
+ small-foreground-color: $foreground
95
+ )
96
+ );
97
+ }
98
+
99
+ @include color-variants-backwards-compatibility();
100
+ }
101
+
102
+ // Material custom color variants backwards compatibility
103
+ @mixin color-variants-backwards-compatibility() {
104
+ .mdc-button {
105
+ &.mat-warn {
106
+ @include mat.button-overrides(
107
+ (
108
+ filled-container-color: var(--sdg-color-red-normal)
109
+ )
110
+ );
111
+ }
112
+ &.mat-primary {
113
+ @include mat.button-overrides(
114
+ (
115
+ filled-container-color: var(--sdg-color-blue-piv)
116
+ )
117
+ );
118
+ }
119
+ }
120
+
121
+ .mdc-icon-button {
122
+ &.mat-warn {
123
+ @include mat.icon-button-overrides(
124
+ (
125
+ icon-color: var(--sdg-color-red-normal)
126
+ )
127
+ );
128
+ }
129
+ &.mat-primary {
130
+ @include mat.icon-button-overrides(
131
+ (
132
+ icon-color: var(--sdg-color-blue-piv)
133
+ )
134
+ );
135
+ }
136
+ }
137
+ }
@@ -0,0 +1,120 @@
1
+ @use '@angular/material' as mat;
2
+
3
+ @mixin overrides() {
4
+ .mat-mdc-checkbox {
5
+ $disabled-color: var(--sdg-color-grey-light);
6
+ $unselected-color: var(--sdg-color-blue-dark);
7
+ $selected-color: var(--sdg-color-blue-normal);
8
+
9
+ $base-size: 8px;
10
+ $checkbox-size: calc($base-size * 3);
11
+ $size-with-padding: var(--mat-checkbox-state-layer-size);
12
+
13
+ @include mat.checkbox-overrides(
14
+ (
15
+ label-text-size: var(--sdg-font-size-md),
16
+ label-text-line-height: var(--sdg-font-size-md),
17
+ // same as font size to avoid extra space above and below
18
+ label-text-color: $unselected-color,
19
+
20
+ disabled-label-color: $disabled-color,
21
+ disabled-unselected-icon-color: $disabled-color,
22
+ disabled-selected-checkmark-color: var(--sdg-color-grey-pale),
23
+ disabled-selected-icon-color: $disabled-color,
24
+
25
+ unselected-icon-color: $unselected-color,
26
+ unselected-hover-icon-color: $unselected-color,
27
+ unselected-focus-icon-color: $selected-color,
28
+
29
+ unselected-hover-state-layer-opacity: 0,
30
+ unselected-focus-state-layer-opacity: 0,
31
+ unselected-pressed-state-layer-opacity: 0,
32
+
33
+ unselected-hover-state-layer-color: transparent,
34
+ unselected-focus-state-layer-color: transparent,
35
+ unselected-pressed-state-layer-color: transparent,
36
+
37
+ selected-icon-color: $selected-color,
38
+ selected-hover-icon-color: $selected-color,
39
+ selected-focus-icon-color: $selected-color,
40
+ selected-pressed-icon-color: $selected-color,
41
+
42
+ selected-hover-state-layer-opacity: 0,
43
+ selected-focus-state-layer-opacity: 0,
44
+ selected-pressed-state-layer-opacity: 0,
45
+
46
+ selected-hover-state-layer-color: transparent,
47
+ selected-focus-state-layer-color: transparent,
48
+ selected-pressed-state-layer-color: transparent
49
+ )
50
+ );
51
+
52
+ .mdc-checkbox__native-control {
53
+ top: calc($base-size / 2);
54
+ left: calc($base-size / 2);
55
+ right: calc($base-size / 2);
56
+
57
+ &:focus:checked ~ .mdc-checkbox__background {
58
+ border-color: $unselected-color;
59
+ }
60
+ }
61
+
62
+ .mdc-checkbox {
63
+ height: $checkbox-size;
64
+ width: $checkbox-size;
65
+ flex-basis: $checkbox-size;
66
+
67
+ .mdc-checkbox__background {
68
+ height: $checkbox-size;
69
+ width: $checkbox-size;
70
+ border-radius: 0px;
71
+ }
72
+ }
73
+
74
+ .mat-mdc-checkbox-touch-target {
75
+ height: $size-with-padding;
76
+ width: $size-with-padding;
77
+ }
78
+
79
+ .mdc-label {
80
+ padding-left: 0;
81
+ transform: translateY(
82
+ 1px
83
+ ); // visually center the label with the radio button
84
+ }
85
+
86
+ &[compact] {
87
+ $checkbox-size: calc($base-size * 2);
88
+ $size-with-padding: calc($checkbox-size + ($base-size * 2));
89
+
90
+ @include mat.checkbox-overrides(
91
+ (
92
+ state-layer-size: $size-with-padding
93
+ )
94
+ );
95
+
96
+ .mdc-checkbox__native-control {
97
+ top: 0;
98
+ left: 0;
99
+ right: 0;
100
+ }
101
+
102
+ .mdc-checkbox {
103
+ height: $checkbox-size;
104
+ width: $checkbox-size;
105
+ flex-basis: $checkbox-size;
106
+
107
+ .mdc-checkbox__background {
108
+ height: $checkbox-size;
109
+ width: $checkbox-size;
110
+ border-width: 1px;
111
+ }
112
+ }
113
+
114
+ .mat-mdc-checkbox-touch-target {
115
+ height: $size-with-padding;
116
+ width: $size-with-padding;
117
+ }
118
+ }
119
+ }
120
+ }
@@ -0,0 +1,122 @@
1
+ @use '@angular/material' as mat;
2
+
3
+ $focus-color: var(--sdg-color-blue-light);
4
+ $white: var(--sdg-color-white);
5
+
6
+ @mixin overrides() {
7
+ $border-outline-width: 2px;
8
+
9
+ .mat-mdc-chip-set {
10
+ .mdc-evolution-chip {
11
+ margin: 0;
12
+ min-height: 40px;
13
+ max-height: 60px;
14
+ min-width: 56px;
15
+
16
+ &-set__chips {
17
+ margin: 0;
18
+ gap: 8px;
19
+ }
20
+
21
+ &__action-primary {
22
+ padding-left: 4px;
23
+ }
24
+
25
+ &:focus-visible {
26
+ border: $border-outline-width solid $white;
27
+ outline: $border-outline-width solid $focus-color;
28
+ }
29
+ }
30
+ }
31
+
32
+ .mdc-evolution-chip__action {
33
+ &--presentational {
34
+ cursor: pointer;
35
+ }
36
+
37
+ &--primary:hover::before {
38
+ border-color: $focus-color !important;
39
+ }
40
+
41
+ &--primary:focus::before {
42
+ border-width: $border-outline-width;
43
+ outline: $border-outline-width solid $focus-color;
44
+ }
45
+ }
46
+
47
+ .mat-mdc-standard-chip {
48
+ &.mdc-evolution-chip--with-trailing-action .mdc-evolution-chip__action {
49
+ &--primary {
50
+ padding-left: 8px;
51
+ }
52
+
53
+ &--trailing {
54
+ padding-left: 4px;
55
+ padding-right: 6px;
56
+ }
57
+ }
58
+
59
+ & .mdc-evolution-chip__action {
60
+ &--primary {
61
+ padding-left: 8px;
62
+ padding-right: 8px;
63
+ }
64
+ }
65
+ }
66
+
67
+ .mat-mdc-chip-remove {
68
+ &::after {
69
+ left: 2px;
70
+ right: 4px;
71
+ }
72
+
73
+ .mat-icon {
74
+ z-index: 1;
75
+ }
76
+ }
77
+
78
+ .mat-mdc-chip {
79
+ $background-color: var(--sdg-color-blue-pale);
80
+ $text-color: var(--sdg-color-blue-piv);
81
+ $disabled-background-color: var(--sdg-color-grey-pale);
82
+ $disabled-color: var(--sdg-color-grey-normal);
83
+
84
+ @include mat.chips-overrides(
85
+ (
86
+ container-shape-radius: 0,
87
+
88
+ outline-width: 1px,
89
+ outline-color: $background-color,
90
+
91
+ focus-outline-color: $white,
92
+ focus-state-layer-color: transparent,
93
+ focus-state-layer-opacity: 0,
94
+
95
+ disabled-outline-color: $disabled-background-color,
96
+ disabled-label-text-color: $disabled-color,
97
+ disabled-container-opacity: 1,
98
+
99
+ hover-state-layer-opacity: 0,
100
+ hover-state-layer-color: transparent,
101
+
102
+ elevated-container-color: $background-color,
103
+ elevated-selected-container-color: $background-color,
104
+ elevated-disabled-container-color: $disabled-background-color,
105
+
106
+ with-trailing-icon-disabled-trailing-icon-opacity: 1,
107
+ with-trailing-icon-disabled-trailing-icon-color: $disabled-color,
108
+ with-trailing-icon-trailing-icon-color: $text-color,
109
+
110
+ label-text-color: $text-color,
111
+ label-text-weight: 600,
112
+ label-text-line-height: var(--sdg-line-height-sm),
113
+ label-text-size: var(--sdg-font-size-sm),
114
+ trailing-action-focus-state-layer-opacity: 1,
115
+ trailing-action-hover-state-layer-opacity: 1,
116
+ trailing-action-state-layer-color: var(--sdg-color-grey-light),
117
+ trailing-action-focus-opacity: 1,
118
+ trailing-action-opacity: 1
119
+ )
120
+ );
121
+ }
122
+ }