material-inspired-component-library 8.0.4 → 8.1.1
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/.claude/settings.local.json +4 -1
- package/CLAUDE.md +53 -0
- package/README.md +4 -0
- package/components/alert/index.scss +2 -2
- package/components/appbar/index.scss +2 -2
- package/components/bottomsheet/index.scss +3 -3
- package/components/button/README.md +68 -10
- package/components/button/index.scss +99 -179
- package/components/button/index.ts +4 -4
- package/components/card/index.scss +3 -3
- package/components/checkbox/index.scss +2 -2
- package/components/datepicker/index.scss +3 -3
- package/components/dialog/index.scss +3 -3
- package/components/iconbutton/README.md +55 -9
- package/components/iconbutton/index.scss +109 -167
- package/components/iconbutton/index.ts +4 -4
- package/components/list/index.scss +8 -8
- package/components/menu/index.scss +3 -3
- package/components/navigationrail/README.md +2 -1
- package/components/navigationrail/index.scss +4 -4
- package/components/radio/index.scss +2 -2
- package/components/select/index.scss +2 -2
- package/components/shapes/README.md +94 -0
- package/components/{shape → shapes}/_paths.generated.scss +0 -6
- package/components/{shape → shapes}/index.scss +10 -10
- package/components/{shape → shapes}/master.scss +3 -3
- package/components/sidesheet/index.scss +3 -3
- package/components/slider/index.scss +5 -5
- package/components/snackbar/index.scss +2 -2
- package/components/switch/index.scss +2 -2
- package/components/textfield/index.scss +2 -2
- package/components/timepicker/index.scss +3 -3
- package/dist/bottomsheet.js +1 -1
- package/dist/button.css +1 -1
- package/dist/button.js +1 -1
- package/dist/card.css +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/components/button/index.d.ts +1 -1
- package/dist/components/iconbutton/index.d.ts +1 -1
- package/dist/datepicker.js +1 -1
- package/dist/iconbutton.css +1 -1
- package/dist/iconbutton.js +1 -1
- package/dist/list.css +1 -1
- package/dist/list.js +1 -1
- package/dist/menu.js +1 -1
- package/dist/micl.css +1 -1
- package/dist/micl.js +1 -1
- package/dist/navigationrail.css +1 -1
- package/dist/navigationrail.js +1 -1
- package/dist/progressindicator.js +1 -1
- package/dist/shapes.css +1 -0
- package/dist/slider.js +1 -1
- package/dist/snackbar.js +1 -1
- package/dist/stepper.js +1 -1
- package/dist/textfield.js +1 -1
- package/dist/timepicker.js +1 -1
- package/docs/button.html +18 -17
- package/docs/iconbutton.html +12 -10
- package/docs/index.html +104 -89
- package/docs/menu.html +1 -1
- package/docs/micl.css +1 -1
- package/docs/micl.js +1 -1
- package/docs/shapes.css +1 -0
- package/docs/shapes.html +49 -40
- package/foundations/layout/index.scss +2 -2
- package/package.json +2 -1
- package/styles/elevation.scss +10 -7
- package/styles/motion.scss +12 -19
- package/styles/{shapes.scss → shape.scss} +6 -4
- package/styles/statelayer.scss +32 -45
- package/styles/typography.scss +4 -5
- package/styles.scss +1 -4
- package/tools/shapes/check.mjs +1 -1
- package/tools/shapes/generate.mjs +2 -8
- package/webpack.config.js +60 -5
- package/components/shape/README.md +0 -103
- package/dist/shape.css +0 -1
- package/docs/shape.css +0 -1
- /package/dist/{shape.js → shapes.js} +0 -0
- /package/docs/{shape.js → shapes.js} +0 -0
package/docs/shapes.html
CHANGED
|
@@ -11,16 +11,24 @@
|
|
|
11
11
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:FILL@0..1&icon_names=content_copy,dark_mode,home&display=block">
|
|
12
12
|
<link rel="stylesheet" href="themes/airblue/theme.css" id="theme-link">
|
|
13
13
|
<link rel="stylesheet" href="micl.css">
|
|
14
|
-
<link rel="stylesheet" href="
|
|
14
|
+
<link rel="stylesheet" href="shapes.css">
|
|
15
15
|
<link rel="stylesheet" href="docs.css">
|
|
16
16
|
<style>
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
.shapes {
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
gap: 16px;
|
|
21
|
+
margin-inline-end: 16px;
|
|
19
22
|
}
|
|
20
|
-
.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
.buttons {
|
|
24
|
+
display: flex;
|
|
25
|
+
align-content: flex-start;
|
|
26
|
+
flex-wrap: wrap;
|
|
27
|
+
gap: 8px;
|
|
28
|
+
}
|
|
29
|
+
.micl-shapes {
|
|
30
|
+
block-size: 140px;
|
|
31
|
+
inline-size: 140px;
|
|
24
32
|
}
|
|
25
33
|
</style>
|
|
26
34
|
</head>
|
|
@@ -42,17 +50,20 @@
|
|
|
42
50
|
<div class="micl-pane__column">
|
|
43
51
|
<div class="micl-card-elevated">
|
|
44
52
|
<div class="micl-card__content" style="display:flex">
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
<
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
<div class="shapes">
|
|
54
|
+
<svg class="micl-shapes micl-shapes--square" viewBox="-10 0 120 100"><path /></svg>
|
|
55
|
+
<svg class="micl-shapes micl-shapes--square micl-shapes--outlined" viewBox="-10 0 120 100"><path /></svg>
|
|
56
|
+
<svg class="micl-shapes micl-shapes--square" viewBox="-10 0 120 100">
|
|
57
|
+
<defs>
|
|
58
|
+
<pattern id="photo-1" patternUnits="userSpaceOnUse" x="-10" y="0" width="120" height="100">
|
|
59
|
+
<image href="https://upload.wikimedia.org/wikipedia/commons/thumb/7/71/Sibirischer_tiger_de_edit02.jpg/330px-Sibirischer_tiger_de_edit02.jpg" width="120" height="100" preserveAspectRatio="xMidYMid slice" />
|
|
60
|
+
</pattern>
|
|
61
|
+
</defs>
|
|
62
|
+
<path fill="url(#photo-1)" />
|
|
63
|
+
</svg>
|
|
64
|
+
<svg class="micl-shapes micl-shapes--square micl-shapes--shadowed" viewBox="-10 0 120 100" style="fill:var(--md-sys-color-tertiary)"><path /></svg>
|
|
65
|
+
</div>
|
|
66
|
+
<div class="buttons">
|
|
56
67
|
<button type="button" data-target="circle" class="micl-button-outlined-s">Circle</button>
|
|
57
68
|
<button type="button" data-target="square" class="micl-button-outlined-s">Square</button>
|
|
58
69
|
<button type="button" data-target="slanted" class="micl-button-outlined-s">Slanted</button>
|
|
@@ -94,14 +105,14 @@
|
|
|
94
105
|
</div>
|
|
95
106
|
</div>
|
|
96
107
|
</section>
|
|
97
|
-
<section class="micl-pane">
|
|
108
|
+
<section class="micl-pane" style="min-inline-size:328px">
|
|
98
109
|
<div class="micl-card-filled" style="margin-top:8px">
|
|
99
110
|
<div class="micl-card__headline-s">
|
|
100
111
|
<h2>Code example</h2>
|
|
101
112
|
<button type="button" id="copycode" class="micl-iconbutton-standard-s material-symbols-outlined" aria-label="Copy code">content_copy</button>
|
|
102
113
|
</div>
|
|
103
114
|
<div class="micl-card__content docs-code">
|
|
104
|
-
<pre tabindex="-1"><code><
|
|
115
|
+
<pre tabindex="-1"><code><svg class="micl-shapes micl-shapes--square" viewBox="-10 0 120 100"><path /></svg></code></pre>
|
|
105
116
|
</div>
|
|
106
117
|
</div>
|
|
107
118
|
</section>
|
|
@@ -111,35 +122,33 @@
|
|
|
111
122
|
<script src="docs.js"></script>
|
|
112
123
|
<script>
|
|
113
124
|
const SHAPES = [
|
|
114
|
-
'circle', 'square', 'slanted', 'arch', 'semicircle',
|
|
115
|
-
'
|
|
116
|
-
'
|
|
117
|
-
'
|
|
118
|
-
'cookie-12', 'clover-4', 'clover-8', 'burst', 'soft-burst',
|
|
119
|
-
'boom', 'soft-boom', 'flower', 'puffy', 'puffy-diamond',
|
|
125
|
+
'circle', 'square', 'slanted', 'arch', 'semicircle', 'oval', 'pill', 'triangle',
|
|
126
|
+
'arrow', 'fan', 'diamond', 'clamshell', 'pentagon', 'gem', 'very-sunny', 'sunny',
|
|
127
|
+
'cookie-4', 'cookie-6', 'cookie-7', 'cookie-9', 'cookie-12', 'clover-4', 'clover-8',
|
|
128
|
+
'burst', 'soft-burst', 'boom', 'soft-boom', 'flower', 'puffy', 'puffy-diamond',
|
|
120
129
|
'ghost-ish', 'pixel-circle', 'pixel-triangle', 'bun', 'heart'
|
|
121
130
|
];
|
|
122
131
|
|
|
123
|
-
document.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
+
document.querySelectorAll('.micl-shapes').forEach(el => {
|
|
133
|
+
el.addEventListener('morph', event => {
|
|
134
|
+
const target = event.currentTarget;
|
|
135
|
+
target.style.setProperty('--micl-shapes-morph-duration', `${event.detail.duration}ms`);
|
|
136
|
+
if (event.detail.easing) {
|
|
137
|
+
target.style.setProperty('--micl-shapes-morph-easing', event.detail.easing);
|
|
138
|
+
}
|
|
139
|
+
SHAPES.forEach(shape => target.classList.remove(`micl-shapes--${shape}`));
|
|
140
|
+
target.classList.add(`micl-shapes--${event.detail.shape}`);
|
|
141
|
+
});
|
|
132
142
|
});
|
|
133
143
|
|
|
134
|
-
document.querySelectorAll('button[data-target]').forEach(button =>
|
|
135
|
-
{
|
|
144
|
+
document.querySelectorAll('button[data-target]').forEach(button => {
|
|
136
145
|
button.addEventListener('click', () => {
|
|
137
|
-
document.querySelectorAll('.micl-
|
|
146
|
+
document.querySelectorAll('.micl-shapes').forEach(el => {
|
|
138
147
|
el.dispatchEvent(new CustomEvent('morph', {
|
|
139
148
|
detail: {
|
|
140
|
-
shape:
|
|
149
|
+
shape : button.dataset.target,
|
|
141
150
|
duration: 2000,
|
|
142
|
-
easing:
|
|
151
|
+
easing : 'cubic-bezier(0.34, 1.56, 0.64, 1)'
|
|
143
152
|
}
|
|
144
153
|
}));
|
|
145
154
|
});
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
20
|
// SOFTWARE.
|
|
21
21
|
|
|
22
|
-
@use '../../styles/
|
|
22
|
+
@use '../../styles/shape';
|
|
23
23
|
|
|
24
|
-
@include
|
|
24
|
+
@include shape.corner('medium');
|
|
25
25
|
|
|
26
26
|
$md-sys-window-compact-max: 599px;
|
|
27
27
|
$md-sys-window-medium-min: 600px;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "material-inspired-component-library",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.1.1",
|
|
4
4
|
"description": "The Material-Inspired Component Library (MICL) offers a collection of beautifully crafted components leveraging native HTML markup, designed to align with the Material Design 3 guidelines.",
|
|
5
5
|
"author": "MICL Hermana <micl.hermana@proton.me> (https://github.com/henkpb/micl)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"navigation rail",
|
|
32
32
|
"radio button",
|
|
33
33
|
"select",
|
|
34
|
+
"shapes",
|
|
34
35
|
"sidesheet",
|
|
35
36
|
"slider",
|
|
36
37
|
"snackbar",
|
package/styles/elevation.scss
CHANGED
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
@use 'sass:map';
|
|
23
23
|
|
|
24
24
|
//
|
|
25
|
-
// Set $master: true (
|
|
26
|
-
// used by the master bundle. When false (default), components opt into
|
|
27
|
-
// @include level($n)
|
|
25
|
+
// Set $master: true (@use 'styles/elevation' with ($master: true)) to install all six levels in
|
|
26
|
+
// a single body block — used by the master bundle. When false (default), components opt into
|
|
27
|
+
// individual levels via @include level($n).
|
|
28
28
|
//
|
|
29
29
|
$master: false !default;
|
|
30
30
|
|
|
@@ -54,16 +54,19 @@ $_levels: (
|
|
|
54
54
|
|
|
55
55
|
@if $master {
|
|
56
56
|
body {
|
|
57
|
-
@each $
|
|
58
|
-
--md-sys-elevation-level#{$
|
|
57
|
+
@each $name, $value in $_levels {
|
|
58
|
+
--md-sys-elevation-level#{$name}: #{$value};
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
@mixin level($
|
|
63
|
+
@mixin level($name) {
|
|
64
64
|
@if not $master {
|
|
65
|
+
@if not map.has-key($_levels, $name) {
|
|
66
|
+
@error "Unknown elevation level '#{$name}'. Available: #{map.keys($_levels)}.";
|
|
67
|
+
}
|
|
65
68
|
body {
|
|
66
|
-
--md-sys-elevation-level#{$
|
|
69
|
+
--md-sys-elevation-level#{$name}: #{map.get($_levels, $name)};
|
|
67
70
|
}
|
|
68
71
|
}
|
|
69
72
|
}
|
package/styles/motion.scss
CHANGED
|
@@ -22,19 +22,12 @@
|
|
|
22
22
|
@use 'sass:map';
|
|
23
23
|
|
|
24
24
|
//
|
|
25
|
-
// Set $master: true (via @use
|
|
26
|
-
// used by the master bundle. When false (default), components opt into
|
|
27
|
-
// tokens via @include duration('medium2')
|
|
28
|
-
// reference via var(--md-sys-motion-duration-...).
|
|
25
|
+
// Set $master: true (via @use 'styles/motion' with ($master: true)) to install every duration
|
|
26
|
+
// token + path on :root — used by the master bundle. When false (default), components opt into
|
|
27
|
+
// individual duration tokens via @include duration('medium2').
|
|
29
28
|
//
|
|
30
29
|
$master: false !default;
|
|
31
30
|
|
|
32
|
-
//
|
|
33
|
-
// Project-tuned cubic-bezier approximations of M3 spring-based motion. M3 itself defines
|
|
34
|
-
// fast/default/slow × spatial/effects motion as spring physics (damping/stiffness pairs),
|
|
35
|
-
// but CSS transitions don't have a native spring() timing function, so these bezier curves
|
|
36
|
-
// stand in. Y values >1 in the spatial easings produce the characteristic M3 Expressive overshoot.
|
|
37
|
-
//
|
|
38
31
|
$md-sys-motion-expressive-fast-spatial: cubic-bezier(0.42, 1.67, 0.21, 0.90);
|
|
39
32
|
$md-sys-motion-expressive-fast-spatial-duration: 350ms;
|
|
40
33
|
$md-sys-motion-expressive-fast-effects: cubic-bezier(0.31, 0.94, 0.34, 1.00);
|
|
@@ -110,6 +103,15 @@ $_durations: (
|
|
|
110
103
|
extra-long4: $md-sys-motion-duration-extra-long4,
|
|
111
104
|
);
|
|
112
105
|
|
|
106
|
+
@if $master {
|
|
107
|
+
:root {
|
|
108
|
+
@each $name, $value in $_durations {
|
|
109
|
+
--md-sys-motion-duration-#{$name}: #{$value};
|
|
110
|
+
}
|
|
111
|
+
--md-sys-motion-path: #{$md-sys-motion-path};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
113
115
|
@mixin duration($name) {
|
|
114
116
|
@if not $master {
|
|
115
117
|
@if not map.has-key($_durations, $name) {
|
|
@@ -120,12 +122,3 @@ $_durations: (
|
|
|
120
122
|
}
|
|
121
123
|
}
|
|
122
124
|
}
|
|
123
|
-
|
|
124
|
-
@if $master {
|
|
125
|
-
:root {
|
|
126
|
-
@each $name, $value in $_durations {
|
|
127
|
-
--md-sys-motion-duration-#{$name}: #{$value};
|
|
128
|
-
}
|
|
129
|
-
--md-sys-motion-path: #{$md-sys-motion-path};
|
|
130
|
-
}
|
|
131
|
-
}
|
|
@@ -22,10 +22,9 @@
|
|
|
22
22
|
@use 'sass:map';
|
|
23
23
|
|
|
24
24
|
//
|
|
25
|
-
// Set $master: true (via @use
|
|
26
|
-
// used by the master bundle. When false (default), components opt into
|
|
27
|
-
// @include corner('medium')
|
|
28
|
-
// reference.
|
|
25
|
+
// Set $master: true (via @use 'styles/shape' with ($master: true)) to install every corner token
|
|
26
|
+
// in a single root block — used by the master bundle. When false (default), components opt into
|
|
27
|
+
// individual tokens via @include corner('medium').
|
|
29
28
|
//
|
|
30
29
|
$master: false !default;
|
|
31
30
|
|
|
@@ -57,6 +56,9 @@ $_corners: (
|
|
|
57
56
|
|
|
58
57
|
@mixin corner($name) {
|
|
59
58
|
@if not $master {
|
|
59
|
+
@if not map.has-key($_corners, $name) {
|
|
60
|
+
@error "Unknown corner rounding '#{$name}'. Available: #{map.keys($_corners)}.";
|
|
61
|
+
}
|
|
60
62
|
:root {
|
|
61
63
|
--md-sys-shape-corner-#{$name}: #{map.get($_corners, $name)};
|
|
62
64
|
}
|
package/styles/statelayer.scss
CHANGED
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
@use 'sass:map';
|
|
23
23
|
|
|
24
24
|
//
|
|
25
|
-
// Set $master: true (via @use
|
|
26
|
-
// registrations, and the ripple keyframes — used by the
|
|
27
|
-
// components opt into individual tokens via
|
|
28
|
-
// the animatable @property registrations via
|
|
29
|
-
// @include
|
|
25
|
+
// Set $master: true (via @use 'styles/statelayer' with ($master: true)) to install every
|
|
26
|
+
// state-layer token, the @property registrations, and the ripple keyframes — used by the
|
|
27
|
+
// master bundle. When false (default), components opt into individual tokens via
|
|
28
|
+
// @include token('hover-state-layer-opacity'), the animatable @property registrations via
|
|
29
|
+
// @include property, and the ripple keyframes via @include keyframes.
|
|
30
30
|
//
|
|
31
31
|
$master: false !default;
|
|
32
32
|
|
|
@@ -37,35 +37,50 @@ $_tokens: (
|
|
|
37
37
|
focus-state-layer-opacity: 10%,
|
|
38
38
|
pressed-state-layer-opacity: 10%,
|
|
39
39
|
dragged-state-layer-opacity: 16%,
|
|
40
|
-
// TODO: misnamed vs M3 spec — value 38% matches DisabledLabelTextOpacity / DisabledIconOpacity
|
|
41
|
-
// (content fade), but M3's `disabled.state-layer.opacity` is 12% (container background).
|
|
42
|
-
// Either rename to --md-sys-state-disabled-opacity (breaking) or split into two tokens.
|
|
43
40
|
disabled-state-layer-opacity: 38%,
|
|
44
41
|
focus-indicator-inner-offset: -3px,
|
|
45
42
|
focus-indicator-outer-offset: 2px,
|
|
46
43
|
focus-indicator-thickness: 3px,
|
|
47
44
|
backdrop-opacity: 32%,
|
|
48
45
|
ripple-opacity-factor: 0.6,
|
|
49
|
-
// TODO: 5000ms is well outside M3's motion scale (max DurationExtraLong4 = 1000ms;
|
|
50
|
-
// standard ripples ~300ms). Used here as an upper-bound cap on the @keyframes spread,
|
|
51
|
-
// not as a perceived animation duration. Consider renaming to ripple-spread-cap or
|
|
52
|
-
// aligning with an M3 motion token.
|
|
53
46
|
ripple-duration: 5000ms,
|
|
54
47
|
);
|
|
55
48
|
|
|
49
|
+
@if $master {
|
|
50
|
+
:root {
|
|
51
|
+
@each $name, $value in $_tokens {
|
|
52
|
+
--md-sys-state-#{$name}: #{$value};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@property --statelayer-color {
|
|
57
|
+
syntax: '<color>';
|
|
58
|
+
initial-value: transparent;
|
|
59
|
+
inherits: false;
|
|
60
|
+
}
|
|
61
|
+
@property --statelayer-opacity {
|
|
62
|
+
syntax: '<percentage>';
|
|
63
|
+
initial-value: 0%;
|
|
64
|
+
inherits: false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@keyframes micl-ripple {
|
|
68
|
+
from { background-size: 0%, 100%; }
|
|
69
|
+
to { background-size: 10000%, 100%; }
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
56
73
|
@mixin token($name) {
|
|
57
74
|
@if not $master {
|
|
75
|
+
@if not map.has-key($_tokens, $name) {
|
|
76
|
+
@error "Unknown state-layer token '#{$name}'. Available: #{map.keys($_tokens)}.";
|
|
77
|
+
}
|
|
58
78
|
:root {
|
|
59
79
|
--md-sys-state-#{$name}: #{map.get($_tokens, $name)};
|
|
60
80
|
}
|
|
61
81
|
}
|
|
62
82
|
}
|
|
63
83
|
|
|
64
|
-
//
|
|
65
|
-
// CSS @property registrations for the ripple animation. Components that animate --statelayer-color
|
|
66
|
-
// or --statelayer-opacity (typed-property interpolation) must include this mixin; otherwise the
|
|
67
|
-
// variables fall back to untyped strings and the browser cannot transition between values.
|
|
68
|
-
//
|
|
69
84
|
@mixin property {
|
|
70
85
|
@if not $master {
|
|
71
86
|
@property --statelayer-color {
|
|
@@ -81,10 +96,6 @@ $_tokens: (
|
|
|
81
96
|
}
|
|
82
97
|
}
|
|
83
98
|
|
|
84
|
-
//
|
|
85
|
-
// Ripple keyframes only required by components that actually run the ripple background-size
|
|
86
|
-
// animation.
|
|
87
|
-
//
|
|
88
99
|
@mixin keyframes {
|
|
89
100
|
@if not $master {
|
|
90
101
|
@keyframes micl-ripple {
|
|
@@ -93,27 +104,3 @@ $_tokens: (
|
|
|
93
104
|
}
|
|
94
105
|
}
|
|
95
106
|
}
|
|
96
|
-
|
|
97
|
-
@if $master {
|
|
98
|
-
:root {
|
|
99
|
-
@each $name, $value in $_tokens {
|
|
100
|
-
--md-sys-state-#{$name}: #{$value};
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
@property --statelayer-color {
|
|
105
|
-
syntax: '<color>';
|
|
106
|
-
initial-value: transparent;
|
|
107
|
-
inherits: false;
|
|
108
|
-
}
|
|
109
|
-
@property --statelayer-opacity {
|
|
110
|
-
syntax: '<percentage>';
|
|
111
|
-
initial-value: 0%;
|
|
112
|
-
inherits: false;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
@keyframes micl-ripple {
|
|
116
|
-
from { background-size: 0%, 100%; }
|
|
117
|
-
to { background-size: 10000%, 100%; }
|
|
118
|
-
}
|
|
119
|
-
}
|
package/styles/typography.scss
CHANGED
|
@@ -22,11 +22,10 @@
|
|
|
22
22
|
@use 'sass:map';
|
|
23
23
|
|
|
24
24
|
//
|
|
25
|
-
// Set $master: true (
|
|
26
|
-
// narrow-tracking overrides, and the .md-sys-typescale-* utility classes —
|
|
27
|
-
// master bundle. When false (default), components opt into individual typescales via
|
|
28
|
-
// scale('body-large')
|
|
29
|
-
// actually reference.
|
|
25
|
+
// Set $master: true (@use 'styles/typography' with ($master: true)) to install every typescale
|
|
26
|
+
// token, the @supports narrow-tracking overrides, and the .md-sys-typescale-* utility classes —
|
|
27
|
+
// used by the master bundle. When false (default), components opt into individual typescales via
|
|
28
|
+
// @include scale('body-large').
|
|
30
29
|
//
|
|
31
30
|
$master: false !default;
|
|
32
31
|
|
package/styles.scss
CHANGED
|
@@ -19,10 +19,7 @@
|
|
|
19
19
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
20
|
// SOFTWARE.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
// transitive consumer (e.g. foundations/layout) loads it with defaults,
|
|
24
|
-
// otherwise Sass errors with "module already loaded".
|
|
25
|
-
@use 'styles/shapes' with ($master: true);
|
|
22
|
+
@use 'styles/shape' with ($master: true);
|
|
26
23
|
@use 'styles/elevation' with ($master: true);
|
|
27
24
|
@use 'styles/statelayer' with ($master: true);
|
|
28
25
|
@use 'styles/typography' with ($master: true);
|
package/tools/shapes/check.mjs
CHANGED
|
@@ -24,7 +24,7 @@ import path from 'node:path';
|
|
|
24
24
|
import { generatePathsScss, TARGET_PATH } from './generate.mjs';
|
|
25
25
|
|
|
26
26
|
//
|
|
27
|
-
// CI staleness gate. Compares the on-disk components/
|
|
27
|
+
// CI staleness gate. Compares the on-disk components/shapes/_paths.generated.scss
|
|
28
28
|
// against what the generator would produce now. Exits non-zero if they differ,
|
|
29
29
|
// instructing the developer to run `npm run gen:shapes` and commit the result.
|
|
30
30
|
//
|
|
@@ -25,19 +25,13 @@ import { fileURLToPath } from 'node:url';
|
|
|
25
25
|
|
|
26
26
|
//
|
|
27
27
|
// Shape-path generator. Run via `npm run gen:shapes`. Writes
|
|
28
|
-
// components/
|
|
28
|
+
// components/shapes/_paths.generated.scss with one map entry per shape; the
|
|
29
29
|
// SCSS partial then looks up the path strings without doing any math at
|
|
30
30
|
// compile time.
|
|
31
31
|
//
|
|
32
|
-
// This file is a faithful port of the Sass math that previously lived in
|
|
33
|
-
// styles/shapes.scss / components/shape/index.scss. Numeric output is
|
|
34
|
-
// formatted to match Sass's default $number-precision: 10 with trailing
|
|
35
|
-
// zeros stripped, so the emitted `d` strings are byte-identical to the
|
|
36
|
-
// Sass-rendered ones.
|
|
37
|
-
//
|
|
38
32
|
|
|
39
33
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
40
|
-
const targetPath = path.resolve(__dirname, '../../components/
|
|
34
|
+
const targetPath = path.resolve(__dirname, '../../components/shapes/_paths.generated.scss');
|
|
41
35
|
|
|
42
36
|
// Sass's default precision is 10 decimal places. Match that, then strip
|
|
43
37
|
// trailing zeros so e.g. 50.0000000000 → 50, 3.1400000000 → 3.14.
|
package/webpack.config.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
2
3
|
const glob = require('glob');
|
|
3
4
|
const webpack = require('webpack');
|
|
4
5
|
const miniCss = require('mini-css-extract-plugin');
|
|
@@ -12,9 +13,19 @@ const scssEntries = scssFiles.reduce((entries, filePath) => {
|
|
|
12
13
|
// dist-bundle entry that installs all shapes). Only the latter should
|
|
13
14
|
// be compiled as a webpack entry.
|
|
14
15
|
const normalized = filePath.replace(/\\/g, '/');
|
|
15
|
-
if (normalized.endsWith('components/
|
|
16
|
+
if (normalized.endsWith('components/shapes/index.scss')) return entries;
|
|
16
17
|
const componentName = path.dirname(filePath).split('\\').pop();
|
|
17
|
-
|
|
18
|
+
|
|
19
|
+
// Pair each component's stylesheet with its sibling TypeScript handler (if
|
|
20
|
+
// present) so the standalone <component>.js contains the component logic
|
|
21
|
+
// instead of an empty UMD stub. Foundations TS are built via tsEntries.
|
|
22
|
+
const sources = ['./' + filePath];
|
|
23
|
+
const tsSibling = path.dirname(normalized) + '/index.ts';
|
|
24
|
+
if (normalized.startsWith('components/') && fs.existsSync(tsSibling)) {
|
|
25
|
+
sources.push('./' + tsSibling);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
entries[componentName] = sources.length > 1 ? sources : sources[0];
|
|
18
29
|
return entries;
|
|
19
30
|
}, {});
|
|
20
31
|
|
|
@@ -26,11 +37,14 @@ const tsEntries = glob.sync('./foundations/**/*.ts').reduce((entries, filePath)
|
|
|
26
37
|
}, {});
|
|
27
38
|
|
|
28
39
|
module.exports = [{
|
|
40
|
+
// Standalone per-component / per-foundation files. Built first and on its
|
|
41
|
+
// own (clean: true) so the micl bundle below can scope-hoist component
|
|
42
|
+
// modules instead of treating them as entry points.
|
|
43
|
+
name: 'parts',
|
|
29
44
|
mode: 'production',
|
|
30
45
|
entry: {
|
|
31
46
|
...scssEntries,
|
|
32
|
-
...tsEntries
|
|
33
|
-
micl: ['./styles.scss', './micl.ts']
|
|
47
|
+
...tsEntries
|
|
34
48
|
},
|
|
35
49
|
resolve: {
|
|
36
50
|
extensions: ['.ts', '.tsx', '.js']
|
|
@@ -64,11 +78,52 @@ module.exports = [{
|
|
|
64
78
|
filename: '[name].css'
|
|
65
79
|
})
|
|
66
80
|
]
|
|
81
|
+
}, {
|
|
82
|
+
// Full dist bundle. Separate compilation (after 'parts', without cleaning)
|
|
83
|
+
// so component modules imported by micl.ts are concatenated into micl.js.
|
|
84
|
+
name: 'bundle',
|
|
85
|
+
dependencies: ['parts'],
|
|
86
|
+
mode: 'production',
|
|
87
|
+
entry: {
|
|
88
|
+
micl: ['./styles.scss', './micl.ts']
|
|
89
|
+
},
|
|
90
|
+
resolve: {
|
|
91
|
+
extensions: ['.ts', '.tsx', '.js']
|
|
92
|
+
},
|
|
93
|
+
output: {
|
|
94
|
+
path: distDir,
|
|
95
|
+
filename: '[name].js',
|
|
96
|
+
clean: false,
|
|
97
|
+
library: {
|
|
98
|
+
name: 'micl',
|
|
99
|
+
type: 'umd'
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
module: {
|
|
103
|
+
rules: [{
|
|
104
|
+
test: /\.scss$/,
|
|
105
|
+
use : [
|
|
106
|
+
miniCss.loader,
|
|
107
|
+
'css-loader',
|
|
108
|
+
'postcss-loader',
|
|
109
|
+
'sass-loader'
|
|
110
|
+
]
|
|
111
|
+
}, {
|
|
112
|
+
test: /\.tsx?$/,
|
|
113
|
+
use: 'ts-loader',
|
|
114
|
+
exclude: /node_modules/
|
|
115
|
+
}]
|
|
116
|
+
},
|
|
117
|
+
plugins: [
|
|
118
|
+
new miniCss({
|
|
119
|
+
filename: '[name].css'
|
|
120
|
+
})
|
|
121
|
+
]
|
|
67
122
|
}, {
|
|
68
123
|
mode: 'production',
|
|
69
124
|
entry: {
|
|
70
125
|
micl: ['./styles.scss', './micl.ts'],
|
|
71
|
-
|
|
126
|
+
shapes: './components/shapes/master.scss'
|
|
72
127
|
},
|
|
73
128
|
resolve: {
|
|
74
129
|
extensions: ['.ts', '.tsx', '.js']
|