@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.
Files changed (166) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +550 -90
  3. package/custom-elements.json +21010 -2354
  4. package/dist/chunks/badge-G4EjcMoy.js +89 -0
  5. package/dist/chunks/badge-G4EjcMoy.js.map +1 -0
  6. package/dist/chunks/button-B4TSZ7Sl.js +250 -0
  7. package/dist/chunks/button-B4TSZ7Sl.js.map +1 -0
  8. package/dist/chunks/card-DVffdPpv.js +163 -0
  9. package/dist/chunks/card-DVffdPpv.js.map +1 -0
  10. package/dist/chunks/checkbox-BqlboAHd.js +194 -0
  11. package/dist/chunks/checkbox-BqlboAHd.js.map +1 -0
  12. package/dist/chunks/chip-CI1ZINnr.js +169 -0
  13. package/dist/chunks/chip-CI1ZINnr.js.map +1 -0
  14. package/dist/chunks/code-C5UFBkCh.js +1830 -0
  15. package/dist/chunks/code-C5UFBkCh.js.map +1 -0
  16. package/dist/chunks/decorate-DXuynaiA.js +39 -0
  17. package/dist/chunks/decorate-DXuynaiA.js.map +1 -0
  18. package/dist/chunks/dialog-DGVEE5m_.js +158 -0
  19. package/dist/chunks/dialog-DGVEE5m_.js.map +1 -0
  20. package/dist/chunks/divider-DNepwoZv.js +82 -0
  21. package/dist/chunks/divider-DNepwoZv.js.map +1 -0
  22. package/dist/chunks/fab-C9j3WBHE.js +150 -0
  23. package/dist/chunks/fab-C9j3WBHE.js.map +1 -0
  24. package/dist/chunks/focus-ring-CuiJuM-y.js +71 -0
  25. package/dist/chunks/focus-ring-CuiJuM-y.js.map +1 -0
  26. package/dist/chunks/{form-associated-fKbeX_2P.js → form-associated-Cty_ZaS9.js} +26 -27
  27. package/dist/chunks/form-associated-Cty_ZaS9.js.map +1 -0
  28. package/dist/chunks/icon-DrNqcNEL.js +62 -0
  29. package/dist/chunks/icon-DrNqcNEL.js.map +1 -0
  30. package/dist/chunks/icon-button-BdSc7eot.js +188 -0
  31. package/dist/chunks/icon-button-BdSc7eot.js.map +1 -0
  32. package/dist/chunks/list-D8olR7oZ.js +204 -0
  33. package/dist/chunks/list-D8olR7oZ.js.map +1 -0
  34. package/dist/chunks/navigation-drawer-CKl44Ef5.js +531 -0
  35. package/dist/chunks/navigation-drawer-CKl44Ef5.js.map +1 -0
  36. package/dist/chunks/player-C4ydiIpr.js +1582 -0
  37. package/dist/chunks/player-C4ydiIpr.js.map +1 -0
  38. package/dist/chunks/progress-LQmLMDjX.js +266 -0
  39. package/dist/chunks/progress-LQmLMDjX.js.map +1 -0
  40. package/dist/chunks/radio-Bily78NT.js +205 -0
  41. package/dist/chunks/radio-Bily78NT.js.map +1 -0
  42. package/dist/chunks/ripple-squbKHhj.js +135 -0
  43. package/dist/chunks/ripple-squbKHhj.js.map +1 -0
  44. package/dist/chunks/search-bar-TXnqJ-gd.js +698 -0
  45. package/dist/chunks/search-bar-TXnqJ-gd.js.map +1 -0
  46. package/dist/chunks/snackbar-Wsz3BzEY.js +161 -0
  47. package/dist/chunks/snackbar-Wsz3BzEY.js.map +1 -0
  48. package/dist/chunks/switch-DdukrvXb.js +190 -0
  49. package/dist/chunks/switch-DdukrvXb.js.map +1 -0
  50. package/dist/chunks/table-aRTYzDyE.js +773 -0
  51. package/dist/chunks/table-aRTYzDyE.js.map +1 -0
  52. package/dist/chunks/tabs-BfOtoeir.js +191 -0
  53. package/dist/chunks/tabs-BfOtoeir.js.map +1 -0
  54. package/dist/chunks/text-field-hN6-2HQy.js +338 -0
  55. package/dist/chunks/text-field-hN6-2HQy.js.map +1 -0
  56. package/dist/chunks/top-app-bar-Dgbp6CFv.js +228 -0
  57. package/dist/chunks/top-app-bar-Dgbp6CFv.js.map +1 -0
  58. package/dist/components/account-menu/account-menu.css.d.ts +3 -0
  59. package/dist/components/account-menu/account-menu.css.d.ts.map +1 -0
  60. package/dist/components/account-menu/account-menu.d.ts +111 -0
  61. package/dist/components/account-menu/account-menu.d.ts.map +1 -0
  62. package/dist/components/app-drawer/app-drawer.css.d.ts +3 -0
  63. package/dist/components/app-drawer/app-drawer.css.d.ts.map +1 -0
  64. package/dist/components/app-drawer/app-drawer.d.ts +173 -0
  65. package/dist/components/app-drawer/app-drawer.d.ts.map +1 -0
  66. package/dist/components/badge/badge.js +2 -91
  67. package/dist/components/button/button.js +2 -261
  68. package/dist/components/card/card.js +2 -167
  69. package/dist/components/checkbox/checkbox.css.d.ts.map +1 -1
  70. package/dist/components/checkbox/checkbox.js +2 -186
  71. package/dist/components/chip/chip.js +3 -172
  72. package/dist/components/code/code.css.d.ts +2 -0
  73. package/dist/components/code/code.css.d.ts.map +1 -0
  74. package/dist/components/code/code.d.ts +106 -0
  75. package/dist/components/code/code.d.ts.map +1 -0
  76. package/dist/components/code/code.js +5 -0
  77. package/dist/components/code/highlighter.d.ts +8 -0
  78. package/dist/components/code/highlighter.d.ts.map +1 -0
  79. package/dist/components/code/linter.d.ts +44 -0
  80. package/dist/components/code/linter.d.ts.map +1 -0
  81. package/dist/components/dialog/dialog.js +2 -165
  82. package/dist/components/divider/divider.js +2 -79
  83. package/dist/components/fab/fab.js +2 -153
  84. package/dist/components/icon/icon.js +2 -68
  85. package/dist/components/icon-button/icon-button.css.d.ts.map +1 -1
  86. package/dist/components/icon-button/icon-button.js +1 -189
  87. package/dist/components/list/list.css.d.ts.map +1 -1
  88. package/dist/components/list/list.d.ts.map +1 -1
  89. package/dist/components/list/list.js +3 -188
  90. package/dist/components/navigation-drawer/navigation-drawer.css.d.ts +3 -0
  91. package/dist/components/navigation-drawer/navigation-drawer.css.d.ts.map +1 -0
  92. package/dist/components/navigation-drawer/navigation-drawer.d.ts +76 -0
  93. package/dist/components/navigation-drawer/navigation-drawer.d.ts.map +1 -0
  94. package/dist/components/navigation-drawer/navigation-drawer.js +8 -0
  95. package/dist/components/player/player.css.d.ts +2 -0
  96. package/dist/components/player/player.css.d.ts.map +1 -0
  97. package/dist/components/player/player.d.ts +99 -0
  98. package/dist/components/player/player.d.ts.map +1 -0
  99. package/dist/components/player/player.js +7 -0
  100. package/dist/components/progress/progress.css.d.ts.map +1 -1
  101. package/dist/components/progress/progress.d.ts +2 -0
  102. package/dist/components/progress/progress.d.ts.map +1 -1
  103. package/dist/components/progress/progress.js +3 -181
  104. package/dist/components/radio/radio.css.d.ts.map +1 -1
  105. package/dist/components/radio/radio.js +3 -203
  106. package/dist/components/search-bar/search-bar.css.d.ts +2 -0
  107. package/dist/components/search-bar/search-bar.css.d.ts.map +1 -0
  108. package/dist/components/search-bar/search-bar.d.ts +81 -0
  109. package/dist/components/search-bar/search-bar.d.ts.map +1 -0
  110. package/dist/components/search-bar/search-bar.js +5 -0
  111. package/dist/components/snackbar/snackbar.js +2 -162
  112. package/dist/components/switch/switch.css.d.ts.map +1 -1
  113. package/dist/components/switch/switch.js +2 -169
  114. package/dist/components/table/table.css.d.ts +8 -0
  115. package/dist/components/table/table.css.d.ts.map +1 -0
  116. package/dist/components/table/table.d.ts +158 -0
  117. package/dist/components/table/table.d.ts.map +1 -0
  118. package/dist/components/table/table.js +13 -0
  119. package/dist/components/tabs/tabs.js +3 -198
  120. package/dist/components/text-field/text-field.css.d.ts.map +1 -1
  121. package/dist/components/text-field/text-field.d.ts +1 -1
  122. package/dist/components/text-field/text-field.d.ts.map +1 -1
  123. package/dist/components/text-field/text-field.js +2 -325
  124. package/dist/components/top-app-bar/top-app-bar.css.d.ts +2 -0
  125. package/dist/components/top-app-bar/top-app-bar.css.d.ts.map +1 -0
  126. package/dist/components/top-app-bar/top-app-bar.d.ts +29 -0
  127. package/dist/components/top-app-bar/top-app-bar.d.ts.map +1 -0
  128. package/dist/components/top-app-bar/top-app-bar.js +5 -0
  129. package/dist/index.d.ts +8 -0
  130. package/dist/index.d.ts.map +1 -1
  131. package/dist/index.js +2264 -58
  132. package/dist/index.js.map +1 -1
  133. package/dist/internal/focus-ring/focus-ring.d.ts.map +1 -1
  134. package/dist/internal/focus-ring/focus-ring.js +4 -0
  135. package/dist/internal/ripple/ripple.css.d.ts.map +1 -1
  136. package/dist/internal/ripple/ripple.d.ts +0 -3
  137. package/dist/internal/ripple/ripple.d.ts.map +1 -1
  138. package/dist/internal/ripple/ripple.js +2 -142
  139. package/dist/tokens/index.js +336 -11
  140. package/dist/tokens/index.js.map +1 -1
  141. package/package.json +118 -12
  142. package/dist/chunks/base-component-DQTjlEVL.js +0 -34
  143. package/dist/chunks/base-component-DQTjlEVL.js.map +0 -1
  144. package/dist/chunks/focus-ring-Dl-XoEKK.js +0 -71
  145. package/dist/chunks/focus-ring-Dl-XoEKK.js.map +0 -1
  146. package/dist/chunks/form-associated-fKbeX_2P.js.map +0 -1
  147. package/dist/chunks/theme.css-DV3DRha-.js +0 -263
  148. package/dist/chunks/theme.css-DV3DRha-.js.map +0 -1
  149. package/dist/components/badge/badge.js.map +0 -1
  150. package/dist/components/button/button.js.map +0 -1
  151. package/dist/components/card/card.js.map +0 -1
  152. package/dist/components/checkbox/checkbox.js.map +0 -1
  153. package/dist/components/chip/chip.js.map +0 -1
  154. package/dist/components/dialog/dialog.js.map +0 -1
  155. package/dist/components/divider/divider.js.map +0 -1
  156. package/dist/components/fab/fab.js.map +0 -1
  157. package/dist/components/icon/icon.js.map +0 -1
  158. package/dist/components/icon-button/icon-button.js.map +0 -1
  159. package/dist/components/list/list.js.map +0 -1
  160. package/dist/components/progress/progress.js.map +0 -1
  161. package/dist/components/radio/radio.js.map +0 -1
  162. package/dist/components/snackbar/snackbar.js.map +0 -1
  163. package/dist/components/switch/switch.js.map +0 -1
  164. package/dist/components/tabs/tabs.js.map +0 -1
  165. package/dist/components/text-field/text-field.js.map +0 -1
  166. 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
