@stackific/md3 0.1.1 → 0.1.3
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 +2486 -191
- package/dist/internal.md +274 -0
- package/dist/md3.css +1 -1
- package/dist/md3.js +1 -1
- package/package.json +1 -3
- package/src/main.js +0 -5
- package/src/runtime/elements/dialogs.js +0 -72
- package/src/runtime/elements/fields.js +0 -181
- package/src/runtime/elements/menus.js +0 -42
- package/src/runtime/elements/pages.js +0 -7
- package/src/runtime/elements/progress.js +0 -35
- package/src/runtime/elements/sliders.js +0 -78
- package/src/runtime/elements/snackbars.js +0 -27
- package/src/runtime/helpers/ripples.js +0 -46
- package/src/runtime/md3.js +0 -141
- package/src/runtime/palette.js +0 -64
- package/src/runtime/settings/theme.js +0 -194
- package/src/runtime/utils.js +0 -165
- package/src/styles/_config.scss +0 -142
- package/src/styles/_mixins.scss +0 -80
- package/src/styles/elements/_badges.scss +0 -65
- package/src/styles/elements/_bars.scss +0 -83
- package/src/styles/elements/_buttons.scss +0 -119
- package/src/styles/elements/_cards.scss +0 -32
- package/src/styles/elements/_chips.scss +0 -46
- package/src/styles/elements/_dialogs.scss +0 -143
- package/src/styles/elements/_dividers.scss +0 -46
- package/src/styles/elements/_expansions.scss +0 -19
- package/src/styles/elements/_fields.scss +0 -458
- package/src/styles/elements/_grids.scss +0 -35
- package/src/styles/elements/_icons.scss +0 -70
- package/src/styles/elements/_layouts.scss +0 -24
- package/src/styles/elements/_lists.scss +0 -76
- package/src/styles/elements/_main-layouts.scss +0 -45
- package/src/styles/elements/_media.scss +0 -104
- package/src/styles/elements/_menus.scss +0 -289
- package/src/styles/elements/_navigations.scss +0 -450
- package/src/styles/elements/_overlays.scss +0 -34
- package/src/styles/elements/_pages.scss +0 -28
- package/src/styles/elements/_progress.scss +0 -141
- package/src/styles/elements/_selections.scss +0 -248
- package/src/styles/elements/_shapes.scss +0 -153
- package/src/styles/elements/_sliders.scss +0 -336
- package/src/styles/elements/_snackbars.scss +0 -44
- package/src/styles/elements/_tables.scss +0 -67
- package/src/styles/elements/_tabs.scss +0 -49
- package/src/styles/elements/_tooltips.scss +0 -125
- package/src/styles/fonts/material-symbols-outlined.woff2 +0 -0
- package/src/styles/fonts/material-symbols-rounded.woff2 +0 -0
- package/src/styles/fonts/material-symbols-sharp.woff2 +0 -0
- package/src/styles/fonts/material-symbols-subset.woff2 +0 -0
- package/src/styles/helpers/_alignments.scss +0 -29
- package/src/styles/helpers/_blurs.scss +0 -26
- package/src/styles/helpers/_colors.scss +0 -39
- package/src/styles/helpers/_directions.scss +0 -30
- package/src/styles/helpers/_elevates.scss +0 -20
- package/src/styles/helpers/_forms.scss +0 -76
- package/src/styles/helpers/_margins.scss +0 -39
- package/src/styles/helpers/_opacities.scss +0 -18
- package/src/styles/helpers/_paddings.scss +0 -35
- package/src/styles/helpers/_positions.scss +0 -44
- package/src/styles/helpers/_responsive.scss +0 -24
- package/src/styles/helpers/_ripples.scss +0 -40
- package/src/styles/helpers/_scrolls.scss +0 -7
- package/src/styles/helpers/_shadows.scss +0 -22
- package/src/styles/helpers/_sizes.scss +0 -34
- package/src/styles/helpers/_spaces.scss +0 -22
- package/src/styles/helpers/_typography.scss +0 -132
- package/src/styles/helpers/_waves.scss +0 -52
- package/src/styles/helpers/_zoom.scss +0 -18
- package/src/styles/md3.scss +0 -61
- package/src/styles/settings/_fonts.scss +0 -41
- package/src/styles/settings/_globals.scss +0 -104
- package/src/styles/settings/_reset.scss +0 -82
- package/src/styles/settings/_theme.scss +0 -126
- package/src/styles/settings/_themes.scss +0 -1525
- package/src/styles/shapes/arch.svg +0 -1
- package/src/styles/shapes/arrow.svg +0 -1
- package/src/styles/shapes/boom.svg +0 -1
- package/src/styles/shapes/bun.svg +0 -1
- package/src/styles/shapes/burst.svg +0 -1
- package/src/styles/shapes/circle.svg +0 -1
- package/src/styles/shapes/clamshell.svg +0 -1
- package/src/styles/shapes/diamond.svg +0 -1
- package/src/styles/shapes/fan.svg +0 -1
- package/src/styles/shapes/flower.svg +0 -1
- package/src/styles/shapes/gem.svg +0 -1
- package/src/styles/shapes/ghost-ish.svg +0 -1
- package/src/styles/shapes/heart.svg +0 -1
- package/src/styles/shapes/leaf-clover4.svg +0 -1
- package/src/styles/shapes/leaf-clover8.svg +0 -1
- package/src/styles/shapes/loading-indicator.svg +0 -1
- package/src/styles/shapes/oval.svg +0 -1
- package/src/styles/shapes/pentagon.svg +0 -1
- package/src/styles/shapes/pill.svg +0 -1
- package/src/styles/shapes/pixel-circle.svg +0 -1
- package/src/styles/shapes/pixel-triangle.svg +0 -1
- package/src/styles/shapes/puffy-diamond.svg +0 -1
- package/src/styles/shapes/puffy.svg +0 -1
- package/src/styles/shapes/semicircle.svg +0 -1
- package/src/styles/shapes/sided-cookie12.svg +0 -1
- package/src/styles/shapes/sided-cookie4.svg +0 -1
- package/src/styles/shapes/sided-cookie6.svg +0 -1
- package/src/styles/shapes/sided-cookie7.svg +0 -1
- package/src/styles/shapes/sided-cookie9.svg +0 -1
- package/src/styles/shapes/slanted.svg +0 -1
- package/src/styles/shapes/soft-boom.svg +0 -1
- package/src/styles/shapes/soft-burst.svg +0 -1
- package/src/styles/shapes/square.svg +0 -1
- package/src/styles/shapes/sunny.svg +0 -1
- package/src/styles/shapes/triangle.svg +0 -1
- package/src/styles/shapes/very-sunny.svg +0 -1
- package/src/styles/shapes/wavy-circle.svg +0 -1
- package/src/styles/shapes/wavy.svg +0 -1
package/dist/internal.md
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# @stackific/md3
|
|
2
|
+
|
|
3
|
+
Material Design 3 framework — SCSS + plain JavaScript. No build step required. No React, Vue, or other framework lock-in. Drop it into any HTML page and write semantic markup.
|
|
4
|
+
|
|
5
|
+
- **Light + dark + auto** modes that follow OS preference, persist across reloads, and update live when the OS theme flips.
|
|
6
|
+
- **Multiple named brand themes** in a single bundle, swap with one attribute.
|
|
7
|
+
- **No JS framework required.** Works in plain HTML, also fine with React, Vue, Svelte, htmx, etc.
|
|
8
|
+
- **Runtime weight**: ~17 kB JS, ~22 kB CSS (gzipped) for the full default build.
|
|
9
|
+
- **Optional dynamic theming** from a hex / image / file via `material-dynamic-colors` (opt-in dependency).
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Quick start (CDN)
|
|
14
|
+
|
|
15
|
+
Paste into any HTML file:
|
|
16
|
+
|
|
17
|
+
```html
|
|
18
|
+
<!doctype html>
|
|
19
|
+
<html data-theme="stackific">
|
|
20
|
+
<head>
|
|
21
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@stackific/md3/dist/md3.css">
|
|
22
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/@stackific/md3/dist/md3.js"></script>
|
|
23
|
+
</head>
|
|
24
|
+
<body>
|
|
25
|
+
<main class="responsive">
|
|
26
|
+
<h1>Hello, M3</h1>
|
|
27
|
+
<button>Click me</button>
|
|
28
|
+
<div class="field label">
|
|
29
|
+
<input type="text">
|
|
30
|
+
<label>Your name</label>
|
|
31
|
+
</div>
|
|
32
|
+
<label class="switch">
|
|
33
|
+
<input type="checkbox">
|
|
34
|
+
<span></span>
|
|
35
|
+
</label>
|
|
36
|
+
</main>
|
|
37
|
+
</body>
|
|
38
|
+
</html>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
That's it. You should see an M3-styled page that picks light or dark automatically from your OS preference.
|
|
42
|
+
|
|
43
|
+
## Install via npm
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
npm install @stackific/md3
|
|
47
|
+
# or: pnpm add @stackific/md3
|
|
48
|
+
# or: yarn add @stackific/md3
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
In your app entry:
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
import "@stackific/md3"; // runtime — registers window.ui()
|
|
55
|
+
import "@stackific/md3/style"; // compiled CSS with M3 tokens + utilities
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The CSS includes all `@font-face` declarations for Material Symbols, so icons render without any Google Fonts import.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Theme + mode
|
|
63
|
+
|
|
64
|
+
Two HTML attributes drive everything:
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<html data-theme="stackific" data-mode="auto">
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
| Attribute | Values | Purpose |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| `data-theme` | any name listed in `$themes` | Which brand theme supplies the tokens |
|
|
73
|
+
| `data-mode` | `"auto"`, `"light"`, `"dark"` | Color mode preference |
|
|
74
|
+
|
|
75
|
+
`data-mode="auto"` is a real attribute state — CSS handles the `auto → dark` switch via `@media (prefers-color-scheme: dark)`, so the page tracks your OS preference live. No JavaScript needed for that to work.
|
|
76
|
+
|
|
77
|
+
### Switching at runtime
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
ui("mode", "dark"); // or "light", or "auto"
|
|
81
|
+
document.documentElement.dataset.theme = "another"; // pure attribute swap, no deps
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Mode is persisted to `localStorage` under the key `md3:mode` and restored on the next page load. Theme is persisted to `md3:theme`.
|
|
85
|
+
|
|
86
|
+
### Listing available themes
|
|
87
|
+
|
|
88
|
+
```js
|
|
89
|
+
ui("themes"); // → ["stackific", "hello-pumpkin", "coral-bloom", ...]
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Adding a brand theme
|
|
93
|
+
|
|
94
|
+
If you've cloned the source, `pnpm theme add acme '#ff5722'` bakes a new theme from a single hex color, then `pnpm build` makes it reachable as `<html data-theme="acme">`. See [Local development](#local-development) below for the full workflow.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Customize tokens
|
|
99
|
+
|
|
100
|
+
All M3 design tokens are CSS custom properties. Override at any scope — no rebuild required.
|
|
101
|
+
|
|
102
|
+
```css
|
|
103
|
+
/* whole site */
|
|
104
|
+
:root {
|
|
105
|
+
--primary: #ff5722;
|
|
106
|
+
--on-primary: #ffffff;
|
|
107
|
+
--primary-container: #ffe0d6;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* one card */
|
|
111
|
+
article.alert {
|
|
112
|
+
--surface-container-low: #fff3e0;
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Common tweaks:
|
|
117
|
+
|
|
118
|
+
```css
|
|
119
|
+
:root {
|
|
120
|
+
--size: 1.1rem; /* 10% larger everywhere */
|
|
121
|
+
--font: "Inter Variable", system-ui; /* body font */
|
|
122
|
+
--font-icon: "Material Symbols Rounded"; /* see icon styles below */
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Full token list
|
|
127
|
+
|
|
128
|
+
| Group | Tokens |
|
|
129
|
+
|---|---|
|
|
130
|
+
| Primary | `--primary`, `--on-primary`, `--primary-container`, `--on-primary-container` |
|
|
131
|
+
| Secondary | `--secondary`, `--on-secondary`, `--secondary-container`, `--on-secondary-container` |
|
|
132
|
+
| Tertiary | `--tertiary`, `--on-tertiary`, `--tertiary-container`, `--on-tertiary-container` |
|
|
133
|
+
| Error | `--error`, `--on-error`, `--error-container`, `--on-error-container` |
|
|
134
|
+
| Neutral | `--background`, `--on-background`, `--surface`, `--on-surface`, `--surface-variant`, `--on-surface-variant`, `--outline`, `--outline-variant`, `--shadow`, `--scrim` |
|
|
135
|
+
| Surface tonal | `--surface-dim`, `--surface-bright`, `--surface-container-lowest`, `--surface-container-low`, `--surface-container`, `--surface-container-high`, `--surface-container-highest` |
|
|
136
|
+
| Inverse | `--inverse-surface`, `--inverse-on-surface`, `--inverse-primary` |
|
|
137
|
+
| Structural | `--size`, `--font`, `--font-icon`, `--speed1`..`--speed4`, `--active`, `--overlay`, `--elevate1`..`--elevate3`, `--top`, `--bottom`, `--left`, `--right`, `--image` |
|
|
138
|
+
|
|
139
|
+
### Icon styles
|
|
140
|
+
|
|
141
|
+
Four Material Symbols variants are pre-bundled in `dist/fonts/`. Switch by changing one variable:
|
|
142
|
+
|
|
143
|
+
```css
|
|
144
|
+
:root {
|
|
145
|
+
--font-icon: "Material Symbols Rounded";
|
|
146
|
+
/* "Material Symbols Outlined" (default)
|
|
147
|
+
"Material Symbols Rounded"
|
|
148
|
+
"Material Symbols Sharp"
|
|
149
|
+
"Material Symbols Subset" (smaller; common icons only) */
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Runtime API
|
|
156
|
+
|
|
157
|
+
A single global function `ui()` (or named import `ui`) handles everything.
|
|
158
|
+
|
|
159
|
+
### Mode + theme
|
|
160
|
+
|
|
161
|
+
```js
|
|
162
|
+
ui("mode"); // → "auto" | "light" | "dark"
|
|
163
|
+
ui("mode", "dark"); // set mode; persisted to localStorage
|
|
164
|
+
ui("themes"); // → ["stackific", ...] list of baked themes
|
|
165
|
+
ui("theme", "stackific"); // swap to a baked theme (no extra deps)
|
|
166
|
+
await ui("theme", "#1447E6"); // generate a theme from a hex — needs MDC
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`ui("theme", source)` accepts a baked theme name, hex string, image URL, `File`, or a pre-computed `{ light, dark }` object. **Only the hex/URL/File forms require [`material-dynamic-colors`](https://www.npmjs.com/package/material-dynamic-colors)** to be loaded in the page:
|
|
170
|
+
|
|
171
|
+
```js
|
|
172
|
+
import "material-dynamic-colors"; // once, at app entry
|
|
173
|
+
await ui("theme", "#1447E6"); // now works
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The framework itself does not bundle MDC — install and import it yourself when you need dynamic generation.
|
|
177
|
+
|
|
178
|
+
### Component triggers
|
|
179
|
+
|
|
180
|
+
```js
|
|
181
|
+
ui("#my-dialog"); // toggle a <dialog>
|
|
182
|
+
ui("#my-snackbar"); // show snackbar for 6s
|
|
183
|
+
ui("#my-snackbar", 3000); // show for 3s
|
|
184
|
+
ui("#my-snackbar", -1); // show until clicked
|
|
185
|
+
ui("#my-page"); // activate a .page (tab-style content)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
These are equivalent to clicking an element with `[data-ui="#id"]`.
|
|
189
|
+
|
|
190
|
+
### Utilities
|
|
191
|
+
|
|
192
|
+
```js
|
|
193
|
+
ui(); // re-scan the DOM (call after dynamically injecting markup)
|
|
194
|
+
ui("guid"); // → UUID-v4 string, handy for unique input ids
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Local development
|
|
200
|
+
|
|
201
|
+
These commands are for hacking on the framework itself, not for consumers of the published package.
|
|
202
|
+
|
|
203
|
+
```sh
|
|
204
|
+
git clone https://github.com/stackific/md3
|
|
205
|
+
cd md3
|
|
206
|
+
pnpm install
|
|
207
|
+
pnpm build # → dist/md3.css + dist/md3.js
|
|
208
|
+
pnpm demo # build + start the demo Vue app at http://localhost:5001
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Adding or removing a brand theme
|
|
212
|
+
|
|
213
|
+
```sh
|
|
214
|
+
pnpm theme add acme '#ff5722' # quote the hex
|
|
215
|
+
pnpm theme remove acme
|
|
216
|
+
pnpm build # re-emit dist/
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
`add` derives the M3 light + dark token sets and a 10-step tonal palette from the source color, then writes both:
|
|
220
|
+
|
|
221
|
+
- `src/styles/_config.scss` → upserts the entry in `$material-palette` so `.acme`, `.acme1`..`.acme10`, `.acme-text`, `.acme-border` utility classes become available.
|
|
222
|
+
- `src/styles/settings/_themes.scss` → upserts a named block in `$themes` so `<html data-theme="acme">` activates it.
|
|
223
|
+
|
|
224
|
+
`remove` strips both.
|
|
225
|
+
|
|
226
|
+
### Editing tokens directly
|
|
227
|
+
|
|
228
|
+
If you'd rather edit token values by hand instead of running `pnpm theme add`, the shape of `$themes` is:
|
|
229
|
+
|
|
230
|
+
```scss
|
|
231
|
+
$themes: (
|
|
232
|
+
"stackific": (
|
|
233
|
+
"light": ( "primary": #1c4bea, "on-primary": #ffffff, /* ... */ ),
|
|
234
|
+
"dark": ( "primary": #b9c3ff, /* ... */ ),
|
|
235
|
+
),
|
|
236
|
+
);
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Token keys are kebab-cased and match the CSS custom-property names verbatim.
|
|
240
|
+
|
|
241
|
+
### Configure which roles get utility classes
|
|
242
|
+
|
|
243
|
+
`src/styles/_config.scss` controls which M3 roles generate `.role`, `.role-text`, `.role-border`, `.role-container`, and `nav.role`/`menu.role` active-state recoloring:
|
|
244
|
+
|
|
245
|
+
```scss
|
|
246
|
+
$theme-roles-paired: ("primary", "secondary", "tertiary", "error", "background");
|
|
247
|
+
$theme-roles-with-edges: ("primary", "secondary", "tertiary", "error");
|
|
248
|
+
$theme-roles-container: ("primary", "secondary", "tertiary", "error");
|
|
249
|
+
$theme-roles-nav-active: ("primary", "secondary", "tertiary");
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Other things you can edit in SCSS
|
|
253
|
+
|
|
254
|
+
| File | What's there |
|
|
255
|
+
|---|---|
|
|
256
|
+
| `src/styles/_config.scss` | `$material-palette`, role lists, `$breakpoints`, mixins |
|
|
257
|
+
| `src/styles/settings/_themes.scss` | `$themes` (light/dark tokens per brand) |
|
|
258
|
+
| `src/styles/settings/_fonts.scss` | Material Symbols `@font-face` declarations |
|
|
259
|
+
| `src/styles/elements/_*.scss` | Per-component scales (`$-button-sizes`, `$-chip-sizes`, etc.) |
|
|
260
|
+
| `src/styles/elements/_shapes.scss` | `$-shapes` list of SVG-backed shape utilities |
|
|
261
|
+
|
|
262
|
+
## Publish
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
pnpm prepublishOnly
|
|
266
|
+
npm publish --access public --dry-run
|
|
267
|
+
npm publish --access public
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## License
|
|
273
|
+
|
|
274
|
+
Apache-2.0. See `LICENSE` and `NOTICE`. The published source includes patterns and SCSS structure derived from [beercss](https://github.com/beercss/beercss) (MIT) — full attribution in `THIRD-PARTY-NOTICES`.
|