material 3.0.0-next.0 → 3.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 +59 -370
- package/dist/components/badge/index.d.ts +1 -1
- package/dist/components/badge/index.js +1 -1
- package/dist/components/button/index.d.ts +1 -1
- package/dist/components/button/index.js +1 -1
- package/dist/components/card/index.d.ts +1 -1
- package/dist/components/card/index.js +1 -1
- package/dist/components/checkbox/index.d.ts +1 -1
- package/dist/components/checkbox/index.js +1 -1
- package/dist/components/chips/index.d.ts +1 -1
- package/dist/components/chips/index.js +1 -1
- package/dist/components/datepicker/index.d.ts +1 -1
- package/dist/components/datepicker/index.js +1 -1
- package/dist/components/dialog/index.d.ts +1 -1
- package/dist/components/dialog/index.js +1 -1
- package/dist/components/divider/index.d.ts +1 -1
- package/dist/components/divider/index.js +1 -1
- package/dist/components/drawer/index.d.ts +1 -1
- package/dist/components/drawer/index.js +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/list/config.js +6 -1
- package/dist/components/list/constants.d.ts +10 -0
- package/dist/components/list/constants.js +4 -0
- package/dist/components/list/index.d.ts +3 -3
- package/dist/components/list/index.js +2 -2
- package/dist/components/list/list.d.ts +17 -0
- package/dist/components/list/list.js +2 -2
- package/dist/components/list/types.d.ts +29 -1
- package/dist/components/loading-indicator/index.d.ts +1 -1
- package/dist/components/loading-indicator/index.js +1 -1
- package/dist/components/menu/index.d.ts +1 -1
- package/dist/components/menu/index.js +1 -1
- package/dist/components/progress/index.d.ts +1 -1
- package/dist/components/progress/index.js +1 -1
- package/dist/components/progress/types.d.ts +20 -10
- package/dist/components/radios/index.d.ts +1 -1
- package/dist/components/radios/index.js +1 -1
- package/dist/components/search/index.d.ts +1 -1
- package/dist/components/search/index.js +1 -1
- package/dist/components/select/index.d.ts +1 -1
- package/dist/components/select/index.js +1 -1
- package/dist/components/slider/index.d.ts +1 -1
- package/dist/components/slider/index.js +1 -1
- package/dist/components/slider/types.d.ts +7 -0
- package/dist/components/snackbar/index.d.ts +1 -1
- package/dist/components/snackbar/index.js +1 -1
- package/dist/components/split-button/index.d.ts +1 -1
- package/dist/components/split-button/index.js +1 -1
- package/dist/components/switch/index.d.ts +1 -1
- package/dist/components/switch/index.js +1 -1
- package/dist/components/tabs/index.d.ts +1 -0
- package/dist/components/tabs/index.js +1 -0
- package/dist/components/tabs/types.d.ts +15 -3
- package/dist/components/text-field/features/placement.js +7 -4
- package/dist/components/timepicker/index.d.ts +1 -1
- package/dist/components/timepicker/index.js +1 -1
- package/dist/components/tooltip/index.d.ts +1 -1
- package/dist/components/tooltip/index.js +1 -1
- package/dist/core/compose/features/textinput.js +3 -1
- package/dist/core/compose/index.d.ts +1 -1
- package/dist/core/dom/html.d.ts +1 -1
- package/dist/elements/css/button.css +1 -1
- package/dist/elements/css/button.js +1 -1
- package/dist/elements/css/card.css +1 -1
- package/dist/elements/css/card.js +1 -1
- package/dist/elements/css/checkbox.css +1 -1
- package/dist/elements/css/checkbox.js +1 -1
- package/dist/elements/css/chips.css +1 -1
- package/dist/elements/css/chips.js +1 -1
- package/dist/elements/css/dialog.css +1 -1
- package/dist/elements/css/dialog.js +1 -1
- package/dist/elements/css/extended-fab.css +1 -1
- package/dist/elements/css/extended-fab.js +1 -1
- package/dist/elements/css/fab-menu.css +1 -1
- package/dist/elements/css/fab-menu.js +1 -1
- package/dist/elements/css/fab.css +1 -1
- package/dist/elements/css/fab.js +1 -1
- package/dist/elements/css/hosts/switch.css +1 -1
- package/dist/elements/css/hosts/text-field.css +1 -1
- package/dist/elements/css/icon-button.css +1 -1
- package/dist/elements/css/icon-button.js +1 -1
- package/dist/elements/css/list.css +1 -1
- package/dist/elements/css/list.js +1 -1
- package/dist/elements/css/menu.css +1 -1
- package/dist/elements/css/menu.js +1 -1
- package/dist/elements/css/radios.css +1 -1
- package/dist/elements/css/radios.js +1 -1
- package/dist/elements/css/select.css +1 -1
- package/dist/elements/css/select.js +1 -1
- package/dist/elements/css/side-sheet.css +1 -1
- package/dist/elements/css/side-sheet.js +1 -1
- package/dist/elements/css/slider.css +1 -1
- package/dist/elements/css/slider.js +1 -1
- package/dist/elements/css/snackbar.css +1 -1
- package/dist/elements/css/snackbar.js +1 -1
- package/dist/elements/css/switch.css +1 -1
- package/dist/elements/css/switch.js +1 -1
- package/dist/elements/css/text-field.css +1 -1
- package/dist/elements/css/text-field.js +1 -1
- package/dist/elements/define.d.ts +20 -0
- package/dist/elements/list.d.ts +6 -0
- package/dist/elements/list.js +1 -0
- package/dist/elements/preupgrade/badge.css +1 -1
- package/dist/elements/preupgrade/bottom-app-bar.css +1 -1
- package/dist/elements/preupgrade/bottom-sheet.css +1 -1
- package/dist/elements/preupgrade/button-group.css +1 -1
- package/dist/elements/preupgrade/button.css +2 -2
- package/dist/elements/preupgrade/card.css +1 -1
- package/dist/elements/preupgrade/carousel.css +1 -1
- package/dist/elements/preupgrade/checkbox.css +2 -2
- package/dist/elements/preupgrade/chips.css +1 -1
- package/dist/elements/preupgrade/datepicker.css +1 -1
- package/dist/elements/preupgrade/dialog.css +1 -1
- package/dist/elements/preupgrade/divider.css +1 -1
- package/dist/elements/preupgrade/drawer.css +1 -1
- package/dist/elements/preupgrade/extended-fab.css +1 -1
- package/dist/elements/preupgrade/fab-menu.css +1 -1
- package/dist/elements/preupgrade/fab.css +1 -1
- package/dist/elements/preupgrade/icon-button.css +1 -1
- package/dist/elements/preupgrade/list.css +2 -2
- package/dist/elements/preupgrade/loading-indicator.css +1 -1
- package/dist/elements/preupgrade/menu.css +1 -1
- package/dist/elements/preupgrade/navigation-bar.css +1 -1
- package/dist/elements/preupgrade/navigation-rail.css +1 -1
- package/dist/elements/preupgrade/progress.css +1 -1
- package/dist/elements/preupgrade/radios.css +2 -2
- package/dist/elements/preupgrade/search.css +1 -1
- package/dist/elements/preupgrade/select.css +1 -1
- package/dist/elements/preupgrade/side-sheet.css +1 -1
- package/dist/elements/preupgrade/slider.css +1 -1
- package/dist/elements/preupgrade/snackbar.css +1 -1
- package/dist/elements/preupgrade/split-button.css +1 -1
- package/dist/elements/preupgrade/switch.css +2 -2
- package/dist/elements/preupgrade/tabs.css +1 -1
- package/dist/elements/preupgrade/text-field.css +2 -2
- package/dist/elements/preupgrade/timepicker.css +1 -1
- package/dist/elements/preupgrade/toolbar.css +1 -1
- package/dist/elements/preupgrade/tooltip.css +1 -1
- package/dist/elements/preupgrade/top-app-bar.css +1 -1
- package/dist/elements/preupgrade.css +2 -2
- package/dist/elements/preupgrade.js +1 -1
- package/dist/elements/styles.d.ts +13 -1
- package/dist/elements/switch.d.ts +1 -0
- package/dist/elements/switch.js +1 -0
- package/dist/elements/text-field.js +1 -5
- package/dist/package.json +28 -4
- package/dist/styles/badge.css +1 -1
- package/dist/styles/base.css +1 -1
- package/dist/styles/bottom-app-bar.css +1 -1
- package/dist/styles/bottom-sheet.css +1 -1
- package/dist/styles/button-group.css +1 -1
- package/dist/styles/button.css +2 -2
- package/dist/styles/card.css +2 -2
- package/dist/styles/carousel.css +1 -1
- package/dist/styles/checkbox.css +2 -2
- package/dist/styles/chips.css +2 -2
- package/dist/styles/contrast.css +1 -1
- package/dist/styles/datepicker.css +1 -1
- package/dist/styles/dialog.css +2 -2
- package/dist/styles/divider.css +1 -1
- package/dist/styles/drawer.css +1 -1
- package/dist/styles/extended-fab.css +2 -2
- package/dist/styles/fab-menu.css +2 -2
- package/dist/styles/fab.css +2 -2
- package/dist/styles/icon-button.css +2 -2
- package/dist/styles/list.css +2 -2
- package/dist/styles/loading-indicator.css +1 -1
- package/dist/styles/menu.css +2 -2
- package/dist/styles/navigation-bar.css +1 -1
- package/dist/styles/navigation-rail.css +1 -1
- package/dist/styles/progress.css +1 -1
- package/dist/styles/radios.css +2 -2
- package/dist/styles/search.css +1 -1
- package/dist/styles/select.css +2 -2
- package/dist/styles/side-sheet.css +2 -2
- package/dist/styles/slider.css +2 -2
- package/dist/styles/snackbar.css +2 -2
- package/dist/styles/split-button.css +1 -1
- package/dist/styles/switch.css +2 -2
- package/dist/styles/tabs.css +1 -1
- package/dist/styles/text-field.css +2 -2
- package/dist/styles/timepicker.css +1 -1
- package/dist/styles/toolbar.css +1 -1
- package/dist/styles/tooltip.css +1 -1
- package/dist/styles/top-app-bar.css +1 -1
- package/dist/styles/typography.css +1 -1
- package/dist/styles/utilities.css +1 -1
- package/dist/styles.css +2 -2
- package/dist/themes/autumn-contrast.css +1 -1
- package/dist/themes/autumn.css +1 -1
- package/dist/themes/baseline-contrast.css +1 -1
- package/dist/themes/baseline.css +1 -1
- package/dist/themes/brownbeige-contrast.css +1 -1
- package/dist/themes/brownbeige.css +1 -1
- package/dist/themes/content-contrast.css +1 -1
- package/dist/themes/content.css +1 -1
- package/dist/themes/desert-contrast.css +1 -1
- package/dist/themes/desert.css +1 -1
- package/dist/themes/expressive-contrast.css +1 -1
- package/dist/themes/expressive.css +1 -1
- package/dist/themes/fidelity-contrast.css +1 -1
- package/dist/themes/fidelity.css +1 -1
- package/dist/themes/forest-contrast.css +1 -1
- package/dist/themes/forest.css +1 -1
- package/dist/themes/fruit-salad-contrast.css +1 -1
- package/dist/themes/fruit-salad.css +1 -1
- package/dist/themes/highcontrast-contrast.css +1 -1
- package/dist/themes/highcontrast.css +1 -1
- package/dist/themes/monochrome-contrast.css +1 -1
- package/dist/themes/monochrome.css +1 -1
- package/dist/themes/neutral-contrast.css +1 -1
- package/dist/themes/neutral.css +1 -1
- package/dist/themes/ocean-contrast.css +1 -1
- package/dist/themes/ocean.css +1 -1
- package/dist/themes/rainbow-contrast.css +1 -1
- package/dist/themes/rainbow.css +1 -1
- package/dist/themes/sageivory-contrast.css +1 -1
- package/dist/themes/sageivory.css +1 -1
- package/dist/themes/spring-contrast.css +1 -1
- package/dist/themes/spring.css +1 -1
- package/dist/themes/summer-contrast.css +1 -1
- package/dist/themes/summer.css +1 -1
- package/dist/themes/sunset-contrast.css +1 -1
- package/dist/themes/sunset.css +1 -1
- package/dist/themes/tealcaramel-contrast.css +1 -1
- package/dist/themes/tealcaramel.css +1 -1
- package/dist/themes/vibrant-contrast.css +1 -1
- package/dist/themes/vibrant.css +1 -1
- package/package.json +28 -4
- package/src/styles/abstract/_mixins.scss +17 -5
- package/src/styles/abstract/_variables.scss +1 -1
- package/src/styles/components/_button.scss +10 -7
- package/src/styles/components/_checkbox.scss +10 -0
- package/src/styles/components/_chips.scss +10 -0
- package/src/styles/components/_dialog.scss +16 -0
- package/src/styles/components/_fab-menu.scss +20 -1
- package/src/styles/components/_icon-button.scss +6 -0
- package/src/styles/components/_list.scss +48 -4
- package/src/styles/components/_menu.scss +8 -0
- package/src/styles/components/_radios.scss +22 -4
- package/src/styles/components/_select.scss +13 -29
- package/src/styles/components/_side-sheet.scss +22 -0
- package/src/styles/components/_slider.scss +3 -3
- package/src/styles/components/_switch.scss +19 -0
- package/src/styles/components/_text-field.scss +97 -319
- package/src/styles/elements/_button.scss +17 -1
- package/src/styles/elements/_checkbox.scss +16 -0
- package/src/styles/elements/_list.scss +6 -0
- package/src/styles/elements/_radios.scss +3 -2
- package/src/styles/elements/_switch.scss +52 -0
- package/src/styles/elements/_text-field.scss +21 -0
- package/dist/LICENSE +0 -21
- package/dist/README.md +0 -438
package/README.md
CHANGED
|
@@ -1,99 +1,48 @@
|
|
|
1
1
|
# material
|
|
2
2
|
|
|
3
|
-
Material Design 3 components for the web: as
|
|
3
|
+
Material Design 3 components for the web: as web components, as React, Vue, Svelte and Solid components, and as plain JavaScript. Written in TypeScript, with zero dependencies.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Documentation, live playgrounds and examples: [md3.io](https://md3.io)**
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
npm install material
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
React, Vue, Svelte and Solid are optional peer dependencies: material uses the one your app has and installs none of them.
|
|
7
|
+
[](https://www.npmjs.com/package/material)
|
|
8
|
+
[](https://github.com/floor/material/actions/workflows/ci.yml)
|
|
9
|
+
[](https://github.com/floor/material/blob/main/LICENSE)
|
|
14
10
|
|
|
15
|
-
|
|
11
|
+
- **Material 3 Expressive.** Component sizes, shapes, colours and spring motion follow the Material 3 tokens.
|
|
12
|
+
- **One implementation, every stack.** A button looks and behaves the same as an element, as a framework component and as a factory.
|
|
13
|
+
- **Zero dependencies.** Installing `material` installs nothing else; the frameworks are optional peers.
|
|
14
|
+
- **Server rendering.** Elements and framework components render to declarative shadow DOM on Node and Bun.
|
|
15
|
+
- **Measured sizes.** A size budget per component, enforced on every pull request.
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|-----|-------------|----------|
|
|
19
|
-
| Web components | `material/elements` | Plain HTML, server templates, Angular, any framework |
|
|
20
|
-
| React | `material/react` | React 18 and 19, Next.js |
|
|
21
|
-
| Vue | `material/vue` | Vue 3, Nuxt |
|
|
22
|
-
| Svelte | `material/svelte` | Svelte 5, SvelteKit |
|
|
23
|
-
| Solid | `material/solid` | SolidJS, SolidStart |
|
|
24
|
-
| Vanilla factories | `material` | The smallest bundles and full control |
|
|
17
|
+
Documentation, a live playground and examples in every framework: **[md3.io](https://md3.io)**.
|
|
25
18
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
```typescript
|
|
29
|
-
import 'material/styles/base';
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
**Web components**: register them once, then write HTML.
|
|
33
|
-
|
|
34
|
-
```html
|
|
35
|
-
<script type="module">
|
|
36
|
-
import 'material/styles/base';
|
|
37
|
-
import 'material/elements/css';
|
|
38
|
-
import { defineAll } from 'material/elements';
|
|
39
|
-
defineAll();
|
|
40
|
-
</script>
|
|
41
|
-
|
|
42
|
-
<form>
|
|
43
|
-
<m-text-field name="email" type="email" label="Email" required></m-text-field>
|
|
44
|
-
<m-switch name="news" checked>Newsletter</m-switch>
|
|
45
|
-
<m-button type="submit">Sign up</m-button>
|
|
46
|
-
</form>
|
|
47
|
-
```
|
|
19
|
+
## Install
|
|
48
20
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
import 'material/styles/base';
|
|
53
|
-
import { Button, Switch, TextField } from 'material/react';
|
|
54
|
-
|
|
55
|
-
export function Signup() {
|
|
56
|
-
return (
|
|
57
|
-
<form>
|
|
58
|
-
<TextField name="email" type="email" label="Email" required />
|
|
59
|
-
<Switch name="news" defaultChecked>Newsletter</Switch>
|
|
60
|
-
<Button type="submit">Sign up</Button>
|
|
61
|
-
</form>
|
|
62
|
-
);
|
|
63
|
-
}
|
|
21
|
+
<!-- install -->
|
|
22
|
+
```bash
|
|
23
|
+
npm install material
|
|
64
24
|
```
|
|
25
|
+
<!-- /install -->
|
|
65
26
|
|
|
66
|
-
|
|
27
|
+
## Quick start
|
|
67
28
|
|
|
29
|
+
<!-- example: run, shows "Save" -->
|
|
68
30
|
```typescript
|
|
69
31
|
import 'material/styles';
|
|
70
32
|
import { createButton, createTextField } from 'material';
|
|
71
33
|
|
|
72
34
|
const name = createTextField({ label: 'Name' });
|
|
73
35
|
const save = createButton({ text: 'Save', variant: 'filled' });
|
|
74
|
-
save.disabled.disable();
|
|
75
36
|
|
|
76
|
-
name.on('input', ({ value }: { value: string }) => {
|
|
77
|
-
if (value.trim()) save.disabled.enable();
|
|
78
|
-
else save.disabled.disable();
|
|
79
|
-
});
|
|
80
37
|
save.on('click', () => console.log('Saved', name.getValue()));
|
|
81
38
|
|
|
82
39
|
document.body.append(name.element, save.element);
|
|
83
|
-
|
|
84
|
-
// When the view goes away, release listeners and DOM
|
|
85
|
-
name.destroy();
|
|
86
|
-
save.destroy();
|
|
87
40
|
```
|
|
88
41
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
The factories are the fastest way to render hundreds of components at once, such as a long editable table; the elements style a shadow root each. `material/styles` loads every component's styles; for a smaller bundle, import only what you use (see [Styles](#styles)).
|
|
42
|
+
`material/styles` is a stylesheet, so this needs a bundler that handles CSS imports (Vite, webpack, Bun, …). Each factory returns a DOM element and a small API; call `destroy()` when the view goes away.
|
|
92
43
|
|
|
93
44
|
## Components
|
|
94
45
|
|
|
95
|
-
Every component comes three ways: a factory (`createButton`), an element (`<m-button>`) and a framework component (`Button`; `MButton` in Vue).
|
|
96
|
-
|
|
97
46
|
| Group | Components |
|
|
98
47
|
|-------|------------|
|
|
99
48
|
| Actions | Button, Icon button, Button group, Split button, FAB, Extended FAB, FAB menu, Toolbar |
|
|
@@ -102,337 +51,77 @@ Every component comes three ways: a factory (`createButton`), an element (`<m-bu
|
|
|
102
51
|
| Containment | Card, Carousel, List, Divider, Dialog, Bottom sheet, Side sheet |
|
|
103
52
|
| Communication | Badge, Progress, Loading indicator, Snackbar, Tooltip |
|
|
104
53
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
## Styles
|
|
108
|
-
|
|
109
|
-
The web components and the framework components carry their own styles in their shadow roots; they need only the base stylesheet, `material/styles/base`, for the theme and its tokens. The factories render in the page, so they use the page's stylesheets. Import the full stylesheet once:
|
|
110
|
-
|
|
111
|
-
```typescript
|
|
112
|
-
import 'material/styles';
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
Or import the base once, followed by the components you use:
|
|
116
|
-
|
|
117
|
-
```typescript
|
|
118
|
-
import 'material/styles/base';
|
|
119
|
-
import 'material/styles/button';
|
|
120
|
-
import 'material/styles/text-field';
|
|
121
|
-
|
|
122
|
-
// Optional: an alternate theme and the utility classes
|
|
123
|
-
import 'material/themes/ocean';
|
|
124
|
-
import 'material/styles/utilities';
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
The base includes the baseline theme in light and dark, the colour, shape and typeface tokens, the three body-medium type tokens the page's text reads (`--mtrl-sys-typescale-body-medium-font`, `-font-size` and `-line-height`), a reset and the ripple. The type classes (`.mtrl-display-large` through `.mtrl-label-small`), the text utilities (`.mtrl-text-*`, `.mtrl-font-*`, `.mtrl-truncate*`), material's styles for `h1`–`h6` and `p`, and the rest of the type scale are a separate import:
|
|
128
|
-
|
|
129
|
-
```typescript
|
|
130
|
-
import 'material/styles/typography';
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
It has to load after the base: both sheets style `h1`–`h6` and `p`, and the later one wins. The import above takes care of it (the module imports `material/styles/base` first, in whatever order your own imports are). If your bundler splits the two into different chunks, make sure the base's CSS loads first: an import order is not a CSS order in every bundler. With `<link>` tags, put `dist/styles/typography.css` after `dist/styles/base.css`.
|
|
134
|
-
|
|
135
|
-
Import it when the page uses those classes or utilities, when it relies on material's heading and paragraph styles, or when its own CSS reads a `--mtrl-sys-typescale-*` token. Without it a `.mtrl-headline-small` element keeps the body's font size, and a `var(--mtrl-sys-typescale-*)` with no fallback is invalid at computed-value time. Body text keeps its font. The full stylesheet includes typography, so `import 'material/styles'` is unchanged.
|
|
136
|
-
|
|
137
|
-
Each selective entry imports what it depends on (the select brings the text field and the menu), so use a CSS-capable bundler to resolve and deduplicate them. Choose either the full stylesheet or selective imports, not both. The `material/styles/*` entries are bundler targets: they import CSS, so they do not load in plain Node.
|
|
138
|
-
|
|
139
|
-
Library styles sit in ordered `mtrl.*` cascade layers, so unlayered application CSS overrides them without specificity battles.
|
|
140
|
-
|
|
141
|
-
The Sass sources ship for reference; configuring them with `@use … with` is not a supported API in `material` 3.0.0. Theme with CSS custom properties.
|
|
142
|
-
|
|
143
|
-
### Themes
|
|
144
|
-
|
|
145
|
-
The baseline theme applies by default and follows the system light or dark preference. Choose a theme and mode on the root element:
|
|
146
|
-
|
|
147
|
-
```html
|
|
148
|
-
<html data-theme="ocean" data-theme-mode="dark">
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
```typescript
|
|
152
|
-
document.documentElement.dataset.theme = 'ocean';
|
|
153
|
-
document.documentElement.dataset.themeMode = 'dark';
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
Available themes: `baseline`, `ocean`, `desert`, `forest`, `sunset`, `spring`, `summer`, `autumn`, `brownbeige`, `sageivory`, `tealcaramel` and `highcontrast`. With selective styles, import the theme's entry, for example `material/themes/ocean`.
|
|
157
|
-
|
|
158
|
-
Every theme supports `data-theme-contrast="standard"`, `"medium"` and `"high"` on the same element as `data-theme` and `data-theme-mode`. The attribute is opt-in: the full stylesheet includes it, and selective styles add `material/styles/contrast` for the baseline theme, or `material/themes/<name>-contrast` beside `material/themes/<name>`. Without that import the attribute changes no colour. The OS preference does not need an import.
|
|
159
|
-
|
|
160
|
-
```html
|
|
161
|
-
<html data-theme="desert" data-theme-mode="dark" data-theme-contrast="high">
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
```typescript
|
|
165
|
-
import 'material/styles/base';
|
|
166
|
-
import 'material/styles/contrast';
|
|
167
|
-
import 'material/themes/desert';
|
|
168
|
-
import 'material/themes/desert-contrast';
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
Import `material/styles/contrast` after `material/styles/base`, as with `material/styles/typography`: the opt-in sheets share the base cascade layer, so their order inside it matters. Typography's heading margins depend on that order. The contrast sheet's colours do not: an explicit level is a more specific selector than the standard rule, and `prefers-contrast: more` is guarded by `:not([data-theme-contrast])`, so either load order resolves the same colours.
|
|
172
|
-
|
|
173
|
-
Without `data-theme-contrast`, `prefers-contrast: more` selects high contrast on every themed element independently. An explicit `standard` opts out on that element; `medium` overrides the preference too. Contrast settings do not inherit from an ancestor across a nested theme: put `data-theme-contrast` on the same element as each `data-theme`, including nested sections. For example, opting out on the root does not opt out a nested theme without its own `data-theme-contrast="standard"`. `data-theme-contrast` is read on the element that carries `data-theme`, or on the root when the page has no `data-theme`; on any other element it does nothing (that element inherits its themed ancestor's level).
|
|
174
|
-
|
|
175
|
-
The default baseline also supports this setting without `data-theme`. On that unthemed root, both standard and higher contrast follow the OS color scheme and `.dark-theme`, ignoring `data-theme-mode`. Medium and high use M3 contrast levels 0.5 and 1.0; hand-authored themes derive them with Tonal Spot from their documented seed (falling back to their light primary), preserving their light secondary and tertiary hues and chroma. Neutral palettes come from the seed, while standard colors stay unchanged. Success, warning and info keep their existing status colors. The `highcontrast` theme is a theme in its own right and supports all three contrast settings.
|
|
176
|
-
|
|
177
|
-
M3's scheme variants, generated from the baseline seed, ship as their own entries only (not in the full stylesheet): `neutral`, `vibrant`, `expressive`, `fidelity`, `content`, `monochrome`, `rainbow` and `fruit-salad`, for example `material/themes/vibrant`. `schemeToTokens` (`material/core/theme`) turns any M3 scheme's role colours into these tokens.
|
|
178
|
-
|
|
179
|
-
### Custom properties
|
|
180
|
-
|
|
181
|
-
Components read the theme's colour roles, so overriding a role restyles every component that uses it:
|
|
182
|
-
|
|
183
|
-
```css
|
|
184
|
-
:root {
|
|
185
|
-
--mtrl-sys-color-primary: #6750a4;
|
|
186
|
-
--mtrl-sys-color-on-primary: #ffffff;
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
The typefaces and the corner scale are custom properties on the base (`--mtrl-ref-typeface-brand`, `--mtrl-ref-typeface-plain`, `--mtrl-sys-shape-corner-*`): setting one on `:root` restyles every component that uses it. The type scale (`--mtrl-sys-typescale-*`) ships in `material/styles/typography` and in the full stylesheet; setting a role's size there restyles the type classes and the heading styles. Component hooks follow one convention, `--mtrl-<component>-<name>`:
|
|
191
|
-
|
|
192
|
-
```css
|
|
193
|
-
.brand-slider {
|
|
194
|
-
--mtrl-slider-color: #006a6a;
|
|
195
|
-
--mtrl-slider-on-color: #ffffff;
|
|
196
|
-
}
|
|
197
|
-
```
|
|
54
|
+
Every component comes three ways: a factory, a custom element and a framework component. Each has a page with a playground on [md3.io/components](https://md3.io/components/).
|
|
198
55
|
|
|
199
56
|
## Web components
|
|
200
57
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
Declaration children describe a component's items, as native `<select>` and `<option>` do:
|
|
58
|
+
A page imports the base stylesheet and the elements' CSS once, then registers the elements with `defineAll()`. After that `<m-button>` and the rest are HTML, in plain pages, server templates and any framework.
|
|
204
59
|
|
|
205
|
-
|
|
206
|
-
<m-tabs value="songs">
|
|
207
|
-
<m-tab value="songs">Songs</m-tab>
|
|
208
|
-
<m-tab value="albums">Albums</m-tab>
|
|
209
|
-
</m-tabs>
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
The page still loads material's base styles and a theme (see [Styles](#styles)); the elements render in shadow DOM and pick up the theme's tokens. Attributes are defaults and properties the live state, as on native controls: a `checked` or `value` attribute sets the state until the user or a script changes it, and `form.reset()` goes back to it. Form controls take part in forms (their host's `name`), reset, validation and back-navigation restore.
|
|
213
|
-
|
|
214
|
-
A server-rendered page sends each element as its tag and light DOM; the element takes its real look once its script defines it. Nothing reserves that box unless the pre-upgrade stylesheet is in `<head>`, after material's base styles and theme. It gives every element not defined yet the box it will have (and its label the final type style), hides what it declares (`<m-tab>`, `<m-menu-item>`, …) and overlays. Its rules match only `:not(:defined)`, in the `mtrl.preupgrade` cascade layer. Without the stylesheet, an element has no reserved box until it is defined.
|
|
215
|
-
|
|
216
|
-
```html
|
|
217
|
-
<link rel="stylesheet" href="/node_modules/material/dist/elements/preupgrade.css">
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
A page that uses one element can load that element's file instead: `material/elements/preupgrade/<name>.css`, named by the spec (`text-field`, `select`, `icon-button`). Each file is that element's rules in the same `@layer mtrl.preupgrade`. With a bundler, `import 'material/elements/preupgrade.css'` or `import 'material/elements/preupgrade/button.css'`.
|
|
221
|
-
|
|
222
|
-
With another tag prefix, `preupgradeStyles('x')` from `material/elements/preupgrade` returns the whole stylesheet for `<x-*>`, to inline on the server. The element CSS modules do not apply these rules.
|
|
60
|
+
Form controls are form-associated: the form value, reset and validation work as on native controls. Overlays open in the browser's top layer. Guide: [md3.io/docs/web-components](https://md3.io/docs/web-components/).
|
|
223
61
|
|
|
224
62
|
## React, Vue, Svelte and Solid
|
|
225
63
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
|
229
|
-
|
|
230
|
-
|
|
|
231
|
-
|
|
|
232
|
-
| Svelte 5 | `import { Switch } from 'material/svelte'` | `bind:checked` |
|
|
233
|
-
| Solid | `import { Switch } from 'material/solid'` | `checked` + `onChange` |
|
|
234
|
-
|
|
235
|
-
The `material/svelte` entry is a bundler target too: it imports `.svelte` files, so it does not load in plain Node.
|
|
236
|
-
|
|
237
|
-
With `skipLibCheck: false`, use `@types/react` 18.2.71 or later.
|
|
64
|
+
| Framework | Import | Guide |
|
|
65
|
+
|-----------|--------|-------|
|
|
66
|
+
| React 18 and 19 | `import { Switch } from 'material/react'` | [md3.io/docs/react](https://md3.io/docs/react/) |
|
|
67
|
+
| Vue 3 | `import { MSwitch } from 'material/vue'` | [md3.io/docs/vue](https://md3.io/docs/vue/) |
|
|
68
|
+
| Svelte 5 | `import { Switch } from 'material/svelte'` | [md3.io/docs/svelte](https://md3.io/docs/svelte/) |
|
|
69
|
+
| Solid | `import { Switch } from 'material/solid'` | [md3.io/docs/solid](https://md3.io/docs/solid/) |
|
|
238
70
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
A component owns the `on…` props of its element's events (`onChange`, `onInput`, `onSelect`, …) and its `default…` props, typed with the element's own payloads. Any other HTML attribute passes to the host; to spread a whole set of HTML attributes into a component, omit the props it owns (`Omit<React.HTMLAttributes<HTMLElement>, "onChange">`).
|
|
242
|
-
|
|
243
|
-
Each framework has a guide on [md3.io](https://md3.io/docs/): props and events, controlled and uncontrolled state, named slots, refs and server rendering.
|
|
71
|
+
The framework components render the elements, load their CSS and register each one the first time it mounts. An app imports `material/styles/base` once for the theme. Each framework is an optional peer dependency: `material` uses the one your app has.
|
|
244
72
|
|
|
245
73
|
## Server rendering
|
|
246
74
|
|
|
247
|
-
`renderElement` from `material/ssr` renders an element to declarative shadow DOM.
|
|
248
|
-
|
|
249
|
-
**Styles: inline by default.** Each root carries its whole CSS as a `<style>`, so it is styled at first paint in every engine with no extra request. That has two costs:
|
|
250
|
-
|
|
251
|
-
- **How well it compresses depends on the compressor.** gzip cannot see a repeat further back than its 32 KB window. A select's root is about 44 KB of style text, so gzip never finds the previous select: 30 selects measured 141.0 KB with gzip against 5.0 KB with brotli. Smaller roots compress well when the same element repeats (30 buttons, at 16 KB a root: 6.4 KB with gzip; 30 dialogs: 10.3 KB), and badly when large roots of different types alternate, because the previous copy of each is then out of the window: selects, text fields, dialogs and buttons in turn measured 83.9 KB with gzip against 8.1 KB with brotli. Serve brotli, or use link mode for pages with many selects, or that mix large roots (text fields, dialogs) in turn.
|
|
252
|
-
- **Uncompressed it is large:** 0.5 to 0.9 MB for 30 to 44 roots (489 KB for 30 buttons, 671 KB for a list page of 44 roots, 878 KB for the 30 large roots). That matters for anything that stores or streams the HTML uncompressed.
|
|
253
|
-
|
|
254
|
-
**Link mode** (`renderElement(tag, attributes, children, { styles: 'link', cssBase: '/css' })`, with `dist/elements/css` served at that base) writes `<link>` tags in place of the style text: the same pages are 15 to 40 KB of HTML, and the stylesheets are fetched once and cached. Its caveat: WebKit paints the roots unstyled until the stylesheets arrive (about 470 ms with each stylesheet 300 ms away; a preload in the head does not help), where Chromium and Firefox wait for them before painting.
|
|
255
|
-
|
|
256
|
-
Measured on Playwright's engines (Chromium 153, Firefox 155, WebKit 26.6); sizes are of the HTML `renderElement` returns, gzip at level 9, brotli at its default.
|
|
257
|
-
|
|
258
|
-
A framework page that server-renders without that bridge (Next.js, Nuxt, SvelteKit, SolidStart) does not reserve an element's box between the HTML and hydration. Put the `<link>` above in `<head>` (or import the stylesheet). The link reserves the box from the first paint, before any script. The overlap, a pre-upgrade rule painting over a host that already has a shadow root, shows only when that page also loads the stylesheet.
|
|
75
|
+
`renderElement` from `material/ssr` renders an element to declarative shadow DOM. Each framework has a bridge, such as `material/ssr/react`, that makes its components emit the same roots and hydrate.
|
|
259
76
|
|
|
260
|
-
|
|
77
|
+
Node and Bun are supported; worker and edge runtimes are not supported in `material` 3.0.0. Guide: [md3.io/docs/server-rendering](https://md3.io/docs/server-rendering/).
|
|
261
78
|
|
|
262
|
-
|
|
79
|
+
## Themes
|
|
263
80
|
|
|
264
|
-
The
|
|
81
|
+
The baseline theme applies by default and follows the system light or dark preference. Eleven more are in the full stylesheet, each in light and dark, with three contrast levels:
|
|
265
82
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
With `material/ssr/react` and `material/ssr/svelte`, the server-rendered shadow root is built in a separate render, without the context of providers above the component. The page's own render (the light DOM) sees the provided value. Until the component upgrades, a child reading context with a default shows that default in the painted shadow root; a child requiring its context leaves that component without a declarative shadow root, while the page still renders. React and Svelte each log a development-only warning naming the element in the latter case. Keep context-dependent text outside material components: pass the resolved string as a prop or attribute, or accept client-rendered text until the upgrade. A fix is planned for a later 3.x release (FLO-517). The Vue and Solid bridges see the provided value in both the shadow root and light DOM.
|
|
269
|
-
|
|
270
|
-
The same HTML policy as [Markup and sanitizing](#markup-and-sanitizing) applies to `material/ssr` and the four bridges.
|
|
271
|
-
|
|
272
|
-
## Imports and tree-shaking
|
|
273
|
-
|
|
274
|
-
material publishes ESM only, with type declarations, so bundlers drop unused exports and split dynamic imports. From CommonJS, load it with a dynamic `import('material')`.
|
|
275
|
-
|
|
276
|
-
| Import | Path |
|
|
277
|
-
|--------|------|
|
|
278
|
-
| Component creators | `import { createButton } from 'material'` |
|
|
279
|
-
| One component directly | `import createSlider from 'material/components/slider'` |
|
|
280
|
-
| Component constants | `import { BUTTON_VARIANTS } from 'material/components/button/constants'` |
|
|
281
|
-
| Core utilities | `import { addClass, removeClass } from 'material/core/dom'` |
|
|
282
|
-
|
|
283
|
-
Constants are not exported from the root; import them from the component's `constants` entry:
|
|
284
|
-
|
|
285
|
-
```typescript
|
|
286
|
-
import { createButton } from 'material';
|
|
287
|
-
import { BUTTON_VARIANTS, BUTTON_SIZES } from 'material/components/button/constants';
|
|
288
|
-
|
|
289
|
-
const button = createButton({
|
|
290
|
-
text: 'Submit',
|
|
291
|
-
variant: BUTTON_VARIANTS.FILLED,
|
|
292
|
-
size: BUTTON_SIZES.L,
|
|
293
|
-
});
|
|
83
|
+
```html
|
|
84
|
+
<html data-theme="ocean" data-theme-mode="dark">
|
|
294
85
|
```
|
|
295
86
|
|
|
296
|
-
|
|
87
|
+
Colours, typefaces and shapes are CSS custom properties (`--mtrl-sys-color-primary`, …), so one declaration restyles every component that reads it. Guide: [md3.io/docs/theming](https://md3.io/docs/theming/); the themes side by side: [md3.io/styles/themes](https://md3.io/styles/themes/).
|
|
297
88
|
|
|
298
|
-
##
|
|
89
|
+
## Sizes
|
|
299
90
|
|
|
300
|
-
|
|
91
|
+
What a bundler keeps, minified and gzipped (kB is 1,000 bytes), measured from the packed package. The table is refreshed at each release, and CI keeps every figure within 2% of the current build:
|
|
301
92
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
component.element.textContent = text;
|
|
314
|
-
},
|
|
315
|
-
})
|
|
316
|
-
)(config);
|
|
317
|
-
|
|
318
|
-
// The component's type is what the pipe builds
|
|
319
|
-
type NoteComponent = ReturnType<typeof createNote>;
|
|
320
|
-
|
|
321
|
-
const note: NoteComponent = createNote();
|
|
322
|
-
note.setText('Saved');
|
|
323
|
-
document.body.append(note.element);
|
|
324
|
-
```
|
|
93
|
+
<!-- sizes -->
|
|
94
|
+
| Import | gzip |
|
|
95
|
+
|--------|-----:|
|
|
96
|
+
| `createButton` from `material`, with code splitting: the initial chunks (the progress indicator loads on demand) | 7.4 kB |
|
|
97
|
+
| `createButton`, without code splitting (the progress indicator included) | 13.7 kB |
|
|
98
|
+
| `createButton`, `createTextField` and `createCheckbox`, without code splitting | 19.9 kB |
|
|
99
|
+
| Everything the root exports (`export * from 'material'`), without code splitting | 126.9 kB |
|
|
100
|
+
| `material/styles/base` | 2.9 kB |
|
|
101
|
+
| `material/styles/base` and `material/styles/button` | 5.2 kB |
|
|
102
|
+
| `material/styles`, the full stylesheet | 62.5 kB |
|
|
103
|
+
<!-- /sizes -->
|
|
325
104
|
|
|
326
|
-
|
|
105
|
+
`material` publishes ESM only, so bundlers drop what you do not import. Each component's page on [md3.io/components](https://md3.io/components/) gives its size.
|
|
327
106
|
|
|
328
|
-
##
|
|
329
|
-
|
|
330
|
-
Icons and `content` options are markup strings, written with `innerHTML`. Every such write goes through one sink, so you can decide once how markup is treated. Set a policy when the strings can come from users or a CMS, or when your page enforces Trusted Types:
|
|
331
|
-
|
|
332
|
-
```typescript
|
|
333
|
-
import { configureHTML } from 'material';
|
|
107
|
+
## Browser support
|
|
334
108
|
|
|
335
|
-
|
|
336
|
-
configureHTML({ sanitize: (html) => DOMPurify.sanitize(html) });
|
|
109
|
+
Current Chrome, Edge, Firefox and Safari. The spring motion uses CSS `linear()` easing (Safari 17.2 or later); older browsers render every component but skip those transitions.
|
|
337
110
|
|
|
338
|
-
|
|
339
|
-
// assignment throws, so return a TrustedHTML from a policy your CSP allows
|
|
340
|
-
const policy = window.trustedTypes.createPolicy('mtrl', {
|
|
341
|
-
createHTML: (html) => DOMPurify.sanitize(html),
|
|
342
|
-
});
|
|
343
|
-
configureHTML({ sanitize: (html) => policy.createHTML(html) });
|
|
344
|
-
```
|
|
111
|
+
## Upgrading
|
|
345
112
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
These attributes are markup. With no policy set they are written as HTML, in the browser and when `material/ssr` or one of the four bridges renders the element. `avatar` and `leading-avatar` are not a person's name or an image URL.
|
|
349
|
-
|
|
350
|
-
<!-- markup-attributes -->
|
|
351
|
-
|
|
352
|
-
On the element:
|
|
353
|
-
|
|
354
|
-
- `icon` on `<m-button>`
|
|
355
|
-
- `icon` on `<m-extended-fab>`
|
|
356
|
-
- `icon` on `<m-fab>`
|
|
357
|
-
- `icon` on `<m-icon-button>`
|
|
358
|
-
- `selected-icon` on `<m-icon-button>` — while `toggle` and `selected`
|
|
359
|
-
- `expand-icon` on `<m-navigation-rail>` — while the rail is collapsed
|
|
360
|
-
- `collapse-icon` on `<m-navigation-rail>` — while the rail is expanded
|
|
361
|
-
- `leading-icon` on `<m-search>`
|
|
362
|
-
- `trailing-icon` on `<m-search>`
|
|
363
|
-
- `avatar` on `<m-search>` — not a person's name or an image URL
|
|
364
|
-
- `icon` on `<m-slider>`
|
|
365
|
-
- `inset-icon` on `<m-slider>` — size M, L or XL, not a range or centred slider, when the track can hold it
|
|
366
|
-
- `inset-icon-at-min` on `<m-slider>` — the same, while the value is at the minimum
|
|
367
|
-
- `icon` on `<m-split-button>`
|
|
368
|
-
- `icon` on `<m-switch>`
|
|
369
|
-
- `leading-icon` on `<m-text-field>`
|
|
370
|
-
- `trailing-icon` on `<m-text-field>`
|
|
371
|
-
|
|
372
|
-
On a declaration child:
|
|
373
|
-
|
|
374
|
-
- `icon` on `<m-button-group-item>`
|
|
375
|
-
- `selected-icon` on `<m-button-group-item>` — an icon-only item, while selected
|
|
376
|
-
- `icon` on `<m-chip>`
|
|
377
|
-
- `trailing-icon` on `<m-chip>`
|
|
378
|
-
- `avatar` on `<m-chip>` — input chips only, and it takes precedence over `icon`; not a person's name or an image URL
|
|
379
|
-
- `icon` on `<m-drawer-item>`
|
|
380
|
-
- `leading-icon` on `<m-list-item>`
|
|
381
|
-
- `leading-avatar` on `<m-list-item>` — not a person's name or an image URL
|
|
382
|
-
- `trailing-icon` on `<m-list-item>`
|
|
383
|
-
- `icon` on `<m-menu-item>`
|
|
384
|
-
- `icon` on `<m-navigation-bar-item>`
|
|
385
|
-
- `selected-icon` on `<m-navigation-bar-item>` — while that destination is active
|
|
386
|
-
- `icon` on `<m-navigation-rail-item>`
|
|
387
|
-
- `selected-icon` on `<m-navigation-rail-item>` — while that destination is active
|
|
388
|
-
- `icon` on `<m-search-suggestion>`
|
|
389
|
-
- `icon` on `<m-select-option>` — written into the menu
|
|
390
|
-
- `icon` on `<m-tab>`
|
|
391
|
-
|
|
392
|
-
`<m-fab-menu>` and `<m-fab-menu-item>` `icon` are markup too. The menu opts out of server rendering, so the server leaves those attributes escaped, and the same policy applies when the component upgrades.
|
|
393
|
-
|
|
394
|
-
<!-- /markup-attributes -->
|
|
113
|
+
Upgrade to the latest `mtrl` 0.10.x first, then change the package name to `material` and follow the [migration guide](https://github.com/floor/material/blob/main/CHANGELOG.md#migrating-from-010x).
|
|
395
114
|
|
|
396
115
|
## Where this came from
|
|
397
116
|
|
|
398
|
-
The package was published as `mtrl` up to 0.10.x
|
|
399
|
-
`floor/mtrl`; `#numbers` in commit subjects before 3.0.0 refer to
|
|
400
|
-
[pull requests there](https://github.com/floor/mtrl/pulls?q=is%3Apr+is%3Aclosed).
|
|
401
|
-
|
|
402
|
-
Versions of `material` up to 1.0.4 are an earlier, separate library (GPL-3). Its code is on the
|
|
403
|
-
`v1` branch of this repository, and it stays installable with `npm install material@legacy`.
|
|
404
|
-
|
|
405
|
-
What a page meets keeps the name: the `mtrl-` class prefix, the `--mtrl-` custom properties,
|
|
406
|
-
the `m-` tags and the `mtrl.*` cascade layers are unchanged.
|
|
407
|
-
|
|
408
|
-
## Upgrading from `mtrl` 0.10
|
|
409
|
-
|
|
410
|
-
`material` 3.0.0 removes what 0.10 deprecated. Upgrade to the latest `mtrl` 0.10.x first: it has the 3.0.0 names beside the old ones and flags in your editor each name, option and constant 3.0.0 removes. Then change the package name to `material` and follow the [3.0.0 migration guide](https://github.com/floor/material/blob/main/CHANGELOG.md#migrating-from-010x): `material` is ESM-only, the package root keeps the components (the internals move to their subpaths), "text field" is two words in every identifier, and a few leftovers fail silently instead of at compile time, such as a chip's `{ text }`, which renders an empty chip.
|
|
411
|
-
|
|
412
|
-
## Upgrading from `mtrl` 0.9
|
|
413
|
-
|
|
414
|
-
0.10.0 adds the elements and framework components; for factory users, most apps need nothing. The changes to check are listed in the [0.10.0 changelog's migration section](https://github.com/floor/material/blob/main/CHANGELOG.md#migrating-from-09x): setters no longer emit `change`, the time picker's events pass `{ value }`, the `--mtrl-sys-color-*-rgb` properties are gone, disabled non-form roots use `aria-disabled`, cards are `article`s, and the text field's DOM gained a `__field` wrapper.
|
|
415
|
-
|
|
416
|
-
## Upgrading from `mtrl` 0.7
|
|
417
|
-
|
|
418
|
-
0.8.0 aligns the components with Material 3 expressive, and some of that changes the API or the styles:
|
|
419
|
-
|
|
420
|
-
- `createSheet` is removed; use `createBottomSheet` or `createSideSheet`.
|
|
421
|
-
- FAB and extended FAB: `variant: 'primary'`, `'secondary'` and `'tertiary'` are now the tone styles; the former look is `'primary-container'` (the default), `'secondary-container'` and `'tertiary-container'`.
|
|
422
|
-
- Component custom properties are renamed to `--mtrl-<component>-<name>`, for example `--drawer-width` to `--mtrl-drawer-width` and `--item-offset` to `--mtrl-list-item-offset`.
|
|
423
|
-
- `title-large` uses weight 400, as M3 specifies.
|
|
424
|
-
- The slider draws with DOM and CSS; styles for `.mtrl-slider-canvas` no longer apply.
|
|
425
|
-
|
|
426
|
-
The full list, with every renamed property, is in the [0.8.0 changelog](https://github.com/floor/material/blob/main/CHANGELOG.md#080---2026-09-15).
|
|
427
|
-
|
|
428
|
-
## Browser support
|
|
117
|
+
The package was published as `mtrl` up to 0.10.x, and its history before 3.0.0 was developed in `floor/mtrl`. The class prefix (`mtrl-`), the custom properties, the `m-` tags and the cascade layers keep their names.
|
|
429
118
|
|
|
430
|
-
|
|
119
|
+
Versions of `material` up to 1.0.4 are an earlier, separate library (GPL-3), still installable with `npm install material@legacy`.
|
|
431
120
|
|
|
432
|
-
##
|
|
121
|
+
## Links
|
|
433
122
|
|
|
434
|
-
|
|
123
|
+
[Documentation](https://md3.io) · [Repository and full README](https://github.com/floor/material#readme) · [Changelog](https://github.com/floor/material/blob/main/CHANGELOG.md) · [Issues](https://github.com/floor/material/issues)
|
|
435
124
|
|
|
436
125
|
## License
|
|
437
126
|
|
|
438
|
-
MIT, see [LICENSE](LICENSE).
|
|
127
|
+
MIT, see [LICENSE](https://github.com/floor/material/blob/main/LICENSE).
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* @description A small element that communicates status, shows a count,
|
|
5
5
|
* or highlights an element requiring attention.
|
|
6
6
|
*/
|
|
7
|
-
export { default } from "./badge.js";
|
|
7
|
+
export { default, default as createBadge } from "./badge.js";
|
|
8
8
|
export type { BadgeConfig, BadgeComponent, BadgeVariant, BadgeColor, BadgePosition, } from "./types.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from "./badge.js";
|
|
1
|
+
export { default, default as createBadge } from "./badge.js";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Button component module
|
|
3
3
|
* @module components/button
|
|
4
4
|
*/
|
|
5
|
-
export { default } from "./button.js";
|
|
5
|
+
export { default, default as createButton } from "./button.js";
|
|
6
6
|
export type { ButtonConfig, ButtonComponent, ButtonVariant, ButtonChangePayload } from "./types.js";
|
|
7
7
|
export type { ButtonEvents } from "./types.js";
|
|
8
8
|
export type { ButtonSize, ButtonShape } from "./constants.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from "./button.js";
|
|
1
|
+
export { default, default as createButton } from "./button.js";
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
* Factory function to create a new Card component.
|
|
60
60
|
* @see CardComponent for the full API reference
|
|
61
61
|
*/
|
|
62
|
-
export { default } from "./card.js";
|
|
62
|
+
export { default, default as createCard } from "./card.js";
|
|
63
63
|
/**
|
|
64
64
|
* Card component types and interfaces
|
|
65
65
|
*
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default } from "./card.js";
|
|
1
|
+
export { default, default as createCard } from "./card.js";
|
|
2
2
|
export { createCardContent, createCardHeader, createCardActions, createCardMedia, } from "./content.js";
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @module components/checkbox
|
|
8
8
|
* @category Components
|
|
9
9
|
*/
|
|
10
|
-
export { default } from "./checkbox.js";
|
|
10
|
+
export { default, default as createCheckbox } from "./checkbox.js";
|
|
11
11
|
export type { CheckboxConfig, CheckboxComponent, CheckboxEvents, CheckboxChangePayload, CheckboxLabelPosition } from "./types.js";
|
|
12
12
|
/**
|
|
13
13
|
* Constants for checkbox configuration
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default } from "./checkbox.js";
|
|
1
|
+
export { default, default as createCheckbox } from "./checkbox.js";
|
|
2
2
|
export { CHECKBOX_LABEL_POSITION, CHECKBOX_STATES, CHECKBOX_CLASSES } from "./constants.js";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { createAssistChip, createFilterChip, createInputChip, createSuggestionChip } from "./factories.js";
|
|
2
|
-
export { default as createChips } from "./chips.js";
|
|
2
|
+
export { default, default as createChips } from "./chips.js";
|
|
3
3
|
export type { ChipConfig, ChipComponent, ChipType, ChipEvents, ChipChangePayload, AssistChipConfig, FilterChipConfig, InputChipConfig, SuggestionChipConfig, ChipsConfig, ChipsComponent, ChipsEvents, ChipsChangeEvent, ChipsAddEvent, ChipsRemoveEvent, } from "./types.js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { createAssistChip, createFilterChip, createInputChip, createSuggestionChip } from "./factories.js";
|
|
2
|
-
export { default as createChips } from "./chips.js";
|
|
2
|
+
export { default, default as createChips } from "./chips.js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default } from "./datepicker.js";
|
|
1
|
+
export { default, default as createDatePicker } from "./datepicker.js";
|
|
2
2
|
export type { DatePickerConfig, DatePickerComponent, DatePickerEvents, DatePickerValue, DatePickerValueOf, DatePickerInput, DatePickerChangePayload, DatePickerVisibilityPayload, DatePickerTapPayload, DatePickerSwipePayload, DatePickerVariant, DatePickerView, DatePickerSelectionMode, CalendarAPI, } from "./types.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from "./datepicker.js";
|
|
1
|
+
export { default, default as createDatePicker } from "./datepicker.js";
|
|
@@ -10,5 +10,5 @@
|
|
|
10
10
|
* @module components/dialog
|
|
11
11
|
* @category Components
|
|
12
12
|
*/
|
|
13
|
-
export { default } from "./dialog.js";
|
|
13
|
+
export { default, default as createDialog } from "./dialog.js";
|
|
14
14
|
export type { DialogConfig, DialogComponent, DialogButton, DialogEvent, DialogConfirmOptions, DialogSize, DialogAnimation, DialogFooterAlignment, DialogEventType, } from "./types.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from "./dialog.js";
|
|
1
|
+
export { default, default as createDialog } from "./dialog.js";
|
|
@@ -28,6 +28,6 @@
|
|
|
28
28
|
* @category Components
|
|
29
29
|
*/
|
|
30
30
|
import { createDivider } from "./divider.js";
|
|
31
|
-
export { createDivider };
|
|
31
|
+
export { createDivider, createDivider as default };
|
|
32
32
|
export type { DividerConfig } from "./config.js";
|
|
33
33
|
export type { DividerComponent } from "./types.js";
|