Skip to content

Commit 295fd67

Browse files
authored
feat(material/schematics): Add custom M3 theme schematic (#28766)
* feat(material/schematics): Add custom M3 theme schematic * fix(material/schematics): Add generated file comment and color source comment to output theme file * fix(material/schematics): Create README and update docs theme example * fix(material/schematics): Move more of the m3-schematic docs into the README and link to it from the m3 and schematics guide
1 parent 0fbc899 commit 295fd67

File tree

14 files changed

+1020
-7
lines changed

14 files changed

+1020
-7
lines changed

guides/material-3.md

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,29 @@ used with the `primary` and `tertiary` options:
7878
- `$m3-violet-palette`
7979
- `$m3-rose-palette`
8080

81+
Alternatively, a theme can be generated with a custom color with the following schematic:
82+
83+
```shell
84+
ng generate @angular/material:m3-theme
85+
```
86+
87+
This schematic integrates with [Material Color Utilities](https://github.com/material-foundation/material-color-utilities) to build a theme based on a generated set of palettes based on a single color. Optionally you can provide additional custom colors for the secondary, tertiary, and neutral palettes.
88+
89+
The output of the schematic is a new Sass file that exports a theme or themes (if generating both a light and dark theme) that can be provided to component theme mixins.
90+
91+
```scss
92+
@use '@angular/material' as mat;
93+
@use './path/to/m3-theme';
94+
95+
@include mat.core();
96+
97+
// Apply the light theme by default
98+
@include mat.core-theme(m3-theme.$light-theme);
99+
@include mat.button-theme(m3-theme.$light-theme);
100+
```
101+
102+
Learn more about this schematic in its [documentation](https://github.com/angular/components/blob/main/src/material/schematics/ng-generate/m3-theme/README.md).
103+
81104
<!-- TODO(mmalerba): Illustrate palettes with example. -->
82105

83106
#### Customizing your typography
@@ -427,11 +450,6 @@ $theme: matx.define-theme();
427450

428451
## FAQ
429452

430-
### Can I use colors other than the pre-defined Material 3 palettes?
431-
432-
Currently, we only offer predefined palettes, but we plan to add support for using custom generated
433-
palettes as part of making the M3 APIs stable and available in `@angular/material`.
434-
435453
### Can I depend on the CSS custom property names being stable?
436454

437455
We may make changes to the custom property names before moving the API out of experimental, but

guides/schematics.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,14 @@ that uses the CDK drag and drop directives.
115115
```
116116
ng generate @angular/cdk:drag-drop <component-name>
117117
```
118+
119+
### Material 3 Theme schematic
120+
121+
The `m3-theme` schematic will generate a file with Material 3 themes created
122+
from custom colors.
123+
124+
```
125+
ng generate @angular/material:m3-theme
126+
```
127+
128+
Learn more about this schematic in its [documentation](https://github.com/angular/components/blob/main/src/material/schematics/ng-generate/m3-theme/README.md).

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@
122122
"@material/line-ripple": "15.0.0-canary.7f224ddd4.0",
123123
"@material/linear-progress": "15.0.0-canary.7f224ddd4.0",
124124
"@material/list": "15.0.0-canary.7f224ddd4.0",
125+
"@material/material-color-utilities": "^0.2.7",
125126
"@material/menu": "15.0.0-canary.7f224ddd4.0",
126127
"@material/menu-surface": "15.0.0-canary.7f224ddd4.0",
127128
"@material/notched-outline": "15.0.0-canary.7f224ddd4.0",

src/material/schematics/BUILD.bazel

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ ts_library(
7575
pkg_npm(
7676
name = "npm_package",
7777
srcs = ["package.json"],
78+
nested_packages = [
79+
"//src/material/schematics/ng-generate/m3-theme:npm_package",
80+
],
7881
deps = [
7982
":collection_assets",
8083
":ng_generate_assets",

src/material/schematics/collection.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@
4444
"factory": "./ng-generate/address-form/index",
4545
"schema": "./ng-generate/address-form/schema.json",
4646
"aliases": ["address-form", "material-address-form", "material-addressForm"]
47+
},
48+
"m3Theme": {
49+
"description": "Generate M3 theme",
50+
"factory": "./ng-generate/m3-theme/index_bundled",
51+
"schema": "./ng-generate/m3-theme/schema.json",
52+
"aliases": ["m3-theme", "M3-theme"]
4753
}
4854
}
4955
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
load("@build_bazel_rules_nodejs//:index.bzl", "copy_to_bin")
2+
load("//tools:defaults.bzl", "esbuild", "jasmine_node_test", "pkg_npm", "spec_bundle", "ts_library")
3+
4+
package(default_visibility = ["//visibility:public"])
5+
6+
STATIC_ASSETS = [
7+
"schema.json",
8+
]
9+
10+
ts_library(
11+
name = "m3_theme_lib",
12+
srcs = glob(
13+
["**/*.ts"],
14+
exclude = ["**/*.spec.ts"] + ["rules/components/test-setup-helper.ts"],
15+
),
16+
deps = [
17+
"//src/cdk/schematics",
18+
"@npm//@angular-devkit/schematics",
19+
"@npm//@material/material-color-utilities",
20+
"@npm//@types/node",
21+
"@npm//sass",
22+
"@npm//typescript",
23+
],
24+
)
25+
26+
esbuild(
27+
name = "m3_theme_bundle",
28+
entry_point = ":index.ts",
29+
external = [
30+
"@angular/cdk/schematics",
31+
"@angular/material-experimental/",
32+
"@angular-devkit/schematics",
33+
"@angular-devkit/core",
34+
"typescript",
35+
],
36+
format = "cjs",
37+
output = "index_bundled.js",
38+
platform = "node",
39+
target = "es2015",
40+
deps = [
41+
":m3_theme_lib",
42+
"//src/material:sass_lib",
43+
"//src/material-experimental:sass_lib",
44+
],
45+
)
46+
47+
pkg_npm(
48+
name = "npm_package",
49+
srcs = STATIC_ASSETS,
50+
deps = [":m3_theme_bundle"],
51+
)
52+
53+
########################################
54+
# Testing configuration #
55+
########################################
56+
57+
ts_library(
58+
name = "unit_tests_lib",
59+
testonly = True,
60+
srcs = glob(["**/*.spec.ts"] + ["rules/components/test-setup-helper.ts"]),
61+
devmode_module = "commonjs",
62+
deps = [
63+
":m3_theme_lib",
64+
"//src/cdk/schematics/testing",
65+
"//tools/sass:sass_lib",
66+
"@npm//@angular-devkit/schematics",
67+
"@npm//@bazel/runfiles",
68+
"@npm//@material/material-color-utilities",
69+
"@npm//@types/jasmine",
70+
"@npm//@types/node",
71+
"@npm//sass",
72+
],
73+
)
74+
75+
spec_bundle(
76+
name = "unit_tests_bundle",
77+
# Exclude the `node` devkit entry-point to avoid bundling native modules like
78+
# `chokidar` and `fsevents`. These rely on native bindings and break with ESBuild.
79+
external = ["@angular-devkit/core/node"],
80+
platform = "node",
81+
target = "es2020",
82+
deps = [":unit_tests_lib"],
83+
)
84+
85+
copy_to_bin(
86+
name = "unit_tests_assets",
87+
testonly = True,
88+
srcs = STATIC_ASSETS,
89+
)
90+
91+
jasmine_node_test(
92+
name = "unit_tests",
93+
data = [
94+
":m3_theme_bundle",
95+
":unit_tests_assets",
96+
"//src/material/schematics:collection_assets",
97+
"//src/material/schematics:ng_generate_assets",
98+
],
99+
shard_count = 10,
100+
deps = [
101+
":unit_tests_bundle",
102+
# Runtime dependencies needed by the test and actual migration sources. These need
103+
# to be specified explicitly here because they are not captured by the bundling.
104+
"@npm//@schematics/angular",
105+
"//src/material:sass_lib",
106+
"//src/material-experimental:sass_lib",
107+
],
108+
)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Material 3 Custom Theme schematic
2+
3+
```shell
4+
ng generate @angular/material:m3-theme
5+
```
6+
7+
This schematic allows users to create new Material 3 theme configurations based
8+
on custom colors by using [Material Color Utilities](https://github.com/material-foundation/material-color-utilities).
9+
10+
The generated [color palettes](https://m3.material.io/styles/color/roles) are
11+
optimized to have enough contrast to be more accessible. See [Science of Color Design](https://material.io/blog/science-of-color-design) for more information about Material's color design.
12+
13+
For more customization, custom palette colors can be also be provided for the
14+
secondary, tertiary, and neutral colors. It is recommended to choose colors that
15+
are contrastful, Material has more detailed guidance for [accessible design](https://m3.material.io/foundations/accessible-design/patterns).
16+
17+
The output of the schematic will create a file named `m3-theme.scss` at the
18+
specified directory or the project root with the generated themes. The exported
19+
themes (`$light-theme` and/or `$dark-theme`) can be provided to component theme
20+
mixins.
21+
22+
```scss
23+
@use '@angular/material' as mat;
24+
@use './path/to/my-theme';
25+
26+
@include mat.core();
27+
28+
// Apply the light theme by default
29+
@include mat.core-theme(my-theme.$light-theme);
30+
@include mat.button-theme(my-theme.$light-theme);
31+
```
32+
33+
## Options
34+
35+
### Required
36+
37+
* `primaryColor` - Color to use for app's primary color palette (Note: the other
38+
palettes described in the Material 3 spec will be automatically chosen based on
39+
your primary palette unless specified, to ensure a harmonious color combination).
40+
41+
### Optional
42+
43+
* `secondaryColor` - Color to use for app's secondary color palette. Defaults to
44+
secondary color generated from Material based on the primary.
45+
* `tertiaryColor` - Color to use for app's tertiary color palette. Defaults to
46+
tertiary color generated from Material based on the primary.
47+
* `neutralColor` - Color to use for app's neutral color palette. Defaults to
48+
neutral color generated from Material based on the primary.
49+
* `directory` - Relative path to a directory within the project that the
50+
generated theme file should be created in. Defaults to the project root.
51+
* `themeTypes` - List of theme types (light and dark) to generate themes for.
52+
Defaults to both light and dark.

0 commit comments

Comments
 (0)