- A modern, accessible, and lightweight **Material Design 3 (M3)** Web Components library built with [Lit](https://lit.dev/).
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
- Works natively across all modern browsers and seamlessly integrates with **React**, **Vue**, **Angular**, **Svelte**, **Solid**, or plain HTML.
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 (Light/Dark mode and custom color palettes).
12
- - **16+ Core Components**: Buttons, Text Fields, Checkboxes, Switches, Radio Groups, Cards, Dialogs, Progress, Badges, Chips, Tabs, Lists, Snackbars, and more.
13
- - **Form-Associated Custom Elements (FACE)**: Inputs directly integrate with native `<form>` elements, form validation, and `FormData`.
14
- - **Lightweight and Tree-Shakeable**: Pure ESM with subpath exports (`@francofantomius/material-components/button`).
15
- - **TypeScript and IDE Autocomplete**: Full TypeScript types and Custom Elements Manifest (`custom-elements.json`).
16
- - **Accessible**: WCAG compliant focus rings, ARIA roles, and keyboard navigation.
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 (Optional but recommended)
31
- Add Google Roboto and Material Symbols to your HTML:
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 and Use Components
123
+ ### 2. Import Components
38
124
 
39
- #### Global Bundle Import
40
- ```typescript
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/card';
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
- #### Use in HTML / JSX / Templates
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 & Icons -->
54
- <md-button variant="filled" icon="send">Submit</md-button>
55
- <md-button variant="outlined">Cancel</md-button>
56
- <md-icon-button icon="favorite"></md-icon-button>
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
- <!-- Form Inputs with Native Form Integration -->
214
+ ```html
59
215
  <form id="login-form">
60
- <md-text-field label="Email" name="email" type="email" required></md-text-field>
61
- <md-checkbox name="remember" checked>Remember me</md-checkbox>
62
- <md-switch name="notifications" selected icons>Enable Notifications</md-switch>
63
- <md-button type="submit" variant="filled">Log In</md-button>
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
- <!-- Card Surface -->
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
- <!-- Modal Dialog -->
79
- <md-dialog id="my-dialog" headline="Dialog Title" icon="info">
80
- Dialog content description.
81
- <div slot="actions">
82
- <md-button id="close-btn" variant="text">Close</md-button>
83
- </div>
84
- </md-dialog>
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
- The library uses standard CSS custom properties adhering to Material 3 specs:
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
- // Apply dark theme
422
+ // Switch to dark theme
115
423
  applyTheme(darkColorScheme);
116
424
 
117
- // Apply custom brand colors
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
- ## Component List
127
-
128
- | Component | Tag | Key Properties & Variants |
129
- | :--- | :--- | :--- |
130
- | **Button** | `<md-button>` | `variant` (filled, elevated, tonal, outlined, text), `icon`, `loading`, `disabled`, `href` |
131
- | **Icon Button** | `<md-icon-button>` | `variant` (standard, filled, tonal, outlined), `icon`, `toggle`, `selected` |
132
- | **FAB** | `<md-fab>` | `size` (small, medium, large), `label`, `icon`, `lowered` |
133
- | **Text Field** | `<md-text-field>` | `variant` (filled, outlined), `label`, `value`, `prefix-text`, `suffix-text`, `error`, `supporting-text` |
134
- | **Checkbox** | `<md-checkbox>` | `checked`, `indeterminate`, `error`, `disabled`, `name`, `value` |
135
- | **Switch** | `<md-switch>` | `selected`, `icons`, `disabled`, `name`, `value` |
136
- | **Radio** | `<md-radio>`, `<md-radio-group>` | `checked`, `value`, `name`, `row` |
137
- | **Card** | `<md-card>` | `variant` (elevated, filled, outlined), `interactive`, `href` |
138
- | **Dialog** | `<md-dialog>` | `open`, `headline`, `icon`, `showModal()`, `close()` |
139
- | **Divider** | `<md-divider>` | `vertical`, `inset`, `inset-start`, `inset-end` |
140
- | **Progress** | `<md-progress>` | `type` (linear, circular), `value` (0 to 1, or indeterminate), `buffer` |
141
- | **Badge** | `<md-badge>` | `value`, `dot` |
142
- | **Chip** | `<md-chip>`, `<md-chip-set>` | `variant` (assist, filter, input, suggestion), `label`, `selected`, `removable` |
143
- | **Tabs** | `<md-tabs>`, `<md-tab>` | `active-index`, `icon`, `label` |
144
- | **List** | `<md-list>`, `<md-list-item>` | `headline`, `supporting-text`, `interactive`, `href` |
145
- | **Snackbar** | `<md-snackbar>` | `open`, `message`, `action-text`, `closeable`, `timeout-ms` |
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
- ## Development and Testing
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 interactive Vite playground
620
+ # Start local development playground & documentation
153
621
  npm run dev
154
622
 
155
- # Start local VitePress documentation
156
- npm run docs:dev
157
-
158
- # Run unit tests
623
+ # Run unit tests with Vitest
159
624
  npm test
160
625
 
161
- # Type check
626
+ # Type-check TypeScript codebase
162
627
  npm run typecheck
163
628
 
164
- # Build library & custom elements manifest
629
+ # Build ESM library, docs & generate Custom Elements Manifest
165
630
  npm run build
166
631
 
167
- # Build documentation for production
168
- npm run docs:build
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 includes a GitHub Actions workflow (`.github/workflows/publish-npm.yml`) that automatically publishes new releases to npm whenever a new version is pushed to the `main` branch.
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 code is pushed to `main`, the workflow inspects the `version` field in `package.json`.
179
- 2. It queries npm to check if that version is already published.
180
- 3. If the version is new, it runs typecheck, tests, builds the library, and publishes the package to npm with provenance.
181
- 4. It creates a Git tag `v<version>` and a GitHub Release.
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