sveld 0.34.0 → 0.35.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 +360 -82
- package/cli.js +6 -1
- package/lib/ComponentParser.d.ts +201 -568
- package/lib/ast-guards.d.ts +3 -1
- package/lib/bundle.d.ts +15 -2
- package/lib/check.d.ts +6 -0
- package/lib/cli.d.ts +18 -16
- package/lib/diagnostics.d.ts +5 -1
- package/lib/example-check.d.ts +3 -1
- package/lib/index.js +446 -719
- package/lib/load-config.d.ts +20 -2
- package/lib/parser/bindings.d.ts +6 -0
- package/lib/parser/context.d.ts +110 -0
- package/lib/parser/contexts.d.ts +19 -0
- package/lib/parser/diagnostics.d.ts +8 -0
- package/lib/parser/events.d.ts +23 -0
- package/lib/parser/generics.d.ts +24 -0
- package/lib/parser/jsdoc.d.ts +59 -0
- package/lib/parser/props.d.ts +67 -0
- package/lib/parser/rest-props.d.ts +6 -0
- package/lib/parser/runes-props.d.ts +18 -0
- package/lib/parser/scopes.d.ts +40 -0
- package/lib/parser/slots.d.ts +29 -0
- package/lib/parser/source-position.d.ts +30 -0
- package/lib/parser/type-resolution.d.ts +27 -0
- package/lib/plugin.d.ts +7 -3
- package/lib/sveld.d.ts +6 -14
- package/lib/writer/MarkdownWriterBase.d.ts +2 -1
- package/lib/writer/Writer.d.ts +13 -49
- package/lib/writer/WriterMarkdown.d.ts +1 -1
- package/lib/writer/format-generated-ts.d.ts +8 -0
- package/lib/writer/writer-custom-elements-core.d.ts +86 -0
- package/lib/writer/writer-custom-elements.d.ts +15 -0
- package/lib/writer/writer-ts-definitions-core.d.ts +12 -1
- package/lib/writer/writer-ts-definitions.d.ts +4 -3
- package/package.json +1 -4
package/README.md
CHANGED
|
@@ -3,24 +3,21 @@
|
|
|
3
3
|
[![NPM][npm]][npm-url]
|
|
4
4
|

