@maggioli-design-system/magma-react 2.5.1 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +19 -4
- package/CHANGELOG.md +69 -0
- package/agents/assets.md +24 -10
- package/agents/color.md +22 -4
- package/agents/components.md +164 -92
- package/agents/conventions.md +19 -8
- package/agents/install.md +7 -0
- package/agents/lint.md +298 -0
- package/agents/mcp.md +107 -0
- package/agents/reporting.md +53 -2
- package/agents/theming.md +8 -0
- package/dist/components.js +1 -0
- package/dist/components.server.js +1 -0
- package/dist/mds-book.js +12 -0
- package/dist/mds-book.server.js +23 -0
- package/dist/types/components.d.ts +1 -0
- package/dist/types/components.server.d.ts +1 -0
- package/dist/types/mds-book.d.ts +9 -0
- package/dist/types/mds-book.server.d.ts +11 -0
- package/package.json +2 -2
package/agents/lint.md
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
GENERATED FILE - do not edit by hand.
|
|
3
|
+
Source of truth: docs/agents/ in the magma monorepo.
|
|
4
|
+
Regenerate with: npm run sync.agent-docs (from the stencil package).
|
|
5
|
+
-->
|
|
6
|
+
# Magma lint
|
|
7
|
+
|
|
8
|
+
> Scope: checking the code you write against the installed Magma, with the ESLint and
|
|
9
|
+
> Stylelint rules that ship inside `@maggioli-design-system/magma`. Set them up once, when
|
|
10
|
+
> you install Magma, and run them after every change.
|
|
11
|
+
|
|
12
|
+
The rules make the prose of these guides executable: a prop value the component does not
|
|
13
|
+
take, a boolean turned "off" with `"false"`, an icon-only control without a name, a colour
|
|
14
|
+
painted with Tailwind's palette or a raw palette step, a hand-written dark mode. They read
|
|
15
|
+
the API and the tokens of the installed version, the same release as the components, so
|
|
16
|
+
they follow every update with nothing to keep in sync.
|
|
17
|
+
|
|
18
|
+
## Set it up
|
|
19
|
+
|
|
20
|
+
Nothing to install from Magma: the rules are in `@maggioli-design-system/magma`, which
|
|
21
|
+
`magma-react` and `magma-angular` require too. The project needs ESLint 9 and Stylelint 16
|
|
22
|
+
(`npm i -D eslint stylelint` when it has none) and the parser of its templates:
|
|
23
|
+
|
|
24
|
+
| Templates | Parser |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| HTML | `@html-eslint/parser` |
|
|
27
|
+
| Angular (external `.html` templates) | `@angular-eslint/template-parser` (with angular-eslint) |
|
|
28
|
+
| React (JSX, TSX) | the one the project already uses |
|
|
29
|
+
|
|
30
|
+
MERGE the blocks below into the project's `eslint.config.js` and `stylelint.config.mjs`:
|
|
31
|
+
never replace an existing configuration. Each ESLint preset sets rules only, so it goes in
|
|
32
|
+
the block that parses the templates.
|
|
33
|
+
|
|
34
|
+
### HTML and web components
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
// eslint.config.js
|
|
38
|
+
import html from '@html-eslint/parser';
|
|
39
|
+
import magma from '@maggioli-design-system/magma/eslint';
|
|
40
|
+
|
|
41
|
+
export default [
|
|
42
|
+
{ files: ['**/*.html'], languageOptions: { parser: html }, ...magma.configs.recommended },
|
|
43
|
+
];
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### React
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
// eslint.config.js
|
|
50
|
+
import magma from '@maggioli-design-system/magma/eslint';
|
|
51
|
+
|
|
52
|
+
export default [
|
|
53
|
+
// ...the block that parses .jsx and .tsx
|
|
54
|
+
{ files: ['**/*.{jsx,tsx}'], ...magma.configs.recommended },
|
|
55
|
+
];
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The rules read both `<mds-button>` and the wrappers of `magma-react` (`<MdsButton>`), and the
|
|
59
|
+
classes of a `className` wherever its expression writes them, `clsx()` and ternaries included
|
|
60
|
+
(see [`no-raw-palette-classes`](#no-raw-palette-classes)).
|
|
61
|
+
|
|
62
|
+
### Angular
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
// eslint.config.js, next to the blocks of angular-eslint
|
|
66
|
+
import angularTemplate from '@angular-eslint/template-parser';
|
|
67
|
+
import magma from '@maggioli-design-system/magma/eslint';
|
|
68
|
+
|
|
69
|
+
export default [
|
|
70
|
+
{ files: ['**/*.html'], languageOptions: { parser: angularTemplate }, ...magma.configs.recommended },
|
|
71
|
+
];
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
With the inline-template processor of angular-eslint, the inline `template` of a component
|
|
75
|
+
is linted as an `.html` file too.
|
|
76
|
+
|
|
77
|
+
### CSS and SCSS
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
// stylelint.config.mjs
|
|
81
|
+
export default {
|
|
82
|
+
extends: ['@maggioli-design-system/magma/stylelint/recommended'],
|
|
83
|
+
};
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Presets
|
|
87
|
+
|
|
88
|
+
- `recommended`, for a product that already exists: what is broken or not accessible is an
|
|
89
|
+
error, the palette and an internal custom property a warning;
|
|
90
|
+
- `strict` (`magma.configs.strict`, `@maggioli-design-system/magma/stylelint/strict`), for a
|
|
91
|
+
new product: every rule is an error.
|
|
92
|
+
|
|
93
|
+
## Run it after writing
|
|
94
|
+
|
|
95
|
+
After every change, run ESLint on the templates you touched and Stylelint on the
|
|
96
|
+
stylesheets, and fix what they report before you hand the work over:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
npx eslint src
|
|
100
|
+
npx stylelint "src/**/*.{css,scss}"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
An error is something broken or not accessible; a warning of `recommended` is a colour that
|
|
104
|
+
does not follow the mode, the named theme and the contrast preference, or a custom property a
|
|
105
|
+
component may change in any release. When a rule is wrong about Magma itself, report it
|
|
106
|
+
([`reporting.md`](reporting.md)) instead of disabling it.
|
|
107
|
+
|
|
108
|
+
## Rules
|
|
109
|
+
|
|
110
|
+
| Rule | Tool | `recommended` | `strict` |
|
|
111
|
+
| --- | --- | --- | --- |
|
|
112
|
+
| [`valid-attribute-values`](#valid-attribute-values) | ESLint | error | error |
|
|
113
|
+
| [`no-false-boolean`](#no-false-boolean) | ESLint | error | error |
|
|
114
|
+
| [`accessible-name`](#accessible-name) | ESLint | error | error |
|
|
115
|
+
| [`no-raw-palette-classes`](#no-raw-palette-classes) | ESLint, Stylelint | warn | error |
|
|
116
|
+
| [`no-color-scheme-override`](#no-color-scheme-override) | Stylelint | error | error |
|
|
117
|
+
| [`no-raw-color`](#no-raw-color) | Stylelint | warning | error |
|
|
118
|
+
| [`no-internal-tokens`](#no-internal-tokens) | ESLint, Stylelint | warn | error |
|
|
119
|
+
|
|
120
|
+
The ESLint rules are named `magma/<rule>` once the preset is loaded, the Stylelint rules
|
|
121
|
+
`magma/<rule>` once the plugin (`@maggioli-design-system/magma/stylelint`) is.
|
|
122
|
+
|
|
123
|
+
### valid-attribute-values
|
|
124
|
+
|
|
125
|
+
A prop whose type is a union of literals takes one of them (the values each prop takes are
|
|
126
|
+
in the component's `AGENTS.md`).
|
|
127
|
+
|
|
128
|
+
```html
|
|
129
|
+
<!-- INCORRECT: tone takes "box", "strong" or "weak" -->
|
|
130
|
+
<mds-banner tone="outline">Saved</mds-banner>
|
|
131
|
+
|
|
132
|
+
<!-- CORRECT -->
|
|
133
|
+
<mds-banner tone="weak">Saved</mds-banner>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
A value bound to an expression (`[tone]="tone"`, `tone={tone}`) is known only at run time and
|
|
137
|
+
is not checked; a literal binding (`[tone]="'box'"`) is.
|
|
138
|
+
|
|
139
|
+
### no-false-boolean
|
|
140
|
+
|
|
141
|
+
A boolean prop is turned off by removing its attribute
|
|
142
|
+
([`conventions.md`](conventions.md#boolean-disabled-and-await-props)): a form-associated
|
|
143
|
+
component reads any value as on, `"false"` included.
|
|
144
|
+
|
|
145
|
+
```html
|
|
146
|
+
<!-- INCORRECT -->
|
|
147
|
+
<mds-button disabled="false">Save</mds-button>
|
|
148
|
+
|
|
149
|
+
<!-- CORRECT -->
|
|
150
|
+
<mds-button>Save</mds-button>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Reported: the string `"false"` in any form, and an Angular attribute binding
|
|
154
|
+
(`[attr.disabled]="false"`), which writes the attribute `"false"`. Bind a real boolean to the
|
|
155
|
+
property instead: `<MdsButton disabled={isDisabled}>`, `[disabled]="isDisabled"`.
|
|
156
|
+
|
|
157
|
+
### accessible-name
|
|
158
|
+
|
|
159
|
+
A component that takes an `icon` next to a `label` or a default slot, shown with its icon
|
|
160
|
+
alone, needs a name: without `label` or `aria-label`, `mds-button` is announced by the slug of
|
|
161
|
+
its icon, which names the icon and not the action. An `mds-img` with a `src` and no `alt` is
|
|
162
|
+
named after its file: describe the image, or set `alt=""` when it is decorative.
|
|
163
|
+
|
|
164
|
+
```html
|
|
165
|
+
<!-- INCORRECT -->
|
|
166
|
+
<mds-button icon="mi/baseline/send"></mds-button>
|
|
167
|
+
<mds-img src="/img/report-2024.jpg"></mds-img>
|
|
168
|
+
|
|
169
|
+
<!-- CORRECT -->
|
|
170
|
+
<mds-button icon="mi/baseline/send" label="Send"></mds-button>
|
|
171
|
+
<mds-img src="/img/report-2024.jpg" alt="Annual report 2024"></mds-img>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Left alone, because one element does not show its name: an element with an `id` (an
|
|
175
|
+
`mds-tooltip` with `relation="label"`, or an `aria-labelledby` elsewhere, may name it) and
|
|
176
|
+
one that spreads its props (`{...props}`).
|
|
177
|
+
|
|
178
|
+
### no-raw-palette-classes
|
|
179
|
+
|
|
180
|
+
A colour class names a role ([`color.md`](color.md)), never Tailwind's palette (`bg-white`,
|
|
181
|
+
`text-gray-700`), which ignores Magma, nor a raw Magma step (`bg-tone-neutral-03`,
|
|
182
|
+
`border-surface-neutral-default`), which follows the mode only. Variants, `!` and opacity are
|
|
183
|
+
read through: `dark:hover:bg-white/50` is `bg-white`.
|
|
184
|
+
|
|
185
|
+
```html
|
|
186
|
+
<!-- INCORRECT -->
|
|
187
|
+
<section class="bg-white text-gray-700">...</section>
|
|
188
|
+
|
|
189
|
+
<!-- CORRECT -->
|
|
190
|
+
<section class="bg-surface-raised text-fg-default">...</section>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Not reported: `label-*` and `brand-*`, for colour that encodes data, and the seed of a tone,
|
|
194
|
+
the pure extreme of the mode.
|
|
195
|
+
|
|
196
|
+
A class is read wherever the project writes one, in the forms the codemod migrates:
|
|
197
|
+
|
|
198
|
+
- the `class` attribute of HTML and Angular templates;
|
|
199
|
+
- React: every string in a `className` (or `class`) expression, the arguments and object keys
|
|
200
|
+
of `clsx()` or `classnames()`, both branches of a ternary, a `||` fallback, and the fixed
|
|
201
|
+
parts of a template literal;
|
|
202
|
+
- Angular: the key of `[class.<name>]` and the quoted strings of `[ngClass]`, `[class]` and
|
|
203
|
+
`[attr.class]`;
|
|
204
|
+
- Stylelint: the classes of `@apply`.
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
// INCORRECT
|
|
208
|
+
<div className={clsx('p-400', active && 'bg-white')} />
|
|
209
|
+
|
|
210
|
+
// CORRECT
|
|
211
|
+
<div className={clsx('p-400', active && 'bg-surface-raised')} />
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Not read: a class put together at run time (`bg-${tone}-03`, of which only the fixed parts are
|
|
215
|
+
read), classes kept in a variable outside the attribute (`const card = clsx(...)`), and HTML
|
|
216
|
+
written as a string in a script (`el.innerHTML = ...`). A string compared in a condition is
|
|
217
|
+
read too, and reported only when it is itself a palette class.
|
|
218
|
+
|
|
219
|
+
### no-color-scheme-override
|
|
220
|
+
|
|
221
|
+
A `prefers-color-scheme` media query follows the OS, not the mode the user picked
|
|
222
|
+
(`mds-pref-mode`). The roles follow both: paint with them, and dark mode comes with no
|
|
223
|
+
query. For a deliberate choice that differs per mode, use the `dark` variant of the Magma
|
|
224
|
+
Tailwind theme, which follows the Magma mode ([`theming.md`](theming.md)).
|
|
225
|
+
|
|
226
|
+
```css
|
|
227
|
+
/* INCORRECT */
|
|
228
|
+
@media (prefers-color-scheme: dark) {
|
|
229
|
+
.panel {
|
|
230
|
+
background: rgb(var(--magma-surface-overlay));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/* CORRECT */
|
|
235
|
+
.panel {
|
|
236
|
+
background: rgb(var(--magma-surface-raised));
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### no-raw-color
|
|
241
|
+
|
|
242
|
+
A hex, `rgb()`, `hsl()`, `oklch()` or other colour literal where a role belongs. A colour that
|
|
243
|
+
names a token is fine (`rgb(var(--magma-text-muted) / 0.5)`), and so are the keywords
|
|
244
|
+
(`currentColor`, `transparent`). In a shadow the hint is the shadow ink,
|
|
245
|
+
`rgb(var(--magma-shadow-ink) / <alpha>)`. Not read: `mask` and `mask-image`, and the
|
|
246
|
+
`initial-value` of an `@property`.
|
|
247
|
+
|
|
248
|
+
Not reported either: the public custom properties marked **Static** in a component's
|
|
249
|
+
`AGENTS.md`, which take a colour of their own, not a role (the skin of an illustration, the
|
|
250
|
+
cover of a book from its catalogue record):
|
|
251
|
+
|
|
252
|
+
```css
|
|
253
|
+
mds-emoji[name='simi'] {
|
|
254
|
+
--mds-emoji-simi-skin: #f5c8a0;
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Any other colour that is not a role keeps its literal under a disable comment that says why:
|
|
259
|
+
`/* stylelint-disable-next-line magma/no-raw-color -- <the reason> */`.
|
|
260
|
+
|
|
261
|
+
### no-internal-tokens
|
|
262
|
+
|
|
263
|
+
An `--mds-*` custom property, set or read, that no component promises. A component's
|
|
264
|
+
`AGENTS.md` lists its public custom properties, the only ones a product sets; the others are
|
|
265
|
+
internal, its implementation, and may change or go in any release without notice. A name no
|
|
266
|
+
component documents is reported too. Stylelint reads the stylesheets, the classes of `@apply`
|
|
267
|
+
included; ESLint reads the inline styles of the templates (a `style` attribute, a React
|
|
268
|
+
`style={{ '--mds-<name>': ... }}` object, an Angular `[style.--mds-<name>]` binding) and their
|
|
269
|
+
Tailwind classes, wherever [`no-raw-palette-classes`](#no-raw-palette-classes) reads a class,
|
|
270
|
+
through variants and `!`: an arbitrary property that sets one
|
|
271
|
+
(`[--mds-<name>:<value>]`, on the component or on a parent that sets it for its descendants)
|
|
272
|
+
and an arbitrary value that reads one (`bg-[var(--mds-<name>)]`, `bg-(--mds-<name>)`).
|
|
273
|
+
|
|
274
|
+
```css
|
|
275
|
+
/* INCORRECT: internal, it may change in any release */
|
|
276
|
+
mds-chip {
|
|
277
|
+
--mds-chip-icon-color: rgb(var(--magma-accent-fg));
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/* CORRECT: a public custom property of the chip */
|
|
281
|
+
mds-chip {
|
|
282
|
+
--mds-chip-icon-background: rgb(var(--magma-accent-surface));
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
When no public custom property does what you need, use a prop, a documented part, or a role
|
|
287
|
+
on the markup around the component; if none does, ask for one ([`reporting.md`](reporting.md))
|
|
288
|
+
rather than setting an internal one.
|
|
289
|
+
|
|
290
|
+
## Settings
|
|
291
|
+
|
|
292
|
+
The rules need no settings: they read the `documentation.json` beside them in the installed
|
|
293
|
+
`magma`, and the tokens of the `design-tokens` and `styles` it depends on. To check against
|
|
294
|
+
other files, set their paths under `settings.magma` in the ESLint configuration (relative to
|
|
295
|
+
`root`, the project by default): `documentation`, `tokens`, `consumption`. The Stylelint rules
|
|
296
|
+
take the paths they read as secondary options, `root` and `documentation` for `no-internal-tokens`
|
|
297
|
+
and `no-raw-color`, `root`, `tokens` and `consumption` for `no-raw-palette-classes`:
|
|
298
|
+
`'magma/no-internal-tokens': [true, { documentation: './documentation.json' }]`.
|
package/agents/mcp.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
GENERATED FILE - do not edit by hand.
|
|
3
|
+
Source of truth: docs/agents/ in the magma monorepo.
|
|
4
|
+
Regenerate with: npm run sync.agent-docs (from the stencil package).
|
|
5
|
+
-->
|
|
6
|
+
# Magma MCP server
|
|
7
|
+
|
|
8
|
+
> Scope: asking Magma precise questions while you work, through the MCP server that ships
|
|
9
|
+
> inside `@maggioli-design-system/magma`. Set it up once, when you install Magma; then reach
|
|
10
|
+
> for its tools instead of reading whole files.
|
|
11
|
+
|
|
12
|
+
The server answers from the version installed in the project: the components and their
|
|
13
|
+
API, the roles and tokens with what each one is for, the classes of the Magma Tailwind
|
|
14
|
+
theme, the icon slugs that exist, the sections of these guides, and the lint
|
|
15
|
+
([`lint.md`](lint.md)) on a snippet before it is written. It is read-only: no tool changes
|
|
16
|
+
a file.
|
|
17
|
+
|
|
18
|
+
## Set it up
|
|
19
|
+
|
|
20
|
+
Nothing to install: the server is the `magma-mcp` command of `@maggioli-design-system/magma`,
|
|
21
|
+
which `magma-react` and `magma-angular` require too. The agent's client starts it on stdio
|
|
22
|
+
from the project's root; MERGE the entry into the client's configuration, never replace
|
|
23
|
+
the file.
|
|
24
|
+
|
|
25
|
+
### Claude Code: the Magma plugin
|
|
26
|
+
|
|
27
|
+
In Claude Code, the Magma plugin starts the server for you and adds the skills that run a
|
|
28
|
+
whole job: `/magma:setup`, `/magma:review`, `/magma:migrate`, and `ui`, which Claude loads by
|
|
29
|
+
itself for UI work. Register it for the whole team in the project's committed
|
|
30
|
+
`.claude/settings.json`; Claude Code loads it once the folder is trusted, in the terminal and
|
|
31
|
+
in the desktop app, which reads the same settings:
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"extraKnownMarketplaces": {
|
|
36
|
+
"magma": { "source": { "source": "github", "repo": "magma-design-system/magma" }, "autoUpdate": true }
|
|
37
|
+
},
|
|
38
|
+
"enabledPlugins": { "magma@magma": true }
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
On one machine only, in a Claude Code session in the terminal:
|
|
43
|
+
`/plugin marketplace add magma-design-system/magma`, then `/plugin install magma@magma`.
|
|
44
|
+
|
|
45
|
+
With the plugin, do not also add the `.mcp.json` entry below: the server would run twice.
|
|
46
|
+
|
|
47
|
+
### Claude Code without the plugin, and the other clients
|
|
48
|
+
|
|
49
|
+
Claude Code, `.mcp.json` at the project root (committed, so the whole team gets it; Claude
|
|
50
|
+
Code asks once before it starts a project server):
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"mcpServers": {
|
|
55
|
+
"magma": { "command": "npx", "args": ["--no", "magma-mcp"] }
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
VS Code (GitHub Copilot), `.vscode/mcp.json`:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"servers": {
|
|
65
|
+
"magma": { "type": "stdio", "command": "npx", "args": ["--no", "magma-mcp"] }
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Cursor, `.cursor/mcp.json`: the same entry as Claude Code, under `mcpServers`.
|
|
71
|
+
|
|
72
|
+
`npx --no magma-mcp` runs the installed version, so the answers always match the components
|
|
73
|
+
the project uses. Keep `--no`: without it, a client that starts the server before
|
|
74
|
+
`npm install` (a fresh clone with the configuration committed) lets `npx` download and run
|
|
75
|
+
whatever package the npm registry has under that name; with it, `npx` stops instead. When the
|
|
76
|
+
client starts servers elsewhere than the project's root, pass it:
|
|
77
|
+
`"args": ["--no", "magma-mcp", "--root", "<the project's folder>"]`.
|
|
78
|
+
|
|
79
|
+
## The tools
|
|
80
|
+
|
|
81
|
+
| Tool | Ask it | Instead of |
|
|
82
|
+
| --- | --- | --- |
|
|
83
|
+
| `find_component` | which component fits a need ("a date range picker") | reading the catalogue |
|
|
84
|
+
| `get_component` | the API of one component: props with their values and default, events, methods, slots, parts, public CSS custom properties | reading its `AGENTS.md` |
|
|
85
|
+
| `get_usage` | how HTML, React or Angular writes it: import, props, events (`onMdsInputChange`, `(mdsInputChange)`) | guessing the names |
|
|
86
|
+
| `list_tokens` | the role for a need ("secondary text"), with its value and class | reading [`color.md`](color.md) |
|
|
87
|
+
| `suggest_role` | the role for a colour, a raw class or a palette step, as a class of the same utility (`shadow-*/80` stays a shadow class) | picking a role by eye |
|
|
88
|
+
| `explain_class` | what a class does with the Magma theme | the trap of the scale: `p-4` is 0.01rem, `p-400` is 1rem |
|
|
89
|
+
| `find_icon` | a slug that exists, by meaning, or whether a slug exists | an `icon="..."` that renders nothing |
|
|
90
|
+
| `get_guide` | one section of a guide | reading the whole file |
|
|
91
|
+
| `check_markup` | whether a snippet passes the lint, before it is written | a lint run after the fact |
|
|
92
|
+
| `check_setup` | what the Magma integration of the project misses | checking the install steps by hand |
|
|
93
|
+
|
|
94
|
+
`check_markup` uses the ESLint, Stylelint and template parsers the project installed with
|
|
95
|
+
the lint ([`lint.md`](lint.md)). The same definitions, for a tool that documents them, are in
|
|
96
|
+
`@maggioli-design-system/magma/dist/lint/mcp/tools.json`: what `tools/list` answers.
|
|
97
|
+
|
|
98
|
+
## When to call them
|
|
99
|
+
|
|
100
|
+
- Before writing a component: `find_component`, then `get_component` and `get_usage`.
|
|
101
|
+
- Before a colour, a spacing or a class: `list_tokens`, `suggest_role`, `explain_class`.
|
|
102
|
+
- Before an icon: `find_icon`.
|
|
103
|
+
- After writing: `check_markup`, then the project's lint ([`lint.md`](lint.md)).
|
|
104
|
+
- After the bootstrap, or when something does not render: `check_setup`.
|
|
105
|
+
- When no tool gives you what the task needs, or an answer carries `gap`: tell the user,
|
|
106
|
+
and at the end of the task propose an issue on Magma
|
|
107
|
+
([`reporting.md`](reporting.md), "A tool or an answer the MCP server is missing").
|
package/agents/reporting.md
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
> Scope: you are working in a project that uses Magma and you hit a problem that is
|
|
9
9
|
> Magma's, not the project's: a component that misbehaves, a guide that is wrong, a
|
|
10
|
-
> missing token or utility, a packaging or install issue
|
|
11
|
-
> the Magma
|
|
10
|
+
> missing token or utility, a packaging or install issue, or something you needed that
|
|
11
|
+
> the Magma MCP server does not answer (section 7). This is how to report it to the
|
|
12
|
+
> Magma repository, `magma-design-system/magma`, labelled with the project it comes
|
|
12
13
|
> from, so the maintainers can tell which project reported what.
|
|
13
14
|
|
|
14
15
|
## 1. Make sure it is Magma's
|
|
@@ -125,3 +126,53 @@ the title, the labels and the body to open it by hand at
|
|
|
125
126
|
|
|
126
127
|
Then give the user the issue URL, and leave a comment in the project next to the
|
|
127
128
|
workaround that links it, so the workaround can go once the fix ships.
|
|
129
|
+
|
|
130
|
+
## 7. A tool or an answer the MCP server is missing
|
|
131
|
+
|
|
132
|
+
The tools of the Magma MCP server ([`mcp.md`](mcp.md)) are there so you never read the
|
|
133
|
+
installed files by hand or guess. When one of them could not give you what the task
|
|
134
|
+
needed, Magma wants to know: the next tool or field comes from these reports. It is a gap
|
|
135
|
+
when:
|
|
136
|
+
|
|
137
|
+
- no tool covers the question, and you answered it by reading Magma's files
|
|
138
|
+
(`documentation.json`, the token data, the guides) or by guessing;
|
|
139
|
+
- a tool said Magma has nothing for a well-formed question: its answer carries `gap`, or
|
|
140
|
+
its error says it does not know;
|
|
141
|
+
- a tool answered, but not with what the task needed: a field it does not return, a
|
|
142
|
+
filter or an argument it does not take.
|
|
143
|
+
|
|
144
|
+
It is not a gap when the answer is right but not the one you hoped for, when your own
|
|
145
|
+
input was wrong (an unknown tag, a missing argument), or when the question is about the
|
|
146
|
+
project rather than Magma.
|
|
147
|
+
|
|
148
|
+
Tell the user when it happens, carry on with the task, and at the end propose one issue
|
|
149
|
+
per missing capability, gathered from the whole task. Follow steps 2, 3, 4 and 6 (look
|
|
150
|
+
for an existing issue, ask before opening it, the labels, create it), with `feature`,
|
|
151
|
+
`prg-stencil` (the server ships inside `magma`) and the project's `prd-*` label, and this
|
|
152
|
+
title and body instead of the ones of step 5. Title: `magma-mcp: <what is missing>`, e.g.
|
|
153
|
+
`magma-mcp: find_component cannot filter by category`. Body:
|
|
154
|
+
|
|
155
|
+
```markdown
|
|
156
|
+
## Need
|
|
157
|
+
|
|
158
|
+
What the task needed to know or to do, in one sentence.
|
|
159
|
+
|
|
160
|
+
## What the server answered
|
|
161
|
+
|
|
162
|
+
The tool you called and its arguments, and what it returned; or that no tool covers it.
|
|
163
|
+
|
|
164
|
+
## What I did instead
|
|
165
|
+
|
|
166
|
+
Read a file by hand, guessed, asked the user, and what it cost.
|
|
167
|
+
|
|
168
|
+
## Proposal
|
|
169
|
+
|
|
170
|
+
The tool, argument or field that would have answered it, if you have one in mind.
|
|
171
|
+
|
|
172
|
+
## Versions
|
|
173
|
+
|
|
174
|
+
- @maggioli-design-system/magma: <installed version>
|
|
175
|
+
- Client: <e.g. Claude Code, VS Code, Cursor>
|
|
176
|
+
|
|
177
|
+
Found in <project> (<repository>).
|
|
178
|
+
```
|
package/agents/theming.md
CHANGED
|
@@ -28,6 +28,14 @@ let the user choose, each preference has its component - `mds-pref-mode`,
|
|
|
28
28
|
`mds-pref-language` - and `mds-pref` groups them in one panel; they write the classes and
|
|
29
29
|
remember the choice. Never write `color-scheme` or dark-mode media queries by hand.
|
|
30
30
|
|
|
31
|
+
Tailwind's `dark:` follows the same mode: the Magma Tailwind theme brings a `dark`
|
|
32
|
+
variant that turns on where the palette turns dark - `pref-mode-dark`, `pref-mode-system`
|
|
33
|
+
or no controller on a dark OS, a theme locked to dark (`pref-theme-scheme-dark`) - and
|
|
34
|
+
never under `pref-mode-light` or a theme locked to light (`pref-theme-scheme-light`). The
|
|
35
|
+
roles flip without it, so `dark:` is never needed to correct a colour: use it only for a
|
|
36
|
+
deliberate per-mode choice. It matches the light DOM only (pages, layouts, stories);
|
|
37
|
+
inside a component's shadow root it matches nothing.
|
|
38
|
+
|
|
31
39
|
## Named themes
|
|
32
40
|
|
|
33
41
|
A named theme retints the whole neutral scaffolding of the page at once - surfaces,
|
package/dist/components.js
CHANGED
|
@@ -15,6 +15,7 @@ export { MdsBadge } from "./mds-badge.js";
|
|
|
15
15
|
export { MdsBanner } from "./mds-banner.js";
|
|
16
16
|
export { MdsBenchmarkBar } from "./mds-benchmark-bar.js";
|
|
17
17
|
export { MdsBibliography } from "./mds-bibliography.js";
|
|
18
|
+
export { MdsBook } from "./mds-book.js";
|
|
18
19
|
export { MdsBreadcrumbItem } from "./mds-breadcrumb-item.js";
|
|
19
20
|
export { MdsBreadcrumb } from "./mds-breadcrumb.js";
|
|
20
21
|
export { MdsButtonDropdown } from "./mds-button-dropdown.js";
|
|
@@ -15,6 +15,7 @@ export { MdsBadge } from "./mds-badge.server.js";
|
|
|
15
15
|
export { MdsBanner } from "./mds-banner.server.js";
|
|
16
16
|
export { MdsBenchmarkBar } from "./mds-benchmark-bar.server.js";
|
|
17
17
|
export { MdsBibliography } from "./mds-bibliography.server.js";
|
|
18
|
+
export { MdsBook } from "./mds-book.server.js";
|
|
18
19
|
export { MdsBreadcrumbItem } from "./mds-breadcrumb-item.server.js";
|
|
19
20
|
export { MdsBreadcrumb } from "./mds-breadcrumb.server.js";
|
|
20
21
|
export { MdsButtonDropdown } from "./mds-button-dropdown.server.js";
|
package/dist/mds-book.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { createComponent } from '@stencil/react-output-target/runtime';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { MdsBook as MdsBookElement, defineCustomElement as defineMdsBook } from "@maggioli-design-system/magma/dist/components/mds-book.js";
|
|
5
|
+
export const MdsBook = /*@__PURE__*/ createComponent({
|
|
6
|
+
tagName: 'mds-book',
|
|
7
|
+
elementClass: MdsBookElement,
|
|
8
|
+
// @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.
|
|
9
|
+
react: React,
|
|
10
|
+
events: {},
|
|
11
|
+
defineCustomElement: defineMdsBook
|
|
12
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { createComponent } from '@stencil/react-output-target/ssr';
|
|
3
|
+
// @ts-ignore - ignore potential type issues as the project is importing itself
|
|
4
|
+
import * as clientComponents from "@maggioli-design-system/magma-react";
|
|
5
|
+
export const serializeShadowRoot = "declarative-shadow-dom";
|
|
6
|
+
export const MdsBook = /*@__PURE__*/ createComponent({
|
|
7
|
+
tagName: 'mds-book',
|
|
8
|
+
properties: {
|
|
9
|
+
alt: 'alt',
|
|
10
|
+
author: 'author',
|
|
11
|
+
binding: 'binding',
|
|
12
|
+
format: 'format',
|
|
13
|
+
loading: 'loading',
|
|
14
|
+
name: 'name',
|
|
15
|
+
pages: 'pages',
|
|
16
|
+
pose: 'pose',
|
|
17
|
+
publisher: 'publisher',
|
|
18
|
+
src: 'src'
|
|
19
|
+
},
|
|
20
|
+
hydrateModule: typeof window === 'undefined' ? import('@maggioli-design-system/magma/hydrate') : undefined,
|
|
21
|
+
clientModule: clientComponents.MdsBook,
|
|
22
|
+
serializeShadowRoot
|
|
23
|
+
});
|
|
@@ -14,6 +14,7 @@ export { MdsBadge } from "./mds-badge.js";
|
|
|
14
14
|
export { MdsBanner } from "./mds-banner.js";
|
|
15
15
|
export { MdsBenchmarkBar } from "./mds-benchmark-bar.js";
|
|
16
16
|
export { MdsBibliography } from "./mds-bibliography.js";
|
|
17
|
+
export { MdsBook } from "./mds-book.js";
|
|
17
18
|
export { MdsBreadcrumbItem } from "./mds-breadcrumb-item.js";
|
|
18
19
|
export { MdsBreadcrumb } from "./mds-breadcrumb.js";
|
|
19
20
|
export { MdsButtonDropdown } from "./mds-button-dropdown.js";
|
|
@@ -16,6 +16,7 @@ export { MdsBadge } from "./mds-badge.server.js";
|
|
|
16
16
|
export { MdsBanner } from "./mds-banner.server.js";
|
|
17
17
|
export { MdsBenchmarkBar } from "./mds-benchmark-bar.server.js";
|
|
18
18
|
export { MdsBibliography } from "./mds-bibliography.server.js";
|
|
19
|
+
export { MdsBook } from "./mds-book.server.js";
|
|
19
20
|
export { MdsBreadcrumbItem } from "./mds-breadcrumb-item.server.js";
|
|
20
21
|
export { MdsBreadcrumb } from "./mds-breadcrumb.server.js";
|
|
21
22
|
export { MdsButtonDropdown } from "./mds-button-dropdown.server.js";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file was automatically generated by the Stencil React Output Target.
|
|
3
|
+
* Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
|
|
4
|
+
*/
|
|
5
|
+
import type { StencilReactComponent } from '@stencil/react-output-target/runtime';
|
|
6
|
+
import type { Components } from "@maggioli-design-system/magma/dist/components";
|
|
7
|
+
import { MdsBook as MdsBookElement } from "@maggioli-design-system/magma/dist/components/mds-book.js";
|
|
8
|
+
export type MdsBookEvents = NonNullable<unknown>;
|
|
9
|
+
export declare const MdsBook: StencilReactComponent<MdsBookElement, MdsBookEvents, Components.MdsBook>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file was automatically generated by the Stencil React Output Target.
|
|
3
|
+
* Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
|
|
4
|
+
*/
|
|
5
|
+
import type { StencilReactComponent } from '@stencil/react-output-target/runtime';
|
|
6
|
+
import { type SerializeShadowRootOptions } from '@stencil/react-output-target/ssr';
|
|
7
|
+
import type { Components } from "@maggioli-design-system/magma/dist/components";
|
|
8
|
+
import { MdsBook as MdsBookElement } from "@maggioli-design-system/magma/dist/components/mds-book.js";
|
|
9
|
+
export declare const serializeShadowRoot: SerializeShadowRootOptions;
|
|
10
|
+
export type MdsBookEvents = NonNullable<unknown>;
|
|
11
|
+
export declare const MdsBook: StencilReactComponent<MdsBookElement, MdsBookEvents, Components.MdsBook>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maggioli-design-system/magma-react",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/components.js",
|
|
6
6
|
"module": "dist/components.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"access": "public"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@maggioli-design-system/magma": "2.
|
|
38
|
+
"@maggioli-design-system/magma": "2.7.0",
|
|
39
39
|
"@stencil/react-output-target": "1.6.5"
|
|
40
40
|
},
|
|
41
41
|
"repository": {
|