material-inspired-component-library 3.1.0 → 4.0.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/README.md +12 -5
- package/components/README.md +1 -1
- package/components/accordion/README.md +29 -5
- package/components/alert/README.md +76 -0
- package/components/alert/index.scss +1 -0
- package/components/appbar/README.md +9 -4
- package/components/appbar/index.scss +1 -1
- package/components/badge/README.md +8 -3
- package/components/badge/index.scss +1 -0
- package/components/bottomsheet/README.md +8 -3
- package/components/button/README.md +8 -3
- package/components/button/index.scss +7 -0
- package/components/card/README.md +10 -4
- package/components/card/index.scss +1 -1
- package/components/checkbox/README.md +8 -3
- package/components/checkbox/index.scss +2 -0
- package/components/dialog/README.md +8 -3
- package/components/dialog/index.scss +1 -0
- package/components/divider/README.md +8 -3
- package/components/divider/index.scss +2 -2
- package/components/iconbutton/README.md +8 -3
- package/components/iconbutton/index.scss +3 -1
- package/components/list/README.md +26 -19
- package/components/list/index.scss +95 -68
- package/components/menu/README.md +9 -3
- package/components/menu/index.scss +6 -18
- package/components/navigationrail/README.md +8 -3
- package/components/navigationrail/index.scss +1 -0
- package/components/radio/README.md +8 -3
- package/components/radio/index.scss +2 -0
- package/components/select/README.md +10 -5
- package/components/select/index.scss +2 -3
- package/components/sidesheet/README.md +21 -22
- package/components/sidesheet/index.scss +15 -16
- package/components/slider/README.md +8 -3
- package/components/slider/index.scss +1 -0
- package/components/stepper/README.md +190 -0
- package/components/stepper/index.scss +93 -14
- package/components/stepper/index.ts +138 -120
- package/components/switch/README.md +8 -3
- package/components/switch/index.scss +2 -0
- package/components/textfield/README.md +8 -3
- package/components/textfield/index.ts +8 -40
- package/dist/alert.css +1 -1
- package/dist/badge.css +1 -1
- package/dist/button.css +1 -1
- package/dist/card.css +1 -1
- package/dist/checkbox.css +1 -1
- package/dist/components/textfield/index.d.ts +0 -1
- package/dist/dialog.css +1 -1
- package/dist/divider.css +1 -1
- package/dist/foundations/form/index.d.ts +5 -0
- package/dist/iconbutton.css +1 -1
- package/dist/list.css +1 -1
- package/dist/menu.css +1 -1
- package/dist/micl.css +1 -1
- package/dist/micl.js +1 -1
- package/dist/navigationrail.css +1 -1
- package/dist/radio.css +1 -1
- package/dist/select.css +1 -1
- package/dist/sidesheet.css +1 -1
- package/dist/slider.css +1 -1
- package/dist/stepper.css +1 -1
- package/dist/switch.css +1 -1
- package/docs/accordion.html +31 -17
- package/docs/alert.html +3 -8
- package/docs/bottomsheet.html +2 -2
- package/docs/button.html +2 -2
- package/docs/card.html +7 -7
- package/docs/checkbox.html +2 -2
- package/docs/dialog.html +2 -2
- package/docs/divider.html +8 -8
- package/docs/iconbutton.html +2 -2
- package/docs/index.html +53 -39
- package/docs/list.html +54 -46
- package/docs/menu.html +4 -3
- package/docs/micl.css +1 -1
- package/docs/micl.js +1 -1
- package/docs/radio.html +2 -2
- package/docs/select.html +2 -2
- package/docs/sidesheet.html +5 -4
- package/docs/slider.html +2 -2
- package/docs/stepper.html +318 -0
- package/docs/switch.html +8 -4
- package/docs/textfield.html +2 -2
- package/foundations/form/index.ts +174 -0
- package/{layout → foundations/layout}/README.md +5 -0
- package/{layout → foundations/layout}/index.scss +1 -1
- package/micl.ts +1 -3
- package/package.json +4 -4
- package/styles.scss +1 -1
- package/webpack.config.js +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Select
|
|
2
|
-
This component implements the
|
|
2
|
+
This component implements the [Material Design 3 Expressive Select](https://m3.material.io/components/menus/guidelines#ee2f3664-c926-47ab-acbf-2ab675506932) design. A select component is used to offer the user with a set of options from which the user can select a single one.
|
|
3
3
|
|
|
4
4
|
## Basic Usage
|
|
5
5
|
|
|
@@ -29,6 +29,11 @@ The Select component relies on styles from the text field and list components. B
|
|
|
29
29
|
@use "material-inspired-component-library/dist/select";
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
+
Or import all MICL styles:
|
|
33
|
+
```CSS
|
|
34
|
+
@use "material-inspired-component-library/styles";
|
|
35
|
+
```
|
|
36
|
+
|
|
32
37
|
### JavaScript
|
|
33
38
|
This component requires JavaScript for functionality:
|
|
34
39
|
|
|
@@ -38,11 +43,11 @@ import micl from "material-inspired-component-library/dist/micl";
|
|
|
38
43
|
|
|
39
44
|
This will initialize any Select component, including those that will be added to the DOM later on.
|
|
40
45
|
|
|
41
|
-
### Demo
|
|
42
|
-
A live example of the [Select component](https://henkpb.github.io/micl/select.html) is available
|
|
46
|
+
### Live Demo
|
|
47
|
+
A live example of the [Select component](https://henkpb.github.io/micl/select.html) is available to interact with.
|
|
43
48
|
|
|
44
49
|
## Variants
|
|
45
|
-
A Select
|
|
50
|
+
A Select component can be disabled by adding the `disabled` attribute to the `<select>` element. An option within the component can be disabled by adding the `disabled` attribute to the `<option>` element.
|
|
46
51
|
|
|
47
52
|
You can add [Dividers](../divider/README.md) into the list of options and they will appear as separators to help visually break up the options.
|
|
48
53
|
|
|
@@ -52,7 +57,7 @@ You can add [Dividers](../divider/README.md) into the list of options and they w
|
|
|
52
57
|
<div class="micl-textfield-outlined">
|
|
53
58
|
<label for="myselect">Country</label>
|
|
54
59
|
<select id="myselect">
|
|
55
|
-
<option class="micl-list-item-two" value=""></option>
|
|
60
|
+
<option class="micl-list-item-two" value="" label="(none)"></option>
|
|
56
61
|
<option class="micl-list-item-two" value="AR">
|
|
57
62
|
<span class="micl-list-item__text">Argentina</span>
|
|
58
63
|
</option>
|
|
@@ -56,9 +56,9 @@
|
|
|
56
56
|
min-inline-size: max(anchor-size(self-inline), 112px);
|
|
57
57
|
max-inline-size: 280px;
|
|
58
58
|
position-try: most-block-size flip-block;
|
|
59
|
-
padding: 8px 0;
|
|
59
|
+
padding: var(--md-sys-list-padding, 8px) 0;
|
|
60
60
|
border: none;
|
|
61
|
-
border-radius: var(--md-sys-shape-corner-extra-small);
|
|
61
|
+
border-radius: var(--md-sys-shape-corner-extra-small, 4px);
|
|
62
62
|
background-color: var(--md-sys-color-surface-container);
|
|
63
63
|
box-shadow: var(--md-sys-elevation-level2);
|
|
64
64
|
opacity: 0;
|
|
@@ -94,7 +94,6 @@
|
|
|
94
94
|
--md-sys-list-item-one-padding: 0;
|
|
95
95
|
--md-sys-list-item-two-padding: 0;
|
|
96
96
|
--md-sys-list-item-space: 12px;
|
|
97
|
-
--md-sys-list-item-padding-inline: 16px;
|
|
98
97
|
--md-sys-list-item-container-color: var(--md-sys-color-surface-container);
|
|
99
98
|
|
|
100
99
|
line-height: normal;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Side sheet
|
|
2
|
-
This component implements the
|
|
2
|
+
This component implements the [Material Design 3 Expressive Side sheet](https://m3.material.io/components/side-sheets/overview) design. Side sheets provide optional content and actions without interrupting the main content.
|
|
3
3
|
|
|
4
4
|
## Basic Usage
|
|
5
5
|
|
|
@@ -29,16 +29,21 @@ Import the side sheet styles into your project:
|
|
|
29
29
|
@use "material-inspired-component-library/dist/sidesheet";
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
+
Or import all MICL styles:
|
|
33
|
+
```CSS
|
|
34
|
+
@use "material-inspired-component-library/styles";
|
|
35
|
+
```
|
|
36
|
+
|
|
32
37
|
### JavaScript
|
|
33
38
|
No custom JavaScript is required for the core functionality of the side sheet component.
|
|
34
39
|
|
|
35
|
-
### Demo
|
|
36
|
-
A live example of the [Side sheet component](https://henkpb.github.io/micl/sidesheet.html) is available
|
|
40
|
+
### Live Demo
|
|
41
|
+
A live example of the [Side sheet component](https://henkpb.github.io/micl/sidesheet.html) is available to interact with.
|
|
37
42
|
|
|
38
43
|
## Variants
|
|
39
44
|
A **modal** side sheet blocks access to the rest of the page and must be dismissed explicitly by the user. This is suitable for critical tasks or information that requires a user's full attention.
|
|
40
45
|
|
|
41
|
-
To create a modal side sheet, use the `<dialog>` element without the `popover` attribute. Use `closedby="closerequest"` to prevent the side sheet from being dismissed by clicking outside of it. You'll also need a button or other control with popovertarget to close it.
|
|
46
|
+
To create a modal side sheet, use the `<dialog>` element without the `popover` attribute. Use `closedby="closerequest"` to prevent the side sheet from being dismissed by clicking outside of it. You'll also need a button or other control with `popovertarget` to close it.
|
|
42
47
|
|
|
43
48
|
```HTML
|
|
44
49
|
<dialog id="mysidesheet" class="micl-sidesheet" closedby="closerequest" aria-labelledby="mytitle">
|
|
@@ -57,39 +62,33 @@ To create a modal side sheet, use the `<dialog>` element without the `popover` a
|
|
|
57
62
|
<div class="micl-sidesheet__content">
|
|
58
63
|
...your content...
|
|
59
64
|
</div>
|
|
65
|
+
<hr class="micl-divider">
|
|
60
66
|
<div class="micl-sidesheet__actions">
|
|
61
67
|
<button type="button" class="micl-button-filled-s">Save</button>
|
|
62
68
|
</div>
|
|
63
69
|
</dialog>
|
|
64
70
|
```
|
|
65
71
|
|
|
66
|
-
To open
|
|
72
|
+
To open a standard or modal side sheet, link a button to the side sheet's ID using the `popovertarget` attribute:
|
|
67
73
|
```HTML
|
|
68
74
|
<button type="button" popovertarget="mysidesheet">Open Side Sheet</button>
|
|
69
75
|
```
|
|
70
76
|
|
|
71
|
-
The back-button and the actions-container are optional. To remove the vertical divider of the
|
|
77
|
+
The back-button and the actions-container are optional. To remove the vertical divider of the standard side sheet, assign zero to the following CSS variable:
|
|
72
78
|
```CSS
|
|
73
79
|
#mysidesheet {
|
|
74
80
|
--md-sys-divider-thickness: 0;
|
|
75
81
|
}
|
|
76
82
|
```
|
|
77
|
-
To remove the horizontal divider of the actions-container:
|
|
78
|
-
```CSS
|
|
79
|
-
#mysidesheet .micl-sidesheet__actions {
|
|
80
|
-
--md-sys-divider-thickness: 0;
|
|
81
|
-
}
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### Warning
|
|
85
|
-
The **standard** side sheet component adds CSS rules to the `<body>` element to properly resize the main content area when the side sheet is open. Overriding these rules may cause the component to behave unexpectedly. The rules that are applied are:
|
|
86
83
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
84
|
+
> [!WARNING]
|
|
85
|
+
> The **standard** side sheet component adds CSS rules to the `<body>` element to properly resize the main content area when the side sheet is open. Overriding these rules may cause the component to behave unexpectedly. The rules that are applied are:
|
|
86
|
+
> ```CSS
|
|
87
|
+
> box-sizing: border-box;
|
|
88
|
+
> margin: 0;
|
|
89
|
+
> max-inline-size: ...varies depending on if the side sheet is opened...
|
|
90
|
+
> transition: ...transition on max-inline-size...
|
|
91
|
+
> ```
|
|
93
92
|
|
|
94
93
|
## Customizations
|
|
95
94
|
You can customize the appearance of the Side sheet component by overriding its global CSS variables. These variables are declared on the `:root` pseudo-class and can be changed on any appropriate parent element to affect its child side sheets.
|
|
@@ -97,7 +96,7 @@ You can customize the appearance of the Side sheet component by overriding its g
|
|
|
97
96
|
| Variable name | Default Value | Description |
|
|
98
97
|
| ------------- | ------------- | ----------- |
|
|
99
98
|
| --md-sys-sidesheet-width | 256px | The default (and minimum allowed) width of the side sheet |
|
|
100
|
-
| --md-sys-sidesheet-maxwidth | 400px | The largest allowed width of
|
|
99
|
+
| --md-sys-sidesheet-maxwidth | 400px | The largest allowed width of the side sheet |
|
|
101
100
|
| --md-sys-sidesheet-padding-standard | 24px | The amount of space between the vertical edges and the content |
|
|
102
101
|
|
|
103
102
|
**Example: Changing the width of the sidesheet**
|
|
@@ -27,14 +27,17 @@
|
|
|
27
27
|
:root {
|
|
28
28
|
--md-sys-sidesheet-width: 256px;
|
|
29
29
|
--md-sys-sidesheet-maxwidth: 400px;
|
|
30
|
-
--md-sys-sidesheet-
|
|
31
|
-
|
|
30
|
+
--md-sys-sidesheet-padding-standard: var(--md-sys-layout-window-margin, 24px);
|
|
31
|
+
}
|
|
32
|
+
body {
|
|
32
33
|
--md-sys-sidesheet-motion-spatial: #{motion.$md-sys-motion-expressive-slow-spatial};
|
|
33
34
|
--md-sys-sidesheet-motion-duration: #{motion.$md-sys-motion-expressive-slow-spatial-duration};
|
|
34
35
|
--md-sys-sidesheet-motion-duration-reverse: #{motion.$md-sys-motion-expressive-default-spatial-duration};
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
dialog.micl-sidesheet {
|
|
39
|
+
--md-sys-sidesheet-spring-buffer: 40px;
|
|
40
|
+
|
|
38
41
|
box-sizing: border-box;
|
|
39
42
|
display: none;
|
|
40
43
|
flex-direction: column;
|
|
@@ -47,7 +50,7 @@ dialog.micl-sidesheet {
|
|
|
47
50
|
margin-block: 0;
|
|
48
51
|
margin-inline-start: auto;
|
|
49
52
|
margin-inline-end: calc(-1 * (var(--md-sys-sidesheet-maxwidth) + var(--md-sys-sidesheet-spring-buffer)));
|
|
50
|
-
padding-block:
|
|
53
|
+
padding-block: var(--md-sys-sidesheet-padding-standard) 0;
|
|
51
54
|
padding-inline: 0 var(--md-sys-sidesheet-spring-buffer);
|
|
52
55
|
background-color: var(--md-sys-color-surface);
|
|
53
56
|
border: none;
|
|
@@ -64,7 +67,9 @@ dialog.micl-sidesheet {
|
|
|
64
67
|
.micl-sidesheet__headline {
|
|
65
68
|
display: flex;
|
|
66
69
|
align-items: center;
|
|
70
|
+
block-size: var(--md-sys-typescale-title-large-line-height);
|
|
67
71
|
padding-inline: var(--md-sys-sidesheet-padding-standard);
|
|
72
|
+
margin-block-end: 16px;
|
|
68
73
|
column-gap: 12px;
|
|
69
74
|
color: var(--md-sys-color-on-surface-variant);
|
|
70
75
|
|
|
@@ -82,14 +87,12 @@ dialog.micl-sidesheet {
|
|
|
82
87
|
margin-inline: -12px;
|
|
83
88
|
}
|
|
84
89
|
button:first-child {
|
|
85
|
-
margin-inline-start: -
|
|
90
|
+
margin-inline-start: -16px;
|
|
86
91
|
}
|
|
87
92
|
}
|
|
88
93
|
.micl-sidesheet__content {
|
|
89
94
|
box-sizing: border-box;
|
|
90
95
|
flex: 1 1 auto;
|
|
91
|
-
inline-size: 100%;
|
|
92
|
-
max-inline-size: 100%;
|
|
93
96
|
padding-inline: var(--md-sys-sidesheet-padding-standard);
|
|
94
97
|
overflow: hidden auto;
|
|
95
98
|
}
|
|
@@ -99,12 +102,10 @@ dialog.micl-sidesheet {
|
|
|
99
102
|
flex-shrink: 0;
|
|
100
103
|
align-items: center;
|
|
101
104
|
justify-content: start;
|
|
102
|
-
|
|
103
|
-
max-inline-size: 100%;
|
|
104
|
-
padding-block: 16px 24px;
|
|
105
|
+
padding-block: 16px var(--md-sys-sidesheet-padding-standard);
|
|
105
106
|
padding-inline: var(--md-sys-sidesheet-padding-standard);
|
|
107
|
+
column-gap: 8px;
|
|
106
108
|
overflow: hidden;
|
|
107
|
-
border-block-start: var(--md-sys-divider-thickness) solid var(--md-sys-divider-color);
|
|
108
109
|
}
|
|
109
110
|
|
|
110
111
|
&[open] {
|
|
@@ -114,9 +115,9 @@ dialog.micl-sidesheet {
|
|
|
114
115
|
box-shadow: var(--md-sys-elevation-level1);
|
|
115
116
|
}
|
|
116
117
|
&:popover-open {
|
|
117
|
-
--md-sys-divider-color: var(--md-sys-color-outline);
|
|
118
|
+
--md-sys-divider-color: var(--md-sys-color-outline, gray);
|
|
118
119
|
|
|
119
|
-
border-inline-start: var(--md-sys-divider-thickness) solid var(--md-sys-divider-color);
|
|
120
|
+
border-inline-start: var(--md-sys-divider-thickness, 1px) solid var(--md-sys-divider-color);
|
|
120
121
|
}
|
|
121
122
|
&:popover-open,
|
|
122
123
|
&[open] {
|
|
@@ -136,13 +137,11 @@ dialog.micl-sidesheet {
|
|
|
136
137
|
}
|
|
137
138
|
&::backdrop {
|
|
138
139
|
background-color: rgba(0, 0, 0, 0);
|
|
139
|
-
transition:
|
|
140
|
-
background-color var(--md-sys-sidesheet-motion-duration) linear,
|
|
141
|
-
overlay var(--md-sys-sidesheet-motion-duration) linear allow-discrete,
|
|
142
|
-
display var(--md-sys-sidesheet-motion-duration) linear allow-discrete;
|
|
140
|
+
transition: background-color var(--md-sys-sidesheet-motion-duration-reverse) linear;
|
|
143
141
|
}
|
|
144
142
|
&[open]::backdrop {
|
|
145
143
|
background-color: rgba(0, 0, 0, 0.2);
|
|
144
|
+
transition: background-color var(--md-sys-sidesheet-motion-duration) linear;
|
|
146
145
|
|
|
147
146
|
@starting-style {
|
|
148
147
|
background-color: rgba(0, 0, 0, 0);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Slider
|
|
2
|
-
This component implements the
|
|
2
|
+
This component implements the [Material Design 3 Expressive Slider](https://m3.material.io/components/sliders/overview) design.
|
|
3
3
|
|
|
4
4
|
## Basic Usage
|
|
5
5
|
|
|
@@ -17,6 +17,11 @@ Import the slider styles into your project:
|
|
|
17
17
|
@use "material-inspired-component-library/dist/slider";
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
+
Or import all MICL styles:
|
|
21
|
+
```CSS
|
|
22
|
+
@use "material-inspired-component-library/styles";
|
|
23
|
+
```
|
|
24
|
+
|
|
20
25
|
### JavaScript
|
|
21
26
|
This component requires JavaScript for functionality:
|
|
22
27
|
|
|
@@ -26,8 +31,8 @@ import micl from "material-inspired-component-library/dist/micl";
|
|
|
26
31
|
|
|
27
32
|
This will initialize any Slider component, including those that will be added to the DOM later on.
|
|
28
33
|
|
|
29
|
-
### Demo
|
|
30
|
-
A live example of the [Slider component](https://henkpb.github.io/micl/slider.html) is available
|
|
34
|
+
### Live Demo
|
|
35
|
+
A live example of the [Slider component](https://henkpb.github.io/micl/slider.html) is available to interact with.
|
|
31
36
|
|
|
32
37
|
## Variants
|
|
33
38
|
Sliders come in **five different sizes**: extra small (`xs`), small (`s`), medium (`m`), large (`l`), and extra large (`xl`). To set a specific size, append the appropriate postfix to the `micl-slider` CSS class name:
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Stepper
|
|
2
|
+
This component creates a **Stepper** to manage a linear, step-by-step process for gathering or displaying information, inspired by the design principles of [Material Design 3 Expressive](https://m3.material.io/components).
|
|
3
|
+
|
|
4
|
+
## Basic Usage
|
|
5
|
+
|
|
6
|
+
### HTML
|
|
7
|
+
To create a basic stepper, use a `<div>` container with the `micl-stepper` class and the `role="tablist"` attribute. The individual steps are placed within `<div class="micl-stepper__steps">`. Each step content is a `<div>` with the `micl-stepper__step` class and the `role="tabpanel"` attribute. The currently active step must be marked with `aria-current="step"`.
|
|
8
|
+
|
|
9
|
+
```HTML
|
|
10
|
+
<div class="micl-stepper" role="tablist" aria-label="My Step-by-Step Process">
|
|
11
|
+
<div class="micl-stepper__steps">
|
|
12
|
+
<div class="micl-stepper__step" role="tabpanel" aria-current="step">
|
|
13
|
+
Step 1 Content
|
|
14
|
+
</div>
|
|
15
|
+
<div class="micl-stepper__step" role="tabpanel">
|
|
16
|
+
Step 2 Content
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<div class="micl-stepper__actions">
|
|
21
|
+
<div>
|
|
22
|
+
<button type="button" class="micl-button-text-m micl-stepper__action-back">Back</button>
|
|
23
|
+
</div>
|
|
24
|
+
<div>
|
|
25
|
+
<button type="button" class="micl-button-tonal-m micl-stepper__action-next">Next</button>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### CSS
|
|
32
|
+
Import the stepper styles into your project:
|
|
33
|
+
|
|
34
|
+
```CSS
|
|
35
|
+
@use "material-inspired-component-library/dist/stepper";
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Or import all MICL styles:
|
|
39
|
+
```CSS
|
|
40
|
+
@use "material-inspired-component-library/styles";
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### JavaScript
|
|
44
|
+
This component requires JavaScript to enable navigation, state management, and form validation. The library will automatically initialize new components as they're added to the DOM.
|
|
45
|
+
|
|
46
|
+
```JavaScript
|
|
47
|
+
import micl from "material-inspired-component-library/dist/micl";
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Live Demo
|
|
51
|
+
A live example of the [Stepper component](https://henkpb.github.io/micl/stepper.html) is available to interact with.
|
|
52
|
+
|
|
53
|
+
## Action and State Management
|
|
54
|
+
The Stepper component automatically manages navigation between steps and controls the visibility of the **Back** and **Next** buttons based on the current step.
|
|
55
|
+
|
|
56
|
+
- **Next Action**: Clicking a button with the `micl-stepper__action-next` class advances the stepper by one step. This button is automatically hidden when the last step is active.
|
|
57
|
+
|
|
58
|
+
- **Back Action**: Clicking a button with the `micl-stepper__action-back` class moves the stepper back one step. This button is automatically hidden when the first step is active.
|
|
59
|
+
|
|
60
|
+
### Stepper Header
|
|
61
|
+
The optional Stepper Header displays the step titles horizontally, allowing users to navigate directly to steps. The `aria-controls` and `aria-labelledby` attributes are essential for accessibility, linking the header buttons to their corresponding step panels.
|
|
62
|
+
|
|
63
|
+
```HTML
|
|
64
|
+
<div class="micl-stepper">
|
|
65
|
+
<div class="micl-stepper__header">
|
|
66
|
+
<button type="button" role="tab" id="step1Label class="micl-button-text-xs" aria-controls="step1" aria-selected="true">
|
|
67
|
+
<span class="micl-stepper__progress-dot" aria-hidden="true"></span>
|
|
68
|
+
Step 1
|
|
69
|
+
</button>
|
|
70
|
+
<button type="button" role="tab" id="step2Label class="micl-button-text-xs" aria-controls="step2">
|
|
71
|
+
<span class="micl-stepper__progress-dot" aria-hidden="true"></span>
|
|
72
|
+
Step 2
|
|
73
|
+
</button>
|
|
74
|
+
</div>
|
|
75
|
+
<div class="micl-stepper__steps">
|
|
76
|
+
<div id="step1" role="tabpanel" class="micl-stepper__step" aria-labelledby="step1Label" aria-current="step">
|
|
77
|
+
Step 1 Content
|
|
78
|
+
</div>
|
|
79
|
+
<div id="step2" role="tabpanel" class="micl-stepper__step" aria-labelledby="step2Label">
|
|
80
|
+
Step 2 Content
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Linear vs. Non-linear Steppers
|
|
87
|
+
- **Linear (Default)**: The user can only click the header buttons of previous steps to revisit them. Navigation to future steps is disabled until they are reached.
|
|
88
|
+
|
|
89
|
+
- **Non-linear**: Apply the `micl-stepper--nonlinear` modifier class to the main stepper container. This allows the user to click any of the header buttons to freely jump between steps.
|
|
90
|
+
|
|
91
|
+
## Variants
|
|
92
|
+
|
|
93
|
+
### Progress indicator
|
|
94
|
+
You can include optional elements to display the user's progress.
|
|
95
|
+
|
|
96
|
+
#### Counter
|
|
97
|
+
Use the `micl-stepper__progress-current` and `micl-stepper__progress-total` classes to automatically display the current step number and the total number of steps (e.g., "1 of 3").
|
|
98
|
+
|
|
99
|
+
```HTML
|
|
100
|
+
<div class="micl-stepper__actions">
|
|
101
|
+
<div>
|
|
102
|
+
<button type="button" class="micl-button-text-m micl-stepper__action-back">Back</button>
|
|
103
|
+
</div>
|
|
104
|
+
<div>
|
|
105
|
+
<span class="micl-stepper__progress-current"></span>
|
|
106
|
+
<span> of </span>
|
|
107
|
+
<span class="micl-stepper__progress-total"></span>
|
|
108
|
+
</div>
|
|
109
|
+
<div>
|
|
110
|
+
<button type="button" class="micl-button-tonal-m micl-stepper__action-next">Next</button>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### Dots
|
|
116
|
+
Use the `micl-stepper__progress-dots` class to generate a visual progress bar using colored dots. The dots dynamically change color to indicate the current step.
|
|
117
|
+
|
|
118
|
+
```HTML
|
|
119
|
+
<div class="micl-stepper__actions">
|
|
120
|
+
<div>
|
|
121
|
+
<button type="button" class="micl-button-text-m micl-stepper__action-back">Back</button>
|
|
122
|
+
</div>
|
|
123
|
+
<div class="micl-stepper__progress-dots"></div>
|
|
124
|
+
<div>
|
|
125
|
+
<button type="button" class="micl-button-tonal-m micl-stepper__action-next">Next</button>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Step validation
|
|
131
|
+
To enable built-in **form validation** for each step, use a `<form>` element as the main stepper container and replace the step `<div>`s with `<fieldset>` elements.
|
|
132
|
+
|
|
133
|
+
#### Validation Flow
|
|
134
|
+
- **Step-by-Step Validation**: When a user clicks **Next**, the browser's built-in validation is triggered only for the input fields within the current step. If any constraints are violated, the stepper will not advance.
|
|
135
|
+
|
|
136
|
+
- **Error Display**: The Stepper component applies the error state to any child MICL component that supports it, displaying the custom error text. Otherwise, the default browser validation message appears.
|
|
137
|
+
|
|
138
|
+
- **Final Submission Validation**: If the final step contains a `type="submit"` button, the component validates the entire form upon submission. The form will only be submitted if all data input fields across all steps are valid.
|
|
139
|
+
|
|
140
|
+
```HTML
|
|
141
|
+
<form class="micl-stepper" action="/submit-data" method="post" role="tablist" aria-label="My Form">
|
|
142
|
+
<div class="micl-stepper__steps">
|
|
143
|
+
<fieldset class="micl-stepper__step" role="tabpanel" aria-current="step">
|
|
144
|
+
<div class="micl-textfield-filled">
|
|
145
|
+
<label for="mytextfield">Label text</label>
|
|
146
|
+
<input type="text" id="mytextfield" name="mytext" required>
|
|
147
|
+
</div>
|
|
148
|
+
</fieldset>
|
|
149
|
+
<fieldset class="micl-stepper__step" role="tabpanel">
|
|
150
|
+
Step 2 Content
|
|
151
|
+
</fieldset>
|
|
152
|
+
</div>
|
|
153
|
+
<div class="micl-stepper__actions">
|
|
154
|
+
...
|
|
155
|
+
</div>
|
|
156
|
+
</form>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
#### Step-Specific Action Buttons
|
|
160
|
+
Action buttons can be made visible only on a specific step by using the `data-step` attribute, which specifies the step number (starting from 1). This is useful for replacing the default **Next** button with a content-specific action, like a **Submit** button on the final step.
|
|
161
|
+
|
|
162
|
+
In this example for a three-step stepper, the **Next** button is hidden on step 3, and the **Submit** button is shown instead:
|
|
163
|
+
|
|
164
|
+
```HTML
|
|
165
|
+
<div class="micl-stepper__actions">
|
|
166
|
+
<div>
|
|
167
|
+
<button type="button" class="micl-button-text-m micl-stepper__action-back">Back</button>
|
|
168
|
+
</div>
|
|
169
|
+
<div>
|
|
170
|
+
<button type="submit" class="micl-button-tonal-m" data-step="3">Submit</button>
|
|
171
|
+
<button type="button" class="micl-button-tonal-m micl-stepper__action-next">Next</button>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Customizations
|
|
177
|
+
You can customize the appearance of the Stepper component by overriding its global CSS variables. These variables are declared on the `:root` pseudo-class and can be changed on any appropriate parent element to affect its child steppers.
|
|
178
|
+
|
|
179
|
+
| Variable name | Default Value | Description |
|
|
180
|
+
| ------------- | ----- | ----------- |
|
|
181
|
+
| --md-sys-stepper-counter-style | decimal | The list-style used for the counter number inside the dots in the stepper header |
|
|
182
|
+
| --md-sys-stepper-dot-size | 12px | Controls the size of each progress dot |
|
|
183
|
+
|
|
184
|
+
**Example: Changing the style of the counter inside header dots**
|
|
185
|
+
|
|
186
|
+
```HTML
|
|
187
|
+
<div class="micl-stepper" style="--md-sys-stepper-counter-style:upper-alpha">
|
|
188
|
+
...
|
|
189
|
+
</div>
|
|
190
|
+
```
|
|
@@ -19,11 +19,15 @@
|
|
|
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 '../../layout';
|
|
22
|
+
@use '../../foundations/layout';
|
|
23
23
|
@use '../../styles/motion';
|
|
24
24
|
|
|
25
25
|
:root {
|
|
26
|
-
--md-sys-stepper-
|
|
26
|
+
--md-sys-stepper-counter-style: decimal;
|
|
27
|
+
--md-sys-stepper-dot-size: 12px;
|
|
28
|
+
}
|
|
29
|
+
body {
|
|
30
|
+
--md-sys-stepper-dot-done-color: var(--md-sys-color-tertiary-container, blue);
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
.micl-stepper {
|
|
@@ -35,8 +39,38 @@
|
|
|
35
39
|
display: flex;
|
|
36
40
|
flex-direction: column;
|
|
37
41
|
row-gap: var(--md-sys-layout-padding-xl, 24px);
|
|
42
|
+
margin: 0;
|
|
38
43
|
background-color: inherit;
|
|
39
44
|
|
|
45
|
+
.micl-stepper__header {
|
|
46
|
+
--md-sys-stepper-dot-size: 24px;
|
|
47
|
+
|
|
48
|
+
display: flex;
|
|
49
|
+
justify-content: space-between;
|
|
50
|
+
align-items: flex-start;
|
|
51
|
+
margin-inline: -10px;
|
|
52
|
+
background-color: inherit;
|
|
53
|
+
background-image: linear-gradient(90deg, var(--md-sys-divider-color), var(--md-sys-divider-color));
|
|
54
|
+
background-position: center;
|
|
55
|
+
background-repeat: no-repeat;
|
|
56
|
+
background-size: 100% 1px;
|
|
57
|
+
counter-reset: dotnumber;
|
|
58
|
+
|
|
59
|
+
button {
|
|
60
|
+
background-color: inherit;
|
|
61
|
+
pointer-events: none;
|
|
62
|
+
|
|
63
|
+
&.micl-stepper__progress--done {
|
|
64
|
+
pointer-events: inherit;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
.micl-stepper__progress-dot::before {
|
|
68
|
+
content: counter(dotnumber, var(--md-sys-stepper-counter-style));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
&.micl-stepper--nonlinear .micl-stepper__header button {
|
|
72
|
+
pointer-events: inherit;
|
|
73
|
+
}
|
|
40
74
|
.micl-stepper__steps {
|
|
41
75
|
display: grid;
|
|
42
76
|
grid-template-areas: "stepper-steps";
|
|
@@ -48,7 +82,9 @@
|
|
|
48
82
|
display: flex;
|
|
49
83
|
visibility: hidden;
|
|
50
84
|
flex-direction: column;
|
|
51
|
-
|
|
85
|
+
margin: 0;
|
|
86
|
+
padding: 0;
|
|
87
|
+
border: none;
|
|
52
88
|
opacity: 0%;
|
|
53
89
|
background-color: inherit;
|
|
54
90
|
transform: translateX(100%);
|
|
@@ -56,30 +92,73 @@
|
|
|
56
92
|
opacity var(--md-sys-stepper-motion-duration) linear,
|
|
57
93
|
transform var(--md-sys-stepper-motion-duration) var(--md-sys-stepper-motion-spatial);
|
|
58
94
|
|
|
59
|
-
&:has(~ .micl-stepper__step
|
|
95
|
+
&:has(~ .micl-stepper__step[aria-current=step]) {
|
|
60
96
|
transform: translateX(-100%);
|
|
61
97
|
}
|
|
62
|
-
&.micl-stepper__step--
|
|
98
|
+
&.micl-stepper__step--toselected {
|
|
63
99
|
visibility: visible;
|
|
64
100
|
}
|
|
65
|
-
|
|
101
|
+
&[aria-current=step] {
|
|
66
102
|
visibility: visible;
|
|
67
103
|
opacity: 100%;
|
|
68
104
|
transform: translateX(0%);
|
|
69
105
|
}
|
|
70
|
-
&.micl-stepper__step--
|
|
106
|
+
&.micl-stepper__step--fromselected {
|
|
71
107
|
visibility: visible;
|
|
72
108
|
}
|
|
73
|
-
|
|
74
|
-
.micl-stepper__content {
|
|
75
|
-
box-sizing: border-box;
|
|
76
|
-
padding-inline: var(--md-sys-stepper-padding-inline);
|
|
77
|
-
background-color: inherit;
|
|
78
|
-
}
|
|
79
109
|
}
|
|
80
110
|
}
|
|
81
111
|
.micl-stepper__actions {
|
|
82
112
|
display: flex;
|
|
83
|
-
|
|
113
|
+
flex-direction: row;
|
|
114
|
+
justify-content: center;
|
|
115
|
+
inline-size: 100%;
|
|
116
|
+
align-items: center;
|
|
117
|
+
|
|
118
|
+
&>:first-child,
|
|
119
|
+
&>:last-child {
|
|
120
|
+
display: flex;
|
|
121
|
+
flex: 1 1 0;
|
|
122
|
+
column-gap: var(--md-sys-layout-padding-xs, 8px)
|
|
123
|
+
}
|
|
124
|
+
&>:last-child {
|
|
125
|
+
justify-content: flex-end;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
.micl-stepper__progress-dots {
|
|
129
|
+
display: flex;
|
|
130
|
+
align-items: center;
|
|
131
|
+
column-gap: 4px;
|
|
132
|
+
}
|
|
133
|
+
.micl-stepper__progress-dot {
|
|
134
|
+
block-size: var(--md-sys-stepper-dot-size);
|
|
135
|
+
inline-size: var(--md-sys-stepper-dot-size);
|
|
136
|
+
min-inline-size: var(--md-sys-stepper-dot-size);
|
|
137
|
+
line-height: var(--md-sys-stepper-dot-size);
|
|
138
|
+
border-radius: calc(var(--md-sys-stepper-dot-size) / 2);
|
|
139
|
+
text-align: center;
|
|
140
|
+
background-color: var(--md-sys-color-on-surface);
|
|
141
|
+
color: var(--md-sys-color-surface);
|
|
142
|
+
opacity: 38%;
|
|
143
|
+
counter-increment: dotnumber 1;
|
|
144
|
+
}
|
|
145
|
+
.micl-stepper__progress--done.micl-stepper__progress-dot,
|
|
146
|
+
.micl-stepper__progress--done .micl-stepper__progress-dot {
|
|
147
|
+
background-color: var(--md-sys-stepper-dot-done-color);
|
|
148
|
+
color: var(--md-sys-color-on-tertiary-container);
|
|
149
|
+
opacity: 100%;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
[dir=rtl] {
|
|
154
|
+
.micl-stepper .micl-stepper__steps .micl-stepper__step {
|
|
155
|
+
transform: translateX(-100%);
|
|
156
|
+
|
|
157
|
+
&:has(~ .micl-stepper__step[aria-current=step]) {
|
|
158
|
+
transform: translateX(100%);
|
|
159
|
+
}
|
|
160
|
+
&[aria-current=step] {
|
|
161
|
+
transform: translateX(0%);
|
|
162
|
+
}
|
|
84
163
|
}
|
|
85
164
|
}
|