@francofantomius/material-components 0.1.0 → 1.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/CHANGELOG.md +80 -0
- package/README.md +550 -90
- package/custom-elements.json +21010 -2354
- package/dist/chunks/badge-G4EjcMoy.js +89 -0
- package/dist/chunks/badge-G4EjcMoy.js.map +1 -0
- package/dist/chunks/button-B4TSZ7Sl.js +250 -0
- package/dist/chunks/button-B4TSZ7Sl.js.map +1 -0
- package/dist/chunks/card-DVffdPpv.js +163 -0
- package/dist/chunks/card-DVffdPpv.js.map +1 -0
- package/dist/chunks/checkbox-BqlboAHd.js +194 -0
- package/dist/chunks/checkbox-BqlboAHd.js.map +1 -0
- package/dist/chunks/chip-CI1ZINnr.js +169 -0
- package/dist/chunks/chip-CI1ZINnr.js.map +1 -0
- package/dist/chunks/code-C5UFBkCh.js +1830 -0
- package/dist/chunks/code-C5UFBkCh.js.map +1 -0
- package/dist/chunks/decorate-DXuynaiA.js +39 -0
- package/dist/chunks/decorate-DXuynaiA.js.map +1 -0
- package/dist/chunks/dialog-DGVEE5m_.js +158 -0
- package/dist/chunks/dialog-DGVEE5m_.js.map +1 -0
- package/dist/chunks/divider-DNepwoZv.js +82 -0
- package/dist/chunks/divider-DNepwoZv.js.map +1 -0
- package/dist/chunks/fab-C9j3WBHE.js +150 -0
- package/dist/chunks/fab-C9j3WBHE.js.map +1 -0
- package/dist/chunks/focus-ring-CuiJuM-y.js +71 -0
- package/dist/chunks/focus-ring-CuiJuM-y.js.map +1 -0
- package/dist/chunks/{form-associated-fKbeX_2P.js → form-associated-Cty_ZaS9.js} +26 -27
- package/dist/chunks/form-associated-Cty_ZaS9.js.map +1 -0
- package/dist/chunks/icon-DrNqcNEL.js +62 -0
- package/dist/chunks/icon-DrNqcNEL.js.map +1 -0
- package/dist/chunks/icon-button-BdSc7eot.js +188 -0
- package/dist/chunks/icon-button-BdSc7eot.js.map +1 -0
- package/dist/chunks/list-D8olR7oZ.js +204 -0
- package/dist/chunks/list-D8olR7oZ.js.map +1 -0
- package/dist/chunks/navigation-drawer-CKl44Ef5.js +531 -0
- package/dist/chunks/navigation-drawer-CKl44Ef5.js.map +1 -0
- package/dist/chunks/player-C4ydiIpr.js +1582 -0
- package/dist/chunks/player-C4ydiIpr.js.map +1 -0
- package/dist/chunks/progress-LQmLMDjX.js +266 -0
- package/dist/chunks/progress-LQmLMDjX.js.map +1 -0
- package/dist/chunks/radio-Bily78NT.js +205 -0
- package/dist/chunks/radio-Bily78NT.js.map +1 -0
- package/dist/chunks/ripple-squbKHhj.js +135 -0
- package/dist/chunks/ripple-squbKHhj.js.map +1 -0
- package/dist/chunks/search-bar-TXnqJ-gd.js +698 -0
- package/dist/chunks/search-bar-TXnqJ-gd.js.map +1 -0
- package/dist/chunks/snackbar-Wsz3BzEY.js +161 -0
- package/dist/chunks/snackbar-Wsz3BzEY.js.map +1 -0
- package/dist/chunks/switch-DdukrvXb.js +190 -0
- package/dist/chunks/switch-DdukrvXb.js.map +1 -0
- package/dist/chunks/table-aRTYzDyE.js +773 -0
- package/dist/chunks/table-aRTYzDyE.js.map +1 -0
- package/dist/chunks/tabs-BfOtoeir.js +191 -0
- package/dist/chunks/tabs-BfOtoeir.js.map +1 -0
- package/dist/chunks/text-field-hN6-2HQy.js +338 -0
- package/dist/chunks/text-field-hN6-2HQy.js.map +1 -0
- package/dist/chunks/top-app-bar-Dgbp6CFv.js +228 -0
- package/dist/chunks/top-app-bar-Dgbp6CFv.js.map +1 -0
- package/dist/components/account-menu/account-menu.css.d.ts +3 -0
- package/dist/components/account-menu/account-menu.css.d.ts.map +1 -0
- package/dist/components/account-menu/account-menu.d.ts +111 -0
- package/dist/components/account-menu/account-menu.d.ts.map +1 -0
- package/dist/components/app-drawer/app-drawer.css.d.ts +3 -0
- package/dist/components/app-drawer/app-drawer.css.d.ts.map +1 -0
- package/dist/components/app-drawer/app-drawer.d.ts +173 -0
- package/dist/components/app-drawer/app-drawer.d.ts.map +1 -0
- package/dist/components/badge/badge.js +2 -91
- package/dist/components/button/button.js +2 -261
- package/dist/components/card/card.js +2 -167
- package/dist/components/checkbox/checkbox.css.d.ts.map +1 -1
- package/dist/components/checkbox/checkbox.js +2 -186
- package/dist/components/chip/chip.js +3 -172
- package/dist/components/code/code.css.d.ts +2 -0
- package/dist/components/code/code.css.d.ts.map +1 -0
- package/dist/components/code/code.d.ts +106 -0
- package/dist/components/code/code.d.ts.map +1 -0
- package/dist/components/code/code.js +5 -0
- package/dist/components/code/highlighter.d.ts +8 -0
- package/dist/components/code/highlighter.d.ts.map +1 -0
- package/dist/components/code/linter.d.ts +44 -0
- package/dist/components/code/linter.d.ts.map +1 -0
- package/dist/components/dialog/dialog.js +2 -165
- package/dist/components/divider/divider.js +2 -79
- package/dist/components/fab/fab.js +2 -153
- package/dist/components/icon/icon.js +2 -68
- package/dist/components/icon-button/icon-button.css.d.ts.map +1 -1
- package/dist/components/icon-button/icon-button.js +1 -189
- package/dist/components/list/list.css.d.ts.map +1 -1
- package/dist/components/list/list.d.ts.map +1 -1
- package/dist/components/list/list.js +3 -188
- package/dist/components/navigation-drawer/navigation-drawer.css.d.ts +3 -0
- package/dist/components/navigation-drawer/navigation-drawer.css.d.ts.map +1 -0
- package/dist/components/navigation-drawer/navigation-drawer.d.ts +76 -0
- package/dist/components/navigation-drawer/navigation-drawer.d.ts.map +1 -0
- package/dist/components/navigation-drawer/navigation-drawer.js +8 -0
- package/dist/components/player/player.css.d.ts +2 -0
- package/dist/components/player/player.css.d.ts.map +1 -0
- package/dist/components/player/player.d.ts +99 -0
- package/dist/components/player/player.d.ts.map +1 -0
- package/dist/components/player/player.js +7 -0
- package/dist/components/progress/progress.css.d.ts.map +1 -1
- package/dist/components/progress/progress.d.ts +2 -0
- package/dist/components/progress/progress.d.ts.map +1 -1
- package/dist/components/progress/progress.js +3 -181
- package/dist/components/radio/radio.css.d.ts.map +1 -1
- package/dist/components/radio/radio.js +3 -203
- package/dist/components/search-bar/search-bar.css.d.ts +2 -0
- package/dist/components/search-bar/search-bar.css.d.ts.map +1 -0
- package/dist/components/search-bar/search-bar.d.ts +81 -0
- package/dist/components/search-bar/search-bar.d.ts.map +1 -0
- package/dist/components/search-bar/search-bar.js +5 -0
- package/dist/components/snackbar/snackbar.js +2 -162
- package/dist/components/switch/switch.css.d.ts.map +1 -1
- package/dist/components/switch/switch.js +2 -169
- package/dist/components/table/table.css.d.ts +8 -0
- package/dist/components/table/table.css.d.ts.map +1 -0
- package/dist/components/table/table.d.ts +158 -0
- package/dist/components/table/table.d.ts.map +1 -0
- package/dist/components/table/table.js +13 -0
- package/dist/components/tabs/tabs.js +3 -198
- package/dist/components/text-field/text-field.css.d.ts.map +1 -1
- package/dist/components/text-field/text-field.d.ts +1 -1
- package/dist/components/text-field/text-field.d.ts.map +1 -1
- package/dist/components/text-field/text-field.js +2 -325
- package/dist/components/top-app-bar/top-app-bar.css.d.ts +2 -0
- package/dist/components/top-app-bar/top-app-bar.css.d.ts.map +1 -0
- package/dist/components/top-app-bar/top-app-bar.d.ts +29 -0
- package/dist/components/top-app-bar/top-app-bar.d.ts.map +1 -0
- package/dist/components/top-app-bar/top-app-bar.js +5 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2264 -58
- package/dist/index.js.map +1 -1
- package/dist/internal/focus-ring/focus-ring.d.ts.map +1 -1
- package/dist/internal/focus-ring/focus-ring.js +4 -0
- package/dist/internal/ripple/ripple.css.d.ts.map +1 -1
- package/dist/internal/ripple/ripple.d.ts +0 -3
- package/dist/internal/ripple/ripple.d.ts.map +1 -1
- package/dist/internal/ripple/ripple.js +2 -142
- package/dist/tokens/index.js +336 -11
- package/dist/tokens/index.js.map +1 -1
- package/package.json +118 -12
- package/dist/chunks/base-component-DQTjlEVL.js +0 -34
- package/dist/chunks/base-component-DQTjlEVL.js.map +0 -1
- package/dist/chunks/focus-ring-Dl-XoEKK.js +0 -71
- package/dist/chunks/focus-ring-Dl-XoEKK.js.map +0 -1
- package/dist/chunks/form-associated-fKbeX_2P.js.map +0 -1
- package/dist/chunks/theme.css-DV3DRha-.js +0 -263
- package/dist/chunks/theme.css-DV3DRha-.js.map +0 -1
- package/dist/components/badge/badge.js.map +0 -1
- package/dist/components/button/button.js.map +0 -1
- package/dist/components/card/card.js.map +0 -1
- package/dist/components/checkbox/checkbox.js.map +0 -1
- package/dist/components/chip/chip.js.map +0 -1
- package/dist/components/dialog/dialog.js.map +0 -1
- package/dist/components/divider/divider.js.map +0 -1
- package/dist/components/fab/fab.js.map +0 -1
- package/dist/components/icon/icon.js.map +0 -1
- package/dist/components/icon-button/icon-button.js.map +0 -1
- package/dist/components/list/list.js.map +0 -1
- package/dist/components/progress/progress.js.map +0 -1
- package/dist/components/radio/radio.js.map +0 -1
- package/dist/components/snackbar/snackbar.js.map +0 -1
- package/dist/components/switch/switch.js.map +0 -1
- package/dist/components/tabs/tabs.js.map +0 -1
- package/dist/components/text-field/text-field.js.map +0 -1
- package/dist/internal/ripple/ripple.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,87 +1,389 @@
|
|
|
1
1
|
# @francofantomius/material-components
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="left">
|
|
4
|
+
<a href="https://www.npmjs.com/package/@francofantomius/material-components"><img src="https://img.shields.io/npm/v/@francofantomius/material-components?color=6750A4&label=npm&logo=npm" alt="npm version" /></a>
|
|
5
|
+
<a href="https://lit.dev/"><img src="https://img.shields.io/badge/Lit-3.x-324FFF?logo=lit&logoColor=white" alt="Lit 3" /></a>
|
|
6
|
+
<a href="https://vite.dev/"><img src="https://img.shields.io/badge/Vite-8.x-646CFF?logo=vite&logoColor=white" alt="Vite 8" /></a>
|
|
7
|
+
<a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-Ready-3178C6?logo=typescript&logoColor=white" alt="TypeScript" /></a>
|
|
8
|
+
<a href="https://m3.material.io/"><img src="https://img.shields.io/badge/Material%20Design-3-6750A4?logo=materialdesign&logoColor=white" alt="Material Design 3" /></a>
|
|
9
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT" /></a>
|
|
10
|
+
<a href="https://bundlephobia.com/package/@francofantomius/material-components"><img src="https://img.shields.io/badge/ESM-tree--shakeable-success" alt="Tree Shakeable ESM" /></a>
|
|
11
|
+
</p>
|
|
4
12
|
|
|
5
|
-
|
|
13
|
+
A modern, accessible, and lightweight **Material Design 3 (M3)** Web Components library built with [Lit](https://lit.dev/), [Vite](https://vite.dev/), and [TypeScript](https://www.typescriptlang.org/).
|
|
14
|
+
|
|
15
|
+
Runs natively in all modern browsers and integrates seamlessly with **React** (18 & 19), **Vue 3**, **Angular**, **Svelte**, **Solid**, or vanilla HTML/JavaScript without requiring framework-specific wrappers.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Table of Contents
|
|
20
|
+
|
|
21
|
+
- [Features](#features)
|
|
22
|
+
- [Installation](#installation)
|
|
23
|
+
- [CDN Quick Start](#cdn-quick-start)
|
|
24
|
+
- [Quick Start](#quick-start)
|
|
25
|
+
- [1. Load Fonts & Icons](#1-load-fonts-and-icons-recommended)
|
|
26
|
+
- [2. Import Components](#2-import-components)
|
|
27
|
+
- [Component Index](#component-index)
|
|
28
|
+
- [Usage Examples](#usage-examples)
|
|
29
|
+
- [Buttons, FABs & Icons](#buttons-fabs--icons)
|
|
30
|
+
- [Form Controls & Native Validation (FACE)](#form-controls-native-form-association)
|
|
31
|
+
- [Top App Bar & Navigation Drawer](#navigation--top-app-bar)
|
|
32
|
+
- [App Drawer & Account Menu](#app-drawer--account-menu)
|
|
33
|
+
- [Data Table](#data-table)
|
|
34
|
+
- [Search Bar with Live Suggestions](#search-bar-with-live-suggestions)
|
|
35
|
+
- [Code Block & Syntax Linter](#code-block--syntax-linter)
|
|
36
|
+
- [Media Player (Audio & Video)](#media-player-audio--video)
|
|
37
|
+
- [Form-Associated Custom Elements (FACE)](#form-integration-face)
|
|
38
|
+
- [Theming & Color Palettes](#theming-and-dark-mode)
|
|
39
|
+
- [CSS Custom Properties](#dynamic-theming-via-css-custom-properties)
|
|
40
|
+
- [TypeScript Theme Helper API](#typescript-theme-helper)
|
|
41
|
+
- [Subpath Exports Reference](#subpath-exports-reference)
|
|
42
|
+
- [Framework Integration](#framework-integration)
|
|
43
|
+
- [React (18 / 19 / Next.js)](#react)
|
|
44
|
+
- [Vue 3 / Nuxt](#vue)
|
|
45
|
+
- [Angular](#angular)
|
|
46
|
+
- [Svelte](#svelte)
|
|
47
|
+
- [LLM & AI Assistant Documentation](#llm--ai-assistant-documentation)
|
|
48
|
+
- [Development Scripts](#development-scripts)
|
|
49
|
+
- [Automated Publishing](#automated-publishing-trusted-publishing)
|
|
50
|
+
- [License](#license)
|
|
6
51
|
|
|
7
52
|
---
|
|
8
53
|
|
|
9
54
|
## Features
|
|
10
55
|
|
|
11
|
-
- **Material Design 3**: Fully tokenized CSS design tokens for dynamic theming
|
|
12
|
-
- **
|
|
13
|
-
- **Form-Associated Custom Elements (FACE)**:
|
|
14
|
-
- **Lightweight
|
|
15
|
-
- **TypeScript
|
|
16
|
-
- **Accessible**: WCAG compliant focus rings,
|
|
56
|
+
- 🎨 **Material Design 3**: Fully tokenized CSS design tokens for dynamic theming, tonal color palettes, surface containers, elevations 0–5, and light/dark modes.
|
|
57
|
+
- 🧩 **23+ Core Components**: Complete suite including Top App Bars, Navigation Drawers, Data Tables, Media Players, Code Blocks/Linters, Search Bars, Form Elements, Dialogs, Cards, and more.
|
|
58
|
+
- 📋 **Form-Associated Custom Elements (FACE)**: Native `<form>` integration, `FormData` compatibility, and standard constraint validation (`required`, `checkValidity()`, `reportValidity()`).
|
|
59
|
+
- ⚡ **Lightweight & Tree-Shakeable**: Pure ESM modules with granular subpath exports (e.g. `@francofantomius/material-components/button`).
|
|
60
|
+
- 🔷 **TypeScript & Custom Elements Manifest**: First-class TypeScript declarations (`.d.ts`), inline sourcemaps, and standard `custom-elements.json` for IDE autocomplete.
|
|
61
|
+
- ♿ **Accessible (a11y)**: WCAG 2.1 AA compliant contrast ratios, high-visibility focus rings (`<md-focus-ring>`), keyboard navigation, and ARIA state handling.
|
|
62
|
+
- 🌐 **Framework Agnostic**: Works out of the box with React, Vue, Angular, Svelte, Solid, or vanilla HTML/JS.
|
|
17
63
|
|
|
18
64
|
---
|
|
19
65
|
|
|
20
66
|
## Installation
|
|
21
67
|
|
|
22
68
|
```bash
|
|
69
|
+
# npm
|
|
23
70
|
npm install @francofantomius/material-components lit
|
|
71
|
+
|
|
72
|
+
# pnpm
|
|
73
|
+
pnpm add @francofantomius/material-components lit
|
|
74
|
+
|
|
75
|
+
# yarn
|
|
76
|
+
yarn add @francofantomius/material-components lit
|
|
77
|
+
|
|
78
|
+
# bun
|
|
79
|
+
bun add @francofantomius/material-components lit
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## CDN Quick Start
|
|
85
|
+
|
|
86
|
+
For quick prototyping or usage directly in HTML without a bundler, import from an ESM CDN:
|
|
87
|
+
|
|
88
|
+
```html
|
|
89
|
+
<!DOCTYPE html>
|
|
90
|
+
<html lang="en">
|
|
91
|
+
<head>
|
|
92
|
+
<meta charset="UTF-8" />
|
|
93
|
+
<title>Material Components Demo</title>
|
|
94
|
+
<!-- Fonts & Icons -->
|
|
95
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
96
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" />
|
|
97
|
+
|
|
98
|
+
<!-- Import from CDN (esm.sh / jsdelivr / unpkg) -->
|
|
99
|
+
<script type="module" src="https://esm.sh/@francofantomius/material-components"></script>
|
|
100
|
+
</head>
|
|
101
|
+
<body>
|
|
102
|
+
<md-button variant="filled" icon="send">Get Started</md-button>
|
|
103
|
+
</body>
|
|
104
|
+
</html>
|
|
24
105
|
```
|
|
25
106
|
|
|
26
107
|
---
|
|
27
108
|
|
|
28
109
|
## Quick Start
|
|
29
110
|
|
|
30
|
-
### 1. Load Fonts and Icons (
|
|
31
|
-
|
|
111
|
+
### 1. Load Fonts and Icons (Recommended)
|
|
112
|
+
|
|
113
|
+
Add Google Roboto and Material Symbols Outlined to your HTML `<head>`:
|
|
114
|
+
|
|
32
115
|
```html
|
|
116
|
+
<!-- Material Symbols Outlined font -->
|
|
33
117
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
118
|
+
|
|
119
|
+
<!-- Roboto font -->
|
|
34
120
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" />
|
|
35
121
|
```
|
|
36
122
|
|
|
37
|
-
### 2. Import
|
|
123
|
+
### 2. Import Components
|
|
38
124
|
|
|
39
|
-
####
|
|
40
|
-
|
|
41
|
-
import '@francofantomius/material-components';
|
|
42
|
-
```
|
|
125
|
+
#### Granular Subpath Imports (Recommended for production)
|
|
126
|
+
Import only the components you use to optimize bundle sizes:
|
|
43
127
|
|
|
44
|
-
#### Tree-shakeable Subpath Imports (Recommended)
|
|
45
128
|
```typescript
|
|
46
129
|
import '@francofantomius/material-components/button';
|
|
47
130
|
import '@francofantomius/material-components/text-field';
|
|
48
|
-
import '@francofantomius/material-components/
|
|
131
|
+
import '@francofantomius/material-components/top-app-bar';
|
|
132
|
+
import '@francofantomius/material-components/navigation-drawer';
|
|
133
|
+
import '@francofantomius/material-components/table';
|
|
134
|
+
import '@francofantomius/material-components/search-bar';
|
|
135
|
+
import '@francofantomius/material-components/app-drawer';
|
|
136
|
+
import '@francofantomius/material-components/account-menu';
|
|
137
|
+
import '@francofantomius/material-components/code';
|
|
138
|
+
import '@francofantomius/material-components/player';
|
|
49
139
|
```
|
|
50
140
|
|
|
51
|
-
####
|
|
141
|
+
#### Global Bundle Import (Ideal for prototyping)
|
|
142
|
+
Registers all components at once:
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
import '@francofantomius/material-components';
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Component Index
|
|
151
|
+
|
|
152
|
+
| Category | Component Tag(s) | Subpath Export | Key Properties & Attributes |
|
|
153
|
+
| :--- | :--- | :--- | :--- |
|
|
154
|
+
| **Actions** | `<md-button>` | `/button` | `variant` (filled, elevated, tonal, outlined, text), `icon`, `trailing-icon`, `loading`, `disabled`, `href`, `target`, `type` |
|
|
155
|
+
| **Actions** | `<md-icon-button>` | `/icon-button` | `variant` (standard, filled, tonal, outlined), `icon`, `selected-icon`, `toggle`, `selected`, `disabled` |
|
|
156
|
+
| **Actions** | `<md-fab>` | `/fab` | `size` (small, medium, large), `label`, `icon`, `lowered`, `disabled` |
|
|
157
|
+
| **Actions** | `<md-icon>` | `/icon` | `name`, `filled`, `size` |
|
|
158
|
+
| **Inputs & Controls** | `<md-text-field>` | `/text-field` | `variant` (filled, outlined), `label`, `value`, `type`, `placeholder`, `prefix-text`, `suffix-text`, `error`, `error-text`, `supporting-text`, `leading-icon`, `trailing-icon`, `maxlength`, `required` |
|
|
159
|
+
| **Inputs & Controls** | `<md-checkbox>` | `/checkbox` | `checked`, `indeterminate`, `error`, `disabled`, `required`, `name`, `value` |
|
|
160
|
+
| **Inputs & Controls** | `<md-switch>` | `/switch` | `selected`, `icons`, `disabled`, `name`, `value` |
|
|
161
|
+
| **Inputs & Controls** | `<md-radio>`, `<md-radio-group>` | `/radio` | `checked`, `value`, `name`, `row`, `disabled` |
|
|
162
|
+
| **Inputs & Controls** | `<md-chip>`, `<md-chip-set>` | `/chip` | `variant` (assist, filter, input, suggestion), `label`, `icon`, `selected`, `removable`, `disabled` |
|
|
163
|
+
| **Inputs & Controls** | `<md-search-bar>`, `<md-search>` | `/search-bar` | `value`, `placeholder`, `active`, `suggestions`, `leading-icon`, `trailing-icon`, `responsive`, `collapse-on-mobile`, `fullscreen` |
|
|
164
|
+
| **Surfaces & Layout** | `<md-card>` | `/card` | `variant` (elevated, filled, outlined), `interactive`, `disabled`, `href`, `target` |
|
|
165
|
+
| **Surfaces & Layout** | `<md-dialog>` | `/dialog` | `open`, `headline`, `icon`, `cancelable`, `showModal()`, `close()` |
|
|
166
|
+
| **Surfaces & Layout** | `<md-divider>` | `/divider` | `vertical`, `inset`, `inset-start`, `inset-end` |
|
|
167
|
+
| **Surfaces & Layout** | `<md-list>`, `<md-list-item>` | `/list` | `headline`, `supporting-text`, `trailing-supporting-text`, `interactive`, `disabled`, `href` |
|
|
168
|
+
| **Surfaces & Layout** | `<md-table>`, `<md-data-table>` | `/table` | `columns`, `rows`, `selectable`, `sortable`, `paginated`, `page`, `page-size`, `bordered`, `striped`, `sticky-header`, `loading` |
|
|
169
|
+
| **Communication** | `<md-badge>` | `/badge` | `value`, `dot`, `max` |
|
|
170
|
+
| **Communication** | `<md-progress>` | `/progress` | `type` (linear, circular), `value` (0 to 1, or indeterminate), `buffer`, `wavy` |
|
|
171
|
+
| **Communication** | `<md-snackbar>` | `/snackbar` | `open`, `message`, `action-text`, `closeable`, `timeout-ms`, `stacked` |
|
|
172
|
+
| **Navigation** | `<md-top-app-bar>`, `<md-top-bar>` | `/top-app-bar` | `variant` (center-aligned, small, medium, large), `headline`, `subtitle`, `elevated`, `fixed` |
|
|
173
|
+
| **Navigation** | `<md-navigation-drawer>`, `<md-drawer>` | `/navigation-drawer` | `open`, `type` (modal, standard, responsive), `pivot` (left, right), `headline`, `responsive` |
|
|
174
|
+
| **Navigation** | `<md-tabs>`, `<md-tab>` | `/tabs` | `active-index`, `icon`, `label`, `secondary` |
|
|
175
|
+
| **Navigation** | `<md-app-drawer>`, `<md-app-launcher>` | `/app-drawer` | `open`, `headline`, `icon`, `columns`, `reorderable`, `editable`, `modal`, `alignment`, `pivot` |
|
|
176
|
+
| **Navigation** | `<md-account-menu>`, `<md-account-drawer>` | `/account-menu` | `open`, `name`, `email`, `avatar`, `initials`, `storage-used`, `storage-total`, `storage-progress`, `show-tabs`, `modal`, `alignment` |
|
|
177
|
+
| **Media & Dev Tools** | `<md-code>`, `<md-code-block>` | `/code` | `code`, `language`, `filename`, `line-numbers`, `highlight-lines`, `lint`, `copyable`, `wrap-lines`, `max-height` |
|
|
178
|
+
| **Media & Dev Tools** | `<md-player>`, `<md-media-player>` | `/player` | `type` (audio, video), `variant` (elevated, filled, outlined, compact, full), `src`, `track-title`, `artist`, `poster` |
|
|
179
|
+
| **Internal Helpers** | `<md-ripple>`, `<md-focus-ring>` | `/ripple`, `/focus-ring` | Interactive ripple effect & accessible WCAG focus indicator |
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Usage Examples
|
|
184
|
+
|
|
185
|
+
### Buttons, FABs & Icons
|
|
186
|
+
|
|
52
187
|
```html
|
|
53
|
-
<!-- Buttons
|
|
54
|
-
<md-button variant="filled" icon="send">
|
|
55
|
-
<md-button variant="
|
|
56
|
-
<md-
|
|
188
|
+
<!-- Buttons with 5 visual variants -->
|
|
189
|
+
<md-button variant="filled" icon="send">Send</md-button>
|
|
190
|
+
<md-button variant="elevated">Elevated</md-button>
|
|
191
|
+
<md-button variant="tonal">Tonal</md-button>
|
|
192
|
+
<md-button variant="outlined">Outlined</md-button>
|
|
193
|
+
<md-button variant="text">Text</md-button>
|
|
194
|
+
|
|
195
|
+
<!-- Loading State -->
|
|
196
|
+
<md-button variant="filled" loading>Saving...</md-button>
|
|
197
|
+
|
|
198
|
+
<!-- Icon Buttons (Standard, Filled, Tonal, Outlined, Toggle) -->
|
|
199
|
+
<md-icon-button icon="favorite" aria-label="Favorite"></md-icon-button>
|
|
200
|
+
<md-icon-button toggle icon="bookmark_border" selected-icon="bookmark" aria-label="Bookmark"></md-icon-button>
|
|
201
|
+
|
|
202
|
+
<!-- Floating Action Button -->
|
|
203
|
+
<md-fab icon="edit" label="Compose"></md-fab>
|
|
204
|
+
<md-fab size="small" icon="add" aria-label="Add"></md-fab>
|
|
205
|
+
|
|
206
|
+
<!-- Material Symbols Icon -->
|
|
207
|
+
<md-icon name="star" filled></md-icon>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Form Controls (Native Form Association)
|
|
211
|
+
|
|
212
|
+
All input components are **Form-Associated Custom Elements (FACE)** that natively integrate with standard `<form>` submission, reset, and `FormData`.
|
|
57
213
|
|
|
58
|
-
|
|
214
|
+
```html
|
|
59
215
|
<form id="login-form">
|
|
60
|
-
<md-text-field
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
216
|
+
<md-text-field
|
|
217
|
+
label="Full Name"
|
|
218
|
+
name="name"
|
|
219
|
+
required
|
|
220
|
+
leading-icon="person"
|
|
221
|
+
supporting-text="Your legal name"
|
|
222
|
+
></md-text-field>
|
|
223
|
+
|
|
224
|
+
<md-text-field
|
|
225
|
+
label="Email"
|
|
226
|
+
name="email"
|
|
227
|
+
type="email"
|
|
228
|
+
required
|
|
229
|
+
leading-icon="email"
|
|
230
|
+
></md-text-field>
|
|
231
|
+
|
|
232
|
+
<md-checkbox name="newsletter" checked>
|
|
233
|
+
Subscribe to newsletter
|
|
234
|
+
</md-checkbox>
|
|
235
|
+
|
|
236
|
+
<md-switch name="notifications" selected icons>
|
|
237
|
+
Enable notifications
|
|
238
|
+
</md-switch>
|
|
239
|
+
|
|
240
|
+
<md-radio-group name="tier" value="pro">
|
|
241
|
+
<md-radio value="free" label="Free"></md-radio>
|
|
242
|
+
<md-radio value="pro" label="Pro"></md-radio>
|
|
243
|
+
</md-radio-group>
|
|
244
|
+
|
|
245
|
+
<div style="display: flex; gap: 8px; margin-top: 16px;">
|
|
246
|
+
<md-button type="reset" variant="outlined">Reset</md-button>
|
|
247
|
+
<md-button type="submit" variant="filled">Log In</md-button>
|
|
248
|
+
</div>
|
|
64
249
|
</form>
|
|
250
|
+
```
|
|
65
251
|
|
|
66
|
-
|
|
67
|
-
<md-card variant="outlined" interactive>
|
|
68
|
-
<div slot="header">
|
|
69
|
-
<h3>Card Title</h3>
|
|
70
|
-
</div>
|
|
71
|
-
Card body content here.
|
|
72
|
-
<div slot="actions">
|
|
73
|
-
<md-button variant="text">Dismiss</md-button>
|
|
74
|
-
<md-button variant="filled">Open</md-button>
|
|
75
|
-
</div>
|
|
76
|
-
</md-card>
|
|
252
|
+
### Navigation & Top App Bar
|
|
77
253
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
<
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
</md-
|
|
254
|
+
```html
|
|
255
|
+
<!-- Top App Bar -->
|
|
256
|
+
<md-top-app-bar variant="center-aligned" headline="My Application">
|
|
257
|
+
<md-icon-button slot="navigation" icon="menu" aria-label="Open menu"></md-icon-button>
|
|
258
|
+
<md-icon-button slot="actions" icon="search" aria-label="Search"></md-icon-button>
|
|
259
|
+
<md-icon-button slot="actions" icon="account_circle" aria-label="Account"></md-icon-button>
|
|
260
|
+
</md-top-app-bar>
|
|
261
|
+
|
|
262
|
+
<!-- Navigation Drawer -->
|
|
263
|
+
<md-navigation-drawer headline="Navigation" type="modal" id="nav-drawer">
|
|
264
|
+
<md-navigation-drawer-item icon="inbox" label="Inbox" badge="24" active></md-navigation-drawer-item>
|
|
265
|
+
<md-navigation-drawer-item icon="send" label="Outbox"></md-navigation-drawer-item>
|
|
266
|
+
<md-navigation-drawer-item icon="favorite" label="Favorites"></md-navigation-drawer-item>
|
|
267
|
+
<md-navigation-drawer-item icon="settings" label="Settings"></md-navigation-drawer-item>
|
|
268
|
+
</md-navigation-drawer>
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### App Drawer & Account Menu
|
|
272
|
+
|
|
273
|
+
```html
|
|
274
|
+
<!-- Google Apps style Launcher Grid -->
|
|
275
|
+
<md-app-drawer headline="Apps">
|
|
276
|
+
<md-app-drawer-item icon="mail" label="Mail" badge="3"></md-app-drawer-item>
|
|
277
|
+
<md-app-drawer-item icon="calendar_today" label="Calendar"></md-app-drawer-item>
|
|
278
|
+
<md-app-drawer-item icon="folder" label="Drive"></md-app-drawer-item>
|
|
279
|
+
</md-app-drawer>
|
|
280
|
+
|
|
281
|
+
<!-- Account Menu & Switcher -->
|
|
282
|
+
<md-account-menu
|
|
283
|
+
name="Franco Fantomius"
|
|
284
|
+
email="franco.fantomius@example.com"
|
|
285
|
+
initials="F"
|
|
286
|
+
role-title="Lead Architect"
|
|
287
|
+
organization="Material Components Team"
|
|
288
|
+
storage-used="10.4 GB"
|
|
289
|
+
storage-total="15 GB"
|
|
290
|
+
storage-progress="0.69"
|
|
291
|
+
>
|
|
292
|
+
<md-account-item slot="accounts" name="Franco Fantomius" email="franco.fantomius@example.com" initials="F" active></md-account-item>
|
|
293
|
+
<md-account-item slot="accounts" name="Work Profile" email="franco@company.com" initials="W"></md-account-item>
|
|
294
|
+
</md-account-menu>
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Data Table
|
|
298
|
+
|
|
299
|
+
```html
|
|
300
|
+
<md-table bordered striped hoverable id="my-table"></md-table>
|
|
301
|
+
|
|
302
|
+
<script>
|
|
303
|
+
const table = document.getElementById('my-table');
|
|
304
|
+
table.columns = [
|
|
305
|
+
{ key: 'name', label: 'User', sortable: true },
|
|
306
|
+
{ key: 'role', label: 'Role', sortable: true },
|
|
307
|
+
{ key: 'score', label: 'Score', numeric: true, sortable: true }
|
|
308
|
+
];
|
|
309
|
+
table.rows = [
|
|
310
|
+
{ name: 'Alice Smith', role: 'Admin', score: 98 },
|
|
311
|
+
{ name: 'Bob Jones', role: 'Developer', score: 85 }
|
|
312
|
+
];
|
|
313
|
+
table.selectable = true;
|
|
314
|
+
table.paginated = true;
|
|
315
|
+
</script>
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Search Bar with Live Suggestions
|
|
319
|
+
|
|
320
|
+
```html
|
|
321
|
+
<md-search-bar placeholder="Search products..." id="search-bar" responsive></md-search-bar>
|
|
322
|
+
|
|
323
|
+
<script>
|
|
324
|
+
const search = document.getElementById('search-bar');
|
|
325
|
+
search.suggestions = [
|
|
326
|
+
{ label: 'Documentation', icon: 'description', supportingText: 'Getting started guide' },
|
|
327
|
+
{ label: 'Component Gallery', icon: 'widgets', supportingText: 'Explore all 23 components' }
|
|
328
|
+
];
|
|
329
|
+
search.addEventListener('search', (e) => console.log('Query:', e.detail.value));
|
|
330
|
+
</script>
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Code Block & Syntax Linter
|
|
334
|
+
|
|
335
|
+
```html
|
|
336
|
+
<md-code
|
|
337
|
+
language="typescript"
|
|
338
|
+
filename="example.ts"
|
|
339
|
+
line-numbers
|
|
340
|
+
highlight-lines="2, 4-5"
|
|
341
|
+
lint
|
|
342
|
+
copyable
|
|
343
|
+
code="const greeting: string = 'Hello, world!';\nconsole.log(greeting);"
|
|
344
|
+
></md-code>
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Media Player (Audio & Video)
|
|
348
|
+
|
|
349
|
+
```html
|
|
350
|
+
<!-- Audio Player -->
|
|
351
|
+
<md-player
|
|
352
|
+
type="audio"
|
|
353
|
+
src="https://example.com/audio.mp3"
|
|
354
|
+
track-title="Ambient Soundscape"
|
|
355
|
+
artist="Sound Design"
|
|
356
|
+
></md-player>
|
|
357
|
+
|
|
358
|
+
<!-- Video Player -->
|
|
359
|
+
<md-player
|
|
360
|
+
type="video"
|
|
361
|
+
src="https://example.com/video.mp4"
|
|
362
|
+
poster="https://example.com/poster.jpg"
|
|
363
|
+
track-title="Product Demo"
|
|
364
|
+
></md-player>
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## Form Integration (FACE)
|
|
370
|
+
|
|
371
|
+
Form elements (`<md-text-field>`, `<md-checkbox>`, `<md-switch>`, `<md-radio>`) use standard browser `ElementInternals`. They participate seamlessly in form life-cycles:
|
|
372
|
+
|
|
373
|
+
```javascript
|
|
374
|
+
const form = document.getElementById('login-form');
|
|
375
|
+
|
|
376
|
+
form.addEventListener('submit', (e) => {
|
|
377
|
+
e.preventDefault();
|
|
378
|
+
|
|
379
|
+
if (!form.checkValidity()) {
|
|
380
|
+
form.reportValidity();
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const formData = new FormData(form);
|
|
385
|
+
console.log('Payload:', Object.fromEntries(formData.entries()));
|
|
386
|
+
});
|
|
85
387
|
```
|
|
86
388
|
|
|
87
389
|
---
|
|
@@ -89,12 +391,15 @@ import '@francofantomius/material-components/card';
|
|
|
89
391
|
## Theming and Dark Mode
|
|
90
392
|
|
|
91
393
|
### Dynamic Theming via CSS Custom Properties
|
|
92
|
-
|
|
394
|
+
|
|
395
|
+
The library uses standard Material Design 3 design tokens. Override them globally on `:root` or scope them to any container:
|
|
93
396
|
|
|
94
397
|
```css
|
|
95
398
|
:root {
|
|
96
399
|
--md-sys-color-primary: #6750A4;
|
|
97
400
|
--md-sys-color-on-primary: #FFFFFF;
|
|
401
|
+
--md-sys-color-primary-container: #EADDFF;
|
|
402
|
+
--md-sys-color-on-primary-container: #21005D;
|
|
98
403
|
--md-sys-color-surface: #FEF7FF;
|
|
99
404
|
--md-sys-color-on-surface: #1D1B20;
|
|
100
405
|
}
|
|
@@ -102,88 +407,243 @@ The library uses standard CSS custom properties adhering to Material 3 specs:
|
|
|
102
407
|
[data-theme='dark'] {
|
|
103
408
|
--md-sys-color-primary: #D0BCFF;
|
|
104
409
|
--md-sys-color-on-primary: #381E72;
|
|
410
|
+
--md-sys-color-primary-container: #4F378B;
|
|
411
|
+
--md-sys-color-on-primary-container: #EADDFF;
|
|
105
412
|
--md-sys-color-surface: #141218;
|
|
106
413
|
--md-sys-color-on-surface: #E6E0E9;
|
|
107
414
|
}
|
|
108
415
|
```
|
|
109
416
|
|
|
110
417
|
### TypeScript Theme Helper
|
|
418
|
+
|
|
111
419
|
```typescript
|
|
112
|
-
import { applyTheme, darkColorScheme } from '@francofantomius/material-components/theme';
|
|
420
|
+
import { applyTheme, darkColorScheme, lightColorScheme } from '@francofantomius/material-components/theme';
|
|
113
421
|
|
|
114
|
-
//
|
|
422
|
+
// Switch to dark theme
|
|
115
423
|
applyTheme(darkColorScheme);
|
|
116
424
|
|
|
117
|
-
//
|
|
425
|
+
// Switch back to light theme
|
|
426
|
+
applyTheme(lightColorScheme);
|
|
427
|
+
|
|
428
|
+
// Apply custom brand palette
|
|
118
429
|
applyTheme({
|
|
119
430
|
primary: '#006A60',
|
|
120
431
|
onPrimary: '#FFFFFF',
|
|
432
|
+
primaryContainer: '#74F8E5',
|
|
433
|
+
onPrimaryContainer: '#00201C',
|
|
121
434
|
});
|
|
122
435
|
```
|
|
123
436
|
|
|
124
437
|
---
|
|
125
438
|
|
|
126
|
-
##
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
439
|
+
## Subpath Exports Reference
|
|
440
|
+
|
|
441
|
+
Each component can be imported individually with full TypeScript type definitions:
|
|
442
|
+
|
|
443
|
+
```typescript
|
|
444
|
+
import { applyTheme } from '@francofantomius/material-components/theme';
|
|
445
|
+
import { MdButton } from '@francofantomius/material-components/button';
|
|
446
|
+
import { MdIconButton } from '@francofantomius/material-components/icon-button';
|
|
447
|
+
import { MdFab } from '@francofantomius/material-components/fab';
|
|
448
|
+
import { MdIcon } from '@francofantomius/material-components/icon';
|
|
449
|
+
import { MdTextField } from '@francofantomius/material-components/text-field';
|
|
450
|
+
import { MdCheckbox } from '@francofantomius/material-components/checkbox';
|
|
451
|
+
import { MdSwitch } from '@francofantomius/material-components/switch';
|
|
452
|
+
import { MdRadio, MdRadioGroup } from '@francofantomius/material-components/radio';
|
|
453
|
+
import { MdCard } from '@francofantomius/material-components/card';
|
|
454
|
+
import { MdDialog } from '@francofantomius/material-components/dialog';
|
|
455
|
+
import { MdDivider } from '@francofantomius/material-components/divider';
|
|
456
|
+
import { MdProgress } from '@francofantomius/material-components/progress';
|
|
457
|
+
import { MdBadge } from '@francofantomius/material-components/badge';
|
|
458
|
+
import { MdChip, MdChipSet } from '@francofantomius/material-components/chip';
|
|
459
|
+
import { MdTabs, MdTab } from '@francofantomius/material-components/tabs';
|
|
460
|
+
import { MdList, MdListItem } from '@francofantomius/material-components/list';
|
|
461
|
+
import { MdSnackbar } from '@francofantomius/material-components/snackbar';
|
|
462
|
+
import { MdTopAppBar, MdTopBar } from '@francofantomius/material-components/top-app-bar';
|
|
463
|
+
import { MdNavigationDrawer, MdDrawer, MdMenuBar, MdNavigationDrawerItem } from '@francofantomius/material-components/navigation-drawer';
|
|
464
|
+
import { MdAppDrawer, MdAppDrawerItem, MdAppLauncher, MdAppsMenu } from '@francofantomius/material-components/app-drawer';
|
|
465
|
+
import { MdAccountMenu, MdAccountItem, MdAccountDrawer, MdAccountProfile } from '@francofantomius/material-components/account-menu';
|
|
466
|
+
import { MdTable, MdDataTable, MdTableHeaderCell, MdTableCell, MdTableRow } from '@francofantomius/material-components/table';
|
|
467
|
+
import { MdSearchBar, MdSearch } from '@francofantomius/material-components/search-bar';
|
|
468
|
+
import { MdCode, MdCodeBlock } from '@francofantomius/material-components/code';
|
|
469
|
+
import { MdPlayer, MdMediaPlayer, MdAudioPlayer, MdVideoPlayer } from '@francofantomius/material-components/player';
|
|
470
|
+
```
|
|
146
471
|
|
|
147
472
|
---
|
|
148
473
|
|
|
149
|
-
##
|
|
474
|
+
## Framework Integration
|
|
475
|
+
|
|
476
|
+
Because Web Components are standard custom elements, they work natively across all frameworks:
|
|
477
|
+
|
|
478
|
+
### React
|
|
479
|
+
|
|
480
|
+
#### React 19
|
|
481
|
+
React 19 supports Custom Elements natively (attributes, properties, and custom events):
|
|
482
|
+
|
|
483
|
+
```tsx
|
|
484
|
+
import '@francofantomius/material-components/button';
|
|
485
|
+
import '@francofantomius/material-components/text-field';
|
|
486
|
+
import '@francofantomius/material-components/switch';
|
|
487
|
+
|
|
488
|
+
export function SettingsForm() {
|
|
489
|
+
return (
|
|
490
|
+
<div>
|
|
491
|
+
<md-text-field
|
|
492
|
+
label="Username"
|
|
493
|
+
onInput={(e: any) => console.log(e.target.value)}
|
|
494
|
+
/>
|
|
495
|
+
<md-switch
|
|
496
|
+
selected
|
|
497
|
+
onChange={(e: any) => console.log(e.target.selected)}
|
|
498
|
+
>
|
|
499
|
+
Enable Notifications
|
|
500
|
+
</md-switch>
|
|
501
|
+
<md-button variant="filled" onClick={() => alert('Saved!')}>
|
|
502
|
+
Save
|
|
503
|
+
</md-button>
|
|
504
|
+
</div>
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
#### React 18 / Next.js
|
|
510
|
+
In React 18, assign complex object/array properties (such as `table.columns` or `search.suggestions`) via React `ref`:
|
|
511
|
+
|
|
512
|
+
```tsx
|
|
513
|
+
import React, { useRef, useEffect } from 'react';
|
|
514
|
+
import '@francofantomius/material-components/table';
|
|
515
|
+
|
|
516
|
+
export function UserTable({ users }) {
|
|
517
|
+
const tableRef = useRef<any>(null);
|
|
518
|
+
|
|
519
|
+
useEffect(() => {
|
|
520
|
+
if (tableRef.current) {
|
|
521
|
+
tableRef.current.columns = [
|
|
522
|
+
{ key: 'name', label: 'Name', sortable: true },
|
|
523
|
+
{ key: 'email', label: 'Email' }
|
|
524
|
+
];
|
|
525
|
+
tableRef.current.rows = users;
|
|
526
|
+
}
|
|
527
|
+
}, [users]);
|
|
528
|
+
|
|
529
|
+
return <md-table ref={tableRef} bordered hoverable />;
|
|
530
|
+
}
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
### Vue
|
|
534
|
+
|
|
535
|
+
In Vue 3 / Nuxt, configure compiler options so Vue doesn't treat `md-*` elements as missing components:
|
|
536
|
+
|
|
537
|
+
```javascript
|
|
538
|
+
// vite.config.js
|
|
539
|
+
import { defineConfig } from 'vite';
|
|
540
|
+
import vue from '@vitejs/plugin-vue';
|
|
541
|
+
|
|
542
|
+
export default defineConfig({
|
|
543
|
+
plugins: [
|
|
544
|
+
vue({
|
|
545
|
+
template: {
|
|
546
|
+
compilerOptions: {
|
|
547
|
+
isCustomElement: (tag) => tag.startsWith('md-')
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
})
|
|
551
|
+
]
|
|
552
|
+
});
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
```vue
|
|
556
|
+
<script setup>
|
|
557
|
+
import { ref } from 'vue';
|
|
558
|
+
import '@francofantomius/material-components/button';
|
|
559
|
+
import '@francofantomius/material-components/switch';
|
|
560
|
+
|
|
561
|
+
const isEnabled = ref(true);
|
|
562
|
+
</script>
|
|
563
|
+
|
|
564
|
+
<template>
|
|
565
|
+
<div>
|
|
566
|
+
<md-switch :selected="isEnabled" @change="isEnabled = !isEnabled">
|
|
567
|
+
Enable Feature
|
|
568
|
+
</md-switch>
|
|
569
|
+
<md-button variant="filled" :disabled="!isEnabled">
|
|
570
|
+
Proceed
|
|
571
|
+
</md-button>
|
|
572
|
+
</div>
|
|
573
|
+
</template>
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
### Angular
|
|
577
|
+
|
|
578
|
+
Include `CUSTOM_ELEMENTS_SCHEMA` in your standalone component or `@NgModule`:
|
|
579
|
+
|
|
580
|
+
```typescript
|
|
581
|
+
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
582
|
+
import '@francofantomius/material-components/button';
|
|
583
|
+
|
|
584
|
+
@Component({
|
|
585
|
+
selector: 'app-root',
|
|
586
|
+
standalone: true,
|
|
587
|
+
template: `<md-button variant="filled">Click Me</md-button>`,
|
|
588
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
|
589
|
+
})
|
|
590
|
+
export class AppComponent {}
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
### Svelte
|
|
594
|
+
|
|
595
|
+
Custom elements work out-of-the-box with standard Svelte bindings:
|
|
596
|
+
|
|
597
|
+
```svelte
|
|
598
|
+
<script>
|
|
599
|
+
import '@francofantomius/material-components/button';
|
|
600
|
+
import '@francofantomius/material-components/text-field';
|
|
601
|
+
|
|
602
|
+
let name = '';
|
|
603
|
+
</script>
|
|
604
|
+
|
|
605
|
+
<md-text-field label="Name" value={name} on:input={(e) => name = e.target.value}></md-text-field>
|
|
606
|
+
<md-button variant="filled" on:click={() => alert(`Hello ${name}`)}>Submit</md-button>
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
---
|
|
610
|
+
|
|
611
|
+
## LLM & AI Assistant Documentation
|
|
612
|
+
|
|
613
|
+
This repository provides an [`llms.txt`](./llms.txt) file structured for AI coding assistants (such as Antigravity, Cursor, GitHub Copilot, ChatGPT, and Claude). It provides complete API specifications, component hierarchies, and ready-to-use code patterns.
|
|
614
|
+
|
|
615
|
+
---
|
|
616
|
+
|
|
617
|
+
## Development Scripts
|
|
150
618
|
|
|
151
619
|
```bash
|
|
152
|
-
# Start local
|
|
620
|
+
# Start local development playground & documentation
|
|
153
621
|
npm run dev
|
|
154
622
|
|
|
155
|
-
#
|
|
156
|
-
npm run docs:dev
|
|
157
|
-
|
|
158
|
-
# Run unit tests
|
|
623
|
+
# Run unit tests with Vitest
|
|
159
624
|
npm test
|
|
160
625
|
|
|
161
|
-
# Type
|
|
626
|
+
# Type-check TypeScript codebase
|
|
162
627
|
npm run typecheck
|
|
163
628
|
|
|
164
|
-
# Build library &
|
|
629
|
+
# Build ESM library, docs & generate Custom Elements Manifest
|
|
165
630
|
npm run build
|
|
166
631
|
|
|
167
|
-
#
|
|
168
|
-
npm run
|
|
632
|
+
# Preview documentation site build
|
|
633
|
+
npm run preview
|
|
169
634
|
```
|
|
170
635
|
|
|
171
636
|
---
|
|
172
637
|
|
|
173
|
-
## Automated Publishing
|
|
638
|
+
## Automated Publishing (Trusted Publishing)
|
|
174
639
|
|
|
175
|
-
This repository
|
|
640
|
+
This repository is configured for **npm Trusted Publishing** using GitHub Actions OpenID Connect (OIDC).
|
|
176
641
|
|
|
177
642
|
### How it works:
|
|
178
|
-
1. When
|
|
179
|
-
2. It queries npm to
|
|
180
|
-
3. If the version is new, it
|
|
181
|
-
4. It creates a Git tag `v<version>`
|
|
182
|
-
|
|
183
|
-
### Setup requirement:
|
|
184
|
-
Add your npm automation token as a secret in your GitHub repository:
|
|
185
|
-
- Go to **Settings > Secrets and variables > Actions**
|
|
186
|
-
- Add secret **`NPM_TOKEN`** with an npm Automation / Publish token.
|
|
643
|
+
1. When changes are merged to `main`, the CI workflow checks the `version` field in `package.json`.
|
|
644
|
+
2. It queries npm to verify if this version is already published.
|
|
645
|
+
3. If the version is new, it executes type checking, automated tests, builds the library, exchanges an OIDC token with npm, and publishes the package with cryptographic provenance (`--provenance`).
|
|
646
|
+
4. It automatically creates a Git release and tag (`v<version>`).
|
|
187
647
|
|
|
188
648
|
---
|
|
189
649
|
|