sveld 0.25.5 → 0.25.7
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 +90 -1
- package/lib/writer/writer-ts-definitions-core.js +20 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ The purpose of this project is to make third party Svelte component libraries co
|
|
|
14
14
|
- [Component Index](https://github.com/IBM/carbon-components-svelte/blob/master/COMPONENT_INDEX.md): Markdown file documenting component props, slots, and events
|
|
15
15
|
- [Component API](https://github.com/IBM/carbon-components-svelte/blob/master/docs/src/COMPONENT_API.json): Component API metadata in JSON format
|
|
16
16
|
|
|
17
|
-
**
|
|
17
|
+
**Note:** `sveld` supports Svelte 3, 4, and 5, but does not support Svelte 5-specific syntax or runes-only usage. Components must use traditional Svelte syntax (e.g., `export let` for props, not `$props()`).
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
@@ -125,6 +125,7 @@ export default class Button extends SvelteComponentTyped<
|
|
|
125
125
|
- [@type](#type)
|
|
126
126
|
- [@typedef](#typedef)
|
|
127
127
|
- [@slot](#slot)
|
|
128
|
+
- [Svelte 5 Snippet Compatibility](#svelte-5-snippet-compatibility)
|
|
128
129
|
- [@event](#event)
|
|
129
130
|
- [Context API](#context-api)
|
|
130
131
|
- [@restProps](#restprops)
|
|
@@ -534,6 +535,94 @@ Example:
|
|
|
534
535
|
</p>
|
|
535
536
|
```
|
|
536
537
|
|
|
538
|
+
#### Svelte 5 Snippet Compatibility
|
|
539
|
+
|
|
540
|
+
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.
|
|
541
|
+
|
|
542
|
+
For slots with props (e.g., `let:prop`), the generated type uses a Snippet-compatible signature:
|
|
543
|
+
|
|
544
|
+
```ts
|
|
545
|
+
slotName?: (this: void, ...args: [{ prop: PropType }]) => void;
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
For slots without props:
|
|
549
|
+
|
|
550
|
+
```ts
|
|
551
|
+
slotName?: (this: void) => void;
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
**Why this signature?**
|
|
555
|
+
|
|
556
|
+
- **`this: void`** – Ensures the snippet cannot be called with a `this` context, matching Svelte's internal enforcement that snippets are pure render functions
|
|
557
|
+
- **`...args: [Props]`** – Uses tuple spread for type-safe parameters. This accepts fixed-length tuples (like `[{ row: Row }]`) while rejecting array types (like `Props[]`), matching how Svelte's `Snippet<T>` type works
|
|
558
|
+
|
|
559
|
+
**Default slot (`children` prop):**
|
|
560
|
+
|
|
561
|
+
The default slot generates an optional `children` snippet prop:
|
|
562
|
+
|
|
563
|
+
```svelte
|
|
564
|
+
<!-- Component with default slot that passes props -->
|
|
565
|
+
<Dropdown {items} selectedId="1">
|
|
566
|
+
{#snippet children({ item, index })}
|
|
567
|
+
<span>{item.text} (#{index})</span>
|
|
568
|
+
{/snippet}
|
|
569
|
+
</Dropdown>
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
Generated types:
|
|
573
|
+
|
|
574
|
+
```ts
|
|
575
|
+
type DropdownProps = {
|
|
576
|
+
items: Item[];
|
|
577
|
+
selectedId?: string;
|
|
578
|
+
|
|
579
|
+
// Default slot as children snippet prop
|
|
580
|
+
children?: (this: void, ...args: [{ item: Item; index: number }]) => void;
|
|
581
|
+
};
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
**Named slots:**
|
|
585
|
+
|
|
586
|
+
```svelte
|
|
587
|
+
<!-- Using the generated types with Svelte 5 syntax -->
|
|
588
|
+
<DataTable headers={headers} rows={rows}>
|
|
589
|
+
{#snippet cell({ cell, row })}
|
|
590
|
+
{#if cell.key === 'actions'}
|
|
591
|
+
<Button on:click={() => handleAction(row)}>Edit</Button>
|
|
592
|
+
{:else}
|
|
593
|
+
{cell.value}
|
|
594
|
+
{/if}
|
|
595
|
+
{/snippet}
|
|
596
|
+
</DataTable>
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
The generated TypeScript definition includes both the snippet prop and the traditional slot definition:
|
|
600
|
+
|
|
601
|
+
```ts
|
|
602
|
+
type DataTableProps<Row> = {
|
|
603
|
+
// ... other props
|
|
604
|
+
|
|
605
|
+
// Snippet prop for Svelte 5 compatibility
|
|
606
|
+
cell?: (
|
|
607
|
+
this: void,
|
|
608
|
+
...args: [{ row: Row; cell: DataTableCell<Row>; rowIndex: number; cellIndex: number }]
|
|
609
|
+
) => void;
|
|
610
|
+
|
|
611
|
+
// Default slot as children prop
|
|
612
|
+
children?: (this: void) => void;
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
export default class DataTable<Row> extends SvelteComponentTyped<
|
|
616
|
+
DataTableProps<Row>,
|
|
617
|
+
{ /* events */ },
|
|
618
|
+
{
|
|
619
|
+
// Traditional slot definition (Svelte 3/4)
|
|
620
|
+
default: Record<string, never>;
|
|
621
|
+
cell: { row: Row; cell: DataTableCell<Row>; rowIndex: number; cellIndex: number };
|
|
622
|
+
}
|
|
623
|
+
> {}
|
|
624
|
+
```
|
|
625
|
+
|
|
537
626
|
### `@event`
|
|
538
627
|
|
|
539
628
|
Use the `@event` tag to type dispatched events. An event name is required and a description optional.
|
|
@@ -95,15 +95,33 @@ function genPropDef(def) {
|
|
|
95
95
|
});
|
|
96
96
|
// Generate snippet props for named slots (Svelte 5 compatibility)
|
|
97
97
|
// Skip default slots and slots that conflict with existing prop names
|
|
98
|
-
const
|
|
98
|
+
const named_snippet_props = (def.slots || [])
|
|
99
99
|
.filter((slot) => !slot.default && slot.name != null && !existingPropNames.has(slot.name))
|
|
100
100
|
.map((slot) => {
|
|
101
101
|
const slotName = slot.name;
|
|
102
102
|
const key = clampKey(slotName);
|
|
103
103
|
const description = slot.description ? `/** ${slot.description} */\n ` : "";
|
|
104
|
+
// Use Snippet-compatible type: (this: void, ...args: [Props]) => void for slots with props
|
|
105
|
+
// or (this: void) => void for slots without props
|
|
106
|
+
const hasSlotProps = slot.slot_props && slot.slot_props !== "Record<string, never>";
|
|
107
|
+
const snippetType = hasSlotProps ? `(this: void, ...args: [${slot.slot_props}]) => void` : "(this: void) => void";
|
|
104
108
|
return `
|
|
105
|
-
${description}${key}?:
|
|
109
|
+
${description}${key}?: ${snippetType};`;
|
|
106
110
|
});
|
|
111
|
+
// Generate children snippet prop for default slot (Svelte 5 compatibility)
|
|
112
|
+
const default_slot = (def.slots || []).find((slot) => slot.default || slot.name === null);
|
|
113
|
+
const children_snippet_prop = default_slot
|
|
114
|
+
? (() => {
|
|
115
|
+
const description = default_slot.description ? `/** ${default_slot.description} */\n ` : "";
|
|
116
|
+
const hasSlotProps = default_slot.slot_props && default_slot.slot_props !== "Record<string, never>";
|
|
117
|
+
const snippetType = hasSlotProps
|
|
118
|
+
? `(this: void, ...args: [${default_slot.slot_props}]) => void`
|
|
119
|
+
: "(this: void) => void";
|
|
120
|
+
return `
|
|
121
|
+
${description}children?: ${snippetType};`;
|
|
122
|
+
})()
|
|
123
|
+
: "";
|
|
124
|
+
const snippet_props = [...named_snippet_props, children_snippet_prop].filter(Boolean);
|
|
107
125
|
const props = [...initial_props, ...snippet_props].join("\n");
|
|
108
126
|
const props_name = `${def.moduleName}Props`;
|
|
109
127
|
let prop_def = EMPTY_STR;
|