sveld 0.27.0 → 0.29.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 +610 -120
- package/lib/ComponentParser.d.ts +49 -6
- package/lib/index.js +146 -146
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -3,13 +3,22 @@
|
|
|
3
3
|
[![NPM][npm]][npm-url]
|
|
4
4
|

|
|
5
5
|
|
|
6
|
-
`sveld`
|
|
6
|
+
`sveld` generates TypeScript definitions and component documentation (Markdown/JSON) for Svelte components. It analyzes props, events, slots, and other component features through static analysis. Types and signatures can be defined using [JSDoc notation](https://jsdoc.app/).
|
|
7
7
|
|
|
8
|
-
The purpose of this project is to make third party Svelte component libraries compatible with the Svelte Language Server and TypeScript with minimal effort required by the author. For example, TypeScript definitions may be used during development via intelligent code completion in Integrated Development Environments (
|
|
8
|
+
The purpose of this project is to make third party Svelte component libraries compatible with the Svelte Language Server and TypeScript with minimal effort required by the author. For example, TypeScript definitions may be used during development via intelligent code completion in Integrated Development Environments (IDEs) like VSCode.
|
|
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
|
-
|
|
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`, …), and Svelte 5 Runes (`$props()`, `$bindable()`, `{@render ...}`, callback props such as `onclick`, …).
|
|
13
|
+
|
|
14
|
+
| Syntax mode | Supported |
|
|
15
|
+
| :------------------- | :-------: |
|
|
16
|
+
| Svelte 3 | ✓ |
|
|
17
|
+
| Svelte 4 | ✓ |
|
|
18
|
+
| Svelte 5 (non-Runes) | ✓ |
|
|
19
|
+
| Svelte 5 Runes | ✓ |
|
|
20
|
+
|
|
21
|
+
**Note** that 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.
|
|
13
22
|
|
|
14
23
|
---
|
|
15
24
|
|
|
@@ -28,7 +37,7 @@ Given a Svelte component, `sveld` can infer basic prop types to generate TypeScr
|
|
|
28
37
|
</button>
|
|
29
38
|
```
|
|
30
39
|
|
|
31
|
-
The generated
|
|
40
|
+
The following generated `.d.ts` extends `SvelteComponentTyped`:
|
|
32
41
|
|
|
33
42
|
**Button.svelte.d.ts**
|
|
34
43
|
|
|
@@ -119,6 +128,7 @@ export default class Button extends SvelteComponentTyped<
|
|
|
119
128
|
- [API Reference](#api-reference)
|
|
120
129
|
- [@type](#type)
|
|
121
130
|
- [@typedef](#typedef)
|
|
131
|
+
- [@callback](#callback)
|
|
122
132
|
- [@slot](#slot)
|
|
123
133
|
- [Svelte 5 Snippet Compatibility](#svelte-5-snippet-compatibility)
|
|
124
134
|
- [@event](#event)
|
|
@@ -309,6 +319,23 @@ sveld({
|
|
|
309
319
|
|
|
310
320
|
## API Reference
|
|
311
321
|
|
|
322
|
+
### `reactive`
|
|
323
|
+
|
|
324
|
+
The `reactive` field in generated JSON is heuristic metadata. It is not a complete statement of whether a parent may use `bind:prop` in Svelte.
|
|
325
|
+
|
|
326
|
+
`sveld` marks `reactive: true` when it finds internal evidence that a prop is writable, including:
|
|
327
|
+
|
|
328
|
+
- the prop is assigned or mutated inside the component
|
|
329
|
+
- the prop is marked bindable in runes mode with `$bindable(...)`
|
|
330
|
+
- the prop is used as the target of `bind:*` on an element or child component
|
|
331
|
+
- wrapper-forwarded bindings such as `bind:value`, `bind:selected`, and `bind:ref`
|
|
332
|
+
|
|
333
|
+
Local variables or parameters that shadow a prop name do not count as writes to the exported prop.
|
|
334
|
+
|
|
335
|
+
`reactive: false` means `sveld` found no such evidence. It does not imply that parent-side `bind:` usage is impossible.
|
|
336
|
+
|
|
337
|
+
For stable output, generated `events` arrays are emitted in deterministic sorted order.
|
|
338
|
+
|
|
312
339
|
### `@type`
|
|
313
340
|
|
|
314
341
|
Without a `@type` annotation, `sveld` will infer the primitive type for a prop:
|
|
@@ -327,7 +354,7 @@ export let id = `ccs-${Math.random().toString(36)}`;
|
|
|
327
354
|
|
|
328
355
|
Use the `@type` tag to explicitly document the type. In the following example, the `kind` property has an enumerated (enum) type.
|
|
329
356
|
|
|
330
|
-
Signature
|
|
357
|
+
**Signature:**
|
|
331
358
|
|
|
332
359
|
```js
|
|
333
360
|
/**
|
|
@@ -336,27 +363,47 @@ Signature:
|
|
|
336
363
|
*/
|
|
337
364
|
```
|
|
338
365
|
|
|
339
|
-
Example
|
|
366
|
+
**Example:**
|
|
340
367
|
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Specify the kind of button
|
|
344
|
-
* @type {"primary" | "secondary" | "tertiary"}
|
|
345
|
-
*/
|
|
346
|
-
export let kind = "primary";
|
|
368
|
+
**Svelte 5 Runes:**
|
|
347
369
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
370
|
+
```svelte
|
|
371
|
+
<script>
|
|
372
|
+
/**
|
|
373
|
+
* Specify the kind of button
|
|
374
|
+
* @type {"primary" | "secondary" | "tertiary"}
|
|
375
|
+
*/
|
|
376
|
+
/**
|
|
377
|
+
* Specify the Carbon icon to render
|
|
378
|
+
* @type {typeof import("carbon-icons-svelte").CarbonIcon}
|
|
379
|
+
*/
|
|
380
|
+
let { kind = "primary", renderIcon = Close20 } = $props();
|
|
381
|
+
</script>
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
**Svelte 3, 4, 5 (non-Runes):**
|
|
385
|
+
|
|
386
|
+
```svelte
|
|
387
|
+
<script>
|
|
388
|
+
/**
|
|
389
|
+
* Specify the kind of button
|
|
390
|
+
* @type {"primary" | "secondary" | "tertiary"}
|
|
391
|
+
*/
|
|
392
|
+
export let kind = "primary";
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Specify the Carbon icon to render
|
|
396
|
+
* @type {typeof import("carbon-icons-svelte").CarbonIcon}
|
|
397
|
+
*/
|
|
398
|
+
export let renderIcon = Close20;
|
|
399
|
+
</script>
|
|
353
400
|
```
|
|
354
401
|
|
|
355
402
|
### `@typedef`
|
|
356
403
|
|
|
357
404
|
The `@typedef` tag can be used to define a common type that is used multiple times within a component. All typedefs defined in a component will be exported from the generated TypeScript definition file.
|
|
358
405
|
|
|
359
|
-
Signature
|
|
406
|
+
**Signature:**
|
|
360
407
|
|
|
361
408
|
```js
|
|
362
409
|
/**
|
|
@@ -364,26 +411,48 @@ Signature:
|
|
|
364
411
|
*/
|
|
365
412
|
```
|
|
366
413
|
|
|
367
|
-
Example
|
|
414
|
+
**Example:**
|
|
368
415
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
416
|
+
**Svelte 5 Runes:**
|
|
417
|
+
|
|
418
|
+
```svelte
|
|
419
|
+
<script>
|
|
420
|
+
/**
|
|
421
|
+
* @typedef {string} AuthorName
|
|
422
|
+
* @typedef {{ name?: AuthorName; dob?: string; }} Author
|
|
423
|
+
*/
|
|
424
|
+
|
|
425
|
+
let {
|
|
426
|
+
/** @type {Author} */
|
|
427
|
+
author = {},
|
|
428
|
+
/** @type {Author[]} */
|
|
429
|
+
authors = [],
|
|
430
|
+
} = $props();
|
|
431
|
+
</script>
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
**Svelte 3, 4, 5 (non-Runes):**
|
|
435
|
+
|
|
436
|
+
```svelte
|
|
437
|
+
<script>
|
|
438
|
+
/**
|
|
439
|
+
* @typedef {string} AuthorName
|
|
440
|
+
* @typedef {{ name?: AuthorName; dob?: string; }} Author
|
|
441
|
+
*/
|
|
374
442
|
|
|
375
|
-
/** @type {Author} */
|
|
376
|
-
export let author = {};
|
|
443
|
+
/** @type {Author} */
|
|
444
|
+
export let author = {};
|
|
377
445
|
|
|
378
|
-
/** @type {Author[]} */
|
|
379
|
-
export let authors = [];
|
|
446
|
+
/** @type {Author[]} */
|
|
447
|
+
export let authors = [];
|
|
448
|
+
</script>
|
|
380
449
|
```
|
|
381
450
|
|
|
382
451
|
#### Using `@property` for complex typedefs
|
|
383
452
|
|
|
384
453
|
For complex object types, use the `@property` tag to document individual properties. This provides better documentation and IDE support with per-property tooltips.
|
|
385
454
|
|
|
386
|
-
Signature
|
|
455
|
+
**Signature:**
|
|
387
456
|
|
|
388
457
|
```js
|
|
389
458
|
/**
|
|
@@ -393,19 +462,40 @@ Signature:
|
|
|
393
462
|
*/
|
|
394
463
|
```
|
|
395
464
|
|
|
396
|
-
Example
|
|
465
|
+
**Example:**
|
|
397
466
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
467
|
+
**Svelte 5 Runes:**
|
|
468
|
+
|
|
469
|
+
```svelte
|
|
470
|
+
<script>
|
|
471
|
+
/**
|
|
472
|
+
* Represents a user in the system
|
|
473
|
+
* @typedef {object} User
|
|
474
|
+
* @property {string} name - The user's full name
|
|
475
|
+
* @property {string} email - The user's email address
|
|
476
|
+
* @property {number} age - The user's age in years
|
|
477
|
+
*/
|
|
478
|
+
|
|
479
|
+
/** @type {User} */
|
|
480
|
+
let { user = { name: "John", email: "john@example.com", age: 30 } } = $props();
|
|
481
|
+
</script>
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
**Svelte 3, 4, 5 (non-Runes):**
|
|
485
|
+
|
|
486
|
+
```svelte
|
|
487
|
+
<script>
|
|
488
|
+
/**
|
|
489
|
+
* Represents a user in the system
|
|
490
|
+
* @typedef {object} User
|
|
491
|
+
* @property {string} name - The user's full name
|
|
492
|
+
* @property {string} email - The user's email address
|
|
493
|
+
* @property {number} age - The user's age in years
|
|
494
|
+
*/
|
|
406
495
|
|
|
407
|
-
/** @type {User} */
|
|
408
|
-
export let user = { name: "John", email: "john@example.com", age: 30 };
|
|
496
|
+
/** @type {User} */
|
|
497
|
+
export let user = { name: "John", email: "john@example.com", age: 30 };
|
|
498
|
+
</script>
|
|
409
499
|
```
|
|
410
500
|
|
|
411
501
|
Output:
|
|
@@ -433,7 +523,7 @@ export type ComponentProps = {
|
|
|
433
523
|
|
|
434
524
|
Following JSDoc standards, use square brackets to mark properties as optional. You can also specify default values using the `[propertyName=defaultValue]` syntax.
|
|
435
525
|
|
|
436
|
-
Signature
|
|
526
|
+
**Signature:**
|
|
437
527
|
|
|
438
528
|
```js
|
|
439
529
|
/**
|
|
@@ -443,20 +533,42 @@ Signature:
|
|
|
443
533
|
*/
|
|
444
534
|
```
|
|
445
535
|
|
|
446
|
-
Example
|
|
536
|
+
**Example:**
|
|
447
537
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
538
|
+
**Svelte 5 Runes:**
|
|
539
|
+
|
|
540
|
+
```svelte
|
|
541
|
+
<script>
|
|
542
|
+
/**
|
|
543
|
+
* Configuration options for the component
|
|
544
|
+
* @typedef {object} ComponentConfig
|
|
545
|
+
* @property {boolean} enabled - Whether the component is enabled
|
|
546
|
+
* @property {string} theme - The component theme
|
|
547
|
+
* @property {number} [timeout=5000] - Optional timeout in milliseconds
|
|
548
|
+
* @property {boolean} [debug] - Optional debug mode flag
|
|
549
|
+
*/
|
|
457
550
|
|
|
458
|
-
/** @type {ComponentConfig} */
|
|
459
|
-
|
|
551
|
+
/** @type {ComponentConfig} */
|
|
552
|
+
let { config = { enabled: true, theme: "dark" } } = $props();
|
|
553
|
+
</script>
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
**Svelte 3, 4, 5 (non-Runes):**
|
|
557
|
+
|
|
558
|
+
```svelte
|
|
559
|
+
<script>
|
|
560
|
+
/**
|
|
561
|
+
* Configuration options for the component
|
|
562
|
+
* @typedef {object} ComponentConfig
|
|
563
|
+
* @property {boolean} enabled - Whether the component is enabled
|
|
564
|
+
* @property {string} theme - The component theme
|
|
565
|
+
* @property {number} [timeout=5000] - Optional timeout in milliseconds
|
|
566
|
+
* @property {boolean} [debug] - Optional debug mode flag
|
|
567
|
+
*/
|
|
568
|
+
|
|
569
|
+
/** @type {ComponentConfig} */
|
|
570
|
+
export let config = { enabled: true, theme: "dark" };
|
|
571
|
+
</script>
|
|
460
572
|
```
|
|
461
573
|
|
|
462
574
|
Output:
|
|
@@ -484,13 +596,97 @@ export type ComponentProps = {
|
|
|
484
596
|
|
|
485
597
|
> **Note:** The inline syntax `@typedef {{ name: string }} User` continues to work for backwards compatibility.
|
|
486
598
|
|
|
599
|
+
### `@callback`
|
|
600
|
+
|
|
601
|
+
The `@callback` tag defines a function type using `@param` and `@returns` tags, following the [TypeScript JSDoc `@callback` specification](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#callback). Like `@typedef`, callbacks are exported from the generated TypeScript definition file.
|
|
602
|
+
|
|
603
|
+
This is useful for typing callback props without using inline function type syntax.
|
|
604
|
+
|
|
605
|
+
**Signature:**
|
|
606
|
+
|
|
607
|
+
```js
|
|
608
|
+
/**
|
|
609
|
+
* Optional description
|
|
610
|
+
* @callback CallbackName
|
|
611
|
+
* @param {Type} paramName - Parameter description
|
|
612
|
+
* @returns {ReturnType}
|
|
613
|
+
*/
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
**Example:**
|
|
617
|
+
|
|
618
|
+
**Svelte 5 Runes:**
|
|
619
|
+
|
|
620
|
+
```svelte
|
|
621
|
+
<script>
|
|
622
|
+
/**
|
|
623
|
+
* Callback fired when the value changes
|
|
624
|
+
* @callback OnChange
|
|
625
|
+
* @param {string} value - The new value
|
|
626
|
+
* @param {number} index - The index of the changed item
|
|
627
|
+
* @returns {void}
|
|
628
|
+
*/
|
|
629
|
+
|
|
630
|
+
/** @type {OnChange} */
|
|
631
|
+
let { onChange = (value, index) => {} } = $props();
|
|
632
|
+
</script>
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
**Svelte 3, 4, 5 (non-Runes):**
|
|
636
|
+
|
|
637
|
+
```svelte
|
|
638
|
+
<script>
|
|
639
|
+
/**
|
|
640
|
+
* Callback fired when the value changes
|
|
641
|
+
* @callback OnChange
|
|
642
|
+
* @param {string} value - The new value
|
|
643
|
+
* @param {number} index - The index of the changed item
|
|
644
|
+
* @returns {void}
|
|
645
|
+
*/
|
|
646
|
+
|
|
647
|
+
/** @type {OnChange} */
|
|
648
|
+
export let onChange = (value, index) => {};
|
|
649
|
+
</script>
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
Output:
|
|
653
|
+
|
|
654
|
+
```ts
|
|
655
|
+
/**
|
|
656
|
+
* Callback fired when the value changes
|
|
657
|
+
*/
|
|
658
|
+
export type OnChange = (value: string, index: number) => void;
|
|
659
|
+
|
|
660
|
+
export type ComponentProps = {
|
|
661
|
+
/**
|
|
662
|
+
* Callback fired when the value changes
|
|
663
|
+
*/
|
|
664
|
+
onChange?: OnChange;
|
|
665
|
+
};
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
Callbacks can be combined with `@typedef` in the same comment block:
|
|
669
|
+
|
|
670
|
+
```js
|
|
671
|
+
/**
|
|
672
|
+
* @typedef {"asc" | "desc"} SortDirection
|
|
673
|
+
* @callback SortFn
|
|
674
|
+
* @param {any} a
|
|
675
|
+
* @param {any} b
|
|
676
|
+
* @param {SortDirection} direction
|
|
677
|
+
* @returns {number}
|
|
678
|
+
*/
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
When `@returns` is omitted, the return type defaults to `void`. When no `@param` tags are present, the callback is typed as a no-argument function.
|
|
682
|
+
|
|
487
683
|
### `@slot`
|
|
488
684
|
|
|
489
685
|
Use the `@slot` tag for typing component slots. Note that `@slot` is a non-standard JSDoc tag.
|
|
490
686
|
|
|
491
687
|
Descriptions are optional for named slots. Currently, the default slot cannot have a description.
|
|
492
688
|
|
|
493
|
-
Signature
|
|
689
|
+
**Signature:**
|
|
494
690
|
|
|
495
691
|
```js
|
|
496
692
|
/**
|
|
@@ -504,7 +700,32 @@ Omit the `slot-name` to type the default slot.
|
|
|
504
700
|
*/
|
|
505
701
|
```
|
|
506
702
|
|
|
507
|
-
Example
|
|
703
|
+
**Example:**
|
|
704
|
+
|
|
705
|
+
**Svelte 5 Runes:**
|
|
706
|
+
|
|
707
|
+
```svelte
|
|
708
|
+
<script>
|
|
709
|
+
/**
|
|
710
|
+
* @slot {{ prop: number; doubled: number; }}
|
|
711
|
+
* @slot {{}} title
|
|
712
|
+
* @slot {{ prop: number }} body - Customize the paragraph text.
|
|
713
|
+
*/
|
|
714
|
+
|
|
715
|
+
let { prop = 0, children, title, body } = $props();
|
|
716
|
+
</script>
|
|
717
|
+
|
|
718
|
+
<h1>
|
|
719
|
+
{@render children?.({ prop, doubled: prop * 2 })}
|
|
720
|
+
{@render title?.()}
|
|
721
|
+
</h1>
|
|
722
|
+
|
|
723
|
+
<p>
|
|
724
|
+
{@render body?.({ prop })}
|
|
725
|
+
</p>
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
**Svelte 3, 4, 5 (non-Runes):**
|
|
508
729
|
|
|
509
730
|
```svelte
|
|
510
731
|
<script>
|
|
@@ -531,6 +752,8 @@ Example:
|
|
|
531
752
|
|
|
532
753
|
For Svelte 5 compatibility, `sveld` automatically generates optional snippet props for all slots. This allows consumers to use either the traditional slot syntax or Svelte 5's `{#snippet}` syntax.
|
|
533
754
|
|
|
755
|
+
When parsing runes components, `sveld` also maps `{@render ...}` calls back into the same slot metadata used for traditional `<slot>` declarations.
|
|
756
|
+
|
|
534
757
|
For slots with props (e.g., `let:prop`), the generated type uses a Snippet-compatible signature:
|
|
535
758
|
|
|
536
759
|
```ts
|
|
@@ -633,9 +856,11 @@ export default class DataTable<Row> extends SvelteComponentTyped<
|
|
|
633
856
|
|
|
634
857
|
Use the `@event` tag to type dispatched events. An event name is required and a description optional.
|
|
635
858
|
|
|
859
|
+
In Svelte 5 runes components, callback props such as `onclick` are treated as component props, not events. The `events` output remains reserved for dispatched events and legacy forwarded events.
|
|
860
|
+
|
|
636
861
|
Use `null` as the value if no event detail is provided.
|
|
637
862
|
|
|
638
|
-
Signature
|
|
863
|
+
**Signature:**
|
|
639
864
|
|
|
640
865
|
```js
|
|
641
866
|
/**
|
|
@@ -644,22 +869,48 @@ Signature:
|
|
|
644
869
|
*/
|
|
645
870
|
```
|
|
646
871
|
|
|
647
|
-
Example
|
|
872
|
+
**Example:**
|
|
648
873
|
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
874
|
+
**Svelte 5 Runes:**
|
|
875
|
+
|
|
876
|
+
```svelte
|
|
877
|
+
<script>
|
|
878
|
+
/**
|
|
879
|
+
* @event {{ key: string }} button:key
|
|
880
|
+
* @event {null} key - Fired when `key` changes.
|
|
881
|
+
*/
|
|
882
|
+
|
|
883
|
+
let { key = "" } = $props();
|
|
884
|
+
|
|
885
|
+
import { createEventDispatcher } from "svelte";
|
|
886
|
+
|
|
887
|
+
const dispatch = createEventDispatcher();
|
|
654
888
|
|
|
655
|
-
|
|
889
|
+
$effect(() => {
|
|
890
|
+
dispatch("button:key", { key });
|
|
891
|
+
if (key) dispatch("key");
|
|
892
|
+
});
|
|
893
|
+
</script>
|
|
894
|
+
```
|
|
656
895
|
|
|
657
|
-
|
|
896
|
+
**Svelte 3, 4, 5 (non-Runes):**
|
|
658
897
|
|
|
659
|
-
|
|
898
|
+
```svelte
|
|
899
|
+
<script>
|
|
900
|
+
/**
|
|
901
|
+
* @event {{ key: string }} button:key
|
|
902
|
+
* @event {null} key - Fired when `key` changes.
|
|
903
|
+
*/
|
|
904
|
+
|
|
905
|
+
export let key = "";
|
|
906
|
+
|
|
907
|
+
import { createEventDispatcher } from "svelte";
|
|
660
908
|
|
|
661
|
-
|
|
662
|
-
|
|
909
|
+
const dispatch = createEventDispatcher();
|
|
910
|
+
|
|
911
|
+
$: dispatch("button:key", { key });
|
|
912
|
+
$: if (key) dispatch("key");
|
|
913
|
+
</script>
|
|
663
914
|
```
|
|
664
915
|
|
|
665
916
|
Output:
|
|
@@ -679,7 +930,7 @@ export default class Component extends SvelteComponentTyped<
|
|
|
679
930
|
|
|
680
931
|
For events with complex object payloads, use the `@property` tag to document individual properties. The main comment description will be used as the event description.
|
|
681
932
|
|
|
682
|
-
Signature
|
|
933
|
+
**Signature:**
|
|
683
934
|
|
|
684
935
|
```js
|
|
685
936
|
/**
|
|
@@ -690,30 +941,64 @@ Signature:
|
|
|
690
941
|
*/
|
|
691
942
|
```
|
|
692
943
|
|
|
693
|
-
Example
|
|
944
|
+
**Example:**
|
|
694
945
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
946
|
+
**Svelte 5 Runes:**
|
|
947
|
+
|
|
948
|
+
```svelte
|
|
949
|
+
<script>
|
|
950
|
+
/**
|
|
951
|
+
* Fired when the user submits the form
|
|
952
|
+
*
|
|
953
|
+
* @event submit
|
|
954
|
+
* @type {object}
|
|
955
|
+
* @property {string} name - The user's name
|
|
956
|
+
* @property {string} email - The user's email address
|
|
957
|
+
* @property {boolean} newsletter - Whether the user opted into the newsletter
|
|
958
|
+
*/
|
|
705
959
|
|
|
706
|
-
|
|
960
|
+
let { name = "Jane Doe", email = "jane@example.com", newsletter = true } = $props();
|
|
707
961
|
|
|
708
|
-
|
|
962
|
+
import { createEventDispatcher } from "svelte";
|
|
709
963
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
964
|
+
const dispatch = createEventDispatcher();
|
|
965
|
+
|
|
966
|
+
function handleSubmit() {
|
|
967
|
+
dispatch("submit", { name, email, newsletter });
|
|
968
|
+
}
|
|
969
|
+
</script>
|
|
970
|
+
|
|
971
|
+
<button type="button" onclick={handleSubmit}>Submit</button>
|
|
972
|
+
```
|
|
973
|
+
|
|
974
|
+
**Svelte 3, 4, 5 (non-Runes):**
|
|
975
|
+
|
|
976
|
+
```svelte
|
|
977
|
+
<script>
|
|
978
|
+
/**
|
|
979
|
+
* Fired when the user submits the form
|
|
980
|
+
*
|
|
981
|
+
* @event submit
|
|
982
|
+
* @type {object}
|
|
983
|
+
* @property {string} name - The user's name
|
|
984
|
+
* @property {string} email - The user's email address
|
|
985
|
+
* @property {boolean} newsletter - Whether the user opted into the newsletter
|
|
986
|
+
*/
|
|
987
|
+
|
|
988
|
+
export let name = "Jane Doe";
|
|
989
|
+
export let email = "jane@example.com";
|
|
990
|
+
export let newsletter = true;
|
|
991
|
+
|
|
992
|
+
import { createEventDispatcher } from "svelte";
|
|
993
|
+
|
|
994
|
+
const dispatch = createEventDispatcher();
|
|
995
|
+
|
|
996
|
+
function handleSubmit() {
|
|
997
|
+
dispatch("submit", { name, email, newsletter });
|
|
998
|
+
}
|
|
999
|
+
</script>
|
|
1000
|
+
|
|
1001
|
+
<button type="button" on:click={handleSubmit}>Submit</button>
|
|
717
1002
|
```
|
|
718
1003
|
|
|
719
1004
|
Output:
|
|
@@ -740,30 +1025,70 @@ export default class Component extends SvelteComponentTyped<
|
|
|
740
1025
|
|
|
741
1026
|
Just like with typedefs, you can mark event detail properties as optional using square brackets. This is useful when some properties may not always be included in the event payload.
|
|
742
1027
|
|
|
743
|
-
Example
|
|
1028
|
+
**Example:**
|
|
744
1029
|
|
|
745
|
-
|
|
746
|
-
/**
|
|
747
|
-
* Snowball event fired when throwing a snowball
|
|
748
|
-
*
|
|
749
|
-
* @event snowball
|
|
750
|
-
* @type {object}
|
|
751
|
-
* @property {boolean} isPacked - Indicates whether the snowball is tightly packed
|
|
752
|
-
* @property {number} speed - The speed of the snowball in mph
|
|
753
|
-
* @property {string} [color] - Optional color of the snowball
|
|
754
|
-
* @property {number} [density=0.9] - Optional density with default value
|
|
755
|
-
*/
|
|
1030
|
+
**Svelte 5 Runes:**
|
|
756
1031
|
|
|
757
|
-
|
|
1032
|
+
```svelte
|
|
1033
|
+
<script>
|
|
1034
|
+
/**
|
|
1035
|
+
* Snowball event fired when throwing a snowball
|
|
1036
|
+
*
|
|
1037
|
+
* @event snowball
|
|
1038
|
+
* @type {object}
|
|
1039
|
+
* @property {boolean} isPacked - Indicates whether the snowball is tightly packed
|
|
1040
|
+
* @property {number} speed - The speed of the snowball in mph
|
|
1041
|
+
* @property {string} [color] - Optional color of the snowball
|
|
1042
|
+
* @property {number} [density=0.9] - Optional density with default value
|
|
1043
|
+
*/
|
|
758
1044
|
|
|
759
|
-
|
|
1045
|
+
let { speed = 50 } = $props();
|
|
760
1046
|
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
1047
|
+
import { createEventDispatcher } from "svelte";
|
|
1048
|
+
|
|
1049
|
+
const dispatch = createEventDispatcher();
|
|
1050
|
+
|
|
1051
|
+
function throwSnowball() {
|
|
1052
|
+
dispatch("snowball", {
|
|
1053
|
+
isPacked: true,
|
|
1054
|
+
speed,
|
|
1055
|
+
});
|
|
1056
|
+
}
|
|
1057
|
+
</script>
|
|
1058
|
+
|
|
1059
|
+
<button type="button" onclick={throwSnowball}>Throw</button>
|
|
1060
|
+
```
|
|
1061
|
+
|
|
1062
|
+
**Svelte 3, 4, 5 (non-Runes):**
|
|
1063
|
+
|
|
1064
|
+
```svelte
|
|
1065
|
+
<script>
|
|
1066
|
+
/**
|
|
1067
|
+
* Snowball event fired when throwing a snowball
|
|
1068
|
+
*
|
|
1069
|
+
* @event snowball
|
|
1070
|
+
* @type {object}
|
|
1071
|
+
* @property {boolean} isPacked - Indicates whether the snowball is tightly packed
|
|
1072
|
+
* @property {number} speed - The speed of the snowball in mph
|
|
1073
|
+
* @property {string} [color] - Optional color of the snowball
|
|
1074
|
+
* @property {number} [density=0.9] - Optional density with default value
|
|
1075
|
+
*/
|
|
1076
|
+
|
|
1077
|
+
export let speed = 50;
|
|
1078
|
+
|
|
1079
|
+
import { createEventDispatcher } from "svelte";
|
|
1080
|
+
|
|
1081
|
+
const dispatch = createEventDispatcher();
|
|
1082
|
+
|
|
1083
|
+
function throwSnowball() {
|
|
1084
|
+
dispatch("snowball", {
|
|
1085
|
+
isPacked: true,
|
|
1086
|
+
speed,
|
|
1087
|
+
});
|
|
1088
|
+
}
|
|
1089
|
+
</script>
|
|
1090
|
+
|
|
1091
|
+
<button type="button" on:click={throwSnowball}>Throw</button>
|
|
767
1092
|
```
|
|
768
1093
|
|
|
769
1094
|
Output:
|
|
@@ -805,9 +1130,11 @@ When you use `setContext` in a component, `sveld` will:
|
|
|
805
1130
|
|
|
806
1131
|
**Modal.svelte**
|
|
807
1132
|
|
|
1133
|
+
**Svelte 5 Runes:**
|
|
1134
|
+
|
|
808
1135
|
```svelte
|
|
809
1136
|
<script>
|
|
810
|
-
import { setContext } from
|
|
1137
|
+
import { setContext } from "svelte";
|
|
811
1138
|
|
|
812
1139
|
/**
|
|
813
1140
|
* Close the modal
|
|
@@ -825,7 +1152,39 @@ When you use `setContext` in a component, `sveld` will:
|
|
|
825
1152
|
// Open logic
|
|
826
1153
|
};
|
|
827
1154
|
|
|
828
|
-
setContext(
|
|
1155
|
+
setContext("simple-modal", { open, close });
|
|
1156
|
+
|
|
1157
|
+
let { children } = $props();
|
|
1158
|
+
</script>
|
|
1159
|
+
|
|
1160
|
+
<div class="modal">
|
|
1161
|
+
{@render children?.()}
|
|
1162
|
+
</div>
|
|
1163
|
+
```
|
|
1164
|
+
|
|
1165
|
+
**Svelte 3, 4, 5 (non-Runes):**
|
|
1166
|
+
|
|
1167
|
+
```svelte
|
|
1168
|
+
<script>
|
|
1169
|
+
import { setContext } from "svelte";
|
|
1170
|
+
|
|
1171
|
+
/**
|
|
1172
|
+
* Close the modal
|
|
1173
|
+
* @type {() => void}
|
|
1174
|
+
*/
|
|
1175
|
+
const close = () => {
|
|
1176
|
+
// Close logic
|
|
1177
|
+
};
|
|
1178
|
+
|
|
1179
|
+
/**
|
|
1180
|
+
* Open the modal with content
|
|
1181
|
+
* @type {(component: any, props?: any) => void}
|
|
1182
|
+
*/
|
|
1183
|
+
const open = (component, props) => {
|
|
1184
|
+
// Open logic
|
|
1185
|
+
};
|
|
1186
|
+
|
|
1187
|
+
setContext("simple-modal", { open, close });
|
|
829
1188
|
</script>
|
|
830
1189
|
|
|
831
1190
|
<div class="modal">
|
|
@@ -963,7 +1322,7 @@ There are several ways to provide type information for contexts:
|
|
|
963
1322
|
|
|
964
1323
|
You can use the `@restProps` tag to specify the element tags that `$$restProps` is forwarded to.
|
|
965
1324
|
|
|
966
|
-
Signature
|
|
1325
|
+
**Signature:**
|
|
967
1326
|
|
|
968
1327
|
```js
|
|
969
1328
|
/**
|
|
@@ -975,14 +1334,35 @@ Signature:
|
|
|
975
1334
|
*/
|
|
976
1335
|
```
|
|
977
1336
|
|
|
978
|
-
Example
|
|
1337
|
+
**Example:**
|
|
1338
|
+
|
|
1339
|
+
**Svelte 5 Runes:**
|
|
1340
|
+
|
|
1341
|
+
```svelte
|
|
1342
|
+
<script>
|
|
1343
|
+
import Button from "./Button.svelte";
|
|
1344
|
+
|
|
1345
|
+
/** @restProps {h1 | button} */
|
|
1346
|
+
let { edit = false, children, ...restProps } = $props();
|
|
1347
|
+
</script>
|
|
1348
|
+
|
|
1349
|
+
{#if edit}
|
|
1350
|
+
<Button {...restProps} />
|
|
1351
|
+
{:else}
|
|
1352
|
+
<h1 {...restProps}>
|
|
1353
|
+
{@render children?.()}
|
|
1354
|
+
</h1>
|
|
1355
|
+
{/if}
|
|
1356
|
+
```
|
|
1357
|
+
|
|
1358
|
+
**Svelte 3, 4, 5 (non-Runes):**
|
|
979
1359
|
|
|
980
1360
|
```svelte
|
|
981
1361
|
<script>
|
|
982
1362
|
/** @restProps {h1 | button} */
|
|
983
1363
|
export let edit = false;
|
|
984
1364
|
|
|
985
|
-
import Button from "
|
|
1365
|
+
import Button from "./Button.svelte";
|
|
986
1366
|
</script>
|
|
987
1367
|
|
|
988
1368
|
{#if edit}
|
|
@@ -998,7 +1378,7 @@ In some cases, a component may be based on another component. The `@extendProps`
|
|
|
998
1378
|
|
|
999
1379
|
> **Note:** `@extends` is supported as an alias but `@extendProps` is preferred to avoid conflicts with standard JSDoc `@extends` (used for class inheritance).
|
|
1000
1380
|
|
|
1001
|
-
Signature
|
|
1381
|
+
**Signature:**
|
|
1002
1382
|
|
|
1003
1383
|
```js
|
|
1004
1384
|
/**
|
|
@@ -1006,7 +1386,7 @@ Signature:
|
|
|
1006
1386
|
*/
|
|
1007
1387
|
```
|
|
1008
1388
|
|
|
1009
|
-
Example
|
|
1389
|
+
**Example:**
|
|
1010
1390
|
|
|
1011
1391
|
```js
|
|
1012
1392
|
/** @extendProps {"./Button.svelte"} ButtonProps */
|
|
@@ -1029,7 +1409,7 @@ However, the `generics` attribute only works if using `lang="ts"`; the language
|
|
|
1029
1409
|
|
|
1030
1410
|
Because `sveld` is designed to support JavaScript-only usage as a baseline, the API design to specify generics uses a custom JSDoc tag `@generics`.
|
|
1031
1411
|
|
|
1032
|
-
Signature
|
|
1412
|
+
**Signature:**
|
|
1033
1413
|
|
|
1034
1414
|
```js
|
|
1035
1415
|
/**
|
|
@@ -1037,7 +1417,7 @@ Signature:
|
|
|
1037
1417
|
*/
|
|
1038
1418
|
```
|
|
1039
1419
|
|
|
1040
|
-
Example
|
|
1420
|
+
**Example:**
|
|
1041
1421
|
|
|
1042
1422
|
```js
|
|
1043
1423
|
/**
|
|
@@ -1045,6 +1425,49 @@ Example
|
|
|
1045
1425
|
*/
|
|
1046
1426
|
```
|
|
1047
1427
|
|
|
1428
|
+
**Component example:**
|
|
1429
|
+
|
|
1430
|
+
**Svelte 5 Runes:**
|
|
1431
|
+
|
|
1432
|
+
```svelte
|
|
1433
|
+
<script>
|
|
1434
|
+
/**
|
|
1435
|
+
* @typedef {{ id: string | number; [key: string]: any; }} DataTableRow
|
|
1436
|
+
* @typedef {Exclude<keyof Row, "id">} DataTableKey<Row>
|
|
1437
|
+
* @typedef {{ key: DataTableKey<Row>; value: string; }} DataTableHeader<Row=DataTableRow>
|
|
1438
|
+
* @template {DataTableRow} <Row extends DataTableRow = DataTableRow>
|
|
1439
|
+
* @generics {Row extends DataTableRow = DataTableRow} Row
|
|
1440
|
+
*/
|
|
1441
|
+
|
|
1442
|
+
/** @type {ReadonlyArray<DataTableHeader<Row>>} */
|
|
1443
|
+
let { headers = [], rows = [], children } = $props();
|
|
1444
|
+
</script>
|
|
1445
|
+
|
|
1446
|
+
{@render children?.({ headers, rows })}
|
|
1447
|
+
```
|
|
1448
|
+
|
|
1449
|
+
**Svelte 3, 4, 5 (non-Runes):**
|
|
1450
|
+
|
|
1451
|
+
```svelte
|
|
1452
|
+
<script>
|
|
1453
|
+
/**
|
|
1454
|
+
* @typedef {{ id: string | number; [key: string]: any; }} DataTableRow
|
|
1455
|
+
* @typedef {Exclude<keyof Row, "id">} DataTableKey<Row>
|
|
1456
|
+
* @typedef {{ key: DataTableKey<Row>; value: string; }} DataTableHeader<Row=DataTableRow>
|
|
1457
|
+
* @template {DataTableRow} <Row extends DataTableRow = DataTableRow>
|
|
1458
|
+
* @generics {Row extends DataTableRow = DataTableRow} Row
|
|
1459
|
+
*/
|
|
1460
|
+
|
|
1461
|
+
/** @type {ReadonlyArray<DataTableHeader<Row>>} */
|
|
1462
|
+
export let headers = [];
|
|
1463
|
+
|
|
1464
|
+
/** @type {ReadonlyArray<Row>} */
|
|
1465
|
+
export let rows = [];
|
|
1466
|
+
</script>
|
|
1467
|
+
|
|
1468
|
+
<slot {headers} {rows} />
|
|
1469
|
+
```
|
|
1470
|
+
|
|
1048
1471
|
The generated TypeScript definition will resemble the following:
|
|
1049
1472
|
|
|
1050
1473
|
```ts
|
|
@@ -1086,7 +1509,27 @@ The Svelte Language Server supports component-level comments through the followi
|
|
|
1086
1509
|
|
|
1087
1510
|
`sveld` will copy these over to the exported default component in the TypeScript definition.
|
|
1088
1511
|
|
|
1089
|
-
Example
|
|
1512
|
+
**Example:**
|
|
1513
|
+
|
|
1514
|
+
**Svelte 5 Runes:**
|
|
1515
|
+
|
|
1516
|
+
```svelte
|
|
1517
|
+
<!-- @component
|
|
1518
|
+
@example
|
|
1519
|
+
<Button>
|
|
1520
|
+
Text
|
|
1521
|
+
</Button>
|
|
1522
|
+
-->
|
|
1523
|
+
<script>
|
|
1524
|
+
let { children } = $props();
|
|
1525
|
+
</script>
|
|
1526
|
+
|
|
1527
|
+
<button>
|
|
1528
|
+
{@render children?.()}
|
|
1529
|
+
</button>
|
|
1530
|
+
```
|
|
1531
|
+
|
|
1532
|
+
**Svelte 3, 4, 5 (non-Runes):**
|
|
1090
1533
|
|
|
1091
1534
|
```svelte
|
|
1092
1535
|
<!-- @component
|
|
@@ -1122,7 +1565,7 @@ Exported functions and consts become accessor props in generated TypeScript defi
|
|
|
1122
1565
|
|
|
1123
1566
|
Note that `@type` tag annotations take precedence over `@param`/`@returns` tags.
|
|
1124
1567
|
|
|
1125
|
-
Signature
|
|
1568
|
+
**Signature:**
|
|
1126
1569
|
|
|
1127
1570
|
```js
|
|
1128
1571
|
/**
|
|
@@ -1133,7 +1576,54 @@ Signature:
|
|
|
1133
1576
|
*/
|
|
1134
1577
|
```
|
|
1135
1578
|
|
|
1136
|
-
Example
|
|
1579
|
+
**Example:**
|
|
1580
|
+
|
|
1581
|
+
**Svelte 5 Runes:**
|
|
1582
|
+
|
|
1583
|
+
```svelte
|
|
1584
|
+
<script>
|
|
1585
|
+
/**
|
|
1586
|
+
* @typedef {object} NotificationData
|
|
1587
|
+
* @property {string} [id] - Optional id for deduplication
|
|
1588
|
+
* @property {"error" | "info" | "success"} [kind]
|
|
1589
|
+
*/
|
|
1590
|
+
|
|
1591
|
+
let { children } = $props();
|
|
1592
|
+
|
|
1593
|
+
/**
|
|
1594
|
+
* Add a notification to the queue.
|
|
1595
|
+
* @param {NotificationData} notification
|
|
1596
|
+
* @returns {string} The notification id
|
|
1597
|
+
*/
|
|
1598
|
+
export function add(notification) {
|
|
1599
|
+
const id = notification.id ?? "id";
|
|
1600
|
+
return id;
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1603
|
+
/**
|
|
1604
|
+
* Remove a notification by id.
|
|
1605
|
+
* @param {string} id
|
|
1606
|
+
* @returns {boolean} True if the notification was found and removed
|
|
1607
|
+
*/
|
|
1608
|
+
export function remove(id) {
|
|
1609
|
+
return true;
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
/**
|
|
1613
|
+
* Get notification count.
|
|
1614
|
+
* @returns {number} The number of notifications
|
|
1615
|
+
*/
|
|
1616
|
+
export function getCount() {
|
|
1617
|
+
return 0;
|
|
1618
|
+
}
|
|
1619
|
+
</script>
|
|
1620
|
+
|
|
1621
|
+
<div>
|
|
1622
|
+
{@render children?.()}
|
|
1623
|
+
</div>
|
|
1624
|
+
```
|
|
1625
|
+
|
|
1626
|
+
**Svelte 3, 4, 5 (non-Runes):**
|
|
1137
1627
|
|
|
1138
1628
|
```svelte
|
|
1139
1629
|
<script>
|