@nysds/mcp-server 1.21.0 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -2
- package/data/cem/custom-elements.json +1791 -1119
- package/data/frameworks.json +14 -0
- package/data/guides/frameworks/angular.md +184 -26
- package/data/guides/frameworks/react-additions.md +69 -0
- package/data/guides/frameworks/react.md +205 -23
- package/data/guides/frameworks/vue.md +356 -0
- package/data/tokens/tokens.css +1 -1
- package/dist/lib/cem-parser.d.ts +12 -0
- package/dist/lib/cem-parser.d.ts.map +1 -1
- package/dist/lib/framework-snippets.d.ts +36 -0
- package/dist/lib/framework-snippets.d.ts.map +1 -0
- package/dist/lib/framework-snippets.js +55 -0
- package/dist/lib/framework-usage.d.ts +20 -0
- package/dist/lib/framework-usage.d.ts.map +1 -0
- package/dist/lib/framework-usage.js +50 -0
- package/dist/lib/frameworks-data.d.ts +19 -0
- package/dist/lib/frameworks-data.d.ts.map +1 -0
- package/dist/lib/frameworks-data.js +40 -0
- package/dist/resources/frameworks.d.ts +15 -0
- package/dist/resources/frameworks.d.ts.map +1 -0
- package/dist/resources/frameworks.js +104 -0
- package/dist/resources/guides.d.ts.map +1 -1
- package/dist/resources/guides.js +12 -1
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +2 -0
- package/dist/tools/component-tools.d.ts.map +1 -1
- package/dist/tools/component-tools.js +20 -5
- package/dist/tools/guide-tools.js +1 -1
- package/package.json +6 -4
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
GENERATED FILE. Do not edit directly.
|
|
3
|
+
Source: packages/vue/README.md
|
|
4
|
+
Regenerate with: npm run sync:guides -w @nysds/mcp-server
|
|
5
|
+
-->
|
|
6
|
+
# @nysds/vue
|
|
7
|
+
|
|
8
|
+
Vue 3 components for the New York State Design System (NYSDS). Generated from the NYSDS web components library.
|
|
9
|
+
|
|
10
|
+
You get two ways to use the design system, and can mix them freely:
|
|
11
|
+
|
|
12
|
+
- **Wrapper components** (`<NysTextinput>`) — real Vue components with
|
|
13
|
+
typed props, `@nys-*` events, `<template #slot>` slots, and `v-model`
|
|
14
|
+
on form controls.
|
|
15
|
+
- **Raw `<nys-*>` tags** — the custom elements themselves, typed in
|
|
16
|
+
templates and TSX.
|
|
17
|
+
|
|
18
|
+
Requires Vue 3.4 or later (tested on 3.4 and 3.5).
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
### Setup a new React project
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm create vue@latest
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Install NYS Design System
|
|
29
|
+
```bash
|
|
30
|
+
npm install @nysds/vue @nysds/styles
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Load styles
|
|
34
|
+
|
|
35
|
+
Import the design system stylesheet once, in your app's main.ts:
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import "@nysds/styles/full";
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Vue's default TypeScript config rejects side-effect imports it can't
|
|
42
|
+
resolve, and a stylesheet isn't a module. If `npm run build` fails with
|
|
43
|
+
`TS2882: Cannot find module or type declarations for side-effect import of
|
|
44
|
+
'@nysds/styles/full'`, declare the stylesheets once in `env.d.ts`:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// env.d.ts
|
|
48
|
+
declare module "@nysds/styles/*";
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Optional agency theme: `<html data-theme="health">`. Themes: `admin`,
|
|
52
|
+
`business`, `environment`, `health`, `local`, `safety`, `transportation`.
|
|
53
|
+
Fonts aren't bundled. Load them the way your agency normally does.
|
|
54
|
+
|
|
55
|
+
### 4. Use a component
|
|
56
|
+
|
|
57
|
+
```vue
|
|
58
|
+
<script setup lang="ts">
|
|
59
|
+
import { NysAlert, NysButton } from "@nysds/vue";
|
|
60
|
+
|
|
61
|
+
const start = () => console.log("started");
|
|
62
|
+
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<template>
|
|
66
|
+
<NysAlert type="info" heading="Welcome" />
|
|
67
|
+
<NysButton label="Start" @nys-click="start" />
|
|
68
|
+
</template>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Importing a wrapper registers its custom element as a side effect — no
|
|
72
|
+
`app.use()` call or global registration. Run `npm run dev`; you should see
|
|
73
|
+
a styled alert and button.
|
|
74
|
+
|
|
75
|
+
That's the whole setup. No compiler options are needed for wrapper
|
|
76
|
+
components. If you'd rather write raw `<nys-*>` tags, see
|
|
77
|
+
[Raw tags](#raw-tags).
|
|
78
|
+
|
|
79
|
+
## Props, events, slots, and refs
|
|
80
|
+
|
|
81
|
+
**Props** are typed from the underlying element class and set as DOM
|
|
82
|
+
properties. Use camelCase or kebab-case in templates, whichever you
|
|
83
|
+
prefer (`appName` and `app-name` are the same prop). Bind numbers and
|
|
84
|
+
booleans with `:` so they keep their type:
|
|
85
|
+
|
|
86
|
+
```vue
|
|
87
|
+
<NysPagination :total-pages="5" :current-page="1" />
|
|
88
|
+
<NysTextinput label="Name" required :disabled="locked" />
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
A prop you don't pass is left alone, so the element keeps its own
|
|
92
|
+
default.
|
|
93
|
+
|
|
94
|
+
**Events** keep their full NYSDS names. Listen with `@nys-change`,
|
|
95
|
+
`@nys-input`, and so on. The handler parameter is the typed event, so
|
|
96
|
+
`e.detail` autocompletes:
|
|
97
|
+
|
|
98
|
+
```vue
|
|
99
|
+
<NysTextinput
|
|
100
|
+
label="First name"
|
|
101
|
+
@nys-input="(e) => console.log(e.detail.value)"
|
|
102
|
+
/>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Use the `nys-*` events rather than native `@input` and `@change`: they
|
|
106
|
+
are NYSDS's public event contract, they carry typed details, and they cover
|
|
107
|
+
cases native events don't (a combobox selection, a date picked from the
|
|
108
|
+
calendar).
|
|
109
|
+
|
|
110
|
+
**Slots** work with `<template #name>`. The default slot renders as direct
|
|
111
|
+
children:
|
|
112
|
+
|
|
113
|
+
```vue
|
|
114
|
+
<NysTextinput label="Email">
|
|
115
|
+
<template #description>We'll never share it.</template>
|
|
116
|
+
</NysTextinput>
|
|
117
|
+
|
|
118
|
+
<NysTooltip text="Tooltip text">
|
|
119
|
+
<NysButton label="Hover me" />
|
|
120
|
+
</NysTooltip>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Named slot content is wrapped in a `<span slot="…" style="display:
|
|
124
|
+
contents">` so any content (text, components, fragments) can fill it. You
|
|
125
|
+
can also put a plain `slot="name"` attribute on your own child element.
|
|
126
|
+
|
|
127
|
+
**Refs** on a wrapper resolve to the Vue component instance. The element
|
|
128
|
+
itself is `$el`, typed as the element class:
|
|
129
|
+
|
|
130
|
+
```vue
|
|
131
|
+
<script setup lang="ts">
|
|
132
|
+
import { ref } from "vue";
|
|
133
|
+
import { NysTextinput } from "@nysds/vue";
|
|
134
|
+
|
|
135
|
+
const name = ref<InstanceType<typeof NysTextinput> | null>(null);
|
|
136
|
+
const check = () => name.value?.$el.checkValidity();
|
|
137
|
+
</script>
|
|
138
|
+
|
|
139
|
+
<template>
|
|
140
|
+
<NysTextinput ref="name" label="Name" />
|
|
141
|
+
</template>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Forms
|
|
145
|
+
|
|
146
|
+
### `v-model`
|
|
147
|
+
|
|
148
|
+
Every form control supports `v-model`. It binds the property the
|
|
149
|
+
component's form contract defines:
|
|
150
|
+
|
|
151
|
+
| Component | `v-model` value |
|
|
152
|
+
| --- | --- |
|
|
153
|
+
| `NysTextinput`, `NysTextarea`, `NysSelect`, `NysCombobox`, `NysDatepicker`, `NysRadiogroup` | `string` |
|
|
154
|
+
| `NysCheckboxgroup` | `string[]` |
|
|
155
|
+
| `NysCheckbox`, `NysToggle` | `boolean` |
|
|
156
|
+
|
|
157
|
+
```vue
|
|
158
|
+
<script setup lang="ts">
|
|
159
|
+
import { reactive } from "vue";
|
|
160
|
+
import {
|
|
161
|
+
NysCheckbox,
|
|
162
|
+
NysCheckboxgroup,
|
|
163
|
+
NysRadiobutton,
|
|
164
|
+
NysRadiogroup,
|
|
165
|
+
NysTextinput,
|
|
166
|
+
} from "@nysds/vue";
|
|
167
|
+
|
|
168
|
+
const model = reactive({
|
|
169
|
+
firstName: "",
|
|
170
|
+
agree: false,
|
|
171
|
+
languages: [] as string[],
|
|
172
|
+
contact: "",
|
|
173
|
+
});
|
|
174
|
+
</script>
|
|
175
|
+
|
|
176
|
+
<template>
|
|
177
|
+
<NysTextinput v-model="model.firstName" label="First name" required />
|
|
178
|
+
<NysCheckbox v-model="model.agree" label="I agree to the terms" />
|
|
179
|
+
|
|
180
|
+
<NysCheckboxgroup v-model="model.languages" label="Languages">
|
|
181
|
+
<NysCheckbox label="English" value="en" />
|
|
182
|
+
<NysCheckbox label="Spanish" value="es" />
|
|
183
|
+
</NysCheckboxgroup>
|
|
184
|
+
|
|
185
|
+
<NysRadiogroup v-model="model.contact" label="Preferred contact" name="contact">
|
|
186
|
+
<NysRadiobutton label="Email" name="contact" value="email" />
|
|
187
|
+
<NysRadiobutton label="Phone" name="contact" value="phone" />
|
|
188
|
+
</NysRadiogroup>
|
|
189
|
+
</template>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
- Bind checkbox and radio groups on `NysCheckboxgroup` and
|
|
193
|
+
`NysRadiogroup`, not on each child.
|
|
194
|
+
- The model updates on the component's `nys-input` and `nys-change`
|
|
195
|
+
events. Add `.lazy` (`v-model.lazy`) to update on `nys-change` alone, as
|
|
196
|
+
on a native input.
|
|
197
|
+
- **File input** has no `v-model`. Listen for the change event and read
|
|
198
|
+
the files from its detail:
|
|
199
|
+
|
|
200
|
+
```vue
|
|
201
|
+
<NysFileinput
|
|
202
|
+
label="Resume"
|
|
203
|
+
@nys-change="(e) => (model.resume = e.detail.files[0]?.name ?? '')"
|
|
204
|
+
/>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Submit and validate with a native form
|
|
208
|
+
|
|
209
|
+
NYSDS form components are form-associated custom elements: they submit
|
|
210
|
+
with a plain `<form>` like native inputs, and `required`, `pattern`, and
|
|
211
|
+
the rest drive the component's own validation and error display.
|
|
212
|
+
|
|
213
|
+
```vue
|
|
214
|
+
<form @submit.prevent="onSubmit">
|
|
215
|
+
<NysTextinput v-model="model.firstName" label="First name" required />
|
|
216
|
+
<NysButton type="submit" label="Submit" />
|
|
217
|
+
</form>
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
`nys-button type="submit"` submits through `form.requestSubmit()`, so an
|
|
221
|
+
invalid form blocks `@submit` and the component shows its error.
|
|
222
|
+
|
|
223
|
+
To drive errors from your own validation library instead, set the
|
|
224
|
+
component's error props:
|
|
225
|
+
|
|
226
|
+
```vue
|
|
227
|
+
<NysTextinput
|
|
228
|
+
v-model="model.firstName"
|
|
229
|
+
label="First name"
|
|
230
|
+
:show-error="!!errors.firstName"
|
|
231
|
+
:error-message="errors.firstName"
|
|
232
|
+
/>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Reset
|
|
236
|
+
|
|
237
|
+
Setting the model back to its initial values resets every control. The
|
|
238
|
+
file input has no bound value, so also call `reset()` on the form:
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
const form = ref<HTMLFormElement | null>(null);
|
|
242
|
+
|
|
243
|
+
function reset() {
|
|
244
|
+
Object.assign(model, initialModel());
|
|
245
|
+
form.value?.reset();
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Raw tags
|
|
250
|
+
|
|
251
|
+
If you prefer the custom elements directly, import the package once for
|
|
252
|
+
its side effects and types, then tell Vue's compiler that `nys-*` tags are
|
|
253
|
+
custom elements so it doesn't try to resolve them as components:
|
|
254
|
+
|
|
255
|
+
```ts
|
|
256
|
+
// vite.config.ts
|
|
257
|
+
import vue from "@vitejs/plugin-vue";
|
|
258
|
+
|
|
259
|
+
export default {
|
|
260
|
+
plugins: [
|
|
261
|
+
vue({
|
|
262
|
+
template: {
|
|
263
|
+
compilerOptions: { isCustomElement: (tag) => tag.startsWith("nys-") },
|
|
264
|
+
},
|
|
265
|
+
}),
|
|
266
|
+
],
|
|
267
|
+
};
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
```vue
|
|
271
|
+
<script setup lang="ts">
|
|
272
|
+
import { reactive } from "vue";
|
|
273
|
+
import "@nysds/vue"; // registers every element and adds the tag types
|
|
274
|
+
|
|
275
|
+
const model = reactive({ firstName: "" });
|
|
276
|
+
</script>
|
|
277
|
+
|
|
278
|
+
<template>
|
|
279
|
+
<nys-textinput
|
|
280
|
+
label="First name"
|
|
281
|
+
:value="model.firstName"
|
|
282
|
+
@nys-input="(e) => (model.firstName = e.detail.value)"
|
|
283
|
+
/>
|
|
284
|
+
</template>
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Raw tags are typed in `.vue` templates (checked by `vue-tsc`) and in TSX.
|
|
288
|
+
Bind properties with `:` and update your state from the `@nys-*`
|
|
289
|
+
listener.
|
|
290
|
+
|
|
291
|
+
**Raw tags have no working `v-model`.** Vue's built-in `v-model` listens for
|
|
292
|
+
native `input` events instead of the `nys-*` events that make up NYSDS's
|
|
293
|
+
contract, so it misses updates (a combobox selection, a calendar pick, a
|
|
294
|
+
checkbox). Use a wrapper component, or bind `:value` and `@nys-input`
|
|
295
|
+
yourself as above.
|
|
296
|
+
|
|
297
|
+
## TypeScript
|
|
298
|
+
|
|
299
|
+
- `NysTextinputProps` is the full prop type, including the `on*` event
|
|
300
|
+
handlers and, for form controls, `modelValue`.
|
|
301
|
+
- `NysTextinputElement` is the element class type.
|
|
302
|
+
- `NysTextinputSlots` and `NysTextinputSlotName` describe the slots.
|
|
303
|
+
- Event detail types come from the component packages:
|
|
304
|
+
`import type { NysTextinputInputEvent } from "@nysds/nys-textinput"`.
|
|
305
|
+
- Run `vue-tsc --noEmit` in your build to type-check templates. Unknown
|
|
306
|
+
props on a wrapper are compile errors; slot names are checked in `.vue`
|
|
307
|
+
files but not in TSX.
|
|
308
|
+
|
|
309
|
+
## SSR and Nuxt
|
|
310
|
+
|
|
311
|
+
The package is safe to import in Node, and a wrapper renders its bare
|
|
312
|
+
element on the server. Components upgrade and become interactive in the
|
|
313
|
+
browser; there is no declarative shadow DOM rendering in this release, and
|
|
314
|
+
hydration has not been verified. For SSR frameworks such as Nuxt, render
|
|
315
|
+
NYSDS components inside client-only boundaries (`<ClientOnly>`) until you
|
|
316
|
+
have tested hydration in your app.
|
|
317
|
+
|
|
318
|
+
## Troubleshooting
|
|
319
|
+
|
|
320
|
+
**The element renders but has no styling or behavior.** The custom
|
|
321
|
+
element didn't upgrade. Import the component from `@nysds/vue` (the import
|
|
322
|
+
registers it) and check the browser console for load errors. If you use
|
|
323
|
+
raw `<nys-*>` tags, add `import "@nysds/vue"` yourself.
|
|
324
|
+
|
|
325
|
+
**Everything renders unstyled.** Import `@nysds/styles/full` once at your
|
|
326
|
+
entry file.
|
|
327
|
+
|
|
328
|
+
**`Failed to resolve component: nys-…`.** You used a raw tag without the
|
|
329
|
+
`isCustomElement` compiler option. Add it (see [Raw tags](#raw-tags)) or
|
|
330
|
+
use the wrapper component instead.
|
|
331
|
+
|
|
332
|
+
**`v-model` on a raw `<nys-*>` tag doesn't update.** See
|
|
333
|
+
[Raw tags](#raw-tags): use a wrapper, or bind `:value` and `@nys-input`.
|
|
334
|
+
|
|
335
|
+
**A prop change doesn't reach the element.** Bind numbers and booleans
|
|
336
|
+
with `:` (`:total-pages="5"`), not as plain attributes, so Vue passes the
|
|
337
|
+
typed value.
|
|
338
|
+
|
|
339
|
+
**Slot content has an extra wrapper.** Named slot content sits inside a
|
|
340
|
+
`display: contents` span. To avoid it, put a `slot="name"` attribute on
|
|
341
|
+
your own child element instead of using `<template #name>`.
|
|
342
|
+
|
|
343
|
+
**`app.use(router)` or the `<nys-*>` types break with two Vue versions.**
|
|
344
|
+
Two copies of Vue in `node_modules` give TypeScript two sets of types. Run
|
|
345
|
+
`npm ls vue` and dedupe. In a monorepo where you pin a different Vue in one
|
|
346
|
+
workspace, map `vue` in that app's `tsconfig.json`:
|
|
347
|
+
|
|
348
|
+
```json
|
|
349
|
+
{ "compilerOptions": { "baseUrl": ".", "paths": { "vue": ["./node_modules/vue"] } } }
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## How this package is built
|
|
353
|
+
|
|
354
|
+
`src/generated/` is written by the `@nysds/codegen` CEM plugin on every
|
|
355
|
+
`npm run cem` and is not committed. The one hand-written file is
|
|
356
|
+
`src/runtime.ts`, which builds each wrapper from the generated metadata.
|
package/data/tokens/tokens.css
CHANGED
package/dist/lib/cem-parser.d.ts
CHANGED
|
@@ -48,6 +48,17 @@ export interface CEMExample {
|
|
|
48
48
|
code: string;
|
|
49
49
|
lang?: string;
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* `@formControl <kind> <changeEvent> [inputEvent]` metadata, written by WS1
|
|
53
|
+
* on every form-control component's class JSDoc and parsed into the
|
|
54
|
+
* manifest by the CEM plugin. Drives the Angular `ControlValueAccessor`
|
|
55
|
+
* base class choice and the React/Angular snippet transformer's forms mode.
|
|
56
|
+
*/
|
|
57
|
+
export interface CEMFormControl {
|
|
58
|
+
kind: "value" | "checked" | "files";
|
|
59
|
+
changeEvent: string;
|
|
60
|
+
inputEvent?: string;
|
|
61
|
+
}
|
|
51
62
|
export interface CEMDeclaration {
|
|
52
63
|
kind: "class";
|
|
53
64
|
name: string;
|
|
@@ -65,6 +76,7 @@ export interface CEMDeclaration {
|
|
|
65
76
|
package?: string;
|
|
66
77
|
};
|
|
67
78
|
examples?: CEMExample[];
|
|
79
|
+
formControl?: CEMFormControl;
|
|
68
80
|
}
|
|
69
81
|
export interface CEMModule {
|
|
70
82
|
kind: "javascript-module";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cem-parser.d.ts","sourceRoot":"","sources":["../../src/lib/cem-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,aAAa,CAAC,EAAE,cAAc,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"cem-parser.d.ts","sourceRoot":"","sources":["../../src/lib/cem-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework snippet generation
|
|
3
|
+
*
|
|
4
|
+
* Turns a component's canonical HTML examples into React and Angular
|
|
5
|
+
* snippets using `@nysds/codegen`'s `transformExample` — the same
|
|
6
|
+
* transformer the docs site and Storybook autodocs use, so an AI assistant
|
|
7
|
+
* asking the MCP server sees exactly the same code a developer sees on
|
|
8
|
+
* designsystem.ny.gov.
|
|
9
|
+
*/
|
|
10
|
+
import { type CEMExample, type CEMFormControl } from "./cem-parser.js";
|
|
11
|
+
export type FrameworkFilter = "html" | "react" | "angular";
|
|
12
|
+
export interface FrameworkSnippet {
|
|
13
|
+
code: string;
|
|
14
|
+
imports: string[];
|
|
15
|
+
warnings: string[];
|
|
16
|
+
unsupported: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface ExampleWithSnippets {
|
|
19
|
+
title: string;
|
|
20
|
+
html: string;
|
|
21
|
+
react: FrameworkSnippet;
|
|
22
|
+
angular: FrameworkSnippet;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Builds React and Angular snippets for every HTML example on a component.
|
|
26
|
+
*
|
|
27
|
+
* When `framework` names one target explicitly, that framework's snippet
|
|
28
|
+
* uses its most idiomatic forms binding for a form-control component —
|
|
29
|
+
* React's controlled pattern (`value` + `onNys*`), Angular's
|
|
30
|
+
* `formControlName` (Reactive Forms). The unrequested framework, and every
|
|
31
|
+
* snippet when `framework` is `"html"` (the default), stays a plain
|
|
32
|
+
* attribute-for-attribute conversion so the default response isn't
|
|
33
|
+
* surprising.
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildExampleSnippets(examples: CEMExample[] | undefined, framework: FrameworkFilter, formControl: CEMFormControl | undefined): ExampleWithSnippets[];
|
|
36
|
+
//# sourceMappingURL=framework-snippets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-snippets.d.ts","sourceRoot":"","sources":["../../src/lib/framework-snippets.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAO,EAAU,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE/E,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAgBD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,UAAU,EAAE,GAAG,SAAS,EAClC,SAAS,EAAE,eAAe,EAC1B,WAAW,EAAE,cAAc,GAAG,SAAS,GACtC,mBAAmB,EAAE,CA+BvB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework snippet generation
|
|
3
|
+
*
|
|
4
|
+
* Turns a component's canonical HTML examples into React and Angular
|
|
5
|
+
* snippets using `@nysds/codegen`'s `transformExample` — the same
|
|
6
|
+
* transformer the docs site and Storybook autodocs use, so an AI assistant
|
|
7
|
+
* asking the MCP server sees exactly the same code a developer sees on
|
|
8
|
+
* designsystem.ny.gov.
|
|
9
|
+
*/
|
|
10
|
+
import { transformExample, } from "@nysds/codegen";
|
|
11
|
+
import { getCEM } from "./cem-parser.js";
|
|
12
|
+
function toSnippet(result) {
|
|
13
|
+
return {
|
|
14
|
+
code: result.code,
|
|
15
|
+
imports: result.imports,
|
|
16
|
+
warnings: result.warnings,
|
|
17
|
+
unsupported: result.unsupported,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Builds React and Angular snippets for every HTML example on a component.
|
|
22
|
+
*
|
|
23
|
+
* When `framework` names one target explicitly, that framework's snippet
|
|
24
|
+
* uses its most idiomatic forms binding for a form-control component —
|
|
25
|
+
* React's controlled pattern (`value` + `onNys*`), Angular's
|
|
26
|
+
* `formControlName` (Reactive Forms). The unrequested framework, and every
|
|
27
|
+
* snippet when `framework` is `"html"` (the default), stays a plain
|
|
28
|
+
* attribute-for-attribute conversion so the default response isn't
|
|
29
|
+
* surprising.
|
|
30
|
+
*/
|
|
31
|
+
export function buildExampleSnippets(examples, framework, formControl) {
|
|
32
|
+
if (!examples || examples.length === 0)
|
|
33
|
+
return [];
|
|
34
|
+
const manifest = getCEM();
|
|
35
|
+
const reactFormsMode = framework === "react" && formControl ? "template" : "none";
|
|
36
|
+
const angularFormsMode = framework === "angular" && formControl ? "reactive" : "none";
|
|
37
|
+
return examples
|
|
38
|
+
.filter((example) => !example.lang || example.lang === "html")
|
|
39
|
+
.map((example) => ({
|
|
40
|
+
title: example.title,
|
|
41
|
+
html: example.code,
|
|
42
|
+
react: toSnippet(transformExample({
|
|
43
|
+
html: example.code,
|
|
44
|
+
framework: "react",
|
|
45
|
+
manifest,
|
|
46
|
+
formsMode: reactFormsMode,
|
|
47
|
+
})),
|
|
48
|
+
angular: toSnippet(transformExample({
|
|
49
|
+
html: example.code,
|
|
50
|
+
framework: "angular",
|
|
51
|
+
manifest,
|
|
52
|
+
formsMode: angularFormsMode,
|
|
53
|
+
})),
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework usage notes
|
|
3
|
+
*
|
|
4
|
+
* Short, framework-specific guidance attached to `get_component` responses
|
|
5
|
+
* when the caller asks for `framework: "react"` or `"angular"` — the import
|
|
6
|
+
* line, the event-prop naming rule, and (when the component is a form
|
|
7
|
+
* control) how it binds into that framework's forms. Naming follows the
|
|
8
|
+
* rules in `.claude/plans/framework-support/README.md` section 4.1, reused
|
|
9
|
+
* here via `@nysds/codegen` rather than re-derived.
|
|
10
|
+
*/
|
|
11
|
+
import type { CEMFormControl } from "./cem-parser.js";
|
|
12
|
+
export interface FrameworkUsageNotes {
|
|
13
|
+
package: string;
|
|
14
|
+
import: string;
|
|
15
|
+
events: string;
|
|
16
|
+
forms?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function buildReactUsageNotes(tagName: string, className: string, formControl: CEMFormControl | undefined): FrameworkUsageNotes;
|
|
19
|
+
export declare function buildAngularUsageNotes(tagName: string, className: string, formControl: CEMFormControl | undefined): FrameworkUsageNotes;
|
|
20
|
+
//# sourceMappingURL=framework-usage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-usage.d.ts","sourceRoot":"","sources":["../../src/lib/framework-usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAQD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,cAAc,GAAG,SAAS,GACtC,mBAAmB,CAqBrB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,cAAc,GAAG,SAAS,GACtC,mBAAmB,CAmBrB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework usage notes
|
|
3
|
+
*
|
|
4
|
+
* Short, framework-specific guidance attached to `get_component` responses
|
|
5
|
+
* when the caller asks for `framework: "react"` or `"angular"` — the import
|
|
6
|
+
* line, the event-prop naming rule, and (when the component is a form
|
|
7
|
+
* control) how it binds into that framework's forms. Naming follows the
|
|
8
|
+
* rules in `.claude/plans/framework-support/README.md` section 4.1, reused
|
|
9
|
+
* here via `@nysds/codegen` rather than re-derived.
|
|
10
|
+
*/
|
|
11
|
+
import { eventToAngularOutput, eventToReactProp, tagToSubpath, } from "@nysds/codegen";
|
|
12
|
+
const FORM_CONTROL_LABEL = {
|
|
13
|
+
value: "value",
|
|
14
|
+
checked: "checked state",
|
|
15
|
+
files: "selected files",
|
|
16
|
+
};
|
|
17
|
+
export function buildReactUsageNotes(tagName, className, formControl) {
|
|
18
|
+
const subpath = tagToSubpath(tagName);
|
|
19
|
+
const changeProp = formControl
|
|
20
|
+
? eventToReactProp(formControl.changeEvent)
|
|
21
|
+
: undefined;
|
|
22
|
+
const inputProp = formControl?.inputEvent !== undefined
|
|
23
|
+
? eventToReactProp(formControl.inputEvent)
|
|
24
|
+
: undefined;
|
|
25
|
+
return {
|
|
26
|
+
package: "@nysds/react",
|
|
27
|
+
import: `import { ${className} } from "@nysds/react/${subpath}";`,
|
|
28
|
+
events: "Events map to onNys* props (nys-change -> onNysChange). The handler receives the typed CustomEvent, so e.detail autocompletes.",
|
|
29
|
+
forms: formControl
|
|
30
|
+
? `Form control (${formControl.kind}). For a controlled component, bind ${formControl.kind} and update state from ${changeProp}${inputProp ? ` (or ${inputProp} for every keystroke)` : ""}; re-rendering with the same ${FORM_CONTROL_LABEL[formControl.kind]} snaps the element back to your state. See get_guide({ topic: "installation", framework: "react" }) for React Hook Form and uncontrolled-form patterns.`
|
|
31
|
+
: undefined,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export function buildAngularUsageNotes(tagName, className, formControl) {
|
|
35
|
+
const subpath = tagToSubpath(tagName);
|
|
36
|
+
const angularClass = `${className}Component`;
|
|
37
|
+
const changeOutput = formControl
|
|
38
|
+
? eventToAngularOutput(formControl.changeEvent)
|
|
39
|
+
: undefined;
|
|
40
|
+
return {
|
|
41
|
+
package: "@nysds/angular",
|
|
42
|
+
import: `import { ${angularClass} } from "@nysds/angular/${subpath}";`,
|
|
43
|
+
events: `Events map to camelCase outputs (nys-change -> (nysChange)); event.detail is typed.${changeOutput
|
|
44
|
+
? ` This component's change output is (${changeOutput}).`
|
|
45
|
+
: ""}`,
|
|
46
|
+
forms: formControl
|
|
47
|
+
? 'Implements ControlValueAccessor: works with [(ngModel)], formControlName (Reactive Forms), and Signal Forms [formField] with no CUSTOM_ELEMENTS_SCHEMA. Add the nysControlErrors directive to let Angular own validation display instead of the component\'s own errorMessage/showError. See get_guide({ topic: "installation", framework: "angular" }).'
|
|
48
|
+
: undefined,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework package index
|
|
3
|
+
*
|
|
4
|
+
* Reads `data/frameworks.json`, written by `scripts/sync-guides.mjs` from
|
|
5
|
+
* the `package.json` of each framework package (react, vue, angular). Gives
|
|
6
|
+
* tools and resources the published package name and version without
|
|
7
|
+
* hand-maintaining either.
|
|
8
|
+
*/
|
|
9
|
+
export interface FrameworkPackageInfo {
|
|
10
|
+
packageName: string;
|
|
11
|
+
version: string;
|
|
12
|
+
}
|
|
13
|
+
export interface FrameworksIndex {
|
|
14
|
+
react: FrameworkPackageInfo;
|
|
15
|
+
vue: FrameworkPackageInfo;
|
|
16
|
+
angular: FrameworkPackageInfo;
|
|
17
|
+
}
|
|
18
|
+
export declare function getFrameworksIndex(): FrameworksIndex;
|
|
19
|
+
//# sourceMappingURL=frameworks-data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frameworks-data.d.ts","sourceRoot":"","sources":["../../src/lib/frameworks-data.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,oBAAoB,CAAC;IAC5B,GAAG,EAAE,oBAAoB,CAAC;IAC1B,OAAO,EAAE,oBAAoB,CAAC;CAC/B;AAiBD,wBAAgB,kBAAkB,IAAI,eAAe,CAepD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework package index
|
|
3
|
+
*
|
|
4
|
+
* Reads `data/frameworks.json`, written by `scripts/sync-guides.mjs` from
|
|
5
|
+
* the `package.json` of each framework package (react, vue, angular). Gives
|
|
6
|
+
* tools and resources the published package name and version without
|
|
7
|
+
* hand-maintaining either.
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
10
|
+
import { resolve, dirname } from "node:path";
|
|
11
|
+
import { fileURLToPath } from "node:url";
|
|
12
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
let cached = null;
|
|
14
|
+
function getFrameworksDataPath() {
|
|
15
|
+
const candidates = [
|
|
16
|
+
resolve(__dirname, "../../data/frameworks.json"),
|
|
17
|
+
resolve(process.cwd(), "data/frameworks.json"),
|
|
18
|
+
];
|
|
19
|
+
for (const path of candidates) {
|
|
20
|
+
if (existsSync(path))
|
|
21
|
+
return path;
|
|
22
|
+
}
|
|
23
|
+
throw new Error(`data/frameworks.json not found. Searched paths:\n${candidates.join("\n")}`);
|
|
24
|
+
}
|
|
25
|
+
export function getFrameworksIndex() {
|
|
26
|
+
if (cached)
|
|
27
|
+
return cached;
|
|
28
|
+
try {
|
|
29
|
+
cached = JSON.parse(readFileSync(getFrameworksDataPath(), "utf-8"));
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.error("Warning: Could not load data/frameworks.json:", error);
|
|
33
|
+
cached = {
|
|
34
|
+
react: { packageName: "@nysds/react", version: "unknown" },
|
|
35
|
+
vue: { packageName: "@nysds/vue", version: "unknown" },
|
|
36
|
+
angular: { packageName: "@nysds/angular", version: "unknown" },
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return cached;
|
|
40
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework Resources
|
|
3
|
+
*
|
|
4
|
+
* MCP resources for NYSDS framework packages (@nysds/react, @nysds/vue,
|
|
5
|
+
* @nysds/angular).
|
|
6
|
+
*
|
|
7
|
+
* Resources:
|
|
8
|
+
* - nysds://frameworks - Index of framework packages with version and guide URI
|
|
9
|
+
* - nysds://frameworks/react - @nysds/react guide (synced from its README)
|
|
10
|
+
* - nysds://frameworks/vue - @nysds/vue guide (synced from its README)
|
|
11
|
+
* - nysds://frameworks/angular - @nysds/angular guide (synced from its README)
|
|
12
|
+
*/
|
|
13
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
14
|
+
export declare function registerFrameworkResources(server: McpServer): void;
|
|
15
|
+
//# sourceMappingURL=frameworks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frameworks.d.ts","sourceRoot":"","sources":["../../src/resources/frameworks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAezE,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwGlE"}
|