|
|
5
5
|
|
|
6
|
-
`sveld` generates TypeScript definitions and component documentation (Markdown/JSON) for Svelte components. It statically analyzes props, events, slots, and
|
|
6
|
+
`sveld` generates TypeScript definitions and component documentation (Markdown/JSON) for Svelte components. It statically analyzes props, events, slots, module exports, context, and `$$restProps`. Add types with [JSDoc](https://jsdoc.app/) when inference is not enough.
|
|
7
7
|
|
|
8
8
|
The goal is to get third-party Svelte libraries working with the Svelte Language Server and TypeScript with minimal effort from the author. Generated `.d.ts` files give you autocomplete in VS Code and other IDEs.
|
|
9
9
|
|
|
10
10
|
[Carbon Components Svelte](https://github.com/carbon-design-system/carbon-components-svelte) uses this library to auto-generate component types and API metadata.
|
|
11
11
|
|
|
12
|
-
`sveld` uses the Svelte 5 compiler to parse `.svelte` files. That single parse path powers docgen and TypeScript output for Svelte 3, Svelte 4, Svelte 5 without runes (`export let`, `<slot>`, `$$restProps`, …)
|
|
12
|
+
`sveld` uses the Svelte 5 compiler to parse `.svelte` files. That single parse path powers docgen and TypeScript output for Svelte 3, Svelte 4, and Svelte 5 without runes (`export let`, `<slot>`, `$$restProps`, …). It also covers Svelte 5 Runes (`$props()`, `$bindable()`, `{@render ...}`, callback props such as `onclick`, …).
|
|
13
13
|
|
|
14
14
|
For `lang="ts"` components, `sveld` keeps source-level prop type annotations when it can, instead of forcing JSDoc. That covers legacy `export let` props, typed `$props()` destructuring, typed whole-object `$props()` captures, local `interface`/`type` declarations, and imported type references in emitted `.d.ts` files.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
| :------------------- | :-------: |
|
|
18
|
-
| Svelte 3 | ✓ |
|
|
19
|
-
| Svelte 4 | ✓ |
|
|
20
|
-
| Svelte 5 (non-Runes) | ✓ |
|
|
21
|
-
| Svelte 5 Runes | ✓ |
|
|
16
|
+
By default, generated `.d.ts` files extend `SvelteComponentTyped` from `svelte`, so TypeScript and the Svelte Language Server work whether consumers use Svelte 3, Svelte 4, or Svelte 5. Set `typesOptions.format: "component"` to instead emit the Svelte 5 `Component` type; see [`typesOptions.format`](#typesoptionsformat).
|
|
22
17
|
|
|
23
|
-
|
|
18
|
+
## When to use sveld
|
|
19
|
+
|
|
20
|
+
SvelteKit's library tooling (`svelte-package`) and `svelte2tsx` already emit `.d.ts` files for SvelteKit-based projects, so start there if that's your setup. `sveld` targets JS-first Svelte libraries: components authored in plain JavaScript with JSDoc rather than `lang="ts"`, where you still want full editor types without adopting TypeScript. It also covers cases `svelte-package` doesn't: generating JSON and Markdown component docs from the same source as the types, checking for API drift between releases (`--check`), and deriving richer types from JSDoc tags (`@typedef`, `@callback`, `@slot`, context types) than plain type inference produces.
|
|
24
21
|
|
|
25
22
|
---
|
|
26
23
|
|
|
@@ -72,6 +69,8 @@ export default class Button extends SvelteComponentTyped<
|
|
|
72
69
|
> {}
|
|
73
70
|
```
|
|
74
71
|
|
|
72
|
+
`sveld` adds the `[key: \`data-${string}\`]: unknown;` index signature whenever `$$restProps` is spread onto an element, so callers can pass arbitrary `data-*` attributes.
|
|
73
|
+
|
|
75
74
|
Inference only gets you so far. Use [JSDoc](https://jsdoc.app/) to document prop, event, and slot types when you need more precision.
|
|
76
75
|
|
|
77
76
|
```js
|
|
@@ -87,6 +86,7 @@ export let primary = false;
|
|
|
87
86
|
With JSDoc, the output looks like this:
|
|
88
87
|
|
|
89
88
|
```ts
|
|
89
|
+
import { SvelteComponentTyped } from "svelte";
|
|
90
90
|
import type { SvelteHTMLElements } from "svelte/elements";
|
|
91
91
|
|
|
92
92
|
type $RestProps = SvelteHTMLElements["button"];
|
|
@@ -117,19 +117,31 @@ export default class Button extends SvelteComponentTyped<
|
|
|
117
117
|
|
|
118
118
|
## Table of Contents
|
|
119
119
|
|
|
120
|
+
- [When to use sveld](#when-to-use-sveld)
|
|
120
121
|
- [Approach](#approach)
|
|
122
|
+
- [Features](#features)
|
|
123
|
+
- [`.d.ts` output format (`typesOptions.format`)](#dts-output-format-typesoptionsformat)
|
|
124
|
+
- [Opt-in semantic resolution (`resolveTypes`)](#opt-in-semantic-resolution-resolvetypes)
|
|
125
|
+
- [Persistent parse cache (`cache`)](#persistent-parse-cache-cache)
|
|
126
|
+
- [Compile-checked `@example` blocks (`checkExamples`)](#compile-checked-example-blocks-checkexamples)
|
|
127
|
+
- [Type inference diagnostics](#type-inference-diagnostics)
|
|
128
|
+
- [Requirements](#requirements)
|
|
121
129
|
- [Usage](#usage)
|
|
122
130
|
- [Installation](#installation)
|
|
123
131
|
- [Vite](#vite)
|
|
124
|
-
- [Node.js](#nodejs)
|
|
125
132
|
- [CLI](#cli)
|
|
126
133
|
- [CI: API-drift checks (`--check`)](#ci-api-drift-checks---check)
|
|
134
|
+
- [Node.js](#nodejs)
|
|
127
135
|
- [Config File](#config-file)
|
|
128
136
|
- [Publishing to NPM](#publishing-to-npm)
|
|
129
137
|
- [Available Options](#available-options)
|
|
130
138
|
- [Documenting Entry Exports](#documenting-entry-exports)
|
|
131
139
|
- [JSON Output](#json-output)
|
|
140
|
+
- [Custom Elements Manifest](#custom-elements-manifest)
|
|
141
|
+
- [Consuming the manifest](#consuming-the-manifest)
|
|
132
142
|
- [API Reference](#api-reference)
|
|
143
|
+
- [reactive](#reactive)
|
|
144
|
+
- [binding](#binding)
|
|
133
145
|
- [@type](#type)
|
|
134
146
|
- [@default](#default)
|
|
135
147
|
- [@typedef](#typedef)
|
|
@@ -146,6 +158,7 @@ export default class Button extends SvelteComponentTyped<
|
|
|
146
158
|
- [@generics](#generics)
|
|
147
159
|
- [@component comments](#component-comments)
|
|
148
160
|
- [Accessor Props](#accessor-props)
|
|
161
|
+
- [Troubleshooting](#troubleshooting)
|
|
149
162
|
- [Contributing](#contributing)
|
|
150
163
|
- [License](#license)
|
|
151
164
|
|
|
@@ -173,7 +186,73 @@ When both TypeScript syntax and JSDoc are present, `sveld` resolves prop types i
|
|
|
173
186
|
|
|
174
187
|
`sveld` stays AST-only. It copies imported and local type text into generated `.d.ts` output but does not run project-wide semantic resolution with the TypeScript compiler. Opaque imported whole-object `$props()` types can therefore stay in declarations without being fully expanded into JSON metadata.
|
|
175
188
|
|
|
176
|
-
|
|
189
|
+
## Features
|
|
190
|
+
|
|
191
|
+
### `.d.ts` output format (`typesOptions.format`)
|
|
192
|
+
|
|
193
|
+
`typesOptions.format` controls the shape of generated `.d.ts` files: `"class"` (the default) or `"component"`.
|
|
194
|
+
|
|
195
|
+
`"class"` extends `SvelteComponentTyped`, deprecated in Svelte 5 and plausibly removed in Svelte 6:
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
import { SvelteComponentTyped } from "svelte";
|
|
199
|
+
|
|
200
|
+
export type ButtonProps = { label?: string };
|
|
201
|
+
|
|
202
|
+
export default class Button extends SvelteComponentTyped<
|
|
203
|
+
ButtonProps,
|
|
204
|
+
{ click: WindowEventMap["click"] },
|
|
205
|
+
{ default: Record<string, never> }
|
|
206
|
+
> {}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
`"component"` emits the Svelte 5 `Component` type instead:
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
import type { Component } from "svelte";
|
|
213
|
+
|
|
214
|
+
export type ButtonProps = { label?: string; onclick?: (event: WindowEventMap["click"]) => void };
|
|
215
|
+
export type ButtonExports = Record<string, never>;
|
|
216
|
+
|
|
217
|
+
declare const Button: Component<ButtonProps, ButtonExports, "">;
|
|
218
|
+
export default Button;
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Publish `"component"` if you target Svelte 5+ consumers. `"class"` remains compatible with Svelte 3, 4, and 5.
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
await sveld({ types: true, typesOptions: { format: "component" } });
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Also available as `--types-format=component` on the CLI.
|
|
228
|
+
|
|
229
|
+
`"component"`'s three type parameters:
|
|
230
|
+
|
|
231
|
+
- **Props**: the same `$Props`/`<Name>Props` type as `"class"`. Runes components already declare callback props (e.g. `onclick`) as regular props. Legacy (non-runes) components additionally get `on<name>?: (event: Type) => void` callback props for every dispatched and forwarded event, so Svelte 5 consumers can attach handlers as props instead of `on:event`.
|
|
232
|
+
- **Exports**: the component's accessor props (exported `function`/`const` members), the same members that render as class members under `"class"`.
|
|
233
|
+
- **Bindings**: a union of string literals for props declared with `$bindable(...)` (runes) or marked `@bindable writable` ([see `binding`](#binding)) (legacy) — e.g. `"value"`, or `"value" | "open"` for more than one. `""` when the component declares none, matching Svelte's own convention for "no bindings."
|
|
234
|
+
|
|
235
|
+
**Generic components.** A `declare const X: Component<...>` value can't itself carry a generic type parameter the way a class can, so generic components (`@template`/`generics`) get a per-component interface instead of `Component<...>` directly:
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
interface GenericListComponent {
|
|
239
|
+
new <Item extends { id: string | number } = { id: string }>(
|
|
240
|
+
options: ComponentConstructorOptions<GenericListProps<Item>>,
|
|
241
|
+
): SvelteComponent<GenericListProps<Item>> & GenericListExports;
|
|
242
|
+
<Item extends { id: string | number } = { id: string }>(
|
|
243
|
+
this: void,
|
|
244
|
+
internals: ComponentInternals,
|
|
245
|
+
props: GenericListProps<Item>,
|
|
246
|
+
): { $on?(...): () => void; $set?(...): void } & GenericListExports;
|
|
247
|
+
z_$$bindings?: "";
|
|
248
|
+
}
|
|
249
|
+
declare const GenericList: GenericListComponent;
|
|
250
|
+
export default GenericList;
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Both signatures carry their own generic parameter (not the `const` itself), so `Item` is inferred per usage site, e.g. `<GenericList items={numbers} />` infers `Item` from `numbers`. The `new` signature is the one place `"component"` format still touches a legacy type (`SvelteComponent`/`ComponentConstructorOptions`, not the deprecated `SvelteComponentTyped`): the Svelte language server resolves generic inference for `<Comp prop={...} />` template usage through `new`, not the plain call signature, confirmed by comparing against `@sveltejs/package`'s own generated output for the same component. Omitting it silently breaks inference instead of erroring, so it stays in even though it means one legacy import for generic components.
|
|
254
|
+
|
|
255
|
+
### Opt-in semantic resolution (`resolveTypes`)
|
|
177
256
|
|
|
178
257
|
Imported whole-object `$props()` types stay opaque in JSON by default (`"props": []`). Turn on `resolveTypes` when a docs site or prop table needs the individual fields.
|
|
179
258
|
|
|
@@ -203,19 +282,19 @@ Without `resolveTypes`, JSON lists no props. With it, each field shows up with `
|
|
|
203
282
|
|
|
204
283
|
**Performance.** Off by default. This is the only path that loads TypeScript. It needs `typescript` and a `tsconfig.json`, runs slower than the AST-only pipeline, and gets slower as your types grow. Use it only when you need expanded JSON. `.d.ts` output is unchanged.
|
|
205
284
|
|
|
206
|
-
|
|
285
|
+
### Persistent parse cache (`cache`)
|
|
207
286
|
|
|
208
|
-
|
|
287
|
+
Parsed output is written to disk and reused when the source file has not changed, on by default. That applies across runs, including CI on a fresh checkout.
|
|
209
288
|
|
|
210
289
|
```ts
|
|
211
|
-
await sveld({ json: true
|
|
290
|
+
await sveld({ json: true });
|
|
212
291
|
```
|
|
213
292
|
|
|
214
|
-
|
|
293
|
+
By default this writes to `node_modules/.cache/sveld/parse-cache.json`. Pass a string to use a different location, e.g. `cache: ".cache/sveld.json"`, or `cache: false` to disable it. Also available as `--cache` / `--cache=<path>` / `--cache=false` on the CLI.
|
|
215
294
|
|
|
216
295
|
If a component [`@extendProps`](#extendprops) / [`@extends`](#extendprops) another file, it is re-parsed when that dependency changes, same as in [`watch`](#available-options) mode. Bumping the `sveld` or Svelte version clears the cache.
|
|
217
296
|
|
|
218
|
-
|
|
297
|
+
### Compile-checked `@example` blocks (`checkExamples`)
|
|
219
298
|
|
|
220
299
|
`@example` blocks are just text. Rename a prop and the sample code can sit there broken for months. Set `checkExamples: true` to run plain TS/JS `@example` blocks through the TypeScript program. Broken examples show up as `example-compile-error` diagnostics.
|
|
221
300
|
|
|
@@ -254,6 +333,68 @@ The check is narrow on purpose. It catches renamed or removed symbols and wrong
|
|
|
254
333
|
|
|
255
334
|
Needs `typescript` and a `tsconfig.json`, same as `resolveTypes`. Use `--strict` (or the `strict` option) to fail CI when an example breaks.
|
|
256
335
|
|
|
336
|
+
### Type inference diagnostics
|
|
337
|
+
|
|
338
|
+
`sveld` collects unresolved-type diagnostics on every run: props that fall back to `any`, context values typed as `any`, `@event` tags with no dispatch or callback, `$props()`/`{@render}` syntax sveld can't model, and (when `checkExamples` is enabled) `example-compile-error`. They are always returned from the programmatic `sveld()` API in `SveldResult.diagnostics`. Each diagnostic carries an optional `source` range (the same `{ start: { line, column }, end: { line, column } }` shape as JSON output source ranges) whenever the parser holds a stable position for it.
|
|
339
|
+
|
|
340
|
+
With `reportDiagnostics` or `strict`, the grouped summary looks like this:
|
|
341
|
+
|
|
342
|
+
```
|
|
343
|
+
sveld: 5 unresolved types found.
|
|
344
|
+
|
|
345
|
+
Props without inferred types (1):
|
|
346
|
+
./icons/Add.svelte
|
|
347
|
+
- Prop "title" type could not be inferred; falling back to "any". (./icons/Add.svelte:4:2)
|
|
348
|
+
|
|
349
|
+
Context values typed as `any` (1):
|
|
350
|
+
./ThemeProvider.svelte
|
|
351
|
+
- Context "theme" variable "themeStore" has no type annotation; defaulted to "any". (./ThemeProvider.svelte:8:6)
|
|
352
|
+
|
|
353
|
+
@event tags with no dispatch or callback (2):
|
|
354
|
+
./Modal.svelte
|
|
355
|
+
- @event "open" has no matching dispatch or callback prop. (./Modal.svelte:3:5)
|
|
356
|
+
- @event "close" has no matching dispatch or callback prop. (./Modal.svelte:4:5)
|
|
357
|
+
|
|
358
|
+
Component syntax sveld skipped (1):
|
|
359
|
+
./Tabs.svelte
|
|
360
|
+
- {@render tabs(getTabProps())} argument is not a plain object literal; the render call was not mapped to slot metadata. (./Tabs.svelte:6:4)
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
When `checkExamples` is also enabled, `@example` compile failures appear as a fifth group:
|
|
364
|
+
|
|
365
|
+
```
|
|
366
|
+
@example blocks that failed to compile (1):
|
|
367
|
+
./Component.svelte
|
|
368
|
+
- Line 1: Cannot find name 'formatValue'.
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
By default, nothing is printed. Opt in when you are working on types or want CI output:
|
|
372
|
+
|
|
373
|
+
```ts
|
|
374
|
+
await sveld({ json: true, reportDiagnostics: true });
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Use `strict: true` (or `--strict`) to exit with code `1` when diagnostics exist. `strict` implies `reportDiagnostics`, so CI always shows why the run failed.
|
|
378
|
+
|
|
379
|
+
```ts
|
|
380
|
+
await sveld({ json: true, strict: true });
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
CLI equivalent:
|
|
384
|
+
|
|
385
|
+
```sh
|
|
386
|
+
npx sveld --json --report-diagnostics
|
|
387
|
+
npx sveld --json --strict
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
`--check` is separate: it diffs `COMPONENT_API.json` for API drift and semver classification, not inference warnings.
|
|
391
|
+
|
|
392
|
+
## Requirements
|
|
393
|
+
|
|
394
|
+
- Node 22+. CI tests against Node 22 on Linux, Windows, and macOS; earlier LTS versions are not verified.
|
|
395
|
+
- `sveld` is ESM-only. `require("sveld")` does not work — use `import` or dynamic `import()`.
|
|
396
|
+
- `sveld` bundles its own Svelte 5 compiler to parse `.svelte` files. Parsing does not depend on the Svelte version installed in your project, so Svelte 3 and Svelte 4 codebases parse the same way Svelte 5 codebases do — there is no compiler version to match up.
|
|
397
|
+
|
|
257
398
|
## Usage
|
|
258
399
|
|
|
259
400
|
### Installation
|
|
@@ -276,7 +417,7 @@ yarn add -D sveld
|
|
|
276
417
|
|
|
277
418
|
### Vite
|
|
278
419
|
|
|
279
|
-
Import and add `sveld` as a plugin to your `vite.config.ts`. The plugin only runs during `vite build`
|
|
420
|
+
Import and add `sveld` as a plugin to your `vite.config.ts`. The plugin only runs during `vite build`, unless `watch: true` is set, in which case it also regenerates output during `vite dev`.
|
|
280
421
|
|
|
281
422
|
```ts
|
|
282
423
|
// vite.config.ts
|
|
@@ -291,7 +432,7 @@ export default defineConfig({
|
|
|
291
432
|
|
|
292
433
|
Since Vite uses Rollup for production builds, the same plugin works in Rollup configs.
|
|
293
434
|
|
|
294
|
-
By default, `sveld`
|
|
435
|
+
By default, `sveld` uses the `"svelte"` field from your `package.json` to determine the entry point. You can override this by specifying an explicit `entry` option:
|
|
295
436
|
|
|
296
437
|
```js
|
|
297
438
|
sveld({
|
|
@@ -302,7 +443,6 @@ sveld({
|
|
|
302
443
|
When building the library, TypeScript definitions are emitted to the `types` folder by default.
|
|
303
444
|
|
|
304
445
|
Customize the output folder using the `typesOptions.outDir` option.
|
|
305
|
-
Use `typesOptions.printWidth` to control Prettier wrapping for generated `.d.ts` files. The default is `80`.
|
|
306
446
|
|
|
307
447
|
The following example emits the output to the `dist` folder:
|
|
308
448
|
|
|
@@ -310,7 +450,6 @@ The following example emits the output to the `dist` folder:
|
|
|
310
450
|
sveld({
|
|
311
451
|
+ typesOptions: {
|
|
312
452
|
+ outDir: 'dist',
|
|
313
|
-
+ printWidth: 80
|
|
314
453
|
+ }
|
|
315
454
|
})
|
|
316
455
|
```
|
|
@@ -329,6 +468,12 @@ Generate documentation in JSON and/or Markdown formats using the following flags
|
|
|
329
468
|
npx sveld --json --markdown
|
|
330
469
|
```
|
|
331
470
|
|
|
471
|
+
If no entry point can be resolved (no `package.json#svelte` field and no `--entry`), the CLI exits `1` and prints the reason to `stderr`. If `src/index.js` happens to exist relative to your working directory, sveld falls back to it and prints a one-line note asking you to set `package.json#svelte` (or `--entry`) instead of relying on the fallback.
|
|
472
|
+
|
|
473
|
+
Flags are kebab-case: `--entry`, `--glob`, `--types`, `--json`, `--markdown`, `--fail-fast`, `--cache`, `--resolve-types`, `--check-examples`, `--report-diagnostics`, `--strict`, `--check`, `--types-format`. The camelCase spellings `--resolveTypes` and `--checkExamples` still work as deprecated aliases for compatibility with existing scripts. An unrecognized flag (e.g. `--markdwon`) prints `Unknown flag: --markdwon` to `stderr`, exits `1`, and skips generation; sveld takes no positional arguments, so any non-flag argument errors the same way.
|
|
474
|
+
|
|
475
|
+
Run `npx sveld --help` for the full flag list with descriptions, or `npx sveld --version` to print the installed version.
|
|
476
|
+
|
|
332
477
|
### CI: API-drift checks (`--check`)
|
|
333
478
|
|
|
334
479
|
`--check` diffs the parsed component API against a committed `COMPONENT_API.json` snapshot, assigns a semver bump to each change, and exits `1` when it finds a breaking change.
|
|
@@ -355,18 +500,22 @@ Removed props, events, or slots, and props that become required, are breaking (`
|
|
|
355
500
|
|
|
356
501
|
Use `--check=<path>` to diff against a snapshot at a custom location (defaults to `jsonOptions.outFile`, or `COMPONENT_API.json`).
|
|
357
502
|
|
|
503
|
+
The CLI exits non-zero on any fatal error (an unreadable entry, a config file that throws, etc.), not just on `--strict`/`--check` findings, so it's safe to use either flag as a CI gate.
|
|
504
|
+
|
|
358
505
|
### Node.js
|
|
359
506
|
|
|
360
|
-
You can also call `sveld` from Node.js.
|
|
507
|
+
You can also call `sveld` from Node.js. See [Requirements](#requirements) for supported Node versions and the ESM-only constraint.
|
|
508
|
+
|
|
509
|
+
If no `entry` is specified, `sveld` infers the entry point based on the `package.json#svelte` field. If no entry point can be resolved, `sveld()` throws with an actionable message (previously it resolved to `{ diagnostics: [] }` and generated nothing).
|
|
361
510
|
|
|
362
|
-
|
|
511
|
+
> `input` was renamed to `entry` to match the CLI, plugin, and config. Calls passing `input` throw with a message pointing at `entry`.
|
|
363
512
|
|
|
364
513
|
```js
|
|
365
514
|
import { sveld } from "sveld";
|
|
366
515
|
import pkg from "./package.json" with { type: "json" };
|
|
367
516
|
|
|
368
|
-
sveld({
|
|
369
|
-
|
|
517
|
+
const { diagnostics } = await sveld({
|
|
518
|
+
entry: "./src/index.js",
|
|
370
519
|
glob: true,
|
|
371
520
|
markdown: true,
|
|
372
521
|
markdownOptions: {
|
|
@@ -385,6 +534,23 @@ sveld({
|
|
|
385
534
|
});
|
|
386
535
|
```
|
|
387
536
|
|
|
537
|
+
`diagnostics` is always populated; printing is opt-in via `reportDiagnostics` or `strict` (see [Type inference diagnostics](#type-inference-diagnostics)).
|
|
538
|
+
|
|
539
|
+
Pass `check: true` (or `check: "<path>"` for a custom snapshot location) to diff against a committed `COMPONENT_API.json`, the same way `--check` does on the CLI. The result lands on `SveldResult.check`; sveld does not print it or touch `process.exitCode` for you, so inspect and act on it yourself:
|
|
540
|
+
|
|
541
|
+
```js
|
|
542
|
+
import { formatCheckReport } from "sveld";
|
|
543
|
+
|
|
544
|
+
const { check } = await sveld({ json: true, check: true });
|
|
545
|
+
|
|
546
|
+
if (check) {
|
|
547
|
+
console.log(formatCheckReport(check));
|
|
548
|
+
if (check.bump === "major") process.exitCode = 1;
|
|
549
|
+
}
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
See [CI: API-drift checks (`--check`)](#ci-api-drift-checks---check) for how changes are classified.
|
|
553
|
+
|
|
388
554
|
#### `jsonOptions.outDir`
|
|
389
555
|
|
|
390
556
|
With `json: true`, `sveld` writes `COMPONENT_API.json` at the project root. The file documents all components.
|
|
@@ -425,17 +591,34 @@ CLI flags > config file > `package.json#svelte` inference / defaults
|
|
|
425
591
|
|
|
426
592
|
With the config above, `npx sveld --json` keeps `glob` and `markdown` from the file. A CLI flag overrides the same key in the config.
|
|
427
593
|
|
|
594
|
+
`strict`, `reportDiagnostics`, and `check` are valid config keys too — not just CLI flags or `sveld()` options — and follow the same precedence: a CLI flag (or an option passed to `sveld()`) overrides the same key set in the config file.
|
|
595
|
+
|
|
596
|
+
```js
|
|
597
|
+
// sveld.config.js
|
|
598
|
+
export default {
|
|
599
|
+
json: true,
|
|
600
|
+
strict: true,
|
|
601
|
+
check: "snapshots/COMPONENT_API.json",
|
|
602
|
+
};
|
|
603
|
+
```
|
|
604
|
+
|
|
428
605
|
A bad config (syntax error, throws at load time, or no default-export object) fails with an error that names the file.
|
|
429
606
|
|
|
430
607
|
### Publishing to NPM
|
|
431
608
|
|
|
432
|
-
TypeScript definitions land in the `types` folder by default.
|
|
609
|
+
TypeScript definitions land in the `types` folder by default. Point consumers at them with an `exports` map, and include that folder in `package.json` when you publish to npm.
|
|
433
610
|
|
|
434
611
|
```diff
|
|
435
612
|
{
|
|
436
613
|
"svelte": "./src/index.js",
|
|
614
|
+
+ "exports": {
|
|
615
|
+
+ ".": {
|
|
616
|
+
+ "types": "./types/index.d.ts",
|
|
617
|
+
+ "svelte": "./src/index.js",
|
|
618
|
+
+ "default": "./lib/index.mjs"
|
|
619
|
+
+ }
|
|
620
|
+
+ },
|
|
437
621
|
"main": "./lib/index.mjs",
|
|
438
|
-
+ "types": "./types/index.d.ts",
|
|
439
622
|
"files": [
|
|
440
623
|
"src",
|
|
441
624
|
"lib",
|
|
@@ -444,24 +627,36 @@ TypeScript definitions land in the `types` folder by default. Include that folde
|
|
|
444
627
|
}
|
|
445
628
|
```
|
|
446
629
|
|
|
630
|
+
The `svelte` condition lets bundlers that understand it (Vite, Rollup, webpack via `svelte-loader`) resolve straight to source; `types` and `default` cover TypeScript and everything else. Keep the top-level `"svelte"` field too — older tooling that predates conditional exports still reads it directly.
|
|
631
|
+
|
|
447
632
|
## Available Options
|
|
448
633
|
|
|
449
634
|
### Plugin Options
|
|
450
635
|
|
|
451
|
-
- **`entry`** (string, optional): Specify the entry point to uncompiled Svelte source. If not provided, sveld
|
|
636
|
+
- **`entry`** (string, optional): Specify the entry point to uncompiled Svelte source. If not provided, sveld uses the `"svelte"` field from `package.json`.
|
|
452
637
|
- **`glob`** (boolean, optional): Enable glob mode to analyze all `*.svelte` files.
|
|
453
638
|
- **`documentExports`** (boolean, optional): Include consts, functions, and types from the entry barrel in JSON (`exports`) and Markdown ("Exports"). Off by default. See [Documenting Entry Exports](#documenting-entry-exports).
|
|
454
639
|
- **`types`** (boolean, optional, default: `true`): Generate TypeScript definitions.
|
|
455
|
-
|
|
640
|
+
<<<<<<< HEAD
|
|
641
|
+
- **`typesOptions`** (object, optional): Options for TypeScript definition generation, including `outDir`, `preamble`, and `format`.
|
|
642
|
+
- **`format`** (`"class"` | `"component"`, optional, default: `"class"`): `.d.ts` output shape. `"class"` extends `SvelteComponentTyped`; `"component"` emits the Svelte 5 `Component` type. Also available as `--types-format`. See [`.d.ts` output format](#dts-output-format-typesoptionsformat).
|
|
643
|
+
=======
|
|
644
|
+
- **`typesOptions`** (object, optional): Options for TypeScript definition generation, including `outDir` and `preamble`.
|
|
645
|
+
>>>>>>> 0724225 (feat(writer)!: remove prettier entirely)
|
|
456
646
|
- **`json`** (boolean, optional): Generate component documentation in JSON format.
|
|
457
647
|
- **`jsonOptions`** (object, optional): Options for JSON output.
|
|
458
648
|
- **`markdown`** (boolean, optional): Generate component documentation in Markdown format.
|
|
459
649
|
- **`markdownOptions`** (object, optional): Options for Markdown output.
|
|
650
|
+
- **`customElements`** (boolean, optional): Generate a [Custom Elements Manifest](#custom-elements-manifest) (`custom-elements.json`). Also available as the `--custom-elements` CLI flag.
|
|
651
|
+
- **`customElementsOptions`** (object, optional): Options for Custom Elements Manifest output, including `outFile`.
|
|
460
652
|
- **`watch`** (boolean, optional, default: `false`): Regenerate output incrementally when `.svelte` source changes during `vite dev` / `vite build --watch`. Only the changed component and the components that depend on it via [`@extendProps`](#extendprops) / `@extends` are re-parsed, rather than rebuilding every component. Without this option, the plugin only runs during `vite build`.
|
|
461
653
|
- **`failFast`** (boolean, optional, default: `false`): Abort the entire run when a single component fails to parse. By default, parse failures are collected as diagnostics (and reported to `stderr`) so the remaining components still emit their output. Also available as the `--fail-fast` CLI flag.
|
|
462
|
-
- **`resolveTypes`** (boolean, optional, default: `false`): Load the TypeScript program to expand opaque imported whole-object `$props()` types into JSON. See [Opt-in semantic resolution](#opt-in-semantic-resolution-resolvetypes).
|
|
463
|
-
- **`cache`** (boolean | string, optional, default: `
|
|
464
|
-
- **`checkExamples`** (boolean, optional, default: `false`): Run plain TS/JS `@example` blocks through the TypeScript program. Broken ones get an `example-compile-error` diagnostic. See [Compile-checked `@example` blocks](#compile-checked-example-blocks-checkexamples).
|
|
654
|
+
- **`resolveTypes`** (boolean, optional, default: `false`): Load the TypeScript program to expand opaque imported whole-object `$props()` types into JSON. Also available as `--resolve-types` (`--resolveTypes` remains as a deprecated alias). See [Opt-in semantic resolution](#opt-in-semantic-resolution-resolvetypes).
|
|
655
|
+
- **`cache`** (boolean | string, optional, default: `true`): Write parsed component output to disk and skip re-parsing unchanged files on later runs. On by default, writing to `node_modules/.cache/sveld/parse-cache.json`; a string sets a custom path; pass `false` to disable. Also available as `--cache` / `--cache=<path>` / `--cache=false`. See [Persistent parse cache](#persistent-parse-cache-cache).
|
|
656
|
+
- **`checkExamples`** (boolean, optional, default: `false`): Run plain TS/JS `@example` blocks through the TypeScript program. Broken ones get an `example-compile-error` diagnostic. Also available as `--check-examples` (`--checkExamples` remains as a deprecated alias). See [Compile-checked `@example` blocks](#compile-checked-example-blocks-checkexamples).
|
|
657
|
+
- **`reportDiagnostics`** (boolean, optional, default: `false`): Print unresolved-type diagnostics to stderr (CLI) or `console.warn` (programmatic API). Also available as `--report-diagnostics`. See [Type inference diagnostics](#type-inference-diagnostics).
|
|
658
|
+
- **`strict`** (boolean, optional, default: `false`): Exit with code `1` when diagnostics exist. Implies `reportDiagnostics`. Also available as `--strict`. See [Type inference diagnostics](#type-inference-diagnostics).
|
|
659
|
+
- **`check`** (boolean | string, optional, default: `false`): Diff the parsed component API against a committed snapshot and assign a semver bump to each change. `true` uses the `json` writer's `outFile` (or `COMPONENT_API.json`); a string sets a custom snapshot path. Also available as `--check` / `--check=<path>`. On the CLI this exits `1` on a breaking change; from `sveld()` it's returned on `SveldResult.check` for you to act on. See [CI: API-drift checks (`--check`)](#ci-api-drift-checks---check).
|
|
465
660
|
|
|
466
661
|
By default, only TypeScript definitions are generated.
|
|
467
662
|
|
|
@@ -503,7 +698,7 @@ JSON adds `exports` and `totalExports`. Markdown adds an "Exports" section. Each
|
|
|
503
698
|
## JSON Output
|
|
504
699
|
|
|
505
700
|
When `json: true` is enabled, `sveld` emits a `COMPONENT_API.json` file with schema and generator metadata plus the parsed
|
|
506
|
-
component API.
|
|
701
|
+
component API. For stable output, generated `events` arrays are emitted in deterministic sorted order.
|
|
507
702
|
|
|
508
703
|
The JSON Schema lives on GitHub ([path to file](https://github.com/carbon-design-system/sveld/blob/main/schema/component-api.schema.json), [raw URL](https://raw.githubusercontent.com/carbon-design-system/sveld/main/schema/component-api.schema.json)). Use it to validate generated `COMPONENT_API.json` files. Optional fields may be missing when the parser has no stable source for that metadata.
|
|
509
704
|
|
|
@@ -559,6 +754,7 @@ interface ComponentDocApi {
|
|
|
559
754
|
componentComment?: string;
|
|
560
755
|
componentCommentSource?: SourceRange;
|
|
561
756
|
contexts?: ComponentContext[];
|
|
757
|
+
customElementTag?: string;
|
|
562
758
|
}
|
|
563
759
|
|
|
564
760
|
interface ComponentProp {
|
|
@@ -625,6 +821,47 @@ Prop metadata is additive and keeps the older public fields:
|
|
|
625
821
|
- `value` remains the raw default expression string. `defaultValue` adds structured metadata with the same raw expression, a coarse `kind`, and a parsed `value` only for JSON-safe literals, arrays, and plain objects. `sveld` does not evaluate arbitrary code.
|
|
626
822
|
- `bindable: true` is emitted only for props explicitly declared with Svelte 5 `$bindable(...)`. Missing `bindable` should be treated as false.
|
|
627
823
|
|
|
824
|
+
## Custom Elements Manifest
|
|
825
|
+
|
|
826
|
+
Set `customElements: true` to emit a [Custom Elements Manifest](https://github.com/webcomponents/custom-elements-manifest) (`custom-elements.json`, `schemaVersion: "1.0.0"`). This is the interchange format the web-components ecosystem standardized on: Storybook autodocs, VS Code/JetBrains HTML data, and other CEM-aware tooling can all read it directly.
|
|
827
|
+
|
|
828
|
+
```diff
|
|
829
|
+
sveld({
|
|
830
|
+
+ customElements: true,
|
|
831
|
+
})
|
|
832
|
+
```
|
|
833
|
+
|
|
834
|
+
- **`customElements`** (boolean, optional): Generate `custom-elements.json`.
|
|
835
|
+
- **`customElementsOptions.outFile`** (string, optional, default: `"custom-elements.json"`): Override the output path.
|
|
836
|
+
- Also available as the `--custom-elements` CLI flag.
|
|
837
|
+
|
|
838
|
+
Each exported component becomes one `javascript-module` with a class declaration:
|
|
839
|
+
|
|
840
|
+
- **Members** — every prop becomes a `ClassField` (`name`, `type.text`, `default`, `description`, `deprecated`).
|
|
841
|
+
- **Attributes** — derived conservatively from props: only props with a bare primitive type (`string`, `number`, or `boolean`) become attributes, using the same default name Svelte's custom-element runtime uses (`prop.toLowerCase()`, unless the tool's own `attribute` override applies). Props whose lowercased name collides with another prop are dropped from `attributes` on both sides, since which one wins at runtime is ambiguous. Complex types (arrays, objects, unions, custom types) never become attributes.
|
|
842
|
+
- **Events** — dispatched events (`createEventDispatcher()`, and `$host().dispatchEvent(...)` from inside a custom element) become `{ name, type: { text: "CustomEvent<...>" } }`. Forwarded (`on:click`) events are left out, since they aren't dispatched by the component's own class.
|
|
843
|
+
- **Slots** — named and default slots, with descriptions. The default slot's `name` is `""`, matching the CEM convention.
|
|
844
|
+
|
|
845
|
+
When a component sets `<svelte:options customElement="x-foo" />` (or the object form, `<svelte:options customElement={{ tag: "x-foo" }} />`), its declaration gets `tagName: "x-foo"` and `customElement: true`, and the module's `exports` include a `custom-element-definition` export alongside the plain `js` export.
|
|
846
|
+
|
|
847
|
+
Components without `customElement` still emit a plain class declaration (no `tagName`/`customElement`) — useful for documenting the class shape even before it's compiled as a custom element, but the manifest is most useful for `customElement`-compiled builds, where downstream tooling can resolve `tagName`, `attributes`, and `events` for actual custom-element usage.
|
|
848
|
+
|
|
849
|
+
### Consuming the manifest
|
|
850
|
+
|
|
851
|
+
Most tools discover `custom-elements.json` through a `customElements` field in `package.json`, pointing at the generated file:
|
|
852
|
+
|
|
853
|
+
```json
|
|
854
|
+
{
|
|
855
|
+
"customElements": "custom-elements.json"
|
|
856
|
+
}
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
With that in place:
|
|
860
|
+
|
|
861
|
+
- The [VS Code custom elements extension](https://marketplace.visualstudio.com/items?itemName=BendingSpoons.vscode-custom-elements) and JetBrains IDEs pick it up automatically, giving tag name, attribute, and slot completion/hover in HTML and Svelte templates.
|
|
862
|
+
- [Storybook](https://storybook.js.org/docs/api/doc-blocks/doc-block-argtypes#extracting-argtypes) for web components reads the manifest to auto-generate `argTypes` (controls, docs tables) for `customElement`-compiled components, once you point it at the file (e.g. `setCustomElementsManifest` from `@storybook/web-components`, or `customElements: "custom-elements.json"` in `.storybook/main.js`).
|
|
863
|
+
- Any other tool built against the [Custom Elements Manifest spec](https://github.com/webcomponents/custom-elements-manifest) (API viewers, doc generators, linters) can read the file directly without sveld-specific integration.
|
|
864
|
+
|
|
628
865
|
## API Reference
|
|
629
866
|
|
|
630
867
|
### `reactive`
|
|
@@ -674,11 +911,9 @@ Generated JSON includes `"binding": "readonly"` or `"binding": "writable"` for a
|
|
|
674
911
|
|
|
675
912
|
This is documentation only. Generated `.svelte.d.ts` prop types do not change. TypeScript cannot express Svelte binding direction reliably.
|
|
676
913
|
|
|
677
|
-
For stable output, generated `events` arrays are emitted in deterministic sorted order.
|
|
678
|
-
|
|
679
914
|
### `@type`
|
|
680
915
|
|
|
681
|
-
Without a `@type` annotation, `sveld`
|
|
916
|
+
Without a `@type` annotation, `sveld` infers the primitive type for a prop:
|
|
682
917
|
|
|
683
918
|
```js
|
|
684
919
|
export let kind = "primary";
|
|
@@ -707,8 +942,6 @@ For `lang="ts"` components, prefer native TypeScript annotations when you alread
|
|
|
707
942
|
|
|
708
943
|
**Example:**
|
|
709
944
|
|
|
710
|
-
**Svelte 5 Runes:**
|
|
711
|
-
|
|
712
945
|
```svelte
|
|
713
946
|
<script>
|
|
714
947
|
let {
|
|
@@ -728,7 +961,8 @@ For `lang="ts"` components, prefer native TypeScript annotations when you alread
|
|
|
728
961
|
|
|
729
962
|
For runes components with multiple destructured props, put JSDoc on the property you want to document. A declaration-level block is a fallback when the destructure exposes a single public prop.
|
|
730
963
|
|
|
731
|
-
|
|
964
|
+
<details>
|
|
965
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
732
966
|
|
|
733
967
|
```svelte
|
|
734
968
|
<script>
|
|
@@ -746,6 +980,8 @@ For runes components with multiple destructured props, put JSDoc on the property
|
|
|
746
980
|
</script>
|
|
747
981
|
```
|
|
748
982
|
|
|
983
|
+
</details>
|
|
984
|
+
|
|
749
985
|
#### Importing types
|
|
750
986
|
|
|
751
987
|
`sveld` supports TypeScript's [`import(...)` type syntax](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#import-types), so a `@type` or `@typedef` can reference a type from another module without a top-level `import`. The expression is copied verbatim into the generated `.d.ts` and resolves the same way as hand-written TypeScript:
|
|
@@ -956,8 +1192,6 @@ The `@typedef` tag defines a shared type used multiple times in a component. All
|
|
|
956
1192
|
|
|
957
1193
|
**Example:**
|
|
958
1194
|
|
|
959
|
-
**Svelte 5 Runes:**
|
|
960
|
-
|
|
961
1195
|
```svelte
|
|
962
1196
|
<script>
|
|
963
1197
|
/**
|
|
@@ -974,7 +1208,8 @@ The `@typedef` tag defines a shared type used multiple times in a component. All
|
|
|
974
1208
|
</script>
|
|
975
1209
|
```
|
|
976
1210
|
|
|
977
|
-
|
|
1211
|
+
<details>
|
|
1212
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
978
1213
|
|
|
979
1214
|
```svelte
|
|
980
1215
|
<script>
|
|
@@ -991,6 +1226,8 @@ The `@typedef` tag defines a shared type used multiple times in a component. All
|
|
|
991
1226
|
</script>
|
|
992
1227
|
```
|
|
993
1228
|
|
|
1229
|
+
</details>
|
|
1230
|
+
|
|
994
1231
|
#### Using `@property` for complex typedefs
|
|
995
1232
|
|
|
996
1233
|
For complex object types, use `@property` to document individual fields. That gives per-property tooltips in the IDE.
|
|
@@ -1007,8 +1244,6 @@ For complex object types, use `@property` to document individual fields. That gi
|
|
|
1007
1244
|
|
|
1008
1245
|
**Example:**
|
|
1009
1246
|
|
|
1010
|
-
**Svelte 5 Runes:**
|
|
1011
|
-
|
|
1012
1247
|
```svelte
|
|
1013
1248
|
<script>
|
|
1014
1249
|
/**
|
|
@@ -1024,7 +1259,8 @@ For complex object types, use `@property` to document individual fields. That gi
|
|
|
1024
1259
|
</script>
|
|
1025
1260
|
```
|
|
1026
1261
|
|
|
1027
|
-
|
|
1262
|
+
<details>
|
|
1263
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
1028
1264
|
|
|
1029
1265
|
```svelte
|
|
1030
1266
|
<script>
|
|
@@ -1041,6 +1277,10 @@ For complex object types, use `@property` to document individual fields. That gi
|
|
|
1041
1277
|
</script>
|
|
1042
1278
|
```
|
|
1043
1279
|
|
|
1280
|
+
</details>
|
|
1281
|
+
|
|
1282
|
+
Output is identical for both syntax modes.
|
|
1283
|
+
|
|
1044
1284
|
Output:
|
|
1045
1285
|
|
|
1046
1286
|
```ts
|
|
@@ -1078,8 +1318,6 @@ Use square brackets for optional properties, per JSDoc. Default values use `[pro
|
|
|
1078
1318
|
|
|
1079
1319
|
**Example:**
|
|
1080
1320
|
|
|
1081
|
-
**Svelte 5 Runes:**
|
|
1082
|
-
|
|
1083
1321
|
```svelte
|
|
1084
1322
|
<script>
|
|
1085
1323
|
/**
|
|
@@ -1096,7 +1334,8 @@ Use square brackets for optional properties, per JSDoc. Default values use `[pro
|
|
|
1096
1334
|
</script>
|
|
1097
1335
|
```
|
|
1098
1336
|
|
|
1099
|
-
|
|
1337
|
+
<details>
|
|
1338
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
1100
1339
|
|
|
1101
1340
|
```svelte
|
|
1102
1341
|
<script>
|
|
@@ -1114,6 +1353,10 @@ Use square brackets for optional properties, per JSDoc. Default values use `[pro
|
|
|
1114
1353
|
</script>
|
|
1115
1354
|
```
|
|
1116
1355
|
|
|
1356
|
+
</details>
|
|
1357
|
+
|
|
1358
|
+
Output is identical for both syntax modes.
|
|
1359
|
+
|
|
1117
1360
|
Output:
|
|
1118
1361
|
|
|
1119
1362
|
```ts
|
|
@@ -1403,8 +1646,6 @@ Use it for callback props when you do not want inline function type syntax.
|
|
|
1403
1646
|
|
|
1404
1647
|
**Example:**
|
|
1405
1648
|
|
|
1406
|
-
**Svelte 5 Runes:**
|
|
1407
|
-
|
|
1408
1649
|
```svelte
|
|
1409
1650
|
<script>
|
|
1410
1651
|
/**
|
|
@@ -1420,7 +1661,8 @@ Use it for callback props when you do not want inline function type syntax.
|
|
|
1420
1661
|
</script>
|
|
1421
1662
|
```
|
|
1422
1663
|
|
|
1423
|
-
|
|
1664
|
+
<details>
|
|
1665
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
1424
1666
|
|
|
1425
1667
|
```svelte
|
|
1426
1668
|
<script>
|
|
@@ -1437,6 +1679,10 @@ Use it for callback props when you do not want inline function type syntax.
|
|
|
1437
1679
|
</script>
|
|
1438
1680
|
```
|
|
1439
1681
|
|
|
1682
|
+
</details>
|
|
1683
|
+
|
|
1684
|
+
Output is identical for both syntax modes.
|
|
1685
|
+
|
|
1440
1686
|
Output:
|
|
1441
1687
|
|
|
1442
1688
|
```ts
|
|
@@ -1494,8 +1740,6 @@ Omit the `slot-name` to type the default slot.
|
|
|
1494
1740
|
|
|
1495
1741
|
**Example:**
|
|
1496
1742
|
|
|
1497
|
-
**Svelte 5 Runes:**
|
|
1498
|
-
|
|
1499
1743
|
```svelte
|
|
1500
1744
|
<script>
|
|
1501
1745
|
/**
|
|
@@ -1517,7 +1761,8 @@ Omit the `slot-name` to type the default slot.
|
|
|
1517
1761
|
</p>
|
|
1518
1762
|
```
|
|
1519
1763
|
|
|
1520
|
-
|
|
1764
|
+
<details>
|
|
1765
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
1521
1766
|
|
|
1522
1767
|
```svelte
|
|
1523
1768
|
<script>
|
|
@@ -1540,6 +1785,8 @@ Omit the `slot-name` to type the default slot.
|
|
|
1540
1785
|
</p>
|
|
1541
1786
|
```
|
|
1542
1787
|
|
|
1788
|
+
</details>
|
|
1789
|
+
|
|
1543
1790
|
#### Extra JSDoc tags before `@slot`
|
|
1544
1791
|
|
|
1545
1792
|
Tags such as `@example`, `@see`, or `@since` that appear after the prose description and before the `@slot` / `@snippet` line are copied into generated `.d.ts` files. The emitted JSDoc above each slot's snippet prop (and the traditional `SlotDefs` shape) lists the description, then those tags in source order. The same entries appear in JSON as `tags: [{ "name", "body" }, ...]`.
|
|
@@ -1693,8 +1940,6 @@ Use `null` as the value if no event detail is provided.
|
|
|
1693
1940
|
|
|
1694
1941
|
**Example:**
|
|
1695
1942
|
|
|
1696
|
-
**Svelte 5 Runes:**
|
|
1697
|
-
|
|
1698
1943
|
```svelte
|
|
1699
1944
|
<script>
|
|
1700
1945
|
/**
|
|
@@ -1729,7 +1974,8 @@ Use `null` as the value if no event detail is provided.
|
|
|
1729
1974
|
</script>
|
|
1730
1975
|
```
|
|
1731
1976
|
|
|
1732
|
-
|
|
1977
|
+
<details>
|
|
1978
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
1733
1979
|
|
|
1734
1980
|
```svelte
|
|
1735
1981
|
<script>
|
|
@@ -1749,6 +1995,10 @@ Use `null` as the value if no event detail is provided.
|
|
|
1749
1995
|
</script>
|
|
1750
1996
|
```
|
|
1751
1997
|
|
|
1998
|
+
</details>
|
|
1999
|
+
|
|
2000
|
+
Output is identical for both syntax modes.
|
|
2001
|
+
|
|
1752
2002
|
Output:
|
|
1753
2003
|
|
|
1754
2004
|
```ts
|
|
@@ -1781,8 +2031,6 @@ This is the idiomatic way to describe each field of an event detail. An inline o
|
|
|
1781
2031
|
|
|
1782
2032
|
**Example:**
|
|
1783
2033
|
|
|
1784
|
-
**Svelte 5 Runes:**
|
|
1785
|
-
|
|
1786
2034
|
```svelte
|
|
1787
2035
|
<script>
|
|
1788
2036
|
/**
|
|
@@ -1809,7 +2057,8 @@ This is the idiomatic way to describe each field of an event detail. An inline o
|
|
|
1809
2057
|
<button type="button" onclick={handleSubmit}>Submit</button>
|
|
1810
2058
|
```
|
|
1811
2059
|
|
|
1812
|
-
|
|
2060
|
+
<details>
|
|
2061
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
1813
2062
|
|
|
1814
2063
|
```svelte
|
|
1815
2064
|
<script>
|
|
@@ -1839,6 +2088,10 @@ This is the idiomatic way to describe each field of an event detail. An inline o
|
|
|
1839
2088
|
<button type="button" on:click={handleSubmit}>Submit</button>
|
|
1840
2089
|
```
|
|
1841
2090
|
|
|
2091
|
+
</details>
|
|
2092
|
+
|
|
2093
|
+
Output is identical for both syntax modes.
|
|
2094
|
+
|
|
1842
2095
|
Output:
|
|
1843
2096
|
|
|
1844
2097
|
```ts
|
|
@@ -1865,8 +2118,6 @@ Like typedefs, you can mark event detail properties as optional with square brac
|
|
|
1865
2118
|
|
|
1866
2119
|
**Example:**
|
|
1867
2120
|
|
|
1868
|
-
**Svelte 5 Runes:**
|
|
1869
|
-
|
|
1870
2121
|
```svelte
|
|
1871
2122
|
<script>
|
|
1872
2123
|
/**
|
|
@@ -1897,7 +2148,8 @@ Like typedefs, you can mark event detail properties as optional with square brac
|
|
|
1897
2148
|
<button type="button" onclick={throwSnowball}>Throw</button>
|
|
1898
2149
|
```
|
|
1899
2150
|
|
|
1900
|
-
|
|
2151
|
+
<details>
|
|
2152
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
1901
2153
|
|
|
1902
2154
|
```svelte
|
|
1903
2155
|
<script>
|
|
@@ -1929,6 +2181,10 @@ Like typedefs, you can mark event detail properties as optional with square brac
|
|
|
1929
2181
|
<button type="button" on:click={throwSnowball}>Throw</button>
|
|
1930
2182
|
```
|
|
1931
2183
|
|
|
2184
|
+
</details>
|
|
2185
|
+
|
|
2186
|
+
Output is identical for both syntax modes.
|
|
2187
|
+
|
|
1932
2188
|
Output:
|
|
1933
2189
|
|
|
1934
2190
|
```ts
|
|
@@ -2067,8 +2323,6 @@ Anything else (dynamic identifiers, template interpolation, other function calls
|
|
|
2067
2323
|
|
|
2068
2324
|
**Modal.svelte**
|
|
2069
2325
|
|
|
2070
|
-
**Svelte 5 Runes:**
|
|
2071
|
-
|
|
2072
2326
|
```svelte
|
|
2073
2327
|
<script>
|
|
2074
2328
|
import { setContext } from "svelte";
|
|
@@ -2099,7 +2353,8 @@ Anything else (dynamic identifiers, template interpolation, other function calls
|
|
|
2099
2353
|
</div>
|
|
2100
2354
|
```
|
|
2101
2355
|
|
|
2102
|
-
|
|
2356
|
+
<details>
|
|
2357
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
2103
2358
|
|
|
2104
2359
|
```svelte
|
|
2105
2360
|
<script>
|
|
@@ -2129,6 +2384,10 @@ Anything else (dynamic identifiers, template interpolation, other function calls
|
|
|
2129
2384
|
</div>
|
|
2130
2385
|
```
|
|
2131
2386
|
|
|
2387
|
+
</details>
|
|
2388
|
+
|
|
2389
|
+
Output is identical for both syntax modes.
|
|
2390
|
+
|
|
2132
2391
|
**Generated TypeScript definition:**
|
|
2133
2392
|
|
|
2134
2393
|
```ts
|
|
@@ -2238,7 +2497,7 @@ There are several ways to type contexts:
|
|
|
2238
2497
|
|
|
2239
2498
|
#### Notes
|
|
2240
2499
|
|
|
2241
|
-
- Context keys must be string
|
|
2500
|
+
- Context keys must be statically resolvable: a string literal, a static template literal, a `const`-bound string, or a `Symbol()` / `Symbol.for()` call with a static description. Dynamic expressions (runtime identifiers, template interpolation, other function calls) are skipped with a warning.
|
|
2242
2501
|
- Variables passed to `setContext` should have JSDoc `@type` annotations for accurate types
|
|
2243
2502
|
- The generated type name follows the pattern: `{PascalCase}Context`. Separators (hyphens, underscores, dots, colons, slashes, spaces) are stripped and each segment is capitalized:
|
|
2244
2503
|
| Context Key | Generated Type Name |
|
|
@@ -2272,8 +2531,6 @@ Use `@restProps` to name the element tags `$$restProps` is forwarded to.
|
|
|
2272
2531
|
|
|
2273
2532
|
**Example:**
|
|
2274
2533
|
|
|
2275
|
-
**Svelte 5 Runes:**
|
|
2276
|
-
|
|
2277
2534
|
```svelte
|
|
2278
2535
|
<script>
|
|
2279
2536
|
import Button from "./Button.svelte";
|
|
@@ -2291,7 +2548,8 @@ Use `@restProps` to name the element tags `$$restProps` is forwarded to.
|
|
|
2291
2548
|
{/if}
|
|
2292
2549
|
```
|
|
2293
2550
|
|
|
2294
|
-
|
|
2551
|
+
<details>
|
|
2552
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
2295
2553
|
|
|
2296
2554
|
```svelte
|
|
2297
2555
|
<script>
|
|
@@ -2308,6 +2566,8 @@ Use `@restProps` to name the element tags `$$restProps` is forwarded to.
|
|
|
2308
2566
|
{/if}
|
|
2309
2567
|
```
|
|
2310
2568
|
|
|
2569
|
+
</details>
|
|
2570
|
+
|
|
2311
2571
|
### `@extendProps`
|
|
2312
2572
|
|
|
2313
2573
|
When a component wraps another, use `@extendProps` to extend generated props.
|
|
@@ -2334,14 +2594,15 @@ import Button from "./Button.svelte";
|
|
|
2334
2594
|
|
|
2335
2595
|
### `@template`
|
|
2336
2596
|
|
|
2337
|
-
Svelte supports defining generics via the [`generics` attribute](https://svelte.dev/docs/svelte/typescript) on the script tag, but this requires `lang="ts"
|
|
2597
|
+
Svelte supports defining generics via the [`generics` attribute](https://svelte.dev/docs/svelte/typescript) on the script tag, but this requires `lang="ts"`:
|
|
2338
2598
|
|
|
2339
2599
|
```svelte
|
|
2340
|
-
<!-- Requires lang="ts" -->
|
|
2341
2600
|
<script lang="ts" generics="Row extends DataTableRow = any"></script>
|
|
2342
2601
|
```
|
|
2343
2602
|
|
|
2344
|
-
Because `sveld` targets JavaScript-only usage as a baseline,
|
|
2603
|
+
`sveld` reads the `generics` attribute directly, and it's the recommended way to declare generics for `lang="ts"` components. Because `sveld` also targets JavaScript-only usage as a baseline, plain JS (or JS-with-JSDoc) components instead use the standard JSDoc `@template` tag; `@generics` is also supported as an alias.
|
|
2604
|
+
|
|
2605
|
+
**Precedence:** if a component declares generics both ways, the `generics` attribute wins — it's the compiler-checked source of truth — and the `@generics`/`@template` tag is reported as a `syntax-skipped` diagnostic rather than silently dropped. The attribute is invalid without `lang="ts"`; if present on a plain-JS script, sveld reports `syntax-skipped` and ignores it rather than guessing.
|
|
2345
2606
|
|
|
2346
2607
|
**Signature:** Uses standard [JSDoc `@template` syntax](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#template):
|
|
2347
2608
|
|
|
@@ -2361,8 +2622,6 @@ Because `sveld` targets JavaScript-only usage as a baseline, generics use the st
|
|
|
2361
2622
|
|
|
2362
2623
|
**Component example:**
|
|
2363
2624
|
|
|
2364
|
-
**Svelte 5 Runes:**
|
|
2365
|
-
|
|
2366
2625
|
```svelte
|
|
2367
2626
|
<script>
|
|
2368
2627
|
/**
|
|
@@ -2384,7 +2643,8 @@ Because `sveld` targets JavaScript-only usage as a baseline, generics use the st
|
|
|
2384
2643
|
{@render children?.({ headers, rows })}
|
|
2385
2644
|
```
|
|
2386
2645
|
|
|
2387
|
-
|
|
2646
|
+
<details>
|
|
2647
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
2388
2648
|
|
|
2389
2649
|
```svelte
|
|
2390
2650
|
<script>
|
|
@@ -2405,6 +2665,10 @@ Because `sveld` targets JavaScript-only usage as a baseline, generics use the st
|
|
|
2405
2665
|
<slot {headers} {rows} />
|
|
2406
2666
|
```
|
|
2407
2667
|
|
|
2668
|
+
</details>
|
|
2669
|
+
|
|
2670
|
+
Output is identical for both syntax modes.
|
|
2671
|
+
|
|
2408
2672
|
Generated output looks like this:
|
|
2409
2673
|
|
|
2410
2674
|
```ts
|
|
@@ -2477,12 +2741,10 @@ For multiple generics, use a single `@generics` tag with comma-separated names:
|
|
|
2477
2741
|
|
|
2478
2742
|
The Svelte Language Server supports component-level comments through the following syntax: `<!-- @component [comment] -->`.
|
|
2479
2743
|
|
|
2480
|
-
`sveld`
|
|
2744
|
+
`sveld` copies these over to the exported default component in the TypeScript definition.
|
|
2481
2745
|
|
|
2482
2746
|
**Example:**
|
|
2483
2747
|
|
|
2484
|
-
**Svelte 5 Runes:**
|
|
2485
|
-
|
|
2486
2748
|
```svelte
|
|
2487
2749
|
<!-- @component
|
|
2488
2750
|
@example
|
|
@@ -2499,7 +2761,8 @@ The Svelte Language Server supports component-level comments through the followi
|
|
|
2499
2761
|
</button>
|
|
2500
2762
|
```
|
|
2501
2763
|
|
|
2502
|
-
|
|
2764
|
+
<details>
|
|
2765
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
2503
2766
|
|
|
2504
2767
|
```svelte
|
|
2505
2768
|
<!-- @component
|
|
@@ -2513,6 +2776,10 @@ The Svelte Language Server supports component-level comments through the followi
|
|
|
2513
2776
|
</button>
|
|
2514
2777
|
```
|
|
2515
2778
|
|
|
2779
|
+
</details>
|
|
2780
|
+
|
|
2781
|
+
Output is identical for both syntax modes.
|
|
2782
|
+
|
|
2516
2783
|
Output:
|
|
2517
2784
|
|
|
2518
2785
|
```ts
|
|
@@ -2548,8 +2815,6 @@ Exported functions and consts become accessor props in generated TypeScript defi
|
|
|
2548
2815
|
|
|
2549
2816
|
**Example:**
|
|
2550
2817
|
|
|
2551
|
-
**Svelte 5 Runes:**
|
|
2552
|
-
|
|
2553
2818
|
```svelte
|
|
2554
2819
|
<script>
|
|
2555
2820
|
/**
|
|
@@ -2593,7 +2858,8 @@ Exported functions and consts become accessor props in generated TypeScript defi
|
|
|
2593
2858
|
</div>
|
|
2594
2859
|
```
|
|
2595
2860
|
|
|
2596
|
-
|
|
2861
|
+
<details>
|
|
2862
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
2597
2863
|
|
|
2598
2864
|
```svelte
|
|
2599
2865
|
<script>
|
|
@@ -2632,6 +2898,10 @@ Exported functions and consts become accessor props in generated TypeScript defi
|
|
|
2632
2898
|
</script>
|
|
2633
2899
|
```
|
|
2634
2900
|
|
|
2901
|
+
</details>
|
|
2902
|
+
|
|
2903
|
+
Output is identical for both syntax modes.
|
|
2904
|
+
|
|
2635
2905
|
Output:
|
|
2636
2906
|
|
|
2637
2907
|
```ts
|
|
@@ -2667,6 +2937,14 @@ export default class Component extends SvelteComponentTyped<
|
|
|
2667
2937
|
|
|
2668
2938
|
When only `@param` tags are present without `@returns`, the return type defaults to `any`. When only `@returns` is present without `@param`, the function signature is `() => returnType`.
|
|
2669
2939
|
|
|
2940
|
+
## Troubleshooting
|
|
2941
|
+
|
|
2942
|
+
**A prop came out `any`.** Enable [`reportDiagnostics`](#type-inference-diagnostics) (or `strict` to fail CI) to see which props sveld couldn't infer, then tighten them with `@type` or a native TypeScript annotation.
|
|
2943
|
+
|
|
2944
|
+
**Generated types don't appear for consumers.** Check that the `types` folder is listed in `exports` and `files` in `package.json`. See [Publishing to NPM](#publishing-to-npm).
|
|
2945
|
+
|
|
2946
|
+
**Output differs in CI.** Commit `COMPONENT_API.json` and run [`--check`](#ci-api-drift-checks---check) in CI so API drift fails the build instead of silently diverging.
|
|
2947
|
+
|
|
2670
2948
|
## Contributing
|
|
2671
2949
|
|
|
2672
2950
|
See [contributing guidelines](CONTRIBUTING.md).